diff --git a/lib/nfc/helpers/iso14443_4_layer.c b/lib/nfc/helpers/iso14443_4_layer.c index 26f4dc3b7..75282c1d6 100644 --- a/lib/nfc/helpers/iso14443_4_layer.c +++ b/lib/nfc/helpers/iso14443_4_layer.c @@ -7,6 +7,18 @@ #define ISO14443_4_BLOCK_PCB_R (5U << 5) #define ISO14443_4_BLOCK_PCB_S (3U << 6) +//KOSTYLY +#define ISO14443_4_BLOCK_PCB_I_ (0U << 6) +#define ISO14443_4_BLOCK_PCB_R_ (2U << 6) +#define ISO14443_4_BLOCK_PCB_TYPE_MASK (3U << 6) +#define ISO14443_4_BLOCK_PCB_S_DESELECT (0U << 4) +#define ISO14443_4_BLOCK_PCB_S_WTX (3U << 4) +#define ISO14443_4_BLOCK_PCB_BLOCK_NUMBER (1U << 0) +#define ISO14443_4_BLOCK_PCB (1U << 1) +#define ISO14443_4_BLOCK_PCB_NAD (1U << 2) +#define ISO14443_4_BLOCK_PCB_CID (1U << 3) +#define ISO14443_4_BLOCK_PCB_CHAINING (1U << 4) + struct Iso14443_4Layer { uint8_t pcb; uint8_t pcb_prev; @@ -62,3 +74,48 @@ bool iso14443_4_layer_decode_block( return ret; } + +Iso14443_4aError iso14443_4_layer_decode_block_pwt_ext( + Iso14443_4Layer* instance, + BitBuffer* output_data, + const BitBuffer* block_data) { + furi_assert(instance); + + Iso14443_4aError ret = Iso14443_4aErrorProtocol; + + do { + const uint8_t pcb_field = bit_buffer_get_byte(block_data, 0); + const uint8_t block_type = pcb_field & ISO14443_4_BLOCK_PCB_TYPE_MASK; + switch(block_type) { + case ISO14443_4_BLOCK_PCB_I_: + if(pcb_field == instance->pcb_prev) { + bit_buffer_copy_right(output_data, block_data, 1); + ret = Iso14443_4aErrorNone; + } else { + // TODO: Need send request again + ret = Iso14443_4aErrorProtocol; + } + break; + case ISO14443_4_BLOCK_PCB_R_: + // TODO + break; + case ISO14443_4_BLOCK_PCB_S: + if((pcb_field & ISO14443_4_BLOCK_PCB_S_WTX) == ISO14443_4_BLOCK_PCB_S_WTX) { + const uint8_t inf_field = bit_buffer_get_byte(block_data, 1); + //const uint8_t power_level = inf_field >> 6; + const uint8_t wtxm = inf_field & 0b111111; + //uint32_t fwt_temp = MIN((fwt * wtxm), fwt_max); + + bit_buffer_reset(output_data); + bit_buffer_append_byte( + output_data, + ISO14443_4_BLOCK_PCB_S | ISO14443_4_BLOCK_PCB_S_WTX | ISO14443_4_BLOCK_PCB); + bit_buffer_append_byte(output_data, wtxm); + ret = Iso14443_4aErrorSendCtrl; + } + break; + } + } while(false); + + return ret; +} \ No newline at end of file diff --git a/lib/nfc/helpers/iso14443_4_layer.h b/lib/nfc/helpers/iso14443_4_layer.h index 712173ce1..14e435c2f 100644 --- a/lib/nfc/helpers/iso14443_4_layer.h +++ b/lib/nfc/helpers/iso14443_4_layer.h @@ -1,5 +1,6 @@ #pragma once +#include "protocols/iso14443_4a/iso14443_4a.h" #include #ifdef __cplusplus @@ -24,6 +25,11 @@ bool iso14443_4_layer_decode_block( BitBuffer* output_data, const BitBuffer* block_data); +Iso14443_4aError iso14443_4_layer_decode_block_pwt_ext( + Iso14443_4Layer* instance, + BitBuffer* output_data, + const BitBuffer* block_data); + #ifdef __cplusplus } #endif diff --git a/lib/nfc/protocols/emv/emv_poller_i.c b/lib/nfc/protocols/emv/emv_poller_i.c index 9494ca199..7e85c7dcc 100644 --- a/lib/nfc/protocols/emv/emv_poller_i.c +++ b/lib/nfc/protocols/emv/emv_poller_i.c @@ -261,7 +261,7 @@ EmvError emv_poller_select_ppse(EmvPoller* instance) { do { FURI_LOG_D(TAG, "Send select PPSE"); - Iso14443_4aError iso14443_4a_error = iso14443_4a_poller_send_block( + Iso14443_4aError iso14443_4a_error = iso14443_4a_poller_send_block_pwt_ext( instance->iso14443_4a_poller, instance->tx_buffer, instance->rx_buffer); if(iso14443_4a_error != Iso14443_4aErrorNone) { @@ -313,7 +313,7 @@ EmvError emv_poller_select_application(EmvPoller* instance) { do { FURI_LOG_D(TAG, "Start application"); - Iso14443_4aError iso14443_4a_error = iso14443_4a_poller_send_block( + Iso14443_4aError iso14443_4a_error = iso14443_4a_poller_send_block_pwt_ext( instance->iso14443_4a_poller, instance->tx_buffer, instance->rx_buffer); emv_trace(instance, "Start application answer:"); @@ -365,7 +365,7 @@ EmvError emv_poller_get_processing_options(EmvPoller* instance) { do { FURI_LOG_D(TAG, "Get proccessing options"); - Iso14443_4aError iso14443_4a_error = iso14443_4a_poller_send_block( + Iso14443_4aError iso14443_4a_error = iso14443_4a_poller_send_block_pwt_ext( instance->iso14443_4a_poller, instance->tx_buffer, instance->rx_buffer); emv_trace(instance, "Get processing options answer:"); @@ -408,7 +408,7 @@ EmvError emv_poller_read_sfi_record(EmvPoller* instance, uint8_t sfi, uint8_t re bit_buffer_copy_bytes(instance->tx_buffer, emv_sfi_header, sizeof(emv_sfi_header)); do { - Iso14443_4aError iso14443_4a_error = iso14443_4a_poller_send_block( + Iso14443_4aError iso14443_4a_error = iso14443_4a_poller_send_block_pwt_ext( instance->iso14443_4a_poller, instance->tx_buffer, instance->rx_buffer); emv_trace(instance, "SFI record:"); diff --git a/lib/nfc/protocols/iso14443_4a/iso14443_4a.h b/lib/nfc/protocols/iso14443_4a/iso14443_4a.h index df212152d..add93cea1 100644 --- a/lib/nfc/protocols/iso14443_4a/iso14443_4a.h +++ b/lib/nfc/protocols/iso14443_4a/iso14443_4a.h @@ -13,6 +13,7 @@ typedef enum { Iso14443_4aErrorNotPresent, Iso14443_4aErrorProtocol, Iso14443_4aErrorTimeout, + Iso14443_4aErrorSendCtrl, } Iso14443_4aError; typedef enum { diff --git a/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller.h b/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller.h index fef565e51..019beb2be 100644 --- a/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller.h +++ b/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller.h @@ -56,6 +56,11 @@ Iso14443_4aError iso14443_4a_poller_send_block( const BitBuffer* tx_buffer, BitBuffer* rx_buffer); +Iso14443_4aError iso14443_4a_poller_send_block_pwt_ext( + Iso14443_4aPoller* instance, + const BitBuffer* tx_buffer, + BitBuffer* rx_buffer); + /** * @brief Send HALT command to the card. * diff --git a/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller_i.c b/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller_i.c index 938e4e715..529c74e27 100644 --- a/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller_i.c +++ b/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller_i.c @@ -81,3 +81,41 @@ Iso14443_4aError iso14443_4a_poller_send_block( return error; } + +Iso14443_4aError iso14443_4a_poller_send_block_pwt_ext( + Iso14443_4aPoller* instance, + const BitBuffer* tx_buffer, + BitBuffer* rx_buffer) { + furi_assert(instance); + + bit_buffer_reset(instance->tx_buffer); + iso14443_4_layer_encode_block(instance->iso14443_4_layer, tx_buffer, instance->tx_buffer); + + Iso14443_4aError error = Iso14443_4aErrorNone; + + do { + bit_buffer_reset(instance->rx_buffer); + Iso14443_3aError iso14443_3a_error = iso14443_3a_poller_send_standard_frame( + instance->iso14443_3a_poller, + instance->tx_buffer, + instance->rx_buffer, + iso14443_4a_get_fwt_fc_max(instance->data)); + + if(iso14443_3a_error != Iso14443_3aErrorNone) { + error = iso14443_4a_process_error(iso14443_3a_error); + break; + + } else { + error = iso14443_4_layer_decode_block_pwt_ext( + instance->iso14443_4_layer, rx_buffer, instance->rx_buffer); + if(error == Iso14443_4aErrorSendCtrl) { + // Send response for Control message + bit_buffer_copy(instance->tx_buffer, rx_buffer); + continue; + } + break; + } + } while(true); + + return error; +} \ No newline at end of file diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 95b0bd5cd..1976ef2de 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,51.0,, +Version,+,52.0,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, @@ -1969,6 +1969,7 @@ Function,+,iso14443_4a_load,_Bool,"Iso14443_4aData*, FlipperFormat*, uint32_t" Function,+,iso14443_4a_poller_halt,Iso14443_4aError,Iso14443_4aPoller* Function,+,iso14443_4a_poller_read_ats,Iso14443_4aError,"Iso14443_4aPoller*, Iso14443_4aAtsData*" Function,+,iso14443_4a_poller_send_block,Iso14443_4aError,"Iso14443_4aPoller*, const BitBuffer*, BitBuffer*" +Function,+,iso14443_4a_poller_send_block_pwt_ext,Iso14443_4aError,"Iso14443_4aPoller*, const BitBuffer*, BitBuffer*" Function,+,iso14443_4a_reset,void,Iso14443_4aData* Function,+,iso14443_4a_save,_Bool,"const Iso14443_4aData*, FlipperFormat*" Function,+,iso14443_4a_set_uid,_Bool,"Iso14443_4aData*, const uint8_t*, size_t"