diff --git a/lib/nfc/protocols/mf_plus/mf_plus_i.c b/lib/nfc/protocols/mf_plus/mf_plus_i.c index 5eb38e0d6..2a291b609 100644 --- a/lib/nfc/protocols/mf_plus/mf_plus_i.c +++ b/lib/nfc/protocols/mf_plus/mf_plus_i.c @@ -17,16 +17,16 @@ const uint8_t mf_plus_ats_t1_tk_values[][7] = { {0xC1, 0x05, 0x2F, 0x2F, 0x01, 0xF6, 0xD1}, // Mifare Plus SE }; -bool mf_plus_get_type_from_version( +MfPlusError mf_plus_get_type_from_version( const Iso14443_4aData* iso14443_4a_data, MfPlusData* mf_plus_data) { furi_assert(iso14443_4a_data); furi_assert(mf_plus_data); - bool detected = false; + MfPlusError error = MfPlusErrorProtocol; if(mf_plus_data->version.hw_major == 0x02 || mf_plus_data->version.hw_major == 0x82) { - detected = true; + error = MfPlusErrorNone; if(iso14443_4a_data->iso14443_3a_data->sak == 0x10) { // Mifare Plus 2K SL2 mf_plus_data->type = MfPlusTypePlus; @@ -87,13 +87,16 @@ bool mf_plus_get_type_from_version( } } - return detected; + return error; } -bool mf_plus_get_type_from_iso4(const Iso14443_4aData* iso4_data, MfPlusData* mf_plus_data) { +MfPlusError + mf_plus_get_type_from_iso4(const Iso14443_4aData* iso4_data, MfPlusData* mf_plus_data) { furi_assert(iso4_data); furi_assert(mf_plus_data); + MfPlusError error = MfPlusErrorProtocol; + switch(iso4_data->iso14443_3a_data->sak) { case 0x08: if(memcmp( @@ -104,8 +107,9 @@ bool mf_plus_get_type_from_iso4(const Iso14443_4aData* iso4_data, MfPlusData* mf mf_plus_data->type = MfPlusTypeS; mf_plus_data->size = MfPlusSize2K; mf_plus_data->security_level = MfPlusSecurityLevel1; + FURI_LOG_D(TAG, "Mifare Plus S 2K SL1"); - return true; + error = MfPlusErrorNone; } else if( memcmp( simple_array_get_data(iso4_data->ats_data.t1_tk), @@ -115,8 +119,9 @@ bool mf_plus_get_type_from_iso4(const Iso14443_4aData* iso4_data, MfPlusData* mf mf_plus_data->type = MfPlusTypeX; mf_plus_data->size = MfPlusSize2K; mf_plus_data->security_level = MfPlusSecurityLevel1; + FURI_LOG_D(TAG, "Mifare Plus X 2K SL1"); - return true; + error = MfPlusErrorNone; } else if( memcmp( simple_array_get_data(iso4_data->ats_data.t1_tk), @@ -130,12 +135,14 @@ bool mf_plus_get_type_from_iso4(const Iso14443_4aData* iso4_data, MfPlusData* mf mf_plus_data->type = MfPlusTypeSE; mf_plus_data->size = MfPlusSize1K; mf_plus_data->security_level = MfPlusSecurityLevel1; + FURI_LOG_D(TAG, "Mifare Plus SE 1K SL1"); - return true; + error = MfPlusErrorNone; } else { FURI_LOG_D(TAG, "Sak 08 but no known Mifare Plus type"); - return false; } + + break; case 0x18: if(memcmp( simple_array_get_data(iso4_data->ats_data.t1_tk), @@ -145,8 +152,9 @@ bool mf_plus_get_type_from_iso4(const Iso14443_4aData* iso4_data, MfPlusData* mf mf_plus_data->type = MfPlusTypeS; mf_plus_data->size = MfPlusSize4K; mf_plus_data->security_level = MfPlusSecurityLevel1; + FURI_LOG_D(TAG, "Mifare Plus S 4K SL1"); - return true; + error = MfPlusErrorNone; } else if( memcmp( simple_array_get_data(iso4_data->ats_data.t1_tk), @@ -156,12 +164,14 @@ bool mf_plus_get_type_from_iso4(const Iso14443_4aData* iso4_data, MfPlusData* mf mf_plus_data->type = MfPlusTypeX; mf_plus_data->size = MfPlusSize4K; mf_plus_data->security_level = MfPlusSecurityLevel1; + FURI_LOG_D(TAG, "Mifare Plus X 4K SL1"); - return true; + error = MfPlusErrorNone; } else { FURI_LOG_D(TAG, "Sak 18 but no known Mifare Plus type"); - return false; } + + break; case 0x20: if(memcmp( simple_array_get_data(iso4_data->ats_data.t1_tk), @@ -175,54 +185,56 @@ bool mf_plus_get_type_from_iso4(const Iso14443_4aData* iso4_data, MfPlusData* mf if((iso4_data->iso14443_3a_data->atqa[0] & 0x0F) == 0x04) { // Mifare Plus S 2K SL3 mf_plus_data->size = MfPlusSize2K; + FURI_LOG_D(TAG, "Mifare Plus S 2K SL3"); + error = MfPlusErrorNone; } else if((iso4_data->iso14443_3a_data->atqa[0] & 0x0F) == 0x02) { // Mifare Plus S 4K SL3 mf_plus_data->size = MfPlusSize4K; + FURI_LOG_D(TAG, "Mifare Plus S 4K SL3"); + error = MfPlusErrorNone; } else { FURI_LOG_D(TAG, "Sak 20 but no known Mifare Plus type (S)"); - return false; } - return true; } else if( memcmp( simple_array_get_data(iso4_data->ats_data.t1_tk), mf_plus_ats_t1_tk_values[1], simple_array_get_count(iso4_data->ats_data.t1_tk)) == 0) { - FURI_LOG_D(TAG, "Mifare Plus X SL3"); mf_plus_data->type = MfPlusTypeX; mf_plus_data->security_level = MfPlusSecurityLevel3; + FURI_LOG_D(TAG, "Mifare Plus X SL3"); if((iso4_data->iso14443_3a_data->atqa[0] & 0x0F) == 0x04) { mf_plus_data->size = MfPlusSize2K; + FURI_LOG_D(TAG, "Mifare Plus X 2K SL3"); + error = MfPlusErrorNone; } else if((iso4_data->iso14443_3a_data->atqa[0] & 0x0F) == 0x02) { mf_plus_data->size = MfPlusSize4K; + FURI_LOG_D(TAG, "Mifare Plus X 4K SL3"); + error = MfPlusErrorNone; } else { FURI_LOG_D(TAG, "Sak 20 but no known Mifare Plus type (X)"); - return false; } - return true; } else { FURI_LOG_D(TAG, "Sak 20 but no known Mifare Plus type"); - return false; } } - FURI_LOG_D(TAG, "No known Mifare Plus type"); - return false; + return error; } -bool mf_plus_version_parse(MfPlusVersion* data, const BitBuffer* buf) { +MfPlusError mf_plus_version_parse(MfPlusVersion* data, const BitBuffer* buf) { const bool can_parse = bit_buffer_get_size_bytes(buf) == sizeof(MfPlusVersion); if(can_parse) { bit_buffer_write_bytes(buf, data, sizeof(MfPlusVersion)); } - return can_parse; + return can_parse ? MfPlusErrorNone : MfPlusErrorProtocol; } bool mf_plus_version_load(MfPlusVersion* data, FlipperFormat* ff) { diff --git a/lib/nfc/protocols/mf_plus/mf_plus_i.h b/lib/nfc/protocols/mf_plus/mf_plus_i.h index 313ccce55..1b80030f9 100644 --- a/lib/nfc/protocols/mf_plus/mf_plus_i.h +++ b/lib/nfc/protocols/mf_plus/mf_plus_i.h @@ -4,13 +4,13 @@ #define MF_PLUS_FFF_PICC_PREFIX "PICC" -bool mf_plus_get_type_from_version( +MfPlusError mf_plus_get_type_from_version( const Iso14443_4aData* iso14443_4a_data, MfPlusData* mf_plus_data); -bool mf_plus_get_type_from_iso4(const Iso14443_4aData* iso4_data, MfPlusData* mf_plus_data); +MfPlusError mf_plus_get_type_from_iso4(const Iso14443_4aData* iso4_data, MfPlusData* mf_plus_data); -bool mf_plus_version_parse(MfPlusVersion* data, const BitBuffer* buf); +MfPlusError mf_plus_version_parse(MfPlusVersion* data, const BitBuffer* buf); bool mf_plus_version_load(MfPlusVersion* data, FlipperFormat* ff); diff --git a/lib/nfc/protocols/mf_plus/mf_plus_poller.c b/lib/nfc/protocols/mf_plus/mf_plus_poller.c index dac95b912..c93ec9e67 100644 --- a/lib/nfc/protocols/mf_plus/mf_plus_poller.c +++ b/lib/nfc/protocols/mf_plus/mf_plus_poller.c @@ -22,7 +22,6 @@ MfPlusPoller* mf_plus_poller_alloc(Iso14443_4aPoller* iso14443_4a_poller) { furi_assert(iso14443_4a_poller); MfPlusPoller* instance = malloc(sizeof(MfPlusPoller)); - furi_assert(instance); instance->iso14443_4a_poller = iso14443_4a_poller; @@ -178,29 +177,27 @@ void mf_plus_poller_free(MfPlusPoller* instance) { } static bool mf_plus_poller_detect(NfcGenericEvent event, void* context) { + furi_assert(context); furi_assert(event.protocol = NfcProtocolIso14443_4a); + furi_assert(event.event_data); MfPlusPoller* instance = context; - furi_assert(instance); - Iso14443_4aPollerEvent* iso14443_4a_event = event.event_data; - furi_assert(iso14443_4a_event); - bool detected = false; + MfPlusError error = MfPlusErrorUnknown; if(iso14443_4a_event->type == Iso14443_4aPollerEventTypeReady) { - detected = - (mf_plus_poller_read_version(instance, &instance->data->version) == MfPlusErrorNone); - if(detected) { - detected = mf_plus_get_type_from_version( + error = mf_plus_poller_read_version(instance, &instance->data->version); + if(error == MfPlusErrorNone) { + error = mf_plus_get_type_from_version( iso14443_4a_poller_get_data(instance->iso14443_4a_poller), instance->data); } else { - detected = mf_plus_get_type_from_iso4( + error = mf_plus_get_type_from_iso4( iso14443_4a_poller_get_data(instance->iso14443_4a_poller), instance->data); } } - return detected; + return (error == MfPlusErrorNone); } const NfcPollerBase mf_plus_poller = { diff --git a/lib/nfc/protocols/mf_plus/mf_plus_poller_i.c b/lib/nfc/protocols/mf_plus/mf_plus_poller_i.c index 3750abf42..9ed3a1d5f 100644 --- a/lib/nfc/protocols/mf_plus/mf_plus_poller_i.c +++ b/lib/nfc/protocols/mf_plus/mf_plus_poller_i.c @@ -30,21 +30,15 @@ MfPlusError mf_plus_poller_send_chunk( furi_assert(tx_buffer); furi_assert(rx_buffer); - MfPlusError error = MfPlusErrorNone; + Iso14443_4aError iso14443_4a_error = iso14443_4a_poller_send_block( + instance->iso14443_4a_poller, tx_buffer, instance->rx_buffer); + MfPlusError error = mf_plus_process_error(iso14443_4a_error); - do { - Iso14443_4aError iso14443_4a_error = iso14443_4a_poller_send_block( - instance->iso14443_4a_poller, tx_buffer, instance->rx_buffer); - - if(iso14443_4a_error != Iso14443_4aErrorNone) { - error = mf_plus_process_error(iso14443_4a_error); - break; - } - - bit_buffer_reset(instance->tx_buffer); + if(error == MfPlusErrorNone) { bit_buffer_copy(rx_buffer, instance->rx_buffer); + } - } while(false); + bit_buffer_reset(instance->tx_buffer); return error; } @@ -55,18 +49,11 @@ MfPlusError mf_plus_poller_read_version(MfPlusPoller* instance, MfPlusVersion* d bit_buffer_reset(instance->input_buffer); bit_buffer_append_byte(instance->input_buffer, MF_PLUS_CMD_GET_VERSION); - MfPlusError error = MfPlusErrorNone; - - do { - error = - mf_plus_poller_send_chunk(instance, instance->input_buffer, instance->result_buffer); - - if(error != MfPlusErrorNone) break; - - if(!mf_plus_version_parse(data, instance->result_buffer)) { - error = MfPlusErrorProtocol; - } - } while(false); + MfPlusError error = + mf_plus_poller_send_chunk(instance, instance->input_buffer, instance->result_buffer); + if(error == MfPlusErrorNone) { + error = mf_plus_version_parse(data, instance->result_buffer); + } return error; }