[FL-3640] NFC: Felica UID emulation (#3190)
* Added basic template of Felica listener * Raw nfc felica listener functions * Added functions to setup chip for felica listener * Cleanup function templates from unnecessary parts * Removed todo comment * Updated api versions * Adjusted chip config for felica * Set proper chip passive target mode for felica * Added felica function to unit tests * Update furi_hal_nfc_felica.c * Removed duplication Co-authored-by: gornekich <n.gorbadey@gmail.com>
This commit is contained in:
		
							parent
							
								
									4b3e8aba29
								
							
						
					
					
						commit
						1c3cbec661
					
				| @ -455,4 +455,19 @@ NfcError nfc_iso15693_listener_tx_sof(Nfc* instance) { | ||||
|     return NfcErrorNone; | ||||
| } | ||||
| 
 | ||||
| NfcError nfc_felica_listener_set_sensf_res_data( | ||||
|     Nfc* instance, | ||||
|     const uint8_t* idm, | ||||
|     const uint8_t idm_len, | ||||
|     const uint8_t* pmm, | ||||
|     const uint8_t pmm_len) { | ||||
|     furi_assert(instance); | ||||
|     furi_assert(idm); | ||||
|     furi_assert(pmm); | ||||
|     furi_assert(idm_len == 8); | ||||
|     furi_assert(pmm_len == 8); | ||||
| 
 | ||||
|     return NfcErrorNone; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -67,8 +67,14 @@ static bool nfc_scene_saved_menu_on_event_felica(NfcApp* instance, uint32_t even | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| static void nfc_scene_emulate_on_enter_felica(NfcApp* instance) { | ||||
|     const FelicaData* data = nfc_device_get_data(instance->nfc_device, NfcProtocolFelica); | ||||
|     instance->listener = nfc_listener_alloc(instance->nfc, NfcProtocolFelica, data); | ||||
|     nfc_listener_start(instance->listener, NULL, NULL); | ||||
| } | ||||
| 
 | ||||
| const NfcProtocolSupportBase nfc_protocol_support_felica = { | ||||
|     .features = NfcProtocolFeatureNone, | ||||
|     .features = NfcProtocolFeatureEmulateUid, | ||||
| 
 | ||||
|     .scene_info = | ||||
|         { | ||||
| @ -102,7 +108,7 @@ const NfcProtocolSupportBase nfc_protocol_support_felica = { | ||||
|         }, | ||||
|     .scene_emulate = | ||||
|         { | ||||
|             .on_enter = nfc_protocol_support_common_on_enter_empty, | ||||
|             .on_enter = nfc_scene_emulate_on_enter_felica, | ||||
|             .on_event = nfc_protocol_support_common_on_event_empty, | ||||
|         }, | ||||
| }; | ||||
|  | ||||
| @ -76,7 +76,7 @@ static const FuriHalNfcTech nfc_tech_table[NfcModeNum][NfcTechNum] = { | ||||
|             [NfcTechIso14443a] = FuriHalNfcTechIso14443a, | ||||
|             [NfcTechIso14443b] = FuriHalNfcTechInvalid, | ||||
|             [NfcTechIso15693] = FuriHalNfcTechIso15693, | ||||
|             [NfcTechFelica] = FuriHalNfcTechInvalid, | ||||
|             [NfcTechFelica] = FuriHalNfcTechFelica, | ||||
|         }, | ||||
| }; | ||||
| 
 | ||||
| @ -646,4 +646,20 @@ NfcError nfc_iso15693_listener_tx_sof(Nfc* instance) { | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| NfcError nfc_felica_listener_set_sensf_res_data( | ||||
|     Nfc* instance, | ||||
|     const uint8_t* idm, | ||||
|     const uint8_t idm_len, | ||||
|     const uint8_t* pmm, | ||||
|     const uint8_t pmm_len) { | ||||
|     furi_assert(instance); | ||||
|     furi_assert(idm); | ||||
|     furi_assert(pmm); | ||||
| 
 | ||||
|     FuriHalNfcError error = | ||||
|         furi_hal_nfc_felica_listener_set_sensf_res_data(idm, idm_len, pmm, pmm_len); | ||||
|     instance->comm_state = NfcCommStateIdle; | ||||
|     return nfc_process_hal_error(error); | ||||
| } | ||||
| 
 | ||||
| #endif // APP_UNIT_TESTS
 | ||||
|  | ||||
| @ -351,6 +351,25 @@ NfcError nfc_iso14443a_listener_set_col_res_data( | ||||
|     uint8_t* atqa, | ||||
|     uint8_t sak); | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Set FeliCa collision resolution parameters in listener mode. | ||||
|  *  | ||||
|  * Configures the NFC hardware for automatic collision resolution. | ||||
|  * | ||||
|  * @param[in,out] instance pointer to the instance to be configured. | ||||
|  * @param[in] idm pointer to a byte array containing the IDm. | ||||
|  * @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. | ||||
|  * @returns NfcErrorNone on success, any other error code on failure. | ||||
| */ | ||||
| NfcError nfc_felica_listener_set_sensf_res_data( | ||||
|     Nfc* instance, | ||||
|     const uint8_t* idm, | ||||
|     const uint8_t idm_len, | ||||
|     const uint8_t* pmm, | ||||
|     const uint8_t pmm_len); | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Send ISO15693 Start of Frame pattern in listener mode | ||||
|  * | ||||
|  | ||||
| @ -14,6 +14,8 @@ extern "C" { | ||||
| #define FELICA_FDT_POLL_FC (10000U) | ||||
| #define FELICA_POLL_POLL_MIN_US (1280U) | ||||
| 
 | ||||
| #define FELICA_FDT_LISTEN_FC (1172) | ||||
| 
 | ||||
| #define FELICA_SYSTEM_CODE_CODE (0xFFFFU) | ||||
| #define FELICA_TIME_SLOT_1 (0x00U) | ||||
| #define FELICA_TIME_SLOT_2 (0x01U) | ||||
|  | ||||
							
								
								
									
										79
									
								
								lib/nfc/protocols/felica/felica_listener.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								lib/nfc/protocols/felica/felica_listener.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,79 @@ | ||||
| #include "felica_listener_i.h" | ||||
| 
 | ||||
| #include "nfc/protocols/nfc_listener_base.h" | ||||
| 
 | ||||
| #define FELICA_LISTENER_MAX_BUFFER_SIZE (64) | ||||
| #define TAG "Felica" | ||||
| 
 | ||||
| FelicaListener* felica_listener_alloc(Nfc* nfc, FelicaData* data) { | ||||
|     furi_assert(nfc); | ||||
|     furi_assert(data); | ||||
| 
 | ||||
|     FelicaListener* instance = malloc(sizeof(FelicaListener)); | ||||
|     instance->nfc = nfc; | ||||
|     instance->data = data; | ||||
|     instance->tx_buffer = bit_buffer_alloc(FELICA_LISTENER_MAX_BUFFER_SIZE); | ||||
|     instance->rx_buffer = bit_buffer_alloc(FELICA_LISTENER_MAX_BUFFER_SIZE); | ||||
| 
 | ||||
|     nfc_set_fdt_listen_fc(instance->nfc, FELICA_FDT_LISTEN_FC); | ||||
| 
 | ||||
|     nfc_config(instance->nfc, NfcModeListener, NfcTechFelica); | ||||
|     nfc_felica_listener_set_sensf_res_data( | ||||
|         nfc, data->idm.data, sizeof(data->idm), data->pmm.data, sizeof(data->pmm)); | ||||
| 
 | ||||
|     return instance; | ||||
| } | ||||
| 
 | ||||
| void felica_listener_free(FelicaListener* instance) { | ||||
|     furi_assert(instance); | ||||
|     furi_assert(instance->tx_buffer); | ||||
| 
 | ||||
|     bit_buffer_free(instance->tx_buffer); | ||||
|     bit_buffer_free(instance->rx_buffer); | ||||
|     free(instance); | ||||
| } | ||||
| 
 | ||||
| void felica_listener_set_callback( | ||||
|     FelicaListener* listener, | ||||
|     NfcGenericCallback callback, | ||||
|     void* context) { | ||||
|     UNUSED(listener); | ||||
|     UNUSED(callback); | ||||
|     UNUSED(context); | ||||
| } | ||||
| 
 | ||||
| const FelicaData* felica_listener_get_data(const FelicaListener* instance) { | ||||
|     furi_assert(instance); | ||||
|     furi_assert(instance->data); | ||||
| 
 | ||||
|     return instance->data; | ||||
| } | ||||
| 
 | ||||
| NfcCommand felica_listener_run(NfcGenericEvent event, void* context) { | ||||
|     furi_assert(context); | ||||
|     furi_assert(event.protocol == NfcProtocolInvalid); | ||||
|     furi_assert(event.event_data); | ||||
| 
 | ||||
|     FelicaListener* instance = context; | ||||
|     NfcEvent* nfc_event = event.event_data; | ||||
|     NfcCommand command = NfcCommandContinue; | ||||
| 
 | ||||
|     if(nfc_event->type == NfcEventTypeListenerActivated) { | ||||
|         instance->state = Felica_ListenerStateActivated; | ||||
|         FURI_LOG_D(TAG, "Activated"); | ||||
|     } else if(nfc_event->type == NfcEventTypeFieldOff) { | ||||
|         instance->state = Felica_ListenerStateIdle; | ||||
|         FURI_LOG_D(TAG, "Field Off"); | ||||
|     } else if(nfc_event->type == NfcEventTypeRxEnd) { | ||||
|         FURI_LOG_D(TAG, "Rx Done"); | ||||
|     } | ||||
|     return command; | ||||
| } | ||||
| 
 | ||||
| const NfcListenerBase nfc_listener_felica = { | ||||
|     .alloc = (NfcListenerAlloc)felica_listener_alloc, | ||||
|     .free = (NfcListenerFree)felica_listener_free, | ||||
|     .set_callback = (NfcListenerSetCallback)felica_listener_set_callback, | ||||
|     .get_data = (NfcListenerGetData)felica_listener_get_data, | ||||
|     .run = (NfcListenerRun)felica_listener_run, | ||||
| }; | ||||
							
								
								
									
										14
									
								
								lib/nfc/protocols/felica/felica_listener.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								lib/nfc/protocols/felica/felica_listener.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "felica.h" | ||||
| #include <lib/nfc/nfc.h> | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| typedef struct FelicaListener FelicaListener; | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										13
									
								
								lib/nfc/protocols/felica/felica_listener_defs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								lib/nfc/protocols/felica/felica_listener_defs.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <nfc/protocols/nfc_listener_base.h> | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| extern const NfcListenerBase nfc_listener_felica; | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										21
									
								
								lib/nfc/protocols/felica/felica_listener_i.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								lib/nfc/protocols/felica/felica_listener_i.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| #include "felica_listener.h" | ||||
| 
 | ||||
| #include <nfc/protocols/nfc_generic_event.h> | ||||
| 
 | ||||
| typedef enum { | ||||
|     Felica_ListenerStateIdle, | ||||
|     Felica_ListenerStateActivated, | ||||
| } FelicaListenerState; | ||||
| 
 | ||||
| struct FelicaListener { | ||||
|     Nfc* nfc; | ||||
|     FelicaData* data; | ||||
|     FelicaListenerState state; | ||||
| 
 | ||||
|     BitBuffer* tx_buffer; | ||||
|     BitBuffer* rx_buffer; | ||||
| 
 | ||||
|     NfcGenericEvent generic_event; | ||||
|     NfcGenericCallback callback; | ||||
|     void* context; | ||||
| }; | ||||
| @ -6,6 +6,7 @@ | ||||
| #include <nfc/protocols/mf_ultralight/mf_ultralight_listener_defs.h> | ||||
| #include <nfc/protocols/mf_classic/mf_classic_listener_defs.h> | ||||
| #include <nfc/protocols/slix/slix_listener_defs.h> | ||||
| #include <nfc/protocols/felica/felica_listener_defs.h> | ||||
| 
 | ||||
| const NfcListenerBase* nfc_listeners_api[NfcProtocolNum] = { | ||||
|     [NfcProtocolIso14443_3a] = &nfc_listener_iso14443_3a, | ||||
| @ -18,4 +19,5 @@ const NfcListenerBase* nfc_listeners_api[NfcProtocolNum] = { | ||||
|     [NfcProtocolMfDesfire] = NULL, | ||||
|     [NfcProtocolSlix] = &nfc_listener_slix, | ||||
|     [NfcProtocolSt25tb] = NULL, | ||||
|     [NfcProtocolFelica] = &nfc_listener_felica, | ||||
| }; | ||||
|  | ||||
| @ -1287,6 +1287,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_field_detect_start,FuriHalNfcError, | ||||
| Function,+,furi_hal_nfc_field_detect_stop,FuriHalNfcError, | ||||
| Function,+,furi_hal_nfc_field_is_present,_Bool, | ||||
| @ -2316,6 +2317,7 @@ Function,+,nfc_dict_get_next_key,_Bool,"NfcDict*, uint8_t*, size_t" | ||||
| Function,+,nfc_dict_get_total_keys,uint32_t,NfcDict* | ||||
| Function,+,nfc_dict_is_key_present,_Bool,"NfcDict*, const uint8_t*, size_t" | ||||
| Function,+,nfc_dict_rewind,_Bool,NfcDict* | ||||
| Function,+,nfc_felica_listener_set_sensf_res_data,NfcError,"Nfc*, const uint8_t*, const uint8_t, const uint8_t*, const uint8_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*" | ||||
|  | ||||
| 
 | 
| @ -1,6 +1,9 @@ | ||||
| #include "furi_hal_nfc_i.h" | ||||
| #include "furi_hal_nfc_tech_i.h" | ||||
| 
 | ||||
| // Prevent FDT timer from starting
 | ||||
| #define FURI_HAL_NFC_FELICA_LISTENER_FDT_COMP_FC (INT32_MAX) | ||||
| 
 | ||||
| static FuriHalNfcError furi_hal_nfc_felica_poller_init(FuriHalSpiBusHandle* handle) { | ||||
|     // Enable Felica mode, AM modulation
 | ||||
|     st25r3916_change_reg_bits( | ||||
| @ -50,6 +53,126 @@ static FuriHalNfcError furi_hal_nfc_felica_poller_deinit(FuriHalSpiBusHandle* ha | ||||
|     return FuriHalNfcErrorNone; | ||||
| } | ||||
| 
 | ||||
| static FuriHalNfcError furi_hal_nfc_felica_listener_init(FuriHalSpiBusHandle* handle) { | ||||
|     furi_assert(handle); | ||||
|     st25r3916_write_reg( | ||||
|         handle, | ||||
|         ST25R3916_REG_OP_CONTROL, | ||||
|         ST25R3916_REG_OP_CONTROL_en | ST25R3916_REG_OP_CONTROL_rx_en | | ||||
|             ST25R3916_REG_OP_CONTROL_en_fd_auto_efd); | ||||
| 
 | ||||
|     // Enable Target Felica mode, AM modulation
 | ||||
|     st25r3916_write_reg( | ||||
|         handle, | ||||
|         ST25R3916_REG_MODE, | ||||
|         ST25R3916_REG_MODE_targ_targ | ST25R3916_REG_MODE_om2 | ST25R3916_REG_MODE_tr_am); | ||||
| 
 | ||||
|     st25r3916_change_reg_bits( | ||||
|         handle, | ||||
|         ST25R3916_REG_BIT_RATE, | ||||
|         ST25R3916_REG_BIT_RATE_txrate_mask | ST25R3916_REG_BIT_RATE_rxrate_mask, | ||||
|         ST25R3916_REG_BIT_RATE_txrate_212 | ST25R3916_REG_BIT_RATE_rxrate_212); | ||||
| 
 | ||||
|     // Receive configuration
 | ||||
|     st25r3916_write_reg( | ||||
|         handle, | ||||
|         ST25R3916_REG_RX_CONF1, | ||||
|         ST25R3916_REG_RX_CONF1_lp0 | ST25R3916_REG_RX_CONF1_hz_12_80khz); | ||||
| 
 | ||||
|     // AGC enabled, ratio 3:1, squelch after TX
 | ||||
|     st25r3916_write_reg( | ||||
|         handle, | ||||
|         ST25R3916_REG_RX_CONF2, | ||||
|         ST25R3916_REG_RX_CONF2_agc6_3 | ST25R3916_REG_RX_CONF2_agc_m | | ||||
|             ST25R3916_REG_RX_CONF2_agc_en | ST25R3916_REG_RX_CONF2_sqm_dyn); | ||||
|     // HF operation, full gain on AM and PM channels
 | ||||
|     st25r3916_write_reg(handle, ST25R3916_REG_RX_CONF3, 0x00); | ||||
|     // No gain reduction on AM and PM channels
 | ||||
|     st25r3916_write_reg(handle, ST25R3916_REG_RX_CONF4, 0x00); | ||||
|     // 10% ASK modulation
 | ||||
|     st25r3916_write_reg(handle, ST25R3916_REG_TX_DRIVER, ST25R3916_REG_TX_DRIVER_am_mod_10percent); | ||||
| 
 | ||||
|     // Correlator setup
 | ||||
|     st25r3916_write_reg( | ||||
|         handle, | ||||
|         ST25R3916_REG_CORR_CONF1, | ||||
|         ST25R3916_REG_CORR_CONF1_corr_s6 | ST25R3916_REG_CORR_CONF1_corr_s4 | | ||||
|             ST25R3916_REG_CORR_CONF1_corr_s2); | ||||
| 
 | ||||
|     // Sleep mode disable, 424kHz mode off
 | ||||
|     st25r3916_write_reg(handle, ST25R3916_REG_CORR_CONF2, 0x00); | ||||
| 
 | ||||
|     st25r3916_write_reg(handle, ST25R3916_REG_MASK_RX_TIMER, 0x02); | ||||
| 
 | ||||
|     st25r3916_direct_cmd(handle, ST25R3916_CMD_STOP); | ||||
|     uint32_t interrupts = | ||||
|         (ST25R3916_IRQ_MASK_FWL | ST25R3916_IRQ_MASK_TXE | ST25R3916_IRQ_MASK_RXS | | ||||
|          ST25R3916_IRQ_MASK_RXE | ST25R3916_IRQ_MASK_PAR | ST25R3916_IRQ_MASK_CRC | | ||||
|          ST25R3916_IRQ_MASK_ERR1 | ST25R3916_IRQ_MASK_ERR2 | ST25R3916_IRQ_MASK_NRE | | ||||
|          ST25R3916_IRQ_MASK_EON | ST25R3916_IRQ_MASK_EOF | ST25R3916_IRQ_MASK_WU_A_X | | ||||
|          ST25R3916_IRQ_MASK_WU_A); | ||||
|     // Clear interrupts
 | ||||
|     st25r3916_get_irq(handle); | ||||
| 
 | ||||
|     st25r3916_write_reg( | ||||
|         handle, | ||||
|         ST25R3916_REG_PASSIVE_TARGET, | ||||
|         ST25R3916_REG_PASSIVE_TARGET_d_106_ac_a | ST25R3916_REG_PASSIVE_TARGET_d_ac_ap2p | | ||||
|             ST25R3916_REG_PASSIVE_TARGET_fdel_1); | ||||
|     // Enable interrupts
 | ||||
|     st25r3916_mask_irq(handle, ~interrupts); | ||||
|     st25r3916_direct_cmd(handle, ST25R3916_CMD_GOTO_SENSE); | ||||
| 
 | ||||
|     return FuriHalNfcErrorNone; | ||||
| } | ||||
| 
 | ||||
| static FuriHalNfcError furi_hal_nfc_felica_listener_deinit(FuriHalSpiBusHandle* handle) { | ||||
|     UNUSED(handle); | ||||
|     return FuriHalNfcErrorNone; | ||||
| } | ||||
| 
 | ||||
| static FuriHalNfcEvent furi_hal_nfc_felica_listener_wait_event(uint32_t timeout_ms) { | ||||
|     UNUSED(timeout_ms); | ||||
|     FuriHalNfcEvent event = furi_hal_nfc_wait_event_common(timeout_ms); | ||||
| 
 | ||||
|     return event; | ||||
| } | ||||
| 
 | ||||
| FuriHalNfcError furi_hal_nfc_felica_listener_tx( | ||||
|     FuriHalSpiBusHandle* handle, | ||||
|     const uint8_t* tx_data, | ||||
|     size_t tx_bits) { | ||||
|     UNUSED(handle); | ||||
|     UNUSED(tx_data); | ||||
|     UNUSED(tx_bits); | ||||
|     return FuriHalNfcErrorNone; | ||||
| } | ||||
| 
 | ||||
| FuriHalNfcError furi_hal_nfc_felica_listener_sleep(FuriHalSpiBusHandle* handle) { | ||||
|     UNUSED(handle); | ||||
|     return FuriHalNfcErrorNone; | ||||
| } | ||||
| 
 | ||||
| FuriHalNfcError furi_hal_nfc_felica_listener_idle(FuriHalSpiBusHandle* handle) { | ||||
|     UNUSED(handle); | ||||
|     return FuriHalNfcErrorNone; | ||||
| } | ||||
| 
 | ||||
| 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) { | ||||
|     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)); | ||||
|     return FuriHalNfcErrorNone; | ||||
| } | ||||
| 
 | ||||
| const FuriHalNfcTechBase furi_hal_nfc_felica = { | ||||
|     .poller = | ||||
|         { | ||||
| @ -65,5 +188,18 @@ const FuriHalNfcTechBase furi_hal_nfc_felica = { | ||||
|             .rx = furi_hal_nfc_common_fifo_rx, | ||||
|         }, | ||||
| 
 | ||||
|     .listener = {}, | ||||
|     .listener = | ||||
|         { | ||||
|             .compensation = | ||||
|                 { | ||||
|                     .fdt = FURI_HAL_NFC_FELICA_LISTENER_FDT_COMP_FC, | ||||
|                 }, | ||||
|             .init = furi_hal_nfc_felica_listener_init, | ||||
|             .deinit = furi_hal_nfc_felica_listener_deinit, | ||||
|             .wait_event = furi_hal_nfc_felica_listener_wait_event, | ||||
|             .tx = furi_hal_nfc_felica_listener_tx, | ||||
|             .rx = furi_hal_nfc_common_fifo_rx, | ||||
|             .sleep = furi_hal_nfc_felica_listener_sleep, | ||||
|             .idle = furi_hal_nfc_felica_listener_idle, | ||||
|         }, | ||||
| }; | ||||
|  | ||||
| @ -452,6 +452,23 @@ FuriHalNfcError furi_hal_nfc_iso14443a_listener_tx_custom_parity( | ||||
| */ | ||||
| FuriHalNfcError furi_hal_nfc_iso15693_listener_tx_sof(); | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Set FeliCa collision resolution parameters in listener mode. | ||||
|  *  | ||||
|  * Configures the NFC hardware for automatic collision resolution. | ||||
|  * | ||||
|  * @param[in] idm pointer to a byte array containing the IDm. | ||||
|  * @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. | ||||
|  * @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); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 RebornedBrain
						RebornedBrain