Merge branch 'ofw_dev' into dev [ci skip]

This commit is contained in:
MX
2023-12-02 16:23:52 +03:00
11 changed files with 486 additions and 26 deletions

View File

@@ -108,28 +108,30 @@ Iso15693_3Error iso15693_3_poller_activate(Iso15693_3Poller* instance, Iso15693_
break;
}
// Read blocks: Optional command
simple_array_init(data->block_data, system_info->block_count * system_info->block_size);
ret = iso15693_3_poller_read_blocks(
instance,
simple_array_get_data(data->block_data),
system_info->block_count,
system_info->block_size);
if(ret != Iso15693_3ErrorNone) {
ret = iso15693_3_poller_filter_error(ret);
break;
if(system_info->block_count > 0) {
// Read blocks: Optional command
simple_array_init(
data->block_data, system_info->block_count * system_info->block_size);
ret = iso15693_3_poller_read_blocks(
instance,
simple_array_get_data(data->block_data),
system_info->block_count,
system_info->block_size);
if(ret != Iso15693_3ErrorNone) {
ret = iso15693_3_poller_filter_error(ret);
break;
}
// Get block security status: Optional command
simple_array_init(data->block_security, system_info->block_count);
ret = iso15693_3_poller_get_blocks_security(
instance, simple_array_get_data(data->block_security), system_info->block_count);
if(ret != Iso15693_3ErrorNone) {
ret = iso15693_3_poller_filter_error(ret);
break;
}
}
// Get block security status: Optional command
simple_array_init(data->block_security, system_info->block_count);
ret = iso15693_3_poller_get_blocks_security(
instance, simple_array_get_data(data->block_security), system_info->block_count);
if(ret != Iso15693_3ErrorNone) {
ret = iso15693_3_poller_filter_error(ret);
break;
}
} while(false);
return ret;

View File

@@ -224,11 +224,24 @@ static NfcCommand mf_ultralight_poller_handler_idle(MfUltralightPoller* instance
instance->tearing_flag_read = 0;
instance->tearing_flag_total = 3;
instance->pages_read = 0;
instance->state = MfUltralightPollerStateReadVersion;
instance->state = MfUltralightPollerStateRequestMode;
instance->current_page = 0;
return NfcCommandContinue;
}
static NfcCommand mf_ultralight_poller_handler_request_mode(MfUltralightPoller* instance) {
NfcCommand command = NfcCommandContinue;
instance->mfu_event.type = MfUltralightPollerEventTypeRequestMode;
instance->mfu_event.data->poller_mode = MfUltralightPollerModeRead;
command = instance->callback(instance->general_event, instance->context);
instance->mode = instance->mfu_event.data->poller_mode;
instance->state = MfUltralightPollerStateReadVersion;
return command;
}
static NfcCommand mf_ultralight_poller_handler_read_version(MfUltralightPoller* instance) {
instance->error = mf_ultralight_poller_read_version(instance, &instance->data->version);
if(instance->error == MfUltralightErrorNone) {
@@ -259,6 +272,7 @@ static NfcCommand mf_ultralight_poller_handler_check_ultralight_c(MfUltralightPo
}
static NfcCommand mf_ultralight_poller_handler_check_ntag_203(MfUltralightPoller* instance) {
MfUltralightPollerState next_state = MfUltralightPollerStateGetFeatureSet;
MfUltralightPageReadCommandData data = {};
instance->error = mf_ultralight_poller_read_page(instance, 41, &data);
if(instance->error == MfUltralightErrorNone) {
@@ -268,8 +282,13 @@ static NfcCommand mf_ultralight_poller_handler_check_ntag_203(MfUltralightPoller
FURI_LOG_D(TAG, "Original Ultralight detected");
iso14443_3a_poller_halt(instance->iso14443_3a_poller);
instance->data->type = MfUltralightTypeUnknown;
if(instance->mode == MfUltralightPollerModeWrite) {
instance->mfu_event.type = MfUltralightPollerEventTypeCardMismatch;
instance->callback(instance->general_event, instance->context);
next_state = MfUltralightPollerStateWriteFail;
}
}
instance->state = MfUltralightPollerStateGetFeatureSet;
instance->state = next_state;
return NfcCommandContinue;
}
@@ -508,6 +527,7 @@ static NfcCommand mf_ultralight_poller_handler_try_default_pass(MfUltralightPoll
static NfcCommand mf_ultralight_poller_handler_read_fail(MfUltralightPoller* instance) {
FURI_LOG_D(TAG, "Read Failed");
iso14443_3a_poller_halt(instance->iso14443_3a_poller);
instance->mfu_event.type = MfUltralightPollerEventTypeReadFailed;
instance->mfu_event.data->error = instance->error;
NfcCommand command = instance->callback(instance->general_event, instance->context);
instance->state = MfUltralightPollerStateIdle;
@@ -516,15 +536,121 @@ static NfcCommand mf_ultralight_poller_handler_read_fail(MfUltralightPoller* ins
static NfcCommand mf_ultralight_poller_handler_read_success(MfUltralightPoller* instance) {
FURI_LOG_D(TAG, "Read success");
iso14443_3a_poller_halt(instance->iso14443_3a_poller);
instance->mfu_event.type = MfUltralightPollerEventTypeReadSuccess;
NfcCommand command = instance->callback(instance->general_event, instance->context);
if(instance->mode == MfUltralightPollerModeRead) {
iso14443_3a_poller_halt(instance->iso14443_3a_poller);
instance->state = MfUltralightPollerStateIdle;
} else {
instance->state = MfUltralightPollerStateRequestWriteData;
}
return command;
}
static NfcCommand mf_ultralight_poller_handler_request_write_data(MfUltralightPoller* instance) {
FURI_LOG_D(TAG, "Check writing capability");
NfcCommand command = NfcCommandContinue;
MfUltralightPollerState next_state = MfUltralightPollerStateWritePages;
instance->current_page = 4;
instance->mfu_event.type = MfUltralightPollerEventTypeRequestWriteData;
instance->callback(instance->general_event, instance->context);
const MfUltralightData* write_data = instance->mfu_event.data->write_data;
const MfUltralightData* tag_data = instance->data;
uint32_t features = mf_ultralight_get_feature_support_set(tag_data->type);
bool check_passed = false;
do {
if(write_data->type != tag_data->type) {
FURI_LOG_D(TAG, "Incorrect tag type");
instance->mfu_event.type = MfUltralightPollerEventTypeCardMismatch;
break;
}
if(!instance->auth_context.auth_success) {
FURI_LOG_D(TAG, "Unknown password");
instance->mfu_event.type = MfUltralightPollerEventTypeCardLocked;
break;
}
const MfUltralightPage staticlock_page = tag_data->page[2];
if(staticlock_page.data[2] != 0 || staticlock_page.data[3] != 0) {
FURI_LOG_D(TAG, "Static lock bits are set");
instance->mfu_event.type = MfUltralightPollerEventTypeCardLocked;
break;
}
if(mf_ultralight_support_feature(features, MfUltralightFeatureSupportDynamicLock)) {
uint8_t dynlock_num = mf_ultralight_get_config_page_num(tag_data->type) - 1;
const MfUltralightPage dynlock_page = tag_data->page[dynlock_num];
if(dynlock_page.data[0] != 0 || dynlock_page.data[1] != 0) {
FURI_LOG_D(TAG, "Dynamic lock bits are set");
instance->mfu_event.type = MfUltralightPollerEventTypeCardLocked;
break;
}
}
check_passed = true;
} while(false);
if(!check_passed) {
iso14443_3a_poller_halt(instance->iso14443_3a_poller);
command = instance->callback(instance->general_event, instance->context);
next_state = MfUltralightPollerStateWriteFail;
}
instance->state = next_state;
return command;
}
static NfcCommand mf_ultralight_poller_handler_write_pages(MfUltralightPoller* instance) {
NfcCommand command = NfcCommandContinue;
do {
const MfUltralightData* write_data = instance->mfu_event.data->write_data;
uint8_t end_page = mf_ultralight_get_config_page_num(write_data->type) - 1;
if(instance->current_page == end_page) {
instance->state = MfUltralightPollerStateWriteSuccess;
break;
}
FURI_LOG_D(TAG, "Writing page %d", instance->current_page);
MfUltralightError error = mf_ultralight_poller_write_page(
instance, instance->current_page, &write_data->page[instance->current_page]);
if(error != MfUltralightErrorNone) {
instance->state = MfUltralightPollerStateWriteFail;
instance->error = error;
break;
}
instance->current_page++;
} while(false);
return command;
}
static NfcCommand mf_ultralight_poller_handler_write_fail(MfUltralightPoller* instance) {
FURI_LOG_D(TAG, "Write failed");
iso14443_3a_poller_halt(instance->iso14443_3a_poller);
instance->mfu_event.data->error = instance->error;
instance->mfu_event.type = MfUltralightPollerEventTypeWriteFail;
NfcCommand command = instance->callback(instance->general_event, instance->context);
return command;
}
static NfcCommand mf_ultralight_poller_handler_write_success(MfUltralightPoller* instance) {
FURI_LOG_D(TAG, "Write success");
iso14443_3a_poller_halt(instance->iso14443_3a_poller);
instance->mfu_event.type = MfUltralightPollerEventTypeWriteSuccess;
NfcCommand command = instance->callback(instance->general_event, instance->context);
return command;
}
static const MfUltralightPollerReadHandler
mf_ultralight_poller_read_handler[MfUltralightPollerStateNum] = {
[MfUltralightPollerStateIdle] = mf_ultralight_poller_handler_idle,
[MfUltralightPollerStateRequestMode] = mf_ultralight_poller_handler_request_mode,
[MfUltralightPollerStateReadVersion] = mf_ultralight_poller_handler_read_version,
[MfUltralightPollerStateDetectMfulC] = mf_ultralight_poller_handler_check_ultralight_c,
[MfUltralightPollerStateDetectNtag203] = mf_ultralight_poller_handler_check_ntag_203,
@@ -538,6 +664,11 @@ static const MfUltralightPollerReadHandler
[MfUltralightPollerStateReadPages] = mf_ultralight_poller_handler_read_pages,
[MfUltralightPollerStateReadFailed] = mf_ultralight_poller_handler_read_fail,
[MfUltralightPollerStateReadSuccess] = mf_ultralight_poller_handler_read_success,
[MfUltralightPollerStateRequestWriteData] =
mf_ultralight_poller_handler_request_write_data,
[MfUltralightPollerStateWritePages] = mf_ultralight_poller_handler_write_pages,
[MfUltralightPollerStateWriteFail] = mf_ultralight_poller_handler_write_fail,
[MfUltralightPollerStateWriteSuccess] = mf_ultralight_poller_handler_write_success,
};

View File

@@ -16,13 +16,27 @@ typedef struct MfUltralightPoller MfUltralightPoller;
* @brief Enumeration of possible MfUltralight poller event types.
*/
typedef enum {
MfUltralightPollerEventTypeRequestMode, /**< Poller requests for operating mode. */
MfUltralightPollerEventTypeAuthRequest, /**< Poller requests to fill authentication context. */
MfUltralightPollerEventTypeAuthSuccess, /**< Authentication succeeded. */
MfUltralightPollerEventTypeAuthFailed, /**< Authentication failed. */
MfUltralightPollerEventTypeReadSuccess, /**< Poller read card successfully. */
MfUltralightPollerEventTypeReadFailed, /**< Poller failed to read card. */
MfUltralightPollerEventTypeRequestWriteData, /**< Poller request card data for write operation. */
MfUltralightPollerEventTypeCardMismatch, /**< Type of card for writing differs from presented one. */
MfUltralightPollerEventTypeCardLocked, /**< Presented card is locked by password, AUTH0 or lock bytes. */
MfUltralightPollerEventTypeWriteSuccess, /**< Poller wrote card successfully. */
MfUltralightPollerEventTypeWriteFail, /**< Poller failed to write card. */
} MfUltralightPollerEventType;
/**
* @brief Enumeration of possible MfUltralight poller operating modes.
*/
typedef enum {
MfUltralightPollerModeRead, /**< Poller will only read card. It's a default mode. */
MfUltralightPollerModeWrite, /**< Poller will write already saved card to another presented card. */
} MfUltralightPollerMode;
/**
* @brief MfUltralight poller authentication context.
*/
@@ -39,6 +53,8 @@ typedef struct {
typedef union {
MfUltralightPollerAuthContext auth_context; /**< Authentication context. */
MfUltralightError error; /**< Error code indicating reading fail reason. */
const MfUltralightData* write_data;
MfUltralightPollerMode poller_mode;
} MfUltralightPollerEventData;
/**

View File

@@ -49,6 +49,7 @@ typedef union {
typedef enum {
MfUltralightPollerStateIdle,
MfUltralightPollerStateRequestMode,
MfUltralightPollerStateReadVersion,
MfUltralightPollerStateDetectMfulC,
MfUltralightPollerStateDetectNtag203,
@@ -61,6 +62,10 @@ typedef enum {
MfUltralightPollerStateTryDefaultPass,
MfUltralightPollerStateReadFailed,
MfUltralightPollerStateReadSuccess,
MfUltralightPollerStateRequestWriteData,
MfUltralightPollerStateWritePages,
MfUltralightPollerStateWriteFail,
MfUltralightPollerStateWriteSuccess,
MfUltralightPollerStateNum,
} MfUltralightPollerState;
@@ -68,6 +73,7 @@ typedef enum {
struct MfUltralightPoller {
Iso14443_3aPoller* iso14443_3a_poller;
MfUltralightPollerState state;
MfUltralightPollerMode mode;
BitBuffer* tx_buffer;
BitBuffer* rx_buffer;
MfUltralightData* data;
@@ -79,6 +85,7 @@ struct MfUltralightPoller {
uint8_t counters_total;
uint8_t tearing_flag_read;
uint8_t tearing_flag_total;
uint16_t current_page;
MfUltralightError error;
NfcGenericEvent general_event;

View File

@@ -227,7 +227,7 @@ void subghz_protocol_decoder_gate_tx_feed(void* context, bool level, uint32_t du
if(duration >= ((uint32_t)subghz_protocol_gate_tx_const.te_short * 10 +
subghz_protocol_gate_tx_const.te_delta)) {
instance->decoder.parser_step = GateTXDecoderStepFoundStartBit;
if(instance->decoder.decode_count_bit >=
if(instance->decoder.decode_count_bit ==
subghz_protocol_gate_tx_const.min_count_bit_for_found) {
instance->generic.data = instance->decoder.decode_data;
instance->generic.data_count_bit = instance->decoder.decode_count_bit;