From 78c5dd95d867941206e1be2fd3585c9c76132bd7 Mon Sep 17 00:00:00 2001 From: Zinong Li <131403964+zinongli@users.noreply.github.com> Date: Mon, 9 Sep 2024 13:23:18 -0400 Subject: [PATCH 1/2] LFRFID GProxII Fix Writing and Rendering Conflict (#3888) --- lib/lfrfid/protocols/protocol_gproxii.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/lfrfid/protocols/protocol_gproxii.c b/lib/lfrfid/protocols/protocol_gproxii.c index ab1d0b94d..341d092e9 100644 --- a/lib/lfrfid/protocols/protocol_gproxii.c +++ b/lib/lfrfid/protocols/protocol_gproxii.c @@ -39,7 +39,7 @@ void protocol_gproxii_free(ProtocolGProxII* protocol) { } uint8_t* protocol_gproxii_get_data(ProtocolGProxII* protocol) { - return protocol->decoded_data; + return protocol->data; } bool wiegand_check(uint64_t fc_and_card, bool even_parity, bool odd_parity, int card_len) { @@ -235,6 +235,7 @@ LevelDuration protocol_gproxii_encoder_yield(ProtocolGProxII* protocol) { } void protocol_gproxii_render_data(ProtocolGProxII* protocol, FuriString* result) { + protocol_gproxii_can_be_decoded(protocol); int xor_code = bit_lib_get_bits(protocol->decoded_data, 0, 8); int card_len = bit_lib_get_bits(protocol->decoded_data, 8, 6); int crc_code = bit_lib_get_bits(protocol->decoded_data, 14, 2); From 5f4f4fcc60f587962b0518b7d58523b4d0bab6de Mon Sep 17 00:00:00 2001 From: RebornedBrain <138568282+RebornedBrain@users.noreply.github.com> Date: Tue, 10 Sep 2024 00:11:53 +0300 Subject: [PATCH 2/2] FeliCa anti-collision fix (#3889) * System code added to felica hal config functions * Felica sensf_res setup logic adjusted with new struct * Set api symbols version to 73.0 * Felica unit tests fix * Furi: prevent use after free on xEventGroupSetBits call Co-authored-by: Aleksandr Kutuzov --- furi/core/event_flag.c | 2 ++ furi/core/event_flag.h | 11 ++++++-- furi/core/timer.c | 8 ++++-- lib/nfc/nfc.c | 5 ++-- lib/nfc/nfc.h | 4 ++- lib/nfc/nfc_mock.c | 9 +++--- lib/nfc/protocols/felica/felica_listener.c | 3 +- targets/f18/api_symbols.csv | 2 +- targets/f7/api_symbols.csv | 6 ++-- targets/f7/furi_hal/furi_hal_nfc_felica.c | 32 ++++++++++++++++++---- targets/furi_hal_include/furi_hal_nfc.h | 4 ++- 11 files changed, 62 insertions(+), 24 deletions(-) diff --git a/furi/core/event_flag.c b/furi/core/event_flag.c index f89c4e77f..19b28a500 100644 --- a/furi/core/event_flag.c +++ b/furi/core/event_flag.c @@ -48,7 +48,9 @@ uint32_t furi_event_flag_set(FuriEventFlag* instance, uint32_t flags) { portYIELD_FROM_ISR(yield); } } else { + vTaskSuspendAll(); rflags = xEventGroupSetBits(hEventGroup, (EventBits_t)flags); + (void)xTaskResumeAll(); } /* Return event flags after setting */ diff --git a/furi/core/event_flag.h b/furi/core/event_flag.h index fbc3bb004..6408f47be 100644 --- a/furi/core/event_flag.h +++ b/furi/core/event_flag.h @@ -26,10 +26,15 @@ void furi_event_flag_free(FuriEventFlag* instance); /** Set flags * - * @param instance pointer to FuriEventFlag - * @param[in] flags The flags + * @warning result of this function can be flags that you've just asked to + * set or not if someone was waiting for them and asked to clear it. + * It is highly recommended to read this function and + * xEventGroupSetBits source code. * - * @return Resulting flags or error (FuriStatus) + * @param instance pointer to FuriEventFlag + * @param[in] flags The flags to set + * + * @return Resulting flags(see warning) or error (FuriStatus) */ uint32_t furi_event_flag_set(FuriEventFlag* instance, uint32_t flags); diff --git a/furi/core/timer.c b/furi/core/timer.c index 21952cf12..01adbeb89 100644 --- a/furi/core/timer.c +++ b/furi/core/timer.c @@ -45,7 +45,9 @@ static void furi_timer_epilogue(void* context, uint32_t arg) { UNUSED(arg); EventGroupHandle_t hEvent = context; + vTaskSuspendAll(); xEventGroupSetBits(hEvent, TIMER_DELETED_EVENT); + (void)xTaskResumeAll(); } void furi_timer_free(FuriTimer* instance) { @@ -55,11 +57,13 @@ void furi_timer_free(FuriTimer* instance) { TimerHandle_t hTimer = (TimerHandle_t)instance; furi_check(xTimerDelete(hTimer, portMAX_DELAY) == pdPASS); - StaticEventGroup_t event_container; + StaticEventGroup_t event_container = {}; EventGroupHandle_t hEvent = xEventGroupCreateStatic(&event_container); furi_check(xTimerPendFunctionCall(furi_timer_epilogue, hEvent, 0, portMAX_DELAY) == pdPASS); - xEventGroupWaitBits(hEvent, TIMER_DELETED_EVENT, 0, pdTRUE, portMAX_DELAY); + furi_check( + xEventGroupWaitBits(hEvent, TIMER_DELETED_EVENT, pdFALSE, pdTRUE, portMAX_DELAY) == + TIMER_DELETED_EVENT); vEventGroupDelete(hEvent); free(instance); diff --git a/lib/nfc/nfc.c b/lib/nfc/nfc.c index d0d342a6b..90e65b282 100644 --- a/lib/nfc/nfc.c +++ b/lib/nfc/nfc.c @@ -651,11 +651,12 @@ NfcError nfc_felica_listener_set_sensf_res_data( const uint8_t* idm, const uint8_t idm_len, const uint8_t* pmm, - const uint8_t pmm_len) { + const uint8_t pmm_len, + const uint16_t sys_code) { furi_check(instance); FuriHalNfcError error = - furi_hal_nfc_felica_listener_set_sensf_res_data(idm, idm_len, pmm, pmm_len); + furi_hal_nfc_felica_listener_set_sensf_res_data(idm, idm_len, pmm, pmm_len, sys_code); instance->comm_state = NfcCommStateIdle; return nfc_process_hal_error(error); } diff --git a/lib/nfc/nfc.h b/lib/nfc/nfc.h index 959bd018f..8fbf90d1f 100644 --- a/lib/nfc/nfc.h +++ b/lib/nfc/nfc.h @@ -361,6 +361,7 @@ NfcError nfc_iso14443a_listener_set_col_res_data( * @param[in] idm_len IDm length in bytes. * @param[in] pmm pointer to a byte array containing the PMm. * @param[in] pmm_len PMm length in bytes. + * @param[in] sys_code System code from SYS_C block * @returns NfcErrorNone on success, any other error code on failure. */ NfcError nfc_felica_listener_set_sensf_res_data( @@ -368,7 +369,8 @@ NfcError nfc_felica_listener_set_sensf_res_data( const uint8_t* idm, const uint8_t idm_len, const uint8_t* pmm, - const uint8_t pmm_len); + const uint8_t pmm_len, + const uint16_t sys_code); /** * @brief Send ISO15693 Start of Frame pattern in listener mode diff --git a/lib/nfc/nfc_mock.c b/lib/nfc/nfc_mock.c index a17f0e104..ee4bb09cc 100644 --- a/lib/nfc/nfc_mock.c +++ b/lib/nfc/nfc_mock.c @@ -270,7 +270,8 @@ static void nfc_worker_listener_pass_col_res(Nfc* instance, uint8_t* rx_data, ui } } else if(rx_bits == 8 * 8) { FelicaPollingRequest* request = (FelicaPollingRequest*)rx_data; - if(request->system_code == instance->pt_memory.system_code) { + if(request->system_code == 0xFFFF || + request->system_code == instance->pt_memory.system_code) { uint8_t response_size = sizeof(FelicaSensfResData) + 1; bit_buffer_reset(tx_buffer); bit_buffer_append_byte(tx_buffer, response_size); @@ -501,19 +502,19 @@ NfcError nfc_felica_listener_set_sensf_res_data( const uint8_t* idm, const uint8_t idm_len, const uint8_t* pmm, - const uint8_t pmm_len) { + const uint8_t pmm_len, + const uint16_t sys_code) { furi_assert(instance); furi_assert(idm); furi_assert(pmm); furi_assert(idm_len == 8); furi_assert(pmm_len == 8); - instance->pt_memory.system_code = 0xFFFF; + instance->pt_memory.system_code = sys_code; instance->pt_memory.sens_res.code = 0x01; instance->software_col_res_required = true; memcpy(instance->pt_memory.sens_res.idm.data, idm, idm_len); memcpy(instance->pt_memory.sens_res.pmm.data, pmm, pmm_len); - return NfcErrorNone; } diff --git a/lib/nfc/protocols/felica/felica_listener.c b/lib/nfc/protocols/felica/felica_listener.c index d019eb21d..90954de97 100644 --- a/lib/nfc/protocols/felica/felica_listener.c +++ b/lib/nfc/protocols/felica/felica_listener.c @@ -26,8 +26,9 @@ FelicaListener* felica_listener_alloc(Nfc* nfc, FelicaData* data) { memcpy(instance->mc_shadow.data, instance->data->data.fs.mc.data, FELICA_DATA_BLOCK_SIZE); instance->data->data.fs.state.data[0] = 0; nfc_config(instance->nfc, NfcModeListener, NfcTechFelica); + const uint16_t system_code = *(uint16_t*)data->data.fs.sys_c.data; nfc_felica_listener_set_sensf_res_data( - nfc, data->idm.data, sizeof(data->idm), data->pmm.data, sizeof(data->pmm)); + nfc, data->idm.data, sizeof(data->idm), data->pmm.data, sizeof(data->pmm), system_code); return instance; } diff --git a/targets/f18/api_symbols.csv b/targets/f18/api_symbols.csv index a8da2b366..553cf1472 100644 --- a/targets/f18/api_symbols.csv +++ b/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,72.5,, +Version,+,73.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, Header,+,applications/services/cli/cli.h,, diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index c294a3b7d..5d5c2a707 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,72.5,, +Version,+,73.0,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, @@ -1444,7 +1444,7 @@ Function,+,furi_hal_nfc_abort,FuriHalNfcError, Function,+,furi_hal_nfc_acquire,FuriHalNfcError, Function,+,furi_hal_nfc_event_start,FuriHalNfcError, Function,+,furi_hal_nfc_event_stop,FuriHalNfcError, -Function,+,furi_hal_nfc_felica_listener_set_sensf_res_data,FuriHalNfcError,"const uint8_t*, const uint8_t, const uint8_t*, const uint8_t" +Function,+,furi_hal_nfc_felica_listener_set_sensf_res_data,FuriHalNfcError,"const uint8_t*, const uint8_t, const uint8_t*, const uint8_t, const uint16_t" Function,+,furi_hal_nfc_field_detect_start,FuriHalNfcError, Function,+,furi_hal_nfc_field_detect_stop,FuriHalNfcError, Function,+,furi_hal_nfc_field_is_present,_Bool, @@ -2778,7 +2778,7 @@ Function,+,nfc_device_save,_Bool,"NfcDevice*, const char*" Function,+,nfc_device_set_data,void,"NfcDevice*, NfcProtocol, const NfcDeviceData*" Function,+,nfc_device_set_loading_callback,void,"NfcDevice*, NfcLoadingCallback, void*" Function,+,nfc_device_set_uid,_Bool,"NfcDevice*, const uint8_t*, size_t" -Function,+,nfc_felica_listener_set_sensf_res_data,NfcError,"Nfc*, const uint8_t*, const uint8_t, const uint8_t*, const uint8_t" +Function,+,nfc_felica_listener_set_sensf_res_data,NfcError,"Nfc*, const uint8_t*, const uint8_t, const uint8_t*, const uint8_t, const uint16_t" Function,+,nfc_free,void,Nfc* Function,+,nfc_iso14443a_listener_set_col_res_data,NfcError,"Nfc*, uint8_t*, uint8_t, uint8_t*, uint8_t" Function,+,nfc_iso14443a_listener_tx_custom_parity,NfcError,"Nfc*, const BitBuffer*" diff --git a/targets/f7/furi_hal/furi_hal_nfc_felica.c b/targets/f7/furi_hal/furi_hal_nfc_felica.c index 89305877e..6c3f55525 100644 --- a/targets/f7/furi_hal/furi_hal_nfc_felica.c +++ b/targets/f7/furi_hal/furi_hal_nfc_felica.c @@ -4,6 +4,20 @@ // Prevent FDT timer from starting #define FURI_HAL_NFC_FELICA_LISTENER_FDT_COMP_FC (INT32_MAX) +#define FURI_HAL_FELICA_COMMUNICATION_PERFORMANCE (0x0083U) +#define FURI_HAL_FELICA_RESPONSE_CODE (0x01) +#define FURI_HAL_FELICA_IDM_PMM_LENGTH (8) + +#pragma pack(push, 1) +typedef struct { + uint16_t system_code; + uint8_t response_code; + uint8_t Idm[FURI_HAL_FELICA_IDM_PMM_LENGTH]; + uint8_t Pmm[FURI_HAL_FELICA_IDM_PMM_LENGTH]; + uint16_t communication_performance; +} FuriHalFelicaPtMemory; +#pragma pack(pop) + static FuriHalNfcError furi_hal_nfc_felica_poller_init(FuriHalSpiBusHandle* handle) { // Enable Felica mode, AM modulation st25r3916_change_reg_bits( @@ -161,17 +175,23 @@ FuriHalNfcError furi_hal_nfc_felica_listener_set_sensf_res_data( const uint8_t* idm, const uint8_t idm_len, const uint8_t* pmm, - const uint8_t pmm_len) { + const uint8_t pmm_len, + const uint16_t sys_code) { furi_check(idm); furi_check(pmm); + furi_check(idm_len == FURI_HAL_FELICA_IDM_PMM_LENGTH); + furi_check(pmm_len == FURI_HAL_FELICA_IDM_PMM_LENGTH); FuriHalSpiBusHandle* handle = &furi_hal_spi_bus_handle_nfc; // Write PT Memory - uint8_t pt_memory[19] = {}; - pt_memory[2] = 0x01; - memcpy(pt_memory + 3, idm, idm_len); - memcpy(pt_memory + 3 + idm_len, pmm, pmm_len); - st25r3916_write_ptf_mem(handle, pt_memory, sizeof(pt_memory)); + FuriHalFelicaPtMemory pt; + pt.system_code = sys_code; + pt.response_code = FURI_HAL_FELICA_RESPONSE_CODE; + pt.communication_performance = __builtin_bswap16(FURI_HAL_FELICA_COMMUNICATION_PERFORMANCE); + memcpy(pt.Idm, idm, idm_len); + memcpy(pt.Pmm, pmm, pmm_len); + + st25r3916_write_ptf_mem(handle, (uint8_t*)&pt, sizeof(FuriHalFelicaPtMemory)); return FuriHalNfcErrorNone; } diff --git a/targets/furi_hal_include/furi_hal_nfc.h b/targets/furi_hal_include/furi_hal_nfc.h index 1c9f54d35..3a81de6f5 100644 --- a/targets/furi_hal_include/furi_hal_nfc.h +++ b/targets/furi_hal_include/furi_hal_nfc.h @@ -461,13 +461,15 @@ FuriHalNfcError furi_hal_nfc_iso15693_listener_tx_sof(void); * @param[in] idm_len IDm length in bytes. * @param[in] pmm pointer to a byte array containing the PMm. * @param[in] pmm_len PMm length in bytes. + * @param[in] sys_code System code from SYS_C block * @returns NfcErrorNone on success, any other error code on failure. */ FuriHalNfcError furi_hal_nfc_felica_listener_set_sensf_res_data( const uint8_t* idm, const uint8_t idm_len, const uint8_t* pmm, - const uint8_t pmm_len); + const uint8_t pmm_len, + const uint16_t sys_code); #ifdef __cplusplus }