mirror of
https://github.com/DarkFlippers/unleashed-firmware
synced 2024-11-10 15:04:19 +00:00
[FL-3719] NFC Plugins loading rework (#3295)
* nfc app: rework supported cards * nfc app: supported cards optimization * nfc app: remove old nfc support implementation * nfc app: add documentation for supported cards * nfc app: format sources * nfc app: fix PVS warnings * nfc app: one more PVS fix * nfc app: PVS please stop * nfc app: add missing documentation Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
parent
09540929c3
commit
d6680d1f75
6 changed files with 236 additions and 63 deletions
|
@ -1,4 +1,5 @@
|
|||
#include "nfc_supported_cards.h"
|
||||
|
||||
#include "../plugins/supported_cards/nfc_supported_card_plugin.h"
|
||||
|
||||
#include <flipper_application/flipper_application.h>
|
||||
|
@ -7,22 +8,72 @@
|
|||
|
||||
#include <furi.h>
|
||||
#include <path.h>
|
||||
#include <m-array.h>
|
||||
|
||||
#define TAG "NfcSupportedCards"
|
||||
|
||||
#define NFC_SUPPORTED_CARDS_PLUGINS_PATH APP_DATA_PATH("plugins")
|
||||
#define NFC_SUPPORTED_CARDS_PLUGIN_SUFFIX "_parser.fal"
|
||||
|
||||
typedef enum {
|
||||
NfcSupportedCardsPluginFeatureHasVerify = (1U << 0),
|
||||
NfcSupportedCardsPluginFeatureHasRead = (1U << 1),
|
||||
NfcSupportedCardsPluginFeatureHasParse = (1U << 2),
|
||||
} NfcSupportedCardsPluginFeature;
|
||||
|
||||
typedef struct {
|
||||
FuriString* path;
|
||||
NfcProtocol protocol;
|
||||
NfcSupportedCardsPluginFeature feature;
|
||||
} NfcSupportedCardsPluginCache;
|
||||
|
||||
ARRAY_DEF(NfcSupportedCardsPluginCache, NfcSupportedCardsPluginCache, M_POD_OPLIST);
|
||||
|
||||
typedef enum {
|
||||
NfcSupportedCardsLoadStateIdle,
|
||||
NfcSupportedCardsLoadStateInProgress,
|
||||
NfcSupportedCardsLoadStateSuccess,
|
||||
NfcSupportedCardsLoadStateFail,
|
||||
} NfcSupportedCardsLoadState;
|
||||
|
||||
typedef struct {
|
||||
Storage* storage;
|
||||
File* directory;
|
||||
FuriString* file_path;
|
||||
char file_name[256];
|
||||
FlipperApplication* app;
|
||||
} NfcSupportedCards;
|
||||
} NfcSupportedCardsLoadContext;
|
||||
|
||||
static NfcSupportedCards* nfc_supported_cards_alloc() {
|
||||
struct NfcSupportedCards {
|
||||
NfcSupportedCardsPluginCache_t plugins_cache_arr;
|
||||
NfcSupportedCardsLoadState load_state;
|
||||
NfcSupportedCardsLoadContext* load_context;
|
||||
};
|
||||
|
||||
NfcSupportedCards* nfc_supported_cards_alloc() {
|
||||
NfcSupportedCards* instance = malloc(sizeof(NfcSupportedCards));
|
||||
NfcSupportedCardsPluginCache_init(instance->plugins_cache_arr);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void nfc_supported_cards_free(NfcSupportedCards* instance) {
|
||||
furi_assert(instance);
|
||||
|
||||
NfcSupportedCardsPluginCache_it_t iter;
|
||||
for(NfcSupportedCardsPluginCache_it(iter, instance->plugins_cache_arr);
|
||||
!NfcSupportedCardsPluginCache_end_p(iter);
|
||||
NfcSupportedCardsPluginCache_next(iter)) {
|
||||
NfcSupportedCardsPluginCache* plugin_cache = NfcSupportedCardsPluginCache_ref(iter);
|
||||
furi_string_free(plugin_cache->path);
|
||||
}
|
||||
|
||||
NfcSupportedCardsPluginCache_clear(instance->plugins_cache_arr);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
static NfcSupportedCardsLoadContext* nfc_supported_cards_load_context_alloc() {
|
||||
NfcSupportedCardsLoadContext* instance = malloc(sizeof(NfcSupportedCardsLoadContext));
|
||||
|
||||
instance->storage = furi_record_open(RECORD_STORAGE);
|
||||
instance->directory = storage_file_alloc(instance->storage);
|
||||
|
@ -35,7 +86,7 @@ static NfcSupportedCards* nfc_supported_cards_alloc() {
|
|||
return instance;
|
||||
}
|
||||
|
||||
static void nfc_supported_cards_free(NfcSupportedCards* instance) {
|
||||
static void nfc_supported_cards_load_context_free(NfcSupportedCardsLoadContext* instance) {
|
||||
if(instance->app) {
|
||||
flipper_application_free(instance->app);
|
||||
}
|
||||
|
@ -50,7 +101,36 @@ static void nfc_supported_cards_free(NfcSupportedCards* instance) {
|
|||
}
|
||||
|
||||
static const NfcSupportedCardsPlugin*
|
||||
nfc_supported_cards_get_next_plugin(NfcSupportedCards* instance) {
|
||||
nfc_supported_cards_get_plugin(NfcSupportedCardsLoadContext* instance, FuriString* path) {
|
||||
furi_assert(instance);
|
||||
furi_assert(path);
|
||||
|
||||
const NfcSupportedCardsPlugin* plugin = NULL;
|
||||
do {
|
||||
if(instance->app) flipper_application_free(instance->app);
|
||||
instance->app = flipper_application_alloc(instance->storage, firmware_api_interface);
|
||||
if(flipper_application_preload(instance->app, furi_string_get_cstr(path)) !=
|
||||
FlipperApplicationPreloadStatusSuccess)
|
||||
break;
|
||||
if(!flipper_application_is_plugin(instance->app)) break;
|
||||
if(flipper_application_map_to_memory(instance->app) != FlipperApplicationLoadStatusSuccess)
|
||||
break;
|
||||
const FlipperAppPluginDescriptor* descriptor =
|
||||
flipper_application_plugin_get_descriptor(instance->app);
|
||||
|
||||
if(descriptor == NULL) break;
|
||||
|
||||
if(strcmp(descriptor->appid, NFC_SUPPORTED_CARD_PLUGIN_APP_ID) != 0) break;
|
||||
if(descriptor->ep_api_version != NFC_SUPPORTED_CARD_PLUGIN_API_VERSION) break;
|
||||
|
||||
plugin = descriptor->entry_point;
|
||||
} while(false);
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
static const NfcSupportedCardsPlugin*
|
||||
nfc_supported_cards_get_next_plugin(NfcSupportedCardsLoadContext* instance) {
|
||||
const NfcSupportedCardsPlugin* plugin = NULL;
|
||||
|
||||
do {
|
||||
|
@ -65,83 +145,137 @@ static const NfcSupportedCardsPlugin*
|
|||
|
||||
path_concat(NFC_SUPPORTED_CARDS_PLUGINS_PATH, instance->file_name, instance->file_path);
|
||||
|
||||
if(instance->app) flipper_application_free(instance->app);
|
||||
instance->app = flipper_application_alloc(instance->storage, firmware_api_interface);
|
||||
|
||||
if(flipper_application_preload(instance->app, furi_string_get_cstr(instance->file_path)) !=
|
||||
FlipperApplicationPreloadStatusSuccess)
|
||||
continue;
|
||||
if(!flipper_application_is_plugin(instance->app)) continue;
|
||||
|
||||
if(flipper_application_map_to_memory(instance->app) != FlipperApplicationLoadStatusSuccess)
|
||||
continue;
|
||||
|
||||
const FlipperAppPluginDescriptor* descriptor =
|
||||
flipper_application_plugin_get_descriptor(instance->app);
|
||||
|
||||
if(descriptor == NULL) continue;
|
||||
|
||||
if(strcmp(descriptor->appid, NFC_SUPPORTED_CARD_PLUGIN_APP_ID) != 0) continue;
|
||||
if(descriptor->ep_api_version != NFC_SUPPORTED_CARD_PLUGIN_API_VERSION) continue;
|
||||
|
||||
plugin = descriptor->entry_point;
|
||||
plugin = nfc_supported_cards_get_plugin(instance, instance->file_path);
|
||||
} while(plugin == NULL); //-V654
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
bool nfc_supported_cards_read(NfcDevice* device, Nfc* nfc) {
|
||||
void nfc_supported_cards_load_cache(NfcSupportedCards* instance) {
|
||||
furi_assert(instance);
|
||||
|
||||
do {
|
||||
if((instance->load_state == NfcSupportedCardsLoadStateSuccess) ||
|
||||
(instance->load_state == NfcSupportedCardsLoadStateFail))
|
||||
break;
|
||||
|
||||
instance->load_context = nfc_supported_cards_load_context_alloc();
|
||||
|
||||
while(true) {
|
||||
const NfcSupportedCardsPlugin* plugin =
|
||||
nfc_supported_cards_get_next_plugin(instance->load_context);
|
||||
if(plugin == NULL) break; //-V547
|
||||
|
||||
NfcSupportedCardsPluginCache plugin_cache = {}; //-V779
|
||||
plugin_cache.path = furi_string_alloc_set(instance->load_context->file_path);
|
||||
plugin_cache.protocol = plugin->protocol;
|
||||
if(plugin->verify) {
|
||||
plugin_cache.feature |= NfcSupportedCardsPluginFeatureHasVerify;
|
||||
}
|
||||
if(plugin->read) {
|
||||
plugin_cache.feature |= NfcSupportedCardsPluginFeatureHasRead;
|
||||
}
|
||||
if(plugin->parse) {
|
||||
plugin_cache.feature |= NfcSupportedCardsPluginFeatureHasParse;
|
||||
}
|
||||
NfcSupportedCardsPluginCache_push_back(instance->plugins_cache_arr, plugin_cache);
|
||||
}
|
||||
|
||||
nfc_supported_cards_load_context_free(instance->load_context);
|
||||
|
||||
size_t plugins_loaded = NfcSupportedCardsPluginCache_size(instance->plugins_cache_arr);
|
||||
if(plugins_loaded == 0) {
|
||||
FURI_LOG_D(TAG, "Plugins not found");
|
||||
instance->load_state = NfcSupportedCardsLoadStateFail;
|
||||
} else {
|
||||
FURI_LOG_D(TAG, "Loaded %zu plugins", plugins_loaded);
|
||||
instance->load_state = NfcSupportedCardsLoadStateSuccess;
|
||||
}
|
||||
|
||||
} while(false);
|
||||
}
|
||||
|
||||
bool nfc_supported_cards_read(NfcSupportedCards* instance, NfcDevice* device, Nfc* nfc) {
|
||||
furi_assert(instance);
|
||||
furi_assert(device);
|
||||
furi_assert(nfc);
|
||||
|
||||
bool card_read = false;
|
||||
|
||||
NfcSupportedCards* supported_cards = nfc_supported_cards_alloc();
|
||||
NfcProtocol protocol = nfc_device_get_protocol(device);
|
||||
|
||||
do {
|
||||
const NfcSupportedCardsPlugin* plugin =
|
||||
nfc_supported_cards_get_next_plugin(supported_cards);
|
||||
if(plugin == NULL) break; //-V547
|
||||
if(instance->load_state != NfcSupportedCardsLoadStateSuccess) break;
|
||||
|
||||
const NfcProtocol protocol = nfc_device_get_protocol(device); //-V779
|
||||
if(plugin->protocol != protocol) continue;
|
||||
instance->load_context = nfc_supported_cards_load_context_alloc();
|
||||
|
||||
if(plugin->verify) {
|
||||
if(!plugin->verify(nfc)) continue;
|
||||
NfcSupportedCardsPluginCache_it_t iter;
|
||||
for(NfcSupportedCardsPluginCache_it(iter, instance->plugins_cache_arr);
|
||||
!NfcSupportedCardsPluginCache_end_p(iter);
|
||||
NfcSupportedCardsPluginCache_next(iter)) {
|
||||
NfcSupportedCardsPluginCache* plugin_cache = NfcSupportedCardsPluginCache_ref(iter);
|
||||
if(plugin_cache->protocol != protocol) continue;
|
||||
if((plugin_cache->feature & NfcSupportedCardsPluginFeatureHasRead) == 0) continue;
|
||||
|
||||
const NfcSupportedCardsPlugin* plugin =
|
||||
nfc_supported_cards_get_plugin(instance->load_context, plugin_cache->path);
|
||||
if(plugin == NULL) continue;
|
||||
|
||||
if(plugin->verify) {
|
||||
if(!plugin->verify(nfc)) continue;
|
||||
}
|
||||
|
||||
if(plugin->read) {
|
||||
if(plugin->read(nfc, device)) {
|
||||
card_read = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(plugin->read) {
|
||||
card_read = plugin->read(nfc, device);
|
||||
}
|
||||
nfc_supported_cards_load_context_free(instance->load_context);
|
||||
} while(false);
|
||||
|
||||
} while(!card_read);
|
||||
|
||||
nfc_supported_cards_free(supported_cards);
|
||||
return card_read;
|
||||
}
|
||||
|
||||
bool nfc_supported_cards_parse(const NfcDevice* device, FuriString* parsed_data) {
|
||||
bool nfc_supported_cards_parse(
|
||||
NfcSupportedCards* instance,
|
||||
NfcDevice* device,
|
||||
FuriString* parsed_data) {
|
||||
furi_assert(instance);
|
||||
furi_assert(device);
|
||||
furi_assert(parsed_data);
|
||||
|
||||
bool parsed = false;
|
||||
|
||||
NfcSupportedCards* supported_cards = nfc_supported_cards_alloc();
|
||||
bool card_parsed = false;
|
||||
NfcProtocol protocol = nfc_device_get_protocol(device);
|
||||
|
||||
do {
|
||||
const NfcSupportedCardsPlugin* plugin =
|
||||
nfc_supported_cards_get_next_plugin(supported_cards);
|
||||
if(plugin == NULL) break; //-V547
|
||||
if(instance->load_state != NfcSupportedCardsLoadStateSuccess) break;
|
||||
|
||||
const NfcProtocol protocol = nfc_device_get_protocol(device); //-V779
|
||||
if(plugin->protocol != protocol) continue;
|
||||
instance->load_context = nfc_supported_cards_load_context_alloc();
|
||||
|
||||
if(plugin->parse) {
|
||||
parsed = plugin->parse(device, parsed_data);
|
||||
NfcSupportedCardsPluginCache_it_t iter;
|
||||
for(NfcSupportedCardsPluginCache_it(iter, instance->plugins_cache_arr);
|
||||
!NfcSupportedCardsPluginCache_end_p(iter);
|
||||
NfcSupportedCardsPluginCache_next(iter)) {
|
||||
NfcSupportedCardsPluginCache* plugin_cache = NfcSupportedCardsPluginCache_ref(iter);
|
||||
if(plugin_cache->protocol != protocol) continue;
|
||||
if((plugin_cache->feature & NfcSupportedCardsPluginFeatureHasParse) == 0) continue;
|
||||
|
||||
const NfcSupportedCardsPlugin* plugin =
|
||||
nfc_supported_cards_get_plugin(instance->load_context, plugin_cache->path);
|
||||
if(plugin == NULL) continue;
|
||||
|
||||
if(plugin->parse) {
|
||||
if(plugin->parse(device, parsed_data)) {
|
||||
card_parsed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} while(!parsed);
|
||||
nfc_supported_cards_load_context_free(instance->load_context);
|
||||
} while(false);
|
||||
|
||||
nfc_supported_cards_free(supported_cards);
|
||||
return parsed;
|
||||
return card_parsed;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,34 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief NfcSupportedCards opaque type definition.
|
||||
*/
|
||||
typedef struct NfcSupportedCards NfcSupportedCards;
|
||||
|
||||
/**
|
||||
* @brief Allocate NfcSupportedCards instance.
|
||||
*
|
||||
* @return pointer to allocated NfcSupportedCards instance.
|
||||
*/
|
||||
NfcSupportedCards* nfc_supported_cards_alloc();
|
||||
|
||||
/**
|
||||
* @brief Delete an NfcSupportedCards instance
|
||||
*
|
||||
* @param[in] instance pointer to instance to be deleted.
|
||||
*/
|
||||
void nfc_supported_cards_free(NfcSupportedCards* instance);
|
||||
|
||||
/**
|
||||
* @brief Load plugins information to cache.
|
||||
*
|
||||
* @note This function must be called before calling read and parse fanctions.
|
||||
*
|
||||
* @param[in, out] instance pointer to NfcSupportedCards instance.
|
||||
*/
|
||||
void nfc_supported_cards_load_cache(NfcSupportedCards* instance);
|
||||
|
||||
/**
|
||||
* @brief Read the card using a custom procedure.
|
||||
*
|
||||
|
@ -22,13 +50,14 @@ extern "C" {
|
|||
* try to execute the custom read procedure specified in each. Upon first success,
|
||||
* no further attempts will be made and the function will return.
|
||||
*
|
||||
* @param[in, out] instance pointer to NfcSupportedCards instance.
|
||||
* @param[in,out] device pointer to a device instance to hold the read data.
|
||||
* @param[in,out] nfc pointer to an Nfc instance.
|
||||
* @returns true if the card was successfully read, false otherwise.
|
||||
*
|
||||
* @see NfcSupportedCardPluginRead for detailed description.
|
||||
*/
|
||||
bool nfc_supported_cards_read(NfcDevice* device, Nfc* nfc);
|
||||
bool nfc_supported_cards_read(NfcSupportedCards* instance, NfcDevice* device, Nfc* nfc);
|
||||
|
||||
/**
|
||||
* @brief Parse raw data into human-readable representation.
|
||||
|
@ -37,13 +66,17 @@ bool nfc_supported_cards_read(NfcDevice* device, Nfc* nfc);
|
|||
* try to parse the data according to each implementation. Upon first success,
|
||||
* no further attempts will be made and the function will return.
|
||||
*
|
||||
* @param[in, out] instance pointer to NfcSupportedCards instance.
|
||||
* @param[in] device pointer to a device instance holding the data is to be parsed.
|
||||
* @param[out] parsed_data pointer to the string to contain the formatted result.
|
||||
* @returns true if the card was successfully parsed, false otherwise.
|
||||
*
|
||||
* @see NfcSupportedCardPluginParse for detailed description.
|
||||
*/
|
||||
bool nfc_supported_cards_parse(const NfcDevice* device, FuriString* parsed_data);
|
||||
bool nfc_supported_cards_parse(
|
||||
NfcSupportedCards* instance,
|
||||
NfcDevice* device,
|
||||
FuriString* parsed_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "nfc_protocol_support.h"
|
||||
|
||||
#include "nfc/nfc_app_i.h"
|
||||
#include "nfc/helpers/nfc_supported_cards.h"
|
||||
|
||||
#include "nfc_protocol_support_defs.h"
|
||||
#include "nfc_protocol_support_gui_common.h"
|
||||
|
@ -157,9 +156,11 @@ static void nfc_protocol_support_scene_read_on_enter(NfcApp* instance) {
|
|||
instance->protocols_detected[instance->protocols_detected_selected_idx];
|
||||
instance->poller = nfc_poller_alloc(instance->nfc, protocol);
|
||||
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup);
|
||||
nfc_supported_cards_load_cache(instance->nfc_supported_cards);
|
||||
|
||||
// Start poller with the appropriate callback
|
||||
nfc_protocol_support[protocol]->scene_read.on_enter(instance);
|
||||
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup);
|
||||
|
||||
nfc_blink_detect_start(instance);
|
||||
}
|
||||
|
@ -178,7 +179,8 @@ static bool nfc_protocol_support_scene_read_on_event(NfcApp* instance, SceneMana
|
|||
} else if(event.event == NfcCustomEventPollerIncomplete) {
|
||||
nfc_poller_stop(instance->poller);
|
||||
nfc_poller_free(instance->poller);
|
||||
bool card_read = nfc_supported_cards_read(instance->nfc_device, instance->nfc);
|
||||
bool card_read = nfc_supported_cards_read(
|
||||
instance->nfc_supported_cards, instance->nfc_device, instance->nfc);
|
||||
if(card_read) {
|
||||
notification_message(instance->notifications, &sequence_success);
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneReadSuccess);
|
||||
|
@ -303,7 +305,7 @@ static void nfc_protocol_support_scene_read_success_on_enter(NfcApp* instance) {
|
|||
Widget* widget = instance->widget;
|
||||
|
||||
FuriString* temp_str = furi_string_alloc();
|
||||
if(nfc_supported_cards_parse(instance->nfc_device, temp_str)) {
|
||||
if(nfc_supported_cards_parse(instance->nfc_supported_cards, instance->nfc_device, temp_str)) {
|
||||
widget_add_text_scroll_element(
|
||||
instance->widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str));
|
||||
} else {
|
||||
|
|
|
@ -51,6 +51,7 @@ NfcApp* nfc_app_alloc() {
|
|||
|
||||
instance->mf_ul_auth = mf_ultralight_auth_alloc();
|
||||
instance->mfc_key_cache = mf_classic_key_cache_alloc();
|
||||
instance->nfc_supported_cards = nfc_supported_cards_alloc();
|
||||
|
||||
// Nfc device
|
||||
instance->nfc_device = nfc_device_alloc();
|
||||
|
@ -110,7 +111,6 @@ NfcApp* nfc_app_alloc() {
|
|||
instance->view_dispatcher, NfcViewWidget, widget_get_view(instance->widget));
|
||||
|
||||
// Dict attack
|
||||
|
||||
instance->dict_attack = dict_attack_alloc();
|
||||
view_dispatcher_add_view(
|
||||
instance->view_dispatcher, NfcViewDictAttack, dict_attack_get_view(instance->dict_attack));
|
||||
|
@ -141,6 +141,7 @@ void nfc_app_free(NfcApp* instance) {
|
|||
|
||||
mf_ultralight_auth_free(instance->mf_ul_auth);
|
||||
mf_classic_key_cache_free(instance->mfc_key_cache);
|
||||
nfc_supported_cards_free(instance->nfc_supported_cards);
|
||||
|
||||
// Nfc device
|
||||
nfc_device_free(instance->nfc_device);
|
||||
|
@ -339,6 +340,8 @@ bool nfc_load_file(NfcApp* instance, FuriString* path, bool show_dialog) {
|
|||
furi_assert(path);
|
||||
bool result = false;
|
||||
|
||||
nfc_supported_cards_load_cache(instance->nfc_supported_cards);
|
||||
|
||||
FuriString* load_path = furi_string_alloc();
|
||||
if(nfc_has_shadow_file_internal(instance, path)) {
|
||||
nfc_set_shadow_file_path(path, load_path);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "helpers/mf_user_dict.h"
|
||||
#include "helpers/mfkey32_logger.h"
|
||||
#include "helpers/mf_classic_key_cache.h"
|
||||
#include "helpers/nfc_supported_cards.h"
|
||||
|
||||
#include <dialogs/dialogs.h>
|
||||
#include <storage/storage.h>
|
||||
|
@ -132,6 +133,7 @@ struct NfcApp {
|
|||
Mfkey32Logger* mfkey32_logger;
|
||||
MfUserDict* mf_user_dict;
|
||||
MfClassicKeyCache* mfc_key_cache;
|
||||
NfcSupportedCards* nfc_supported_cards;
|
||||
|
||||
NfcDevice* nfc_device;
|
||||
Iso14443_3aData* iso14443_3a_edit_data;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "nfc/nfc_app_i.h"
|
||||
|
||||
#include "nfc/helpers/nfc_supported_cards.h"
|
||||
#include "nfc/helpers/protocol_support/nfc_protocol_support_gui_common.h"
|
||||
|
||||
void nfc_scene_supported_card_on_enter(void* context) {
|
||||
|
@ -8,7 +7,7 @@ void nfc_scene_supported_card_on_enter(void* context) {
|
|||
|
||||
FuriString* temp_str = furi_string_alloc();
|
||||
|
||||
if(nfc_supported_cards_parse(instance->nfc_device, temp_str)) {
|
||||
if(nfc_supported_cards_parse(instance->nfc_supported_cards, instance->nfc_device, temp_str)) {
|
||||
widget_add_text_scroll_element(
|
||||
instance->widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str));
|
||||
widget_add_button_element(
|
||||
|
|
Loading…
Reference in a new issue