From d116b3fac19c31a076ca8cadcbb88c8580d9358d Mon Sep 17 00:00:00 2001 From: g3gg0 Date: Sat, 10 Dec 2022 03:22:34 +0100 Subject: [PATCH] fix emulation by using latest sources fixed file saving --- .../main/nfc/scenes/nfc_scene_nfc_data_info.c | 4 +- .../main/nfc/scenes/nfc_scene_nfcv_unlock.c | 9 +- firmware/targets/f7/api_symbols.csv | 5 +- lib/digital_signal/digital_signal.c | 21 +- lib/digital_signal/digital_signal.h | 2 + lib/nfc/nfc_device.c | 8 +- lib/nfc/protocols/nfcv.c | 306 ++++++++++-------- lib/nfc/protocols/nfcv.h | 62 ++-- lib/nfc/protocols/slix.c | 27 +- lib/pulse_reader/pulse_reader.c | 3 - 10 files changed, 272 insertions(+), 175 deletions(-) diff --git a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c index 7f207b815..01cec026c 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c +++ b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c @@ -55,7 +55,7 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { } else if(protocol == NfcDeviceProtocolMifareDesfire) { furi_string_cat_printf(temp_str, "\e#MIFARE DESfire\n"); } else if(protocol == NfcDeviceProtocolNfcV) { - switch(dev_data->nfcv_data.type) { + switch(dev_data->nfcv_data.sub_type) { case NfcVTypePlain: furi_string_cat_printf(temp_str, "\e#ISO15693\n"); break; @@ -113,7 +113,7 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { } furi_string_cat_printf(temp_str, "\n"); - switch(dev_data->nfcv_data.type) { + switch(dev_data->nfcv_data.sub_type) { case NfcVTypePlain: furi_string_cat_printf(temp_str, "Type: Plain\n"); break; diff --git a/applications/main/nfc/scenes/nfc_scene_nfcv_unlock.c b/applications/main/nfc/scenes/nfc_scene_nfcv_unlock.c index f40edf856..b52cc0caa 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfcv_unlock.c +++ b/applications/main/nfc/scenes/nfc_scene_nfcv_unlock.c @@ -35,7 +35,8 @@ void nfc_scene_nfcv_unlock_set_state(Nfc* nfc, NfcSceneNfcVUnlockState state) { Popup* popup = nfc->popup; if(state == NfcSceneNfcVUnlockStateDetecting) { popup_reset(popup); - popup_set_text(popup, "Put Tonie On\nFlipper's Back", 97, 24, AlignCenter, AlignTop); + popup_set_text( + popup, "Put figurine on\nFlipper's back", 97, 24, AlignCenter, AlignTop); popup_set_icon(popup, 0, 8, &I_NFC_manual_60x50); } else if(state == NfcSceneNfcVUnlockStateUnlocked) { popup_reset(popup); @@ -43,7 +44,8 @@ void nfc_scene_nfcv_unlock_set_state(Nfc* nfc, NfcSceneNfcVUnlockState state) { if(nfc_worker_get_state(nfc->worker) == NfcWorkerStateNfcVUnlockAndSave) { nfc_text_store_set( nfc, - "SLIX_%02X%02X%02X%02X%02X%02X%02X%02X", + "%s/SLIX_%02X%02X%02X%02X%02X%02X%02X%02X%s", + NFC_APP_FOLDER, nfc_data->uid[0], nfc_data->uid[1], nfc_data->uid[2], @@ -51,7 +53,8 @@ void nfc_scene_nfcv_unlock_set_state(Nfc* nfc, NfcSceneNfcVUnlockState state) { nfc_data->uid[4], nfc_data->uid[5], nfc_data->uid[6], - nfc_data->uid[7]); + nfc_data->uid[7], + NFC_APP_EXTENSION); nfc->dev->format = NfcDeviceSaveFormatNfcV; diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 0e86319f2..01a1311d5 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,10.1,, +Version,+,10.2,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -732,6 +732,7 @@ Function,-,digital_sequence_alloc,DigitalSequence*,"uint32_t, const GpioPin*" Function,-,digital_sequence_clear,void,DigitalSequence* Function,-,digital_sequence_free,void,DigitalSequence* Function,-,digital_sequence_send,_Bool,DigitalSequence* +Function,-,digital_sequence_set_sendtime,void,"DigitalSequence*, uint32_t" Function,-,digital_sequence_set_signal,void,"DigitalSequence*, uint8_t, DigitalSignal*" Function,-,digital_signal_add,void,"DigitalSignal*, uint32_t" Function,-,digital_signal_add_pulse,void,"DigitalSignal*, uint32_t, _Bool" @@ -2031,7 +2032,7 @@ Function,-,nfca_signal_free,void,NfcaSignal* Function,-,nfcv_emu_deinit,void,NfcVData* Function,-,nfcv_emu_init,void,"FuriHalNfcDevData*, NfcVData*" Function,-,nfcv_emu_loop,_Bool,"FuriHalNfcTxRxContext*, FuriHalNfcDevData*, NfcVData*, uint32_t" -Function,-,nfcv_emu_send,void,"FuriHalNfcTxRxContext*, NfcVData*, uint8_t*, uint8_t, NfcVSendFlags" +Function,-,nfcv_emu_send,void,"FuriHalNfcTxRxContext*, NfcVData*, uint8_t*, uint8_t, NfcVSendFlags, uint32_t" Function,-,nfcv_inventory,ReturnCode,uint8_t* Function,-,nfcv_read_blocks,ReturnCode,"NfcVReader*, NfcVData*" Function,-,nfcv_read_card,_Bool,"NfcVReader*, FuriHalNfcDevData*, NfcVData*" diff --git a/lib/digital_signal/digital_signal.c b/lib/digital_signal/digital_signal.c index faea80933..8e52491ea 100644 --- a/lib/digital_signal/digital_signal.c +++ b/lib/digital_signal/digital_signal.c @@ -250,6 +250,7 @@ void digital_sequence_alloc_sequence(DigitalSequence* sequence, uint32_t size) { sequence->sequence_used = 0; sequence->sequence_size = size; sequence->sequence = malloc(sequence->sequence_size); + sequence->send_time = 0; } DigitalSequence* digital_sequence_alloc(uint32_t size, const GpioPin* gpio) { @@ -287,6 +288,10 @@ void digital_sequence_set_signal( digital_signal_prepare(signal); } +void digital_sequence_set_sendtime(DigitalSequence* sequence, uint32_t send_time) { + sequence->send_time = send_time; +} + void digital_sequence_add(DigitalSequence* sequence, uint8_t signal_index) { furi_assert(sequence); furi_assert(signal_index < sequence->signals_size); @@ -347,7 +352,8 @@ void digital_signal_update_dma(DigitalSignal* signal) { LL_DMA_ClearFlag_TC2(DMA1); } -static bool digital_sequence_send_signal(DigitalSignal* signal) { +static bool digital_sequence_send_signal(DigitalSequence* sequence, DigitalSignal* signal) { + furi_assert(sequence); furi_assert(signal); /* the first iteration has to set up the whole machinery */ @@ -357,6 +363,17 @@ static bool digital_sequence_send_signal(DigitalSignal* signal) { return false; } digital_signal_setup_timer(); + + /* if the send time is specified, wait till the core timer passed beyond that time */ + if(sequence->send_time != 0) { + while(true) { + uint32_t delta = sequence->send_time - DWT->CYCCNT; + /* yeah, it's making use of underflows... */ + if(delta > 0x80000000) { + break; + } + } + } digital_signal_start_timer(); } else { /* configure next polarities and timings */ @@ -438,7 +455,7 @@ bool digital_sequence_send(DigitalSequence* sequence) { sequence->signals_prolonged[signal_index] = needs_prolongation; } - bool success = digital_sequence_send_signal(sig); + bool success = digital_sequence_send_signal(sequence, sig); if(!success) { break; diff --git a/lib/digital_signal/digital_signal.h b/lib/digital_signal/digital_signal.h index 3b250074b..2e1a05522 100644 --- a/lib/digital_signal/digital_signal.h +++ b/lib/digital_signal/digital_signal.h @@ -41,6 +41,7 @@ typedef struct { bool* signals_prolonged; uint8_t* sequence; const GpioPin* gpio; + uint32_t send_time; } DigitalSequence; DigitalSignal* digital_signal_alloc(uint32_t max_edges_cnt); @@ -69,6 +70,7 @@ void digital_sequence_set_signal( DigitalSequence* sequence, uint8_t signal_index, DigitalSignal* signal); +void digital_sequence_set_sendtime(DigitalSequence* sequence, uint32_t send_time); void digital_sequence_add(DigitalSequence* sequence, uint8_t signal_index); bool digital_sequence_send(DigitalSequence* sequence); void digital_sequence_clear(DigitalSequence* sequence); diff --git a/lib/nfc/nfc_device.c b/lib/nfc/nfc_device.c index 1c78cae2f..343181269 100644 --- a/lib/nfc/nfc_device.c +++ b/lib/nfc/nfc_device.c @@ -860,10 +860,10 @@ static bool nfc_device_save_nfcv_data(FlipperFormat* file, NfcDevice* dev) { file, "Subtype of this card (0 = ISO15693, 1 = SLIX, 2 = SLIX-S, 3 = SLIX-L, 4 = SLIX2)")) break; - temp_uint8 = (uint8_t)data->type; + temp_uint8 = (uint8_t)data->sub_type; if(!flipper_format_write_hex(file, "Subtype", &temp_uint8, 1)) break; - switch(data->type) { + switch(data->sub_type) { case NfcVTypePlain: if(!flipper_format_write_comment_cstr(file, "End of ISO15693 parameters")) break; saved = true; @@ -906,9 +906,9 @@ bool nfc_device_load_nfcv_data(FlipperFormat* file, NfcDevice* dev) { file, "Data Content", data->data, data->block_num * data->block_size)) break; if(!flipper_format_read_hex(file, "Subtype", &temp_value, 1)) break; - data->type = temp_value; + data->sub_type = temp_value; - switch(data->type) { + switch(data->sub_type) { case NfcVTypePlain: parsed = true; break; diff --git a/lib/nfc/protocols/nfcv.c b/lib/nfc/protocols/nfcv.c index c9927851c..435a368f5 100644 --- a/lib/nfc/protocols/nfcv.c +++ b/lib/nfc/protocols/nfcv.c @@ -38,13 +38,13 @@ ReturnCode nfcv_inventory(uint8_t* uid) { return ret; } -ReturnCode nfcv_read_blocks(NfcVReader* reader, NfcVData* data) { +ReturnCode nfcv_read_blocks(NfcVReader* reader, NfcVData* nfcv_data) { UNUSED(reader); uint16_t received = 0; - for(size_t block = 0; block < data->block_num; block++) { + for(size_t block = 0; block < nfcv_data->block_num; block++) { uint8_t rxBuf[32]; - FURI_LOG_D(TAG, "Reading block %d/%d", block, (data->block_num - 1)); + FURI_LOG_D(TAG, "Reading block %d/%d", block, (nfcv_data->block_num - 1)); ReturnCode ret = ERR_NONE; for(int tries = 0; tries < 5; tries++) { @@ -59,20 +59,21 @@ ReturnCode nfcv_read_blocks(NfcVReader* reader, NfcVData* data) { FURI_LOG_D(TAG, "failed to read: %d", ret); return ret; } - memcpy(&(data->data[block * data->block_size]), &rxBuf[1], data->block_size); + memcpy( + &(nfcv_data->data[block * nfcv_data->block_size]), &rxBuf[1], nfcv_data->block_size); FURI_LOG_D( TAG, " %02X %02X %02X %02X", - data->data[block * data->block_size + 0], - data->data[block * data->block_size + 1], - data->data[block * data->block_size + 2], - data->data[block * data->block_size + 3]); + nfcv_data->data[block * nfcv_data->block_size + 0], + nfcv_data->data[block * nfcv_data->block_size + 1], + nfcv_data->data[block * nfcv_data->block_size + 2], + nfcv_data->data[block * nfcv_data->block_size + 3]); } return ERR_NONE; } -ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* data) { +ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) { uint8_t rxBuf[32]; uint16_t received = 0; ReturnCode ret = ERR_NONE; @@ -96,11 +97,11 @@ ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* data) { for(int pos = 0; pos < nfc_data->uid_len; pos++) { nfc_data->uid[pos] = rxBuf[2 + (7 - pos)]; } - data->dsfid = rxBuf[10]; - data->afi = rxBuf[11]; - data->block_num = rxBuf[12] + 1; - data->block_size = rxBuf[13] + 1; - data->ic_ref = rxBuf[14]; + nfcv_data->dsfid = rxBuf[10]; + nfcv_data->afi = rxBuf[11]; + nfcv_data->block_num = rxBuf[12] + 1; + nfcv_data->block_size = rxBuf[13] + 1; + nfcv_data->ic_ref = rxBuf[14]; FURI_LOG_D( TAG, " UID: %02X %02X %02X %02X %02X %02X %02X %02X", @@ -115,11 +116,11 @@ ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* data) { FURI_LOG_D( TAG, " DSFID %d, AFI %d, Blocks %d, Size %d, IC Ref %d", - data->dsfid, - data->afi, - data->block_num, - data->block_size, - data->ic_ref); + nfcv_data->dsfid, + nfcv_data->afi, + nfcv_data->block_num, + nfcv_data->block_size, + nfcv_data->ic_ref); return ret; } FURI_LOG_D(TAG, "Failed: %d", ret); @@ -142,18 +143,18 @@ bool nfcv_read_card(NfcVReader* reader, FuriHalNfcDevData* nfc_data, NfcVData* n if(slix_check_card_type(nfc_data)) { FURI_LOG_I(TAG, "NXP SLIX detected"); - nfcv_data->type = NfcVTypeSlix; + nfcv_data->sub_type = NfcVTypeSlix; } else if(slix2_check_card_type(nfc_data)) { FURI_LOG_I(TAG, "NXP SLIX2 detected"); - nfcv_data->type = NfcVTypeSlix2; + nfcv_data->sub_type = NfcVTypeSlix2; } else if(slix_s_check_card_type(nfc_data)) { FURI_LOG_I(TAG, "NXP SLIX-S detected"); - nfcv_data->type = NfcVTypeSlixS; + nfcv_data->sub_type = NfcVTypeSlixS; } else if(slix_l_check_card_type(nfc_data)) { FURI_LOG_I(TAG, "NXP SLIX-L detected"); - nfcv_data->type = NfcVTypeSlixL; + nfcv_data->sub_type = NfcVTypeSlixL; } else { - nfcv_data->type = NfcVTypePlain; + nfcv_data->sub_type = NfcVTypePlain; } return true; @@ -179,97 +180,128 @@ void nfcv_crc(uint8_t* data, uint32_t length) { data[length + 1] = crc >> 8; } -void nfcv_emu_free(NfcVData* data) { - digital_sequence_free(data->emu_air.nfcv_signal); - digital_signal_free(data->emu_air.nfcv_resp_unmod_256); - digital_signal_free(data->emu_air.nfcv_resp_pulse_32); - digital_signal_free(data->emu_air.nfcv_resp_one); - digital_signal_free(data->emu_air.nfcv_resp_zero); - digital_signal_free(data->emu_air.nfcv_resp_sof); - digital_signal_free(data->emu_air.nfcv_resp_eof); +void nfcv_emu_free(NfcVData* nfcv_data) { + if(nfcv_data->emu_air.nfcv_signal) { + digital_sequence_free(nfcv_data->emu_air.nfcv_signal); + } + if(nfcv_data->emu_air.nfcv_resp_unmod_256) { + digital_signal_free(nfcv_data->emu_air.nfcv_resp_unmod_256); + } + if(nfcv_data->emu_air.nfcv_resp_pulse_32) { + digital_signal_free(nfcv_data->emu_air.nfcv_resp_pulse_32); + } + if(nfcv_data->emu_air.nfcv_resp_one) { + digital_signal_free(nfcv_data->emu_air.nfcv_resp_one); + } + if(nfcv_data->emu_air.nfcv_resp_zero) { + digital_signal_free(nfcv_data->emu_air.nfcv_resp_zero); + } + if(nfcv_data->emu_air.nfcv_resp_sof) { + digital_signal_free(nfcv_data->emu_air.nfcv_resp_sof); + } + if(nfcv_data->emu_air.nfcv_resp_eof) { + digital_signal_free(nfcv_data->emu_air.nfcv_resp_eof); + } + if(nfcv_data->emu_air.reader_signal) { + pulse_reader_free(nfcv_data->emu_air.reader_signal); + } - data->emu_air.nfcv_signal = NULL; - data->emu_air.nfcv_resp_unmod_256 = NULL; - data->emu_air.nfcv_resp_pulse_32 = NULL; - data->emu_air.nfcv_resp_one = NULL; - data->emu_air.nfcv_resp_zero = NULL; - data->emu_air.nfcv_resp_sof = NULL; - data->emu_air.nfcv_resp_eof = NULL; + nfcv_data->emu_air.nfcv_signal = NULL; + nfcv_data->emu_air.nfcv_resp_unmod_256 = NULL; + nfcv_data->emu_air.nfcv_resp_pulse_32 = NULL; + nfcv_data->emu_air.nfcv_resp_one = NULL; + nfcv_data->emu_air.nfcv_resp_zero = NULL; + nfcv_data->emu_air.nfcv_resp_sof = NULL; + nfcv_data->emu_air.nfcv_resp_eof = NULL; + nfcv_data->emu_air.reader_signal = NULL; } -void nfcv_emu_alloc(NfcVData* data) { - if(!data->emu_air.nfcv_signal) { +void nfcv_emu_alloc(NfcVData* nfcv_data) { + if(!nfcv_data->emu_air.nfcv_signal) { /* assuming max frame length is 255 bytes */ - data->emu_air.nfcv_signal = digital_sequence_alloc(8 * 255 + 2, &gpio_spi_r_mosi); + nfcv_data->emu_air.nfcv_signal = digital_sequence_alloc(8 * 255 + 2, &gpio_spi_r_mosi); } - if(!data->emu_air.nfcv_resp_unmod_256) { + if(!nfcv_data->emu_air.nfcv_resp_unmod_256) { /* unmodulated 256/fc signal as building block */ - data->emu_air.nfcv_resp_unmod_256 = digital_signal_alloc(4); - data->emu_air.nfcv_resp_unmod_256->start_level = false; - data->emu_air.nfcv_resp_unmod_256->edge_timings[0] = + nfcv_data->emu_air.nfcv_resp_unmod_256 = digital_signal_alloc(4); + nfcv_data->emu_air.nfcv_resp_unmod_256->start_level = false; + nfcv_data->emu_air.nfcv_resp_unmod_256->edge_timings[0] = (uint32_t)(NFCV_RESP_SUBC1_UNMOD_256 * DIGITAL_SIGNAL_UNIT_S); - data->emu_air.nfcv_resp_unmod_256->edge_cnt = 1; + nfcv_data->emu_air.nfcv_resp_unmod_256->edge_cnt = 1; } - if(!data->emu_air.nfcv_resp_pulse_32) { + if(!nfcv_data->emu_air.nfcv_resp_pulse_32) { /* modulated fc/32 pulse as building block */ - data->emu_air.nfcv_resp_pulse_32 = digital_signal_alloc(4); - data->emu_air.nfcv_resp_pulse_32->start_level = true; - data->emu_air.nfcv_resp_pulse_32->edge_timings[0] = + nfcv_data->emu_air.nfcv_resp_pulse_32 = digital_signal_alloc(4); + nfcv_data->emu_air.nfcv_resp_pulse_32->start_level = true; + nfcv_data->emu_air.nfcv_resp_pulse_32->edge_timings[0] = (uint32_t)(NFCV_RESP_SUBC1_PULSE_32 * DIGITAL_SIGNAL_UNIT_S); - data->emu_air.nfcv_resp_pulse_32->edge_timings[1] = + nfcv_data->emu_air.nfcv_resp_pulse_32->edge_timings[1] = (uint32_t)(NFCV_RESP_SUBC1_PULSE_32 * DIGITAL_SIGNAL_UNIT_S); - data->emu_air.nfcv_resp_pulse_32->edge_cnt = 2; + nfcv_data->emu_air.nfcv_resp_pulse_32->edge_cnt = 2; } - if(!data->emu_air.nfcv_resp_one) { + if(!nfcv_data->emu_air.nfcv_resp_one) { /* logical one: 256/fc unmodulated then 8 pulses fc/32 */ - data->emu_air.nfcv_resp_one = digital_signal_alloc(24); - digital_signal_append(data->emu_air.nfcv_resp_one, data->emu_air.nfcv_resp_unmod_256); + nfcv_data->emu_air.nfcv_resp_one = digital_signal_alloc(24); + digital_signal_append( + nfcv_data->emu_air.nfcv_resp_one, nfcv_data->emu_air.nfcv_resp_unmod_256); for(size_t i = 0; i < 8; i++) { - digital_signal_append(data->emu_air.nfcv_resp_one, data->emu_air.nfcv_resp_pulse_32); + digital_signal_append( + nfcv_data->emu_air.nfcv_resp_one, nfcv_data->emu_air.nfcv_resp_pulse_32); } } - if(!data->emu_air.nfcv_resp_zero) { + if(!nfcv_data->emu_air.nfcv_resp_zero) { /* logical zero: 8 pulses fc/32 then 256/fc unmodulated */ - data->emu_air.nfcv_resp_zero = digital_signal_alloc(24); + nfcv_data->emu_air.nfcv_resp_zero = digital_signal_alloc(24); for(size_t i = 0; i < 8; i++) { - digital_signal_append(data->emu_air.nfcv_resp_zero, data->emu_air.nfcv_resp_pulse_32); + digital_signal_append( + nfcv_data->emu_air.nfcv_resp_zero, nfcv_data->emu_air.nfcv_resp_pulse_32); } - digital_signal_append(data->emu_air.nfcv_resp_zero, data->emu_air.nfcv_resp_unmod_256); + digital_signal_append( + nfcv_data->emu_air.nfcv_resp_zero, nfcv_data->emu_air.nfcv_resp_unmod_256); } - if(!data->emu_air.nfcv_resp_sof) { + if(!nfcv_data->emu_air.nfcv_resp_sof) { /* SOF: unmodulated 768/fc, 24 pulses fc/32, logic 1 */ - data->emu_air.nfcv_resp_sof = digital_signal_alloc(128); - digital_signal_append(data->emu_air.nfcv_resp_sof, data->emu_air.nfcv_resp_unmod_256); - digital_signal_append(data->emu_air.nfcv_resp_sof, data->emu_air.nfcv_resp_unmod_256); - digital_signal_append(data->emu_air.nfcv_resp_sof, data->emu_air.nfcv_resp_unmod_256); + nfcv_data->emu_air.nfcv_resp_sof = digital_signal_alloc(128); + digital_signal_append( + nfcv_data->emu_air.nfcv_resp_sof, nfcv_data->emu_air.nfcv_resp_unmod_256); + digital_signal_append( + nfcv_data->emu_air.nfcv_resp_sof, nfcv_data->emu_air.nfcv_resp_unmod_256); + digital_signal_append( + nfcv_data->emu_air.nfcv_resp_sof, nfcv_data->emu_air.nfcv_resp_unmod_256); for(size_t i = 0; i < 24; i++) { - digital_signal_append(data->emu_air.nfcv_resp_sof, data->emu_air.nfcv_resp_pulse_32); + digital_signal_append( + nfcv_data->emu_air.nfcv_resp_sof, nfcv_data->emu_air.nfcv_resp_pulse_32); } - digital_signal_append(data->emu_air.nfcv_resp_sof, data->emu_air.nfcv_resp_one); + digital_signal_append(nfcv_data->emu_air.nfcv_resp_sof, nfcv_data->emu_air.nfcv_resp_one); } - if(!data->emu_air.nfcv_resp_eof) { + if(!nfcv_data->emu_air.nfcv_resp_eof) { /* EOF: logic 0, 24 pulses fc/32, unmodulated 768/fc */ - data->emu_air.nfcv_resp_eof = digital_signal_alloc(128); - digital_signal_append(data->emu_air.nfcv_resp_eof, data->emu_air.nfcv_resp_zero); + nfcv_data->emu_air.nfcv_resp_eof = digital_signal_alloc(128); + digital_signal_append(nfcv_data->emu_air.nfcv_resp_eof, nfcv_data->emu_air.nfcv_resp_zero); for(size_t i = 0; i < 24; i++) { - digital_signal_append(data->emu_air.nfcv_resp_eof, data->emu_air.nfcv_resp_pulse_32); + digital_signal_append( + nfcv_data->emu_air.nfcv_resp_eof, nfcv_data->emu_air.nfcv_resp_pulse_32); } - digital_signal_append(data->emu_air.nfcv_resp_eof, data->emu_air.nfcv_resp_unmod_256); - digital_signal_append(data->emu_air.nfcv_resp_eof, data->emu_air.nfcv_resp_unmod_256); - digital_signal_append(data->emu_air.nfcv_resp_eof, data->emu_air.nfcv_resp_unmod_256); + digital_signal_append( + nfcv_data->emu_air.nfcv_resp_eof, nfcv_data->emu_air.nfcv_resp_unmod_256); + digital_signal_append( + nfcv_data->emu_air.nfcv_resp_eof, nfcv_data->emu_air.nfcv_resp_unmod_256); + digital_signal_append( + nfcv_data->emu_air.nfcv_resp_eof, nfcv_data->emu_air.nfcv_resp_unmod_256); /* add extra silence */ - digital_signal_append(data->emu_air.nfcv_resp_eof, data->emu_air.nfcv_resp_unmod_256); + digital_signal_append( + nfcv_data->emu_air.nfcv_resp_eof, nfcv_data->emu_air.nfcv_resp_unmod_256); } digital_sequence_set_signal( - data->emu_air.nfcv_signal, NFCV_SIG_SOF, data->emu_air.nfcv_resp_sof); + nfcv_data->emu_air.nfcv_signal, NFCV_SIG_SOF, nfcv_data->emu_air.nfcv_resp_sof); digital_sequence_set_signal( - data->emu_air.nfcv_signal, NFCV_SIG_BIT0, data->emu_air.nfcv_resp_zero); + nfcv_data->emu_air.nfcv_signal, NFCV_SIG_BIT0, nfcv_data->emu_air.nfcv_resp_zero); digital_sequence_set_signal( - data->emu_air.nfcv_signal, NFCV_SIG_BIT1, data->emu_air.nfcv_resp_one); + nfcv_data->emu_air.nfcv_signal, NFCV_SIG_BIT1, nfcv_data->emu_air.nfcv_resp_one); digital_sequence_set_signal( - data->emu_air.nfcv_signal, NFCV_SIG_EOF, data->emu_air.nfcv_resp_eof); + nfcv_data->emu_air.nfcv_signal, NFCV_SIG_EOF, nfcv_data->emu_air.nfcv_resp_eof); } void nfcv_emu_send( @@ -277,7 +309,8 @@ void nfcv_emu_send( NfcVData* nfcv, uint8_t* data, uint8_t length, - NfcVSendFlags flags) { + NfcVSendFlags flags, + uint32_t send_time) { /* picked default value (0) to match the most common format */ if(!flags) { flags = NfcVSendFlagsSof | NfcVSendFlagsCrc | NfcVSendFlagsEof | @@ -309,6 +342,7 @@ void nfcv_emu_send( } FURI_CRITICAL_ENTER(); + digital_sequence_set_sendtime(nfcv->emu_air.nfcv_signal, send_time); digital_sequence_send(nfcv->emu_air.nfcv_signal); FURI_CRITICAL_EXIT(); furi_hal_gpio_write(&gpio_spi_r_mosi, false); @@ -318,13 +352,13 @@ void nfcv_emu_send( } } -static void nfcv_uidcpy(uint8_t* dst, uint8_t* src) { +static void nfcv_revuidcpy(uint8_t* dst, uint8_t* src) { for(int pos = 0; pos < 8; pos++) { dst[pos] = src[7 - pos]; } } -static int nfcv_uidcmp(uint8_t* dst, uint8_t* src) { +static int nfcv_revuidcmp(uint8_t* dst, uint8_t* src) { for(int pos = 0; pos < 8; pos++) { if(dst[pos] != src[7 - pos]) { return 1; @@ -336,37 +370,29 @@ static int nfcv_uidcmp(uint8_t* dst, uint8_t* src) { void nfcv_emu_handle_packet( FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, - void* nfcv_data_in, - uint8_t* payload, - uint32_t payload_length) { - if(!payload_length) { + void* nfcv_data_in) { + NfcVData* nfcv_data = (NfcVData*)nfcv_data_in; + NfcVEmuProtocolCtx* ctx = nfcv_data->emu_protocol_ctx; + + if(nfcv_data->frame_length < 2) { return; } - NfcVData* nfcv_data = (NfcVData*)nfcv_data_in; - NfcVEmuProtocolCtx* ctx = &nfcv_data->emu_protocol_ctx; - - ctx->frame = payload; - ctx->frame_length = payload_length; - ctx->flags = ctx->frame[0]; - ctx->command = ctx->frame[1]; + /* parse the frame data for the upcoming part 3 handling */ + ctx->flags = nfcv_data->frame[0]; + ctx->command = nfcv_data->frame[1]; ctx->addressed = !(ctx->flags & RFAL_NFCV_REQ_FLAG_INVENTORY) && (ctx->flags & RFAL_NFCV_REQ_FLAG_ADDRESS); ctx->advanced = (ctx->command >= 0xA0); ctx->address_offset = 2 + (ctx->advanced ? 1 : 0); ctx->payload_offset = ctx->address_offset + (ctx->addressed ? 8 : 0); ctx->response_flags = NfcVSendFlagsNormal; + ctx->send_time = nfcv_data->eof_timestamp + NFCV_FDT_FC(4130); - /* first give control to the card specific protocol handler */ - if(nfcv_data->emu_protocol_filter != NULL) { - if(nfcv_data->emu_protocol_filter(tx_rx, nfc_data, nfcv_data)) { - return; - } - } - + /* standard behavior is implemented */ if(ctx->addressed) { - uint8_t* address = &ctx->frame[ctx->address_offset]; - if(nfcv_uidcmp(address, nfc_data->uid)) { + uint8_t* address = &nfcv_data->frame[ctx->address_offset]; + if(nfcv_revuidcmp(address, nfc_data->uid)) { FURI_LOG_D(TAG, "addressed command 0x%02X, but not for us:", ctx->command); FURI_LOG_D( TAG, @@ -394,16 +420,25 @@ void nfcv_emu_handle_packet( } } - /* unfortunately our response is quicker than the original NFC tag which causes frame misses */ - furi_delay_us(270); + /* then give control to the card subtype specific protocol filter */ + if(ctx->emu_protocol_filter != NULL) { + if(ctx->emu_protocol_filter(tx_rx, nfc_data, nfcv_data)) { + if(strlen(nfcv_data->last_command) > 0) { + FURI_LOG_D( + TAG, "Received command %s (handled by filter)", nfcv_data->last_command); + } + return; + } + } switch(ctx->command) { case ISO15693_INVENTORY: { ctx->response_buffer[0] = ISO15693_NOERROR; ctx->response_buffer[1] = nfcv_data->dsfid; - nfcv_uidcpy(&ctx->response_buffer[2], nfc_data->uid); + nfcv_revuidcpy(&ctx->response_buffer[2], nfc_data->uid); - nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 10, ctx->response_flags); + nfcv_emu_send( + tx_rx, nfcv_data, ctx->response_buffer, 10, ctx->response_flags, ctx->send_time); snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "INVENTORY"); break; } @@ -420,23 +455,25 @@ void nfcv_emu_handle_packet( case ISO15693_SELECT: { ctx->response_buffer[0] = ISO15693_NOERROR; - nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags); + nfcv_emu_send( + tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags, ctx->send_time); snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "SELECT"); break; } case ISO15693_READ_MULTI_BLOCK: case ISO15693_READBLOCK: { - uint8_t block = ctx->frame[ctx->payload_offset]; + uint8_t block = nfcv_data->frame[ctx->payload_offset]; uint8_t blocks = 1; if(ctx->command == ISO15693_READ_MULTI_BLOCK) { - blocks = ctx->frame[ctx->payload_offset + 1] + 1; + blocks = nfcv_data->frame[ctx->payload_offset + 1] + 1; } if(block + blocks > nfcv_data->block_num) { ctx->response_buffer[0] = ISO15693_ERROR_CMD_NOT_REC; - nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags); + nfcv_emu_send( + tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags, ctx->send_time); } else { ctx->response_buffer[0] = ISO15693_NOERROR; memcpy( @@ -448,7 +485,8 @@ void nfcv_emu_handle_packet( nfcv_data, ctx->response_buffer, 1 + nfcv_data->block_size * blocks, - ctx->response_flags); + ctx->response_flags, + ctx->send_time); } snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "READ BLOCK %d", block); break; @@ -456,29 +494,30 @@ void nfcv_emu_handle_packet( case ISO15693_WRITE_MULTI_BLOCK: case ISO15693_WRITEBLOCK: { - uint8_t block = ctx->frame[ctx->payload_offset]; + uint8_t block = nfcv_data->frame[ctx->payload_offset]; uint8_t blocks = 1; uint8_t data_pos = 1; if(ctx->command == ISO15693_WRITE_MULTI_BLOCK) { - blocks = ctx->frame[ctx->payload_offset + 1] + 1; + blocks = nfcv_data->frame[ctx->payload_offset + 1] + 1; data_pos++; } - uint8_t* data = &ctx->frame[ctx->payload_offset + data_pos]; + uint8_t* data = &nfcv_data->frame[ctx->payload_offset + data_pos]; uint32_t data_len = nfcv_data->block_size * blocks; if(block + blocks > nfcv_data->block_num || - ctx->payload_offset + data_len + 2 > payload_length) { + ctx->payload_offset + data_len + 2 > nfcv_data->frame_length) { ctx->response_buffer[0] = ISO15693_ERROR_CMD_NOT_REC; } else { ctx->response_buffer[0] = ISO15693_NOERROR; memcpy( &nfcv_data->data[nfcv_data->block_size * block], - &ctx->frame[ctx->payload_offset + data_pos], + &nfcv_data->frame[ctx->payload_offset + data_pos], data_len); } - nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags); + nfcv_emu_send( + tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags, ctx->send_time); if(ctx->command == ISO15693_WRITE_MULTI_BLOCK) { snprintf( @@ -504,14 +543,15 @@ void nfcv_emu_handle_packet( case ISO15693_GET_SYSTEM_INFO: { ctx->response_buffer[0] = ISO15693_NOERROR; ctx->response_buffer[1] = 0x0F; - nfcv_uidcpy(&ctx->response_buffer[2], nfc_data->uid); + nfcv_revuidcpy(&ctx->response_buffer[2], nfc_data->uid); ctx->response_buffer[10] = nfcv_data->dsfid; /* DSFID */ ctx->response_buffer[11] = nfcv_data->afi; /* AFI */ ctx->response_buffer[12] = nfcv_data->block_num - 1; /* number of blocks */ ctx->response_buffer[13] = nfcv_data->block_size - 1; /* block size */ ctx->response_buffer[14] = nfcv_data->ic_ref; /* IC reference */ - nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 15, ctx->response_flags); + nfcv_emu_send( + tx_rx, nfcv_data, ctx->response_buffer, 15, ctx->response_flags, ctx->send_time); snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "SYSTEMINFO"); break; } @@ -533,15 +573,22 @@ void nfcv_emu_handle_packet( void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) { nfcv_emu_alloc(nfcv_data); rfal_platform_spi_acquire(); - + /* configure for transparent and passive mode */ st25r3916ExecuteCommand(ST25R3916_CMD_STOP); + /* set enable, rx_enable and field detector enable */ st25r3916WriteRegister(ST25R3916_REG_OP_CONTROL, 0xC3); + /* target mode: ISO14443 passive mode */ st25r3916WriteRegister(ST25R3916_REG_MODE, 0x88); + /* let us modulate the field using MOSI, read modulation using MISO */ st25r3916ExecuteCommand(ST25R3916_CMD_TRANSPARENT_MODE); furi_hal_spi_bus_handle_deinit(&furi_hal_spi_bus_handle_nfc); - nfcv_data->emu_protocol_handler = &nfcv_emu_handle_packet; + /* if not set already, initialize the default protocol handler */ + if(!nfcv_data->emu_protocol_ctx) { + nfcv_data->emu_protocol_ctx = malloc(sizeof(NfcVEmuProtocolCtx)); + nfcv_data->emu_protocol_handler = &nfcv_emu_handle_packet; + } FURI_LOG_D(TAG, "Starting NfcV emulation"); FURI_LOG_D( @@ -556,7 +603,7 @@ void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) { nfc_data->uid[6], nfc_data->uid[7]); - switch(nfcv_data->type) { + switch(nfcv_data->sub_type) { case NfcVTypeSlixL: FURI_LOG_D(TAG, " Card type: SLIX-L"); slix_l_prepare(nfcv_data); @@ -592,7 +639,10 @@ void nfcv_emu_deinit(NfcVData* nfcv_data) { rfal_platform_spi_release(); nfcv_emu_free(nfcv_data); - pulse_reader_free(nfcv_data->emu_air.reader_signal); + if(nfcv_data->emu_protocol_ctx) { + free(nfcv_data->emu_protocol_ctx); + nfcv_data->emu_protocol_ctx = NULL; + } } bool nfcv_emu_loop( @@ -613,6 +663,7 @@ bool nfcv_emu_loop( while(true) { uint32_t periods = pulse_reader_receive(nfcv_data->emu_air.reader_signal, timeout_ms * 1000); + uint32_t timestamp = DWT->CYCCNT; if(periods == PULSE_READER_NO_EDGE) { break; @@ -754,6 +805,9 @@ bool nfcv_emu_loop( FURI_LOG_D(TAG, "Resetting state machine, reason: '%s'", reset_reason); } else if(frame_state == NFCV_FRAME_STATE_EOF) { + nfcv_data->frame = frame_payload; + nfcv_data->frame_length = frame_pos; + nfcv_data->eof_timestamp = timestamp; break; } } @@ -764,10 +818,10 @@ bool nfcv_emu_loop( if(tx_rx->sniff_rx) { tx_rx->sniff_rx(frame_payload, frame_pos * 8, false, tx_rx->sniff_context); } - nfcv_data->emu_protocol_handler(tx_rx, nfc_data, nfcv_data, frame_payload, frame_pos); + nfcv_data->emu_protocol_handler(tx_rx, nfc_data, nfcv_data); pulse_reader_start(nfcv_data->emu_air.reader_signal); ret = true; } return ret; -} \ No newline at end of file +} diff --git a/lib/nfc/protocols/nfcv.h b/lib/nfc/protocols/nfcv.h index 3e76aa206..cc0aac18c 100644 --- a/lib/nfc/protocols/nfcv.h +++ b/lib/nfc/protocols/nfcv.h @@ -8,6 +8,10 @@ #include "nfc_util.h" #include +#ifdef __cplusplus +extern "C" { +#endif + #define NFCV_FC (13560000.0f) /* MHz */ #define NFCV_RESP_SUBC1_PULSE_32 (1.0f / (NFCV_FC / 32) / 2.0f) /* 1.1799 µs */ #define NFCV_RESP_SUBC1_UNMOD_256 (256.0f / NFCV_FC) /* 18.8791 µs */ @@ -21,6 +25,10 @@ #define NFCV_BLOCK_SIZE 4 #define NFCV_MAX_DUMP_SIZE (NFCV_BLOCK_SIZE * NFCV_TOTAL_BLOCKS_MAX) +/* helpers to calculate the send time based on DWT->CYCCNT */ +#define NFCV_FDT_USEC(usec) (usec * 64) +#define NFCV_FDT_FC(ticks) (ticks * 6400 / 1356) + #define NFCV_FRAME_STATE_SOF1 0 #define NFCV_FRAME_STATE_SOF2 1 #define NFCV_FRAME_STATE_CODING_4 2 @@ -73,7 +81,7 @@ typedef enum { NfcVTypeSlixS = 2, NfcVTypeSlixL = 3, NfcVTypeSlix2 = 4, -} NfcVType; +} NfcVSubtype; typedef enum { NfcVSendFlagsNormal = 0, @@ -113,10 +121,16 @@ typedef struct { DigitalSequence* nfcv_signal; } NfcVEmuAir; -typedef struct { - uint8_t* frame; /* ISO15693-2 incoming raw data from air layer */ - uint8_t frame_length; /* ISO15693-2 length of incoming data */ +typedef void (*NfcVEmuProtocolHandler)( + FuriHalNfcTxRxContext* tx_rx, + FuriHalNfcDevData* nfc_data, + void* nfcv_data); +typedef bool (*NfcVEmuProtocolFilter)( + FuriHalNfcTxRxContext* tx_rx, + FuriHalNfcDevData* nfc_data, + void* nfcv_data); +typedef struct { uint8_t flags; /* ISO15693-3 flags of the header as specified */ uint8_t command; /* ISO15693-3 command at offset 1 as specified */ bool addressed; /* ISO15693-3 flags: addressed frame */ @@ -126,21 +140,13 @@ typedef struct { uint8_t response_buffer[128]; /* pre-allocated response buffer */ NfcVSendFlags response_flags; /* flags to use when sending response */ + uint32_t send_time; /* timestamp when to send the response */ + + NfcVEmuProtocolFilter emu_protocol_filter; } NfcVEmuProtocolCtx; -typedef void (*NfcVEmuProtocolHandler)( - FuriHalNfcTxRxContext* tx_rx, - FuriHalNfcDevData* nfc_data, - void* nfcv_data, - uint8_t* payload, - uint32_t payload_length); -typedef bool (*NfcVEmuProtocolFilter)( - FuriHalNfcTxRxContext* tx_rx, - FuriHalNfcDevData* nfc_data, - void* nfcv_data); - typedef struct { - /* common ISO15693 fields */ + /* common ISO15693 fields, being specified in ISO15693-3 */ uint8_t dsfid; uint8_t afi; uint8_t ic_ref; @@ -149,18 +155,24 @@ typedef struct { uint8_t data[NFCV_MAX_DUMP_SIZE]; /* specfic variant infos */ - NfcVType type; + NfcVSubtype sub_type; NfcVSubtypeData sub_data; + NfcVAuthMethod auth_method; + + /* precalced air level data */ NfcVEmuAir emu_air; - NfcVEmuProtocolCtx emu_protocol_ctx; + + uint8_t* frame; /* ISO15693-2 incoming raw data from air layer */ + uint8_t frame_length; /* ISO15693-2 length of incoming data */ + uint32_t eof_timestamp; /* ISO15693-2 EOF timestamp, read from DWT->CYCCNT */ + + /* handler for the protocol layer as specified in ISO15693-3 */ NfcVEmuProtocolHandler emu_protocol_handler; - NfcVEmuProtocolFilter emu_protocol_filter; + void* emu_protocol_ctx; /* runtime data */ char last_command[128]; char error[32]; - NfcVAuthMethod auth_method; - bool auth_success; } NfcVData; typedef struct { @@ -175,7 +187,6 @@ bool nfcv_read_card(NfcVReader* reader, FuriHalNfcDevData* nfc_data, NfcVData* d void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data); void nfcv_emu_deinit(NfcVData* nfcv_data); - bool nfcv_emu_loop( FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, @@ -186,4 +197,9 @@ void nfcv_emu_send( NfcVData* nfcv, uint8_t* data, uint8_t length, - NfcVSendFlags flags); + NfcVSendFlags flags, + uint32_t send_time); + +#ifdef __cplusplus +} +#endif diff --git a/lib/nfc/protocols/slix.c b/lib/nfc/protocols/slix.c index 3ef4a7c75..e61c70919 100644 --- a/lib/nfc/protocols/slix.c +++ b/lib/nfc/protocols/slix.c @@ -147,7 +147,7 @@ bool slix_generic_protocol_filter( furi_assert(nfcv_data_in); NfcVData* nfcv_data = (NfcVData*)nfcv_data_in; - NfcVEmuProtocolCtx* ctx = &nfcv_data->emu_protocol_ctx; + NfcVEmuProtocolCtx* ctx = nfcv_data->emu_protocol_ctx; NfcVSlixData* slix = &nfcv_data->sub_data.slix; if(slix->privacy && ctx->command != ISO15693_CMD_NXP_GET_RANDOM_NUMBER && @@ -172,7 +172,8 @@ bool slix_generic_protocol_filter( ctx->response_buffer[1] = slix->rand[1]; ctx->response_buffer[2] = slix->rand[0]; - nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 3, ctx->response_flags); + nfcv_emu_send( + tx_rx, nfcv_data, ctx->response_buffer, 3, ctx->response_flags, ctx->send_time); snprintf( nfcv_data->last_command, sizeof(nfcv_data->last_command), @@ -185,13 +186,13 @@ bool slix_generic_protocol_filter( } case ISO15693_CMD_NXP_SET_PASSWORD: { - uint8_t password_id = ctx->frame[ctx->payload_offset]; + uint8_t password_id = nfcv_data->frame[ctx->payload_offset]; if(!(password_id & password_supported)) { break; } - uint8_t* password_xored = &ctx->frame[ctx->payload_offset + 1]; + uint8_t* password_xored = &nfcv_data->frame[ctx->payload_offset + 1]; uint8_t* rand = slix->rand; uint8_t* password = NULL; uint8_t password_rcv[4]; @@ -241,7 +242,8 @@ bool slix_generic_protocol_filter( break; } ctx->response_buffer[0] = ISO15693_NOERROR; - nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags); + nfcv_emu_send( + tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags, ctx->send_time); snprintf( nfcv_data->last_command, sizeof(nfcv_data->last_command), @@ -264,7 +266,8 @@ bool slix_generic_protocol_filter( case ISO15693_CMD_NXP_ENABLE_PRIVACY: { ctx->response_buffer[0] = ISO15693_NOERROR; - nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags); + nfcv_emu_send( + tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags, ctx->send_time); snprintf( nfcv_data->last_command, sizeof(nfcv_data->last_command), @@ -309,7 +312,8 @@ void slix_l_prepare(NfcVData* nfcv_data) { FURI_LOG_D(TAG, " EAS pass: 0x%08lX", slix_read_be(nfcv_data->sub_data.slix.key_eas, 4)); FURI_LOG_D(TAG, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF"); - nfcv_data->emu_protocol_filter = &slix_l_protocol_filter; + NfcVEmuProtocolCtx* ctx = nfcv_data->emu_protocol_ctx; + ctx->emu_protocol_filter = &slix_l_protocol_filter; } bool slix_s_protocol_filter( @@ -338,7 +342,8 @@ void slix_s_prepare(NfcVData* nfcv_data) { FURI_LOG_D(TAG, " EAS pass: 0x%08lX", slix_read_be(nfcv_data->sub_data.slix.key_eas, 4)); FURI_LOG_D(TAG, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF"); - nfcv_data->emu_protocol_filter = &slix_s_protocol_filter; + NfcVEmuProtocolCtx* ctx = nfcv_data->emu_protocol_ctx; + ctx->emu_protocol_filter = &slix_s_protocol_filter; } bool slix_protocol_filter( @@ -367,7 +372,8 @@ void slix_prepare(NfcVData* nfcv_data) { FURI_LOG_D(TAG, " EAS pass: 0x%08lX", slix_read_be(nfcv_data->sub_data.slix.key_eas, 4)); FURI_LOG_D(TAG, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF"); - nfcv_data->emu_protocol_filter = &slix_protocol_filter; + NfcVEmuProtocolCtx* ctx = nfcv_data->emu_protocol_ctx; + ctx->emu_protocol_filter = &slix_protocol_filter; } bool slix2_protocol_filter( @@ -396,5 +402,6 @@ void slix2_prepare(NfcVData* nfcv_data) { FURI_LOG_D(TAG, " EAS pass: 0x%08lX", slix_read_be(nfcv_data->sub_data.slix.key_eas, 4)); FURI_LOG_D(TAG, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF"); - nfcv_data->emu_protocol_filter = &slix2_protocol_filter; + NfcVEmuProtocolCtx* ctx = nfcv_data->emu_protocol_ctx; + ctx->emu_protocol_filter = &slix2_protocol_filter; } diff --git a/lib/pulse_reader/pulse_reader.c b/lib/pulse_reader/pulse_reader.c index 18ebfefe8..20f993844 100644 --- a/lib/pulse_reader/pulse_reader.c +++ b/lib/pulse_reader/pulse_reader.c @@ -198,8 +198,5 @@ uint32_t pulse_reader_receive(PulseReader* signal, int timeout_us) { if(elapsed > timeout_ticks) { return PULSE_READER_NO_EDGE; } - - //furi_delay_ms(0); - } while(true); }