[FL-3666] NFC API improvements (#3214)

* drivers: expose st25r3916 driver API
* nfc poller: add start with custom callback
* mf classic: rework sync API with poller custom start
* mf ultralight: rework sync API with poller custom start
* iso14443_3a poller: remove unused col res state
* nfc: rework nfc poller custom start
* mf ultralight: rename sync API
* mf classic: rename sync API
* iso14443-3a: rename sync API
* nfc: remove async prefix in internal functions
* nfc: expose internal API
* nfc: fix sync api include and docs
* targets: fix f18 build
* nfc: rework NfcGenericEventEx type
* nfc poller: add documentation
* iso14443-3a poller: add documentation
* felica poller: add documentation
* iso14443_3b poller: add documentation
* so14443_4a poller: add documentation
* iso14443_4b poller: add documentation
* iso15693 poller: add documentation
* slix poller: add documentation
* mf desfire poller: add documentation
* mf ultralight poller: fix API and add documentation
* mf classic poller: add documentation

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
gornekich
2023-11-15 17:32:45 +09:00
committed by GitHub
co-authored by あく
parent d0b9a3a4ae
commit c00776ca22
62 changed files with 1708 additions and 719 deletions
@@ -85,7 +85,7 @@ NfcCommand mf_classic_poller_handler_detect_type(MfClassicPoller* instance) {
iso14443_3a_copy(
instance->data->iso14443_3a_data,
iso14443_3a_poller_get_data(instance->iso14443_3a_poller));
MfClassicError error = mf_classic_async_get_nt(instance, 254, MfClassicKeyTypeA, NULL);
MfClassicError error = mf_classic_poller_get_nt(instance, 254, MfClassicKeyTypeA, NULL);
if(error == MfClassicErrorNone) {
instance->data->type = MfClassicType4k;
instance->state = MfClassicPollerStateStart;
@@ -95,7 +95,7 @@ NfcCommand mf_classic_poller_handler_detect_type(MfClassicPoller* instance) {
instance->current_type_check = MfClassicType1k;
}
} else if(instance->current_type_check == MfClassicType1k) {
MfClassicError error = mf_classic_async_get_nt(instance, 62, MfClassicKeyTypeA, NULL);
MfClassicError error = mf_classic_poller_get_nt(instance, 62, MfClassicKeyTypeA, NULL);
if(error == MfClassicErrorNone) {
instance->data->type = MfClassicType1k;
FURI_LOG_D(TAG, "1K detected");
@@ -234,7 +234,7 @@ NfcCommand mf_classic_poller_handler_read_block(MfClassicPoller* instance) {
do {
// Authenticate to sector
error = mf_classic_async_auth(
error = mf_classic_poller_auth(
instance, write_ctx->current_block, auth_key, write_ctx->key_type_read, NULL);
if(error != MfClassicErrorNone) {
FURI_LOG_D(TAG, "Failed to auth to block %d", write_ctx->current_block);
@@ -243,8 +243,8 @@ NfcCommand mf_classic_poller_handler_read_block(MfClassicPoller* instance) {
}
// Read block from tag
error =
mf_classic_async_read_block(instance, write_ctx->current_block, &write_ctx->tag_block);
error = mf_classic_poller_read_block(
instance, write_ctx->current_block, &write_ctx->tag_block);
if(error != MfClassicErrorNone) {
FURI_LOG_D(TAG, "Failed to read block %d", write_ctx->current_block);
instance->state = MfClassicPollerStateFail;
@@ -252,11 +252,11 @@ NfcCommand mf_classic_poller_handler_read_block(MfClassicPoller* instance) {
}
if(write_ctx->is_value_block) {
mf_classic_async_halt(instance);
mf_classic_poller_halt(instance);
instance->state = MfClassicPollerStateWriteValueBlock;
} else {
if(write_ctx->need_halt_before_write) {
mf_classic_async_halt(instance);
mf_classic_poller_halt(instance);
}
instance->state = MfClassicPollerStateWriteBlock;
}
@@ -292,7 +292,7 @@ NfcCommand mf_classic_poller_handler_write_block(MfClassicPoller* instance) {
// Reauth if necessary
if(write_ctx->need_halt_before_write) {
error = mf_classic_async_auth(
error = mf_classic_poller_auth(
instance, write_ctx->current_block, auth_key, write_ctx->key_type_write, NULL);
if(error != MfClassicErrorNone) {
FURI_LOG_D(
@@ -303,7 +303,7 @@ NfcCommand mf_classic_poller_handler_write_block(MfClassicPoller* instance) {
}
// Write block
error = mf_classic_async_write_block(
error = mf_classic_poller_write_block(
instance,
write_ctx->current_block,
&instance->mfc_event_data.write_block_data.write_block);
@@ -315,7 +315,7 @@ NfcCommand mf_classic_poller_handler_write_block(MfClassicPoller* instance) {
} while(false);
mf_classic_async_halt(instance);
mf_classic_poller_halt(instance);
write_ctx->current_block++;
instance->state = MfClassicPollerStateCheckWriteConditions;
@@ -403,18 +403,18 @@ NfcCommand mf_classic_poller_handler_write_value_block(MfClassicPoller* instance
&write_ctx->sec_tr.key_b;
MfClassicError error =
mf_classic_async_auth(instance, write_ctx->current_block, key, auth_key_type, NULL);
mf_classic_poller_auth(instance, write_ctx->current_block, key, auth_key_type, NULL);
if(error != MfClassicErrorNone) break;
error = mf_classic_async_value_cmd(instance, write_ctx->current_block, value_cmd, diff);
error = mf_classic_poller_value_cmd(instance, write_ctx->current_block, value_cmd, diff);
if(error != MfClassicErrorNone) break;
error = mf_classic_async_value_transfer(instance, write_ctx->current_block);
error = mf_classic_poller_value_transfer(instance, write_ctx->current_block);
if(error != MfClassicErrorNone) break;
} while(false);
mf_classic_async_halt(instance);
mf_classic_poller_halt(instance);
write_ctx->is_value_block = false;
write_ctx->current_block++;
instance->state = MfClassicPollerStateCheckWriteConditions;
@@ -462,7 +462,7 @@ NfcCommand mf_classic_poller_handler_request_read_sector_blocks(MfClassicPoller*
sec_read_ctx->current_block,
sec_read_ctx->key_type == MfClassicKeyTypeA ? 'A' : 'B',
key);
error = mf_classic_async_auth(
error = mf_classic_poller_auth(
instance,
sec_read_ctx->current_block,
&sec_read_ctx->key,
@@ -481,7 +481,7 @@ NfcCommand mf_classic_poller_handler_request_read_sector_blocks(MfClassicPoller*
FURI_LOG_D(TAG, "Reading block %d", sec_read_ctx->current_block);
MfClassicBlock read_block = {};
error = mf_classic_async_read_block(instance, sec_read_ctx->current_block, &read_block);
error = mf_classic_poller_read_block(instance, sec_read_ctx->current_block, &read_block);
if(error == MfClassicErrorNone) {
mf_classic_set_block_read(instance->data, sec_read_ctx->current_block, &read_block);
if(sec_read_ctx->key_type == MfClassicKeyTypeA) {
@@ -489,7 +489,7 @@ NfcCommand mf_classic_poller_handler_request_read_sector_blocks(MfClassicPoller*
instance, sec_read_ctx->current_block, &read_block);
}
} else {
mf_classic_async_halt(instance);
mf_classic_poller_halt(instance);
sec_read_ctx->auth_passed = false;
}
} while(false);
@@ -497,7 +497,7 @@ NfcCommand mf_classic_poller_handler_request_read_sector_blocks(MfClassicPoller*
uint8_t sec_tr_num = mf_classic_get_sector_trailer_num_by_sector(sec_read_ctx->current_sector);
sec_read_ctx->current_block++;
if(sec_read_ctx->current_block > sec_tr_num) {
mf_classic_async_halt(instance);
mf_classic_poller_halt(instance);
instance->state = MfClassicPollerStateRequestReadSector;
}
@@ -532,7 +532,7 @@ NfcCommand mf_classic_poller_handler_auth_a(MfClassicPoller* instance) {
uint64_t key = nfc_util_bytes2num(dict_attack_ctx->current_key.data, sizeof(MfClassicKey));
FURI_LOG_D(TAG, "Auth to block %d with key A: %06llx", block, key);
MfClassicError error = mf_classic_async_auth(
MfClassicError error = mf_classic_poller_auth(
instance, block, &dict_attack_ctx->current_key, MfClassicKeyTypeA, NULL);
if(error == MfClassicErrorNone) {
FURI_LOG_I(TAG, "Key A found");
@@ -545,7 +545,7 @@ NfcCommand mf_classic_poller_handler_auth_a(MfClassicPoller* instance) {
dict_attack_ctx->auth_passed = true;
instance->state = MfClassicPollerStateReadSector;
} else {
mf_classic_async_halt(instance);
mf_classic_poller_halt(instance);
instance->state = MfClassicPollerStateAuthKeyB;
}
}
@@ -570,7 +570,7 @@ NfcCommand mf_classic_poller_handler_auth_b(MfClassicPoller* instance) {
uint64_t key = nfc_util_bytes2num(dict_attack_ctx->current_key.data, sizeof(MfClassicKey));
FURI_LOG_D(TAG, "Auth to block %d with key B: %06llx", block, key);
MfClassicError error = mf_classic_async_auth(
MfClassicError error = mf_classic_poller_auth(
instance, block, &dict_attack_ctx->current_key, MfClassicKeyTypeB, NULL);
if(error == MfClassicErrorNone) {
FURI_LOG_I(TAG, "Key B found");
@@ -584,7 +584,7 @@ NfcCommand mf_classic_poller_handler_auth_b(MfClassicPoller* instance) {
dict_attack_ctx->auth_passed = true;
instance->state = MfClassicPollerStateReadSector;
} else {
mf_classic_async_halt(instance);
mf_classic_poller_halt(instance);
instance->state = MfClassicPollerStateRequestKey;
}
}
@@ -621,7 +621,7 @@ NfcCommand mf_classic_poller_handler_read_sector(MfClassicPoller* instance) {
if(mf_classic_is_block_read(instance->data, block_num)) break;
if(!dict_attack_ctx->auth_passed) {
error = mf_classic_async_auth(
error = mf_classic_poller_auth(
instance,
block_num,
&dict_attack_ctx->current_key,
@@ -635,10 +635,10 @@ NfcCommand mf_classic_poller_handler_read_sector(MfClassicPoller* instance) {
}
FURI_LOG_D(TAG, "Reading block %d", block_num);
error = mf_classic_async_read_block(instance, block_num, &block);
error = mf_classic_poller_read_block(instance, block_num, &block);
if(error != MfClassicErrorNone) {
mf_classic_async_halt(instance);
mf_classic_poller_halt(instance);
dict_attack_ctx->auth_passed = false;
FURI_LOG_D(TAG, "Failed to read block %d", block_num);
} else {
@@ -655,7 +655,7 @@ NfcCommand mf_classic_poller_handler_read_sector(MfClassicPoller* instance) {
if(dict_attack_ctx->current_block > sec_tr_block_num) {
mf_classic_poller_handle_data_update(instance);
mf_classic_async_halt(instance);
mf_classic_poller_halt(instance);
dict_attack_ctx->auth_passed = false;
if(dict_attack_ctx->current_sector == instance->sectors_total) {
@@ -713,7 +713,7 @@ NfcCommand mf_classic_poller_handler_key_reuse_auth_key_a(MfClassicPoller* insta
uint64_t key = nfc_util_bytes2num(dict_attack_ctx->current_key.data, sizeof(MfClassicKey));
FURI_LOG_D(TAG, "Key attack auth to block %d with key A: %06llx", block, key);
MfClassicError error = mf_classic_async_auth(
MfClassicError error = mf_classic_poller_auth(
instance, block, &dict_attack_ctx->current_key, MfClassicKeyTypeA, NULL);
if(error == MfClassicErrorNone) {
FURI_LOG_I(TAG, "Key A found");
@@ -726,7 +726,7 @@ NfcCommand mf_classic_poller_handler_key_reuse_auth_key_a(MfClassicPoller* insta
dict_attack_ctx->auth_passed = true;
instance->state = MfClassicPollerStateKeyReuseReadSector;
} else {
mf_classic_async_halt(instance);
mf_classic_poller_halt(instance);
dict_attack_ctx->auth_passed = false;
instance->state = MfClassicPollerStateKeyReuseStart;
}
@@ -748,7 +748,7 @@ NfcCommand mf_classic_poller_handler_key_reuse_auth_key_b(MfClassicPoller* insta
uint64_t key = nfc_util_bytes2num(dict_attack_ctx->current_key.data, sizeof(MfClassicKey));
FURI_LOG_D(TAG, "Key attack auth to block %d with key B: %06llx", block, key);
MfClassicError error = mf_classic_async_auth(
MfClassicError error = mf_classic_poller_auth(
instance, block, &dict_attack_ctx->current_key, MfClassicKeyTypeB, NULL);
if(error == MfClassicErrorNone) {
FURI_LOG_I(TAG, "Key B found");
@@ -762,7 +762,7 @@ NfcCommand mf_classic_poller_handler_key_reuse_auth_key_b(MfClassicPoller* insta
dict_attack_ctx->auth_passed = true;
instance->state = MfClassicPollerStateKeyReuseReadSector;
} else {
mf_classic_async_halt(instance);
mf_classic_poller_halt(instance);
dict_attack_ctx->auth_passed = false;
instance->state = MfClassicPollerStateKeyReuseStart;
}
@@ -783,7 +783,7 @@ NfcCommand mf_classic_poller_handler_key_reuse_read_sector(MfClassicPoller* inst
if(mf_classic_is_block_read(instance->data, block_num)) break;
if(!dict_attack_ctx->auth_passed) {
error = mf_classic_async_auth(
error = mf_classic_poller_auth(
instance,
block_num,
&dict_attack_ctx->current_key,
@@ -796,10 +796,10 @@ NfcCommand mf_classic_poller_handler_key_reuse_read_sector(MfClassicPoller* inst
}
FURI_LOG_D(TAG, "Reading block %d", block_num);
error = mf_classic_async_read_block(instance, block_num, &block);
error = mf_classic_poller_read_block(instance, block_num, &block);
if(error != MfClassicErrorNone) {
mf_classic_async_halt(instance);
mf_classic_poller_halt(instance);
dict_attack_ctx->auth_passed = false;
FURI_LOG_D(TAG, "Failed to read block %d", block_num);
} else {
@@ -814,7 +814,7 @@ NfcCommand mf_classic_poller_handler_key_reuse_read_sector(MfClassicPoller* inst
mf_classic_get_sector_trailer_num_by_sector(dict_attack_ctx->reuse_key_sector);
dict_attack_ctx->current_block++;
if(dict_attack_ctx->current_block > sec_tr_block_num) {
mf_classic_async_halt(instance);
mf_classic_poller_halt(instance);
dict_attack_ctx->auth_passed = false;
mf_classic_poller_handle_data_update(instance);
+226 -55
View File
@@ -7,103 +7,274 @@
extern "C" {
#endif
/**
* @brief MfClassicPoller opaque type definition.
*/
typedef struct MfClassicPoller MfClassicPoller;
/**
* @brief Enumeration of possible MfClassic poller event types.
*/
typedef enum {
// Start event
MfClassicPollerEventTypeRequestMode,
MfClassicPollerEventTypeRequestMode, /**< Poller requests to fill the mode. */
// Read with key cache events
MfClassicPollerEventTypeRequestReadSector,
MfClassicPollerEventTypeRequestReadSector, /**< Poller requests data to read sector. */
// Write events
MfClassicPollerEventTypeRequestSectorTrailer,
MfClassicPollerEventTypeRequestWriteBlock,
MfClassicPollerEventTypeRequestSectorTrailer, /**< Poller requests sector trailer for writing block. */
MfClassicPollerEventTypeRequestWriteBlock, /**< Poller requests data to write block. */
// Dictionary attack events
MfClassicPollerEventTypeRequestKey,
MfClassicPollerEventTypeNextSector,
MfClassicPollerEventTypeDataUpdate,
MfClassicPollerEventTypeFoundKeyA,
MfClassicPollerEventTypeFoundKeyB,
MfClassicPollerEventTypeCardNotDetected,
MfClassicPollerEventTypeKeyAttackStart,
MfClassicPollerEventTypeKeyAttackStop,
MfClassicPollerEventTypeKeyAttackNextSector,
MfClassicPollerEventTypeRequestKey, /**< Poller requests key for sector authentication. */
MfClassicPollerEventTypeNextSector, /**< Poller switches to next sector during dictionary attack. */
MfClassicPollerEventTypeDataUpdate, /**< Poller updates data. */
MfClassicPollerEventTypeFoundKeyA, /**< Poller found key A. */
MfClassicPollerEventTypeFoundKeyB, /**< Poller found key B. */
MfClassicPollerEventTypeKeyAttackStart, /**< Poller starts key attack. */
MfClassicPollerEventTypeKeyAttackStop, /**< Poller stops key attack. */
MfClassicPollerEventTypeKeyAttackNextSector, /**< Poller switches to next sector during key attack. */
// Common events
MfClassicPollerEventTypeCardDetected,
MfClassicPollerEventTypeCardLost,
MfClassicPollerEventTypeSuccess,
MfClassicPollerEventTypeFail,
MfClassicPollerEventTypeCardDetected, /**< Poller detected card. */
MfClassicPollerEventTypeCardLost, /**< Poller lost card. */
MfClassicPollerEventTypeSuccess, /**< Poller succeeded. */
MfClassicPollerEventTypeFail, /**< Poller failed. */
} MfClassicPollerEventType;
/**
* @brief MfClassic poller mode.
*/
typedef enum {
MfClassicPollerModeRead,
MfClassicPollerModeWrite,
MfClassicPollerModeDictAttack,
MfClassicPollerModeRead, /**< Poller reading mode. */
MfClassicPollerModeWrite, /**< Poller writing mode. */
MfClassicPollerModeDictAttack, /**< Poller dictionary attack mode. */
} MfClassicPollerMode;
/**
* @brief MfClassic poller request mode event data.
*
* This instance of this structure must be filled on MfClassicPollerEventTypeRequestMode event.
*/
typedef struct {
MfClassicPollerMode mode;
const MfClassicData* data;
MfClassicPollerMode mode; /**< Mode to be used by poller. */
const MfClassicData* data; /**< Data to be used by poller. */
} MfClassicPollerEventDataRequestMode;
/**
* @brief MfClassic poller next sector event data.
*
* The instance of this structure is filled by poller and passed with
* MfClassicPollerEventTypeNextSector event.
*/
typedef struct {
uint8_t current_sector;
uint8_t current_sector; /**< Current sector number. */
} MfClassicPollerEventDataDictAttackNextSector;
/**
* @brief MfClassic poller update event data.
*
* The instance of this structure is filled by poller and passed with
* MfClassicPollerEventTypeDataUpdate event.
*/
typedef struct {
uint8_t sectors_read;
uint8_t keys_found;
uint8_t current_sector;
uint8_t sectors_read; /**< Number of sectors read. */
uint8_t keys_found; /**< Number of keys found. */
uint8_t current_sector; /**< Current sector number. */
} MfClassicPollerEventDataUpdate;
/**
* @brief MfClassic poller key request event data.
*
* The instance of this structure must be filled on MfClassicPollerEventTypeRequestKey event.
*/
typedef struct {
MfClassicKey key;
bool key_provided;
MfClassicKey key; /**< Key to be used by poller. */
bool key_provided; /**< Flag indicating if key is provided. */
} MfClassicPollerEventDataKeyRequest;
/**
* @brief MfClassic poller read sector request event data.
*
* The instance of this structure must be filled on MfClassicPollerEventTypeRequestReadSector event.
*/
typedef struct {
uint8_t sector_num;
MfClassicKey key;
MfClassicKeyType key_type;
bool key_provided;
uint8_t sector_num; /**< Sector number to be read. */
MfClassicKey key; /**< Key to be used by poller. */
MfClassicKeyType key_type; /**< Key type to be used by poller. */
bool key_provided; /**< Flag indicating if key is provided. */
} MfClassicPollerEventDataReadSectorRequest;
/**
* @brief MfClassic poller sector trailer request event data.
*
* The instance of this structure must be filled on MfClassicPollerEventTypeRequestSectorTrailer event.
*/
typedef struct {
uint8_t sector_num;
MfClassicBlock sector_trailer;
bool sector_trailer_provided;
uint8_t sector_num; /**< Sector number to be read. */
MfClassicBlock sector_trailer; /**< Sector trailer to be used by poller. */
bool sector_trailer_provided; /**< Flag indicating if sector trailer is provided. */
} MfClassicPollerEventDataSectorTrailerRequest;
/**
* @brief MfClassic poller write block request event data.
*
* The instance of this structure must be filled on MfClassicPollerEventTypeRequestWriteBlock event.
*/
typedef struct {
uint8_t block_num;
MfClassicBlock write_block;
bool write_block_provided;
uint8_t block_num; /**< Block number to be written. */
MfClassicBlock write_block; /**< Block to be written. */
bool write_block_provided; /**< Flag indicating if block is provided. */
} MfClassicPollerEventDataWriteBlockRequest;
/**
* @brief MfClassic poller key attack event data.
*
* The instance of this structure is filled by poller and passed with
* MfClassicPollerEventTypeKeyAttackNextSector event.
*/
typedef struct {
uint8_t current_sector;
uint8_t current_sector; /**< Current sector number. */
} MfClassicPollerEventKeyAttackData;
/**
* @brief MfClassic poller event data.
*/
typedef union {
MfClassicError error;
MfClassicPollerEventDataRequestMode poller_mode;
MfClassicPollerEventDataDictAttackNextSector next_sector_data;
MfClassicPollerEventDataKeyRequest key_request_data;
MfClassicPollerEventDataUpdate data_update;
MfClassicPollerEventDataReadSectorRequest read_sector_request_data;
MfClassicPollerEventKeyAttackData key_attack_data;
MfClassicPollerEventDataSectorTrailerRequest sec_tr_data;
MfClassicPollerEventDataWriteBlockRequest write_block_data;
MfClassicError error; /**< Error code on MfClassicPollerEventTypeFail event. */
MfClassicPollerEventDataRequestMode poller_mode; /**< Poller mode context. */
MfClassicPollerEventDataDictAttackNextSector next_sector_data; /**< Next sector context. */
MfClassicPollerEventDataKeyRequest key_request_data; /**< Key request context. */
MfClassicPollerEventDataUpdate data_update; /**< Data update context. */
MfClassicPollerEventDataReadSectorRequest
read_sector_request_data; /**< Read sector request context. */
MfClassicPollerEventKeyAttackData key_attack_data; /**< Key attack context. */
MfClassicPollerEventDataSectorTrailerRequest sec_tr_data; /**< Sector trailer request context. */
MfClassicPollerEventDataWriteBlockRequest write_block_data; /**< Write block request context. */
} MfClassicPollerEventData;
/**
* @brief MfClassic poller event.
*
* Upon emission of an event, an instance of this struct will be passed to the callback.
*/
typedef struct {
MfClassicPollerEventType type;
MfClassicPollerEventData* data;
MfClassicPollerEventType type; /**< Event type. */
MfClassicPollerEventData* data; /**< Pointer to event specific data. */
} MfClassicPollerEvent;
/**
* @brief Collect tag nonce during authentication.
*
* Must ONLY be used inside the callback function.
*
* Starts authentication procedure and collects tag nonce.
*
* @param[in, out] instance pointer to the instance to be used in the transaction.
* @param[in] block_num block number for authentication.
* @param[in] key_type key type to be used for authentication.
* @param[out] nt pointer to the MfClassicNt structure to be filled with nonce data.
* @return MfClassicErrorNone on success, an error code on failure.
*/
MfClassicError mf_classic_poller_get_nt(
MfClassicPoller* instance,
uint8_t block_num,
MfClassicKeyType key_type,
MfClassicNt* nt);
/**
* @brief Perform authentication.
*
* Must ONLY be used inside the callback function.
*
* Perform authentication as specified in Mf Classic protocol. Initialize crypto state for futher
* communication with the tag.
*
* @param[in, out] instance pointer to the instance to be used in the transaction.
* @param[in] block_num block number for authentication.
* @param[in] key key to be used for authentication.
* @param[in] key_type key type to be used for authentication.
* @param[out] data pointer to MfClassicAuthContext structure to be filled with authentication data.
* @return MfClassicErrorNone on success, an error code on failure.
*/
MfClassicError mf_classic_poller_auth(
MfClassicPoller* instance,
uint8_t block_num,
MfClassicKey* key,
MfClassicKeyType key_type,
MfClassicAuthContext* data);
/**
* @brief Halt the tag.
*
* Must ONLY be used inside the callback function.
*
* Halt the tag and reset crypto state of the poller.
*
* @param[in, out] instance pointer to the instance to be used in the transaction.
* @return MfClassicErrorNone on success, an error code on failure.
*/
MfClassicError mf_classic_poller_halt(MfClassicPoller* instance);
/**
* @brief Read block from tag.
*
* Must ONLY be used inside the callback function.
*
* @param[in, out] instance pointer to the instance to be used in the transaction.
* @param[in] block_num block number to be read.
* @param[out] data pointer to the MfClassicBlock structure to be filled with block data.
* @return MfClassicErrorNone on success, an error code on failure.
*/
MfClassicError mf_classic_poller_read_block(
MfClassicPoller* instance,
uint8_t block_num,
MfClassicBlock* data);
/**
* @brief Write block to tag.
*
* Must ONLY be used inside the callback function.
*
* @param[in, out] instance pointer to the instance to be used in the transaction.
* @param[in] block_num block number to be written.
* @param[in] data pointer to the MfClassicBlock structure to be written.
* @return MfClassicErrorNone on success, an error code on failure.
*/
MfClassicError mf_classic_poller_write_block(
MfClassicPoller* instance,
uint8_t block_num,
MfClassicBlock* data);
/**
* @brief Perform value command on tag.
*
* Must ONLY be used inside the callback function.
*
* Perform Increment, Decrement or Restore command on tag. The result is stored in internal transfer
* block of the tag. Use mf_classic_poller_value_transfer to transfer the result to the tag.
*
* @param[in, out] instance pointer to the instance to be used in the transaction.
* @param[in] block_num block number to be used for value command.
* @param[in] cmd value command to be performed.
* @param[in] data value to be used for value command.
* @return MfClassicErrorNone on success, an error code on failure.
*/
MfClassicError mf_classic_poller_value_cmd(
MfClassicPoller* instance,
uint8_t block_num,
MfClassicValueCommand cmd,
int32_t data);
/**
* @brief Transfer internal transfer block to tag.
*
* Must ONLY be used inside the callback function.
*
* Transfer internal transfer block to tag. The block is filled by mf_classic_poller_value_cmd.
*
* @param[in, out] instance pointer to the instance to be used in the transaction.
* @param[in] block_num block number to be used for value command.
* @return MfClassicErrorNone on success, an error code on failure.
*/
MfClassicError mf_classic_poller_value_transfer(MfClassicPoller* instance, uint8_t block_num);
#ifdef __cplusplus
}
#endif
@@ -33,7 +33,7 @@ MfClassicError mf_classic_process_error(Iso14443_3aError error) {
return ret;
}
MfClassicError mf_classic_async_get_nt(
MfClassicError mf_classic_poller_get_nt(
MfClassicPoller* instance,
uint8_t block_num,
MfClassicKeyType key_type,
@@ -69,7 +69,7 @@ MfClassicError mf_classic_async_get_nt(
return ret;
}
MfClassicError mf_classic_async_auth(
MfClassicError mf_classic_poller_auth(
MfClassicPoller* instance,
uint8_t block_num,
MfClassicKey* key,
@@ -84,7 +84,7 @@ MfClassicError mf_classic_async_auth(
iso14443_3a_poller_get_data(instance->iso14443_3a_poller));
MfClassicNt nt = {};
ret = mf_classic_async_get_nt(instance, block_num, key_type, &nt);
ret = mf_classic_poller_get_nt(instance, block_num, key_type, &nt);
if(ret != MfClassicErrorNone) break;
if(data) {
data->nt = nt;
@@ -130,7 +130,7 @@ MfClassicError mf_classic_async_auth(
return ret;
}
MfClassicError mf_classic_async_halt(MfClassicPoller* instance) {
MfClassicError mf_classic_poller_halt(MfClassicPoller* instance) {
MfClassicError ret = MfClassicErrorNone;
Iso14443_3aError error = Iso14443_3aErrorNone;
@@ -158,7 +158,7 @@ MfClassicError mf_classic_async_halt(MfClassicPoller* instance) {
return ret;
}
MfClassicError mf_classic_async_read_block(
MfClassicError mf_classic_poller_read_block(
MfClassicPoller* instance,
uint8_t block_num,
MfClassicBlock* data) {
@@ -204,7 +204,7 @@ MfClassicError mf_classic_async_read_block(
return ret;
}
MfClassicError mf_classic_async_write_block(
MfClassicError mf_classic_poller_write_block(
MfClassicPoller* instance,
uint8_t block_num,
MfClassicBlock* data) {
@@ -275,7 +275,7 @@ MfClassicError mf_classic_async_write_block(
return ret;
}
MfClassicError mf_classic_async_value_cmd(
MfClassicError mf_classic_poller_value_cmd(
MfClassicPoller* instance,
uint8_t block_num,
MfClassicValueCommand cmd,
@@ -345,7 +345,7 @@ MfClassicError mf_classic_async_value_cmd(
return ret;
}
MfClassicError mf_classic_async_value_transfer(MfClassicPoller* instance, uint8_t block_num) {
MfClassicError mf_classic_poller_value_transfer(MfClassicPoller* instance, uint8_t block_num) {
MfClassicError ret = MfClassicErrorNone;
Iso14443_3aError error = Iso14443_3aErrorNone;
@@ -169,37 +169,6 @@ MfClassicPoller* mf_classic_poller_alloc(Iso14443_3aPoller* iso14443_3a_poller);
void mf_classic_poller_free(MfClassicPoller* instance);
MfClassicError mf_classic_async_get_nt(
MfClassicPoller* instance,
uint8_t block_num,
MfClassicKeyType key_type,
MfClassicNt* nt);
MfClassicError mf_classic_async_auth(
MfClassicPoller* instance,
uint8_t block_num,
MfClassicKey* key,
MfClassicKeyType key_type,
MfClassicAuthContext* data);
MfClassicError mf_classic_async_halt(MfClassicPoller* instance);
MfClassicError
mf_classic_async_read_block(MfClassicPoller* instance, uint8_t block_num, MfClassicBlock* data);
MfClassicError mf_classic_async_write_block(
MfClassicPoller* instance,
uint8_t block_num,
MfClassicBlock* data);
MfClassicError mf_classic_async_value_cmd(
MfClassicPoller* instance,
uint8_t block_num,
MfClassicValueCommand cmd,
int32_t data);
MfClassicError mf_classic_async_value_transfer(MfClassicPoller* instance, uint8_t block_num);
#ifdef __cplusplus
}
#endif
@@ -1,3 +1,4 @@
#include "mf_classic_poller_sync.h"
#include "mf_classic_poller_i.h"
#include <nfc/nfc_poller.h>
@@ -32,7 +33,7 @@ typedef MfClassicError (
static MfClassicError mf_classic_poller_collect_nt_handler(
MfClassicPoller* poller,
MfClassicPollerContextData* data) {
return mf_classic_async_get_nt(
return mf_classic_poller_get_nt(
poller,
data->collect_nt_context.block,
data->collect_nt_context.key_type,
@@ -41,7 +42,7 @@ static MfClassicError mf_classic_poller_collect_nt_handler(
static MfClassicError
mf_classic_poller_auth_handler(MfClassicPoller* poller, MfClassicPollerContextData* data) {
return mf_classic_async_auth(
return mf_classic_poller_auth(
poller,
data->auth_context.block_num,
&data->auth_context.key,
@@ -55,7 +56,7 @@ static MfClassicError mf_classic_poller_read_block_handler(
MfClassicError error = MfClassicErrorNone;
do {
error = mf_classic_async_auth(
error = mf_classic_poller_auth(
poller,
data->read_block_context.block_num,
&data->read_block_context.key,
@@ -63,11 +64,11 @@ static MfClassicError mf_classic_poller_read_block_handler(
NULL);
if(error != MfClassicErrorNone) break;
error = mf_classic_async_read_block(
error = mf_classic_poller_read_block(
poller, data->read_block_context.block_num, &data->read_block_context.block);
if(error != MfClassicErrorNone) break;
error = mf_classic_async_halt(poller);
error = mf_classic_poller_halt(poller);
if(error != MfClassicErrorNone) break;
} while(false);
@@ -81,7 +82,7 @@ static MfClassicError mf_classic_poller_write_block_handler(
MfClassicError error = MfClassicErrorNone;
do {
error = mf_classic_async_auth(
error = mf_classic_poller_auth(
poller,
data->read_block_context.block_num,
&data->read_block_context.key,
@@ -89,11 +90,11 @@ static MfClassicError mf_classic_poller_write_block_handler(
NULL);
if(error != MfClassicErrorNone) break;
error = mf_classic_async_write_block(
error = mf_classic_poller_write_block(
poller, data->write_block_context.block_num, &data->write_block_context.block);
if(error != MfClassicErrorNone) break;
error = mf_classic_async_halt(poller);
error = mf_classic_poller_halt(poller);
if(error != MfClassicErrorNone) break;
} while(false);
@@ -107,7 +108,7 @@ static MfClassicError mf_classic_poller_read_value_handler(
MfClassicError error = MfClassicErrorNone;
do {
error = mf_classic_async_auth(
error = mf_classic_poller_auth(
poller,
data->read_value_context.block_num,
&data->read_value_context.key,
@@ -116,7 +117,7 @@ static MfClassicError mf_classic_poller_read_value_handler(
if(error != MfClassicErrorNone) break;
MfClassicBlock block = {};
error = mf_classic_async_read_block(poller, data->read_value_context.block_num, &block);
error = mf_classic_poller_read_block(poller, data->read_value_context.block_num, &block);
if(error != MfClassicErrorNone) break;
if(!mf_classic_block_to_value(&block, &data->read_value_context.value, NULL)) {
@@ -124,7 +125,7 @@ static MfClassicError mf_classic_poller_read_value_handler(
break;
}
error = mf_classic_async_halt(poller);
error = mf_classic_poller_halt(poller);
if(error != MfClassicErrorNone) break;
} while(false);
@@ -138,7 +139,7 @@ static MfClassicError mf_classic_poller_change_value_handler(
MfClassicError error = MfClassicErrorNone;
do {
error = mf_classic_async_auth(
error = mf_classic_poller_auth(
poller,
data->change_value_context.block_num,
&data->change_value_context.key,
@@ -146,21 +147,21 @@ static MfClassicError mf_classic_poller_change_value_handler(
NULL);
if(error != MfClassicErrorNone) break;
error = mf_classic_async_value_cmd(
error = mf_classic_poller_value_cmd(
poller,
data->change_value_context.block_num,
data->change_value_context.value_cmd,
data->change_value_context.data);
if(error != MfClassicErrorNone) break;
error = mf_classic_async_value_transfer(poller, data->change_value_context.block_num);
error = mf_classic_poller_value_transfer(poller, data->change_value_context.block_num);
if(error != MfClassicErrorNone) break;
MfClassicBlock block = {};
error = mf_classic_async_read_block(poller, data->change_value_context.block_num, &block);
error = mf_classic_poller_read_block(poller, data->change_value_context.block_num, &block);
if(error != MfClassicErrorNone) break;
error = mf_classic_async_halt(poller);
error = mf_classic_poller_halt(poller);
if(error != MfClassicErrorNone) break;
if(!mf_classic_block_to_value(&block, &data->change_value_context.new_value, NULL)) {
@@ -182,16 +183,14 @@ static const MfClassicPollerCmdHandler mf_classic_poller_cmd_handlers[MfClassicP
[MfClassicPollerCmdTypeChangeValue] = mf_classic_poller_change_value_handler,
};
static NfcCommand mf_classic_poller_cmd_callback(NfcGenericEvent event, void* context) {
furi_assert(event.instance);
furi_assert(event.protocol == NfcProtocolIso14443_3a);
furi_assert(event.event_data);
static NfcCommand mf_classic_poller_cmd_callback(NfcGenericEventEx event, void* context) {
furi_assert(event.poller);
furi_assert(event.parent_event_data);
furi_assert(context);
MfClassicPollerContext* poller_context = context;
Iso14443_3aPollerEvent* iso14443_3a_event = event.event_data;
Iso14443_3aPoller* iso14443_3a_poller = event.instance;
MfClassicPoller* mfc_poller = mf_classic_poller_alloc(iso14443_3a_poller);
Iso14443_3aPollerEvent* iso14443_3a_event = event.parent_event_data;
MfClassicPoller* mfc_poller = event.poller;
if(iso14443_3a_event->type == Iso14443_3aPollerEventTypeReady) {
poller_context->error = mf_classic_poller_cmd_handlers[poller_context->cmd_type](
@@ -202,8 +201,6 @@ static NfcCommand mf_classic_poller_cmd_callback(NfcGenericEvent event, void* co
furi_thread_flags_set(poller_context->thread_id, MF_CLASSIC_POLLER_COMPLETE_EVENT);
mf_classic_poller_free(mfc_poller);
return NfcCommandStop;
}
@@ -212,8 +209,8 @@ static MfClassicError mf_classic_poller_cmd_execute(Nfc* nfc, MfClassicPollerCon
poller_ctx->thread_id = furi_thread_get_current_id();
NfcPoller* poller = nfc_poller_alloc(nfc, NfcProtocolIso14443_3a);
nfc_poller_start(poller, mf_classic_poller_cmd_callback, poller_ctx);
NfcPoller* poller = nfc_poller_alloc(nfc, NfcProtocolMfClassic);
nfc_poller_start_ex(poller, mf_classic_poller_cmd_callback, poller_ctx);
furi_thread_flags_wait(MF_CLASSIC_POLLER_COMPLETE_EVENT, FuriFlagWaitAny, FuriWaitForever);
furi_thread_flags_clear(MF_CLASSIC_POLLER_COMPLETE_EVENT);
@@ -223,7 +220,7 @@ static MfClassicError mf_classic_poller_cmd_execute(Nfc* nfc, MfClassicPollerCon
return poller_ctx->error;
}
MfClassicError mf_classic_poller_collect_nt(
MfClassicError mf_classic_poller_sync_collect_nt(
Nfc* nfc,
uint8_t block_num,
MfClassicKeyType key_type,
@@ -247,7 +244,7 @@ MfClassicError mf_classic_poller_collect_nt(
return error;
}
MfClassicError mf_classic_poller_auth(
MfClassicError mf_classic_poller_sync_auth(
Nfc* nfc,
uint8_t block_num,
MfClassicKey* key,
@@ -274,7 +271,7 @@ MfClassicError mf_classic_poller_auth(
return error;
}
MfClassicError mf_classic_poller_read_block(
MfClassicError mf_classic_poller_sync_read_block(
Nfc* nfc,
uint8_t block_num,
MfClassicKey* key,
@@ -300,7 +297,7 @@ MfClassicError mf_classic_poller_read_block(
return error;
}
MfClassicError mf_classic_poller_write_block(
MfClassicError mf_classic_poller_sync_write_block(
Nfc* nfc,
uint8_t block_num,
MfClassicKey* key,
@@ -323,7 +320,7 @@ MfClassicError mf_classic_poller_write_block(
return error;
}
MfClassicError mf_classic_poller_read_value(
MfClassicError mf_classic_poller_sync_read_value(
Nfc* nfc,
uint8_t block_num,
MfClassicKey* key,
@@ -349,7 +346,7 @@ MfClassicError mf_classic_poller_read_value(
return error;
}
MfClassicError mf_classic_poller_change_value(
MfClassicError mf_classic_poller_sync_change_value(
Nfc* nfc,
uint8_t block_num,
MfClassicKey* key,
@@ -461,7 +458,7 @@ NfcCommand mf_classic_poller_read_callback(NfcGenericEvent event, void* context)
}
MfClassicError
mf_classic_poller_read(Nfc* nfc, const MfClassicDeviceKeys* keys, MfClassicData* data) {
mf_classic_poller_sync_read(Nfc* nfc, const MfClassicDeviceKeys* keys, MfClassicData* data) {
furi_assert(nfc);
furi_assert(keys);
furi_assert(data);
@@ -498,7 +495,7 @@ MfClassicError
return error;
}
MfClassicError mf_classic_poller_detect_type(Nfc* nfc, MfClassicType* type) {
MfClassicError mf_classic_poller_sync_detect_type(Nfc* nfc, MfClassicType* type) {
furi_assert(nfc);
furi_assert(type);
@@ -512,7 +509,7 @@ MfClassicError mf_classic_poller_detect_type(Nfc* nfc, MfClassicType* type) {
size_t i = 0;
for(i = 0; i < COUNT_OF(mf_classic_verify_block); i++) {
error = mf_classic_poller_collect_nt(
error = mf_classic_poller_sync_collect_nt(
nfc, mf_classic_verify_block[MfClassicTypeNum - i - 1], MfClassicKeyTypeA, NULL);
if(error == MfClassicErrorNone) {
*type = MfClassicTypeNum - i - 1;
@@ -7,41 +7,41 @@
extern "C" {
#endif
MfClassicError mf_classic_poller_collect_nt(
MfClassicError mf_classic_poller_sync_collect_nt(
Nfc* nfc,
uint8_t block_num,
MfClassicKeyType key_type,
MfClassicNt* nt);
MfClassicError mf_classic_poller_auth(
MfClassicError mf_classic_poller_sync_auth(
Nfc* nfc,
uint8_t block_num,
MfClassicKey* key,
MfClassicKeyType key_type,
MfClassicAuthContext* data);
MfClassicError mf_classic_poller_read_block(
MfClassicError mf_classic_poller_sync_read_block(
Nfc* nfc,
uint8_t block_num,
MfClassicKey* key,
MfClassicKeyType key_type,
MfClassicBlock* data);
MfClassicError mf_classic_poller_write_block(
MfClassicError mf_classic_poller_sync_write_block(
Nfc* nfc,
uint8_t block_num,
MfClassicKey* key,
MfClassicKeyType key_type,
MfClassicBlock* data);
MfClassicError mf_classic_poller_read_value(
MfClassicError mf_classic_poller_sync_read_value(
Nfc* nfc,
uint8_t block_num,
MfClassicKey* key,
MfClassicKeyType key_type,
int32_t* value);
MfClassicError mf_classic_poller_change_value(
MfClassicError mf_classic_poller_sync_change_value(
Nfc* nfc,
uint8_t block_num,
MfClassicKey* key,
@@ -49,10 +49,10 @@ MfClassicError mf_classic_poller_change_value(
int32_t data,
int32_t* new_value);
MfClassicError mf_classic_poller_detect_type(Nfc* nfc, MfClassicType* type);
MfClassicError mf_classic_poller_sync_detect_type(Nfc* nfc, MfClassicType* type);
MfClassicError
mf_classic_poller_read(Nfc* nfc, const MfClassicDeviceKeys* keys, MfClassicData* data);
mf_classic_poller_sync_read(Nfc* nfc, const MfClassicDeviceKeys* keys, MfClassicData* data);
#ifdef __cplusplus
}