Merge branch 'dev' into astra/3746-mfp-detect

This commit is contained in:
Astra
2024-04-23 10:39:34 +09:00
committed by GitHub
1001 changed files with 15407 additions and 6205 deletions

View File

@@ -7,6 +7,11 @@
#include "../nfc_protocol_support_common.h"
#include "../nfc_protocol_support_gui_common.h"
#include "../nfc_protocol_support_unlock_helper.h"
enum {
SubmenuIndexUnlock = SubmenuIndexCommonMax,
};
static void nfc_scene_info_on_enter_felica(NfcApp* instance) {
const NfcDevice* device = instance->nfc_device;
@@ -18,6 +23,35 @@ static void nfc_scene_info_on_enter_felica(NfcApp* instance) {
temp_str, "\e#%s\n", nfc_device_get_name(device, NfcDeviceNameTypeFull));
nfc_render_felica_info(data, NfcProtocolFormatTypeFull, temp_str);
widget_add_text_scroll_element(
instance->widget, 0, 0, 128, 48, furi_string_get_cstr(temp_str));
widget_add_button_element(
instance->widget,
GuiButtonTypeRight,
"More",
nfc_protocol_support_common_widget_callback,
instance);
furi_string_free(temp_str);
}
static bool nfc_scene_info_on_event_felica(NfcApp* instance, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom && event.event == GuiButtonTypeRight) {
scene_manager_next_scene(instance->scene_manager, NfcSceneMoreInfo);
return true;
}
return false;
}
static void nfc_scene_more_info_on_enter_felica(NfcApp* instance) {
const NfcDevice* device = instance->nfc_device;
const FelicaData* data = nfc_device_get_data(device, NfcProtocolFelica);
FuriString* temp_str = furi_string_alloc();
nfc_render_felica_dump(data, temp_str);
widget_add_text_scroll_element(
instance->widget, 0, 0, 128, 64, furi_string_get_cstr(temp_str));
@@ -29,29 +63,75 @@ static NfcCommand nfc_scene_read_poller_callback_felica(NfcGenericEvent event, v
NfcApp* instance = context;
const FelicaPollerEvent* felica_event = event.event_data;
NfcCommand command = NfcCommandContinue;
if(felica_event->type == FelicaPollerEventTypeReady) {
nfc_device_set_data(
instance->nfc_device, NfcProtocolFelica, nfc_poller_get_data(instance->poller));
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerSuccess);
return NfcCommandStop;
command = NfcCommandStop;
} else if(
felica_event->type == FelicaPollerEventTypeError ||
felica_event->type == FelicaPollerEventTypeIncomplete) {
nfc_device_set_data(
instance->nfc_device, NfcProtocolFelica, nfc_poller_get_data(instance->poller));
view_dispatcher_send_custom_event(
instance->view_dispatcher, NfcCustomEventPollerIncomplete);
command = NfcCommandStop;
} else if(felica_event->type == FelicaPollerEventTypeRequestAuthContext) {
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventCardDetected);
FelicaAuthenticationContext* ctx = felica_event->data->auth_context;
ctx->skip_auth = instance->felica_auth->skip_auth;
memcpy(ctx->card_key.data, instance->felica_auth->card_key.data, FELICA_DATA_BLOCK_SIZE);
}
return NfcCommandContinue;
return command;
}
static void nfc_scene_read_on_enter_felica(NfcApp* instance) {
nfc_unlock_helper_setup_from_state(instance);
nfc_poller_start(instance->poller, nfc_scene_read_poller_callback_felica, instance);
}
bool nfc_scene_read_on_event_felica(NfcApp* instance, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventCardDetected) {
nfc_unlock_helper_card_detected_handler(instance);
} else if(event.event == NfcCustomEventPollerIncomplete) {
notification_message(instance->notifications, &sequence_semi_success);
scene_manager_next_scene(instance->scene_manager, NfcSceneReadSuccess);
dolphin_deed(DolphinDeedNfcReadSuccess);
}
}
return true;
}
static void nfc_scene_read_success_on_enter_felica(NfcApp* instance) {
const NfcDevice* device = instance->nfc_device;
const FelicaData* data = nfc_device_get_data(device, NfcProtocolFelica);
FuriString* temp_str = furi_string_alloc();
furi_string_cat_printf(
temp_str, "\e#%s\n", nfc_device_get_name(device, NfcDeviceNameTypeFull));
nfc_render_felica_info(data, NfcProtocolFormatTypeShort, temp_str);
if(!scene_manager_has_previous_scene(instance->scene_manager, NfcSceneFelicaUnlockWarn)) {
furi_string_cat_printf(
temp_str, "\e#%s\n", nfc_device_get_name(device, NfcDeviceNameTypeFull));
nfc_render_felica_info(data, NfcProtocolFormatTypeShort, temp_str);
} else {
bool all_unlocked = data->blocks_read == data->blocks_total;
furi_string_cat_printf(
temp_str,
"\e#%s\n",
all_unlocked ? "All Blocks Are Unlocked" : "Some Blocks Are Locked");
nfc_render_felica_idm(data, NfcProtocolFormatTypeShort, temp_str);
uint8_t* ck_data = instance->felica_auth->card_key.data;
furi_string_cat_printf(temp_str, "Key:");
for(uint8_t i = 0; i < 7; i++) {
furi_string_cat_printf(temp_str, " %02X", ck_data[i]);
if(i == 6) furi_string_cat_printf(temp_str, "...");
}
nfc_render_felica_blocks_count(data, temp_str, false);
}
felica_auth_reset(instance->felica_auth);
widget_add_text_scroll_element(
instance->widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str));
@@ -74,23 +154,50 @@ static void nfc_scene_emulate_on_enter_felica(NfcApp* instance) {
nfc_listener_start(instance->listener, NULL, NULL);
}
static void nfc_scene_read_menu_on_enter_felica(NfcApp* instance) {
const FelicaData* data = nfc_device_get_data(instance->nfc_device, NfcProtocolFelica);
if(data->blocks_read != data->blocks_total) {
submenu_add_item(
instance->submenu,
"Unlock",
SubmenuIndexUnlock,
nfc_protocol_support_common_submenu_callback,
instance);
}
}
static bool nfc_scene_read_menu_on_event_felica(NfcApp* instance, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubmenuIndexUnlock) {
scene_manager_next_scene(instance->scene_manager, NfcSceneFelicaKeyInput);
return true;
}
}
return false;
}
const NfcProtocolSupportBase nfc_protocol_support_felica = {
.features = NfcProtocolFeatureEmulateUid,
.scene_info =
{
.on_enter = nfc_scene_info_on_enter_felica,
.on_event = nfc_scene_info_on_event_felica,
},
.scene_more_info =
{
.on_enter = nfc_scene_more_info_on_enter_felica,
.on_event = nfc_protocol_support_common_on_event_empty,
},
.scene_read =
{
.on_enter = nfc_scene_read_on_enter_felica,
.on_event = nfc_protocol_support_common_on_event_empty,
.on_event = nfc_scene_read_on_event_felica,
},
.scene_read_menu =
{
.on_enter = nfc_protocol_support_common_on_enter_empty,
.on_event = nfc_protocol_support_common_on_event_empty,
.on_enter = nfc_scene_read_menu_on_enter_felica,
.on_event = nfc_scene_read_menu_on_event_felica,
},
.scene_read_success =
{

View File

@@ -1,19 +1,107 @@
#include "felica_render.h"
void nfc_render_felica_blocks_count(
const FelicaData* data,
FuriString* str,
bool render_auth_notification) {
furi_string_cat_printf(str, "\nBlocks Read: %u/%u", data->blocks_read, data->blocks_total);
if(render_auth_notification && data->blocks_read != data->blocks_total) {
furi_string_cat_printf(str, "\nAuth-protected blocks!");
}
}
void nfc_render_felica_idm(
const FelicaData* data,
NfcProtocolFormatType format_type,
FuriString* str) {
furi_string_cat_printf(str, (format_type == NfcProtocolFormatTypeFull) ? "IDm:\n" : "IDm:");
for(size_t i = 0; i < FELICA_IDM_SIZE; i++) {
furi_string_cat_printf(
str,
(format_type == NfcProtocolFormatTypeFull) ? "%02X " : " %02X",
data->idm.data[i]);
}
}
void nfc_render_felica_info(
const FelicaData* data,
NfcProtocolFormatType format_type,
FuriString* str) {
furi_string_cat_printf(str, "IDm:");
for(size_t i = 0; i < FELICA_IDM_SIZE; i++) {
furi_string_cat_printf(str, " %02X", data->idm.data[i]);
if(format_type == NfcProtocolFormatTypeFull) {
furi_string_cat_printf(str, "Tech: JIS X 6319-4,\nISO 18092 [NFC-F]\n");
}
nfc_render_felica_idm(data, format_type, str);
if(format_type == NfcProtocolFormatTypeFull) {
furi_string_cat_printf(str, "\nPMm:");
furi_string_cat_printf(str, "\nPMm:\n");
for(size_t i = 0; i < FELICA_PMM_SIZE; ++i) {
furi_string_cat_printf(str, " %02X", data->pmm.data[i]);
furi_string_cat_printf(str, "%02X ", data->pmm.data[i]);
}
}
nfc_render_felica_blocks_count(data, str, true);
}
static void nfc_render_felica_block_name(
const char* name,
FuriString* str,
uint8_t prefix_separator_cnt,
uint8_t suffix_separator_cnt) {
for(uint8_t i = 0; i < prefix_separator_cnt; i++) {
furi_string_cat_printf(str, ":");
}
furi_string_cat_printf(str, "[ %s ]", name);
for(uint8_t i = 0; i < suffix_separator_cnt; i++) {
furi_string_cat_printf(str, ":");
}
}
static void nfc_render_felica_block_data(const FelicaBlock* block, FuriString* str) {
furi_string_cat_printf(str, "\nSF1=%02X; SF2=%02X\n", block->SF1, block->SF2);
for(size_t j = 0; j < FELICA_DATA_BLOCK_SIZE; j++) {
if((j != 0) && (j % 8 == 0)) furi_string_cat_printf(str, "\n");
furi_string_cat_printf(str, "%02X ", block->data[j]);
}
furi_string_cat_printf(str, "\n");
}
static void nfc_render_felica_block(
const FelicaBlock* block,
FuriString* str,
const char* name,
uint8_t prefix_separator_cnt,
uint8_t suffix_separator_cnt) {
nfc_render_felica_block_name(name, str, prefix_separator_cnt, suffix_separator_cnt);
nfc_render_felica_block_data(block, str);
}
void nfc_render_felica_dump(const FelicaData* data, FuriString* str) {
FuriString* name = furi_string_alloc();
for(size_t i = 0; i < 14; i++) {
furi_string_printf(name, "S_PAD%d", i);
uint8_t suf_cnt = 18;
if(i == 1) {
suf_cnt = 19;
} else if((i == 10) || (i == 12) || (i == 13)) {
suf_cnt = 16;
}
nfc_render_felica_block(
&data->data.fs.spad[i], str, furi_string_get_cstr(name), 20, suf_cnt);
}
furi_string_free(name);
nfc_render_felica_block(&data->data.fs.reg, str, "REG", 23, 23);
nfc_render_felica_block(&data->data.fs.rc, str, "RC", 25, 25);
nfc_render_felica_block(&data->data.fs.mac, str, "MAC", 23, 23);
nfc_render_felica_block(&data->data.fs.id, str, "ID", 25, 25);
nfc_render_felica_block(&data->data.fs.d_id, str, "D_ID", 22, 24);
nfc_render_felica_block(&data->data.fs.ser_c, str, "SER_C", 20, 21);
nfc_render_felica_block(&data->data.fs.sys_c, str, "SYS_C", 20, 21);
nfc_render_felica_block(&data->data.fs.ckv, str, "CKV", 23, 23);
nfc_render_felica_block(&data->data.fs.ck, str, "CK", 25, 25);
nfc_render_felica_block(&data->data.fs.mc, str, "MC", 25, 24);
nfc_render_felica_block(&data->data.fs.wcnt, str, "WCNT", 22, 20);
nfc_render_felica_block(&data->data.fs.mac_a, str, "MAC_A", 20, 20);
nfc_render_felica_block(&data->data.fs.state, str, "STATE", 20, 21);
nfc_render_felica_block(&data->data.fs.crc_check, str, "CRC_CHCK", 15, 17);
}

View File

@@ -4,7 +4,19 @@
#include "../nfc_protocol_support_render_common.h"
void nfc_render_felica_blocks_count(
const FelicaData* data,
FuriString* str,
bool render_auth_notification);
void nfc_render_felica_info(
const FelicaData* data,
NfcProtocolFormatType format_type,
FuriString* str);
void nfc_render_felica_dump(const FelicaData* data, FuriString* str);
void nfc_render_felica_idm(
const FelicaData* data,
NfcProtocolFormatType format_type,
FuriString* str);

View File

@@ -34,6 +34,8 @@ static void nfc_scene_more_info_on_enter_mf_desfire(NfcApp* instance) {
static NfcCommand nfc_scene_read_poller_callback_mf_desfire(NfcGenericEvent event, void* context) {
furi_assert(event.protocol == NfcProtocolMfDesfire);
NfcCommand command = NfcCommandContinue;
NfcApp* instance = context;
const MfDesfirePollerEvent* mf_desfire_event = event.event_data;
@@ -41,10 +43,12 @@ static NfcCommand nfc_scene_read_poller_callback_mf_desfire(NfcGenericEvent even
nfc_device_set_data(
instance->nfc_device, NfcProtocolMfDesfire, nfc_poller_get_data(instance->poller));
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerSuccess);
return NfcCommandStop;
command = NfcCommandStop;
} else if(mf_desfire_event->type == MfDesfirePollerEventTypeReadFailed) {
command = NfcCommandReset;
}
return NfcCommandContinue;
return command;
}
static void nfc_scene_read_on_enter_mf_desfire(NfcApp* instance) {

View File

@@ -11,24 +11,29 @@ void nfc_render_mf_desfire_info(
const uint32_t bytes_total = 1UL << (data->version.sw_storage >> 1);
const uint32_t bytes_free = data->free_memory.is_present ? data->free_memory.bytes_free : 0;
if(data->master_key_settings.is_free_directory_list) {
const uint32_t app_count = simple_array_get_count(data->applications);
uint32_t file_count = 0;
for(uint32_t i = 0; i < app_count; ++i) {
const MfDesfireApplication* app = simple_array_cget(data->applications, i);
if(app->key_settings.is_free_directory_list) {
file_count += simple_array_get_count(app->file_ids);
}
}
furi_string_cat_printf(str, "\n%lu Application%s", app_count, app_count != 1 ? "s" : "");
furi_string_cat_printf(str, ", %lu File%s", file_count, file_count != 1 ? "s" : "");
} else {
furi_string_cat_printf(str, "\nAuth required to read apps!");
}
furi_string_cat_printf(str, "\n%lu", bytes_total);
if(data->version.sw_storage & 1) {
furi_string_push_back(str, '+');
}
furi_string_cat_printf(str, " bytes, %lu bytes free\n", bytes_free);
const uint32_t app_count = simple_array_get_count(data->applications);
uint32_t file_count = 0;
for(uint32_t i = 0; i < app_count; ++i) {
const MfDesfireApplication* app = simple_array_cget(data->applications, i);
file_count += simple_array_get_count(app->file_ids);
}
furi_string_cat_printf(str, "%lu Application%s", app_count, app_count != 1 ? "s" : "");
furi_string_cat_printf(str, ", %lu File%s", file_count, file_count != 1 ? "s" : "");
furi_string_cat_printf(str, " bytes, %lu bytes free", bytes_free);
if(format_type != NfcProtocolFormatTypeFull) return;
@@ -101,17 +106,29 @@ void nfc_render_mf_desfire_free_memory(const MfDesfireFreeMemory* data, FuriStri
}
void nfc_render_mf_desfire_key_settings(const MfDesfireKeySettings* data, FuriString* str) {
furi_string_cat_printf(str, "changeKeyID %d\n", data->change_key_id);
furi_string_cat_printf(str, "configChangeable %d\n", data->is_config_changeable);
furi_string_cat_printf(str, "freeCreateDelete %d\n", data->is_free_create_delete);
furi_string_cat_printf(str, "freeDirectoryList %d\n", data->is_free_directory_list);
furi_string_cat_printf(str, "masterChangeable %d\n", data->is_master_key_changeable);
if(data->is_free_directory_list) {
furi_string_cat_printf(str, "changeKeyID %d\n", data->change_key_id);
furi_string_cat_printf(str, "configChangeable %d\n", data->is_config_changeable);
furi_string_cat_printf(str, "freeCreateDelete %d\n", data->is_free_create_delete);
furi_string_cat_printf(str, "freeDirectoryList %d\n", data->is_free_directory_list);
furi_string_cat_printf(str, "masterChangeable %d\n", data->is_master_key_changeable);
} else {
furi_string_cat_printf(str, "changeKeyID ??\n");
furi_string_cat_printf(str, "configChangeable ??\n");
furi_string_cat_printf(str, "freeCreateDelete ??\n");
furi_string_cat_printf(str, "freeDirectoryList 0\n");
furi_string_cat_printf(str, "masterChangeable ??\n");
}
if(data->flags) {
furi_string_cat_printf(str, "flags %d\n", data->flags);
}
furi_string_cat_printf(str, "maxKeys %d\n", data->max_keys);
if(data->is_free_directory_list) {
furi_string_cat_printf(str, "maxKeys %d\n", data->max_keys);
} else {
furi_string_cat_printf(str, "maxKeys ??\n");
}
}
void nfc_render_mf_desfire_key_version(
@@ -123,14 +140,16 @@ void nfc_render_mf_desfire_key_version(
void nfc_render_mf_desfire_application_id(const MfDesfireApplicationId* data, FuriString* str) {
const uint8_t* app_id = data->data;
furi_string_cat_printf(str, "Application %02x%02x%02x\n", app_id[0], app_id[1], app_id[2]);
furi_string_cat_printf(str, "Application %02x%02x%02x\n", app_id[2], app_id[1], app_id[0]);
}
void nfc_render_mf_desfire_application(const MfDesfireApplication* data, FuriString* str) {
nfc_render_mf_desfire_key_settings(&data->key_settings, str);
for(uint32_t i = 0; i < simple_array_get_count(data->key_versions); ++i) {
nfc_render_mf_desfire_key_version(simple_array_cget(data->key_versions, i), i, str);
if(data->key_settings.is_free_directory_list) {
for(uint32_t i = 0; i < simple_array_get_count(data->key_versions); ++i) {
nfc_render_mf_desfire_key_version(simple_array_cget(data->key_versions, i), i, str);
}
}
}
@@ -179,13 +198,16 @@ void nfc_render_mf_desfire_file_settings_data(
}
furi_string_cat_printf(str, "%s %s\n", type, comm);
furi_string_cat_printf(
str,
"r %d w %d rw %d c %d\n",
settings->access_rights >> 12 & 0xF,
settings->access_rights >> 8 & 0xF,
settings->access_rights >> 4 & 0xF,
settings->access_rights & 0xF);
for(size_t i = 0; i < settings->access_rights_len; i++) {
furi_string_cat_printf(
str,
"r %d w %d rw %d c %d\n",
settings->access_rights[i] >> 12 & 0xF,
settings->access_rights[i] >> 8 & 0xF,
settings->access_rights[i] >> 4 & 0xF,
settings->access_rights[i] & 0xF);
}
uint32_t record_count = 1;
uint32_t record_size = 0;
@@ -217,6 +239,20 @@ void nfc_render_mf_desfire_file_settings_data(
break;
}
bool is_auth_required = true;
for(size_t i = 0; i < settings->access_rights_len; i++) {
uint8_t read_rights = (settings->access_rights[i] >> 12) & 0x0f;
uint8_t read_write_rights = (settings->access_rights[i] >> 4) & 0x0f;
if((read_rights == 0x0e) || (read_write_rights == 0x0e)) {
is_auth_required = false;
break;
}
}
if(is_auth_required) {
furi_string_cat_printf(str, "Auth required to read file data\n");
return;
}
if(simple_array_get_count(data->data) == 0) {
return;
}

View File

@@ -8,6 +8,7 @@
#include "../nfc_protocol_support_common.h"
#include "../nfc_protocol_support_gui_common.h"
#include "../nfc_protocol_support_unlock_helper.h"
enum {
SubmenuIndexUnlock = SubmenuIndexCommonMax,
@@ -30,6 +31,8 @@ static void nfc_scene_info_on_enter_mf_ultralight(NfcApp* instance) {
furi_string_cat_printf(
temp_str, "\e#%s\n", nfc_device_get_name(device, NfcDeviceNameTypeFull));
furi_string_replace(temp_str, "Mifare", "MIFARE");
nfc_render_mf_ultralight_info(data, NfcProtocolFormatTypeFull, temp_str);
widget_add_text_scroll_element(
@@ -155,48 +158,15 @@ static NfcCommand
return NfcCommandContinue;
}
enum {
NfcSceneMfUltralightReadMenuStateCardSearch,
NfcSceneMfUltralightReadMenuStateCardFound,
};
static void nfc_scene_read_setup_view(NfcApp* instance) {
Popup* popup = instance->popup;
popup_reset(popup);
uint32_t state = scene_manager_get_scene_state(instance->scene_manager, NfcSceneRead);
if(state == NfcSceneMfUltralightReadMenuStateCardSearch) {
popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50);
popup_set_header(instance->popup, "Unlocking", 97, 15, AlignCenter, AlignTop);
popup_set_text(
instance->popup, "Apply card to\nFlipper's back", 97, 27, AlignCenter, AlignTop);
} else {
popup_set_header(instance->popup, "Don't move", 85, 27, AlignCenter, AlignTop);
popup_set_icon(instance->popup, 12, 20, &A_Loading_24);
}
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup);
}
static void nfc_scene_read_on_enter_mf_ultralight(NfcApp* instance) {
bool unlocking =
scene_manager_has_previous_scene(instance->scene_manager, NfcSceneMfUltralightUnlockWarn);
uint32_t state = unlocking ? NfcSceneMfUltralightReadMenuStateCardSearch :
NfcSceneMfUltralightReadMenuStateCardFound;
scene_manager_set_scene_state(instance->scene_manager, NfcSceneRead, state);
nfc_scene_read_setup_view(instance);
nfc_unlock_helper_setup_from_state(instance);
nfc_poller_start(instance->poller, nfc_scene_read_poller_callback_mf_ultralight, instance);
}
bool nfc_scene_read_on_event_mf_ultralight(NfcApp* instance, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventCardDetected) {
scene_manager_set_scene_state(
instance->scene_manager, NfcSceneRead, NfcSceneMfUltralightReadMenuStateCardFound);
nfc_scene_read_setup_view(instance);
nfc_unlock_helper_card_detected_handler(instance);
} else if((event.event == NfcCustomEventPollerIncomplete)) {
notification_message(instance->notifications, &sequence_semi_success);
scene_manager_next_scene(instance->scene_manager, NfcSceneReadSuccess);
@@ -245,6 +215,8 @@ static void nfc_scene_read_success_on_enter_mf_ultralight(NfcApp* instance) {
furi_string_cat_printf(
temp_str, "\e#%s\n", nfc_device_get_name(device, NfcDeviceNameTypeFull));
furi_string_replace(temp_str, "Mifare", "MIFARE");
nfc_render_mf_ultralight_info(data, NfcProtocolFormatTypeShort, temp_str);
}

View File

@@ -11,7 +11,11 @@ static void nfc_render_mf_ultralight_pages_count(const MfUltralightData* data, F
void nfc_render_mf_ultralight_pwd_pack(const MfUltralightData* data, FuriString* str) {
bool all_pages = mf_ultralight_is_all_data_read(data);
furi_string_cat_printf(str, "\e#%s pages unlocked!", all_pages ? "All" : "Not all");
if(all_pages) {
furi_string_cat_printf(str, "\e#All Pages Are Unlocked!");
} else {
furi_string_cat_printf(str, "\e#Some Pages Are Locked!");
}
MfUltralightConfigPages* config;
mf_ultralight_get_config_page(data, &config);

View File

@@ -600,7 +600,7 @@ static void nfc_protocol_support_scene_emulate_on_enter(NfcApp* instance) {
}
widget_add_text_box_element(
widget, 56, 33, 71, 25, AlignCenter, AlignTop, furi_string_get_cstr(temp_str), false);
widget, 50, 33, 78, 31, AlignCenter, AlignTop, furi_string_get_cstr(temp_str), false);
furi_string_free(temp_str);

View File

@@ -0,0 +1,38 @@
#include "nfc_protocol_support_unlock_helper.h"
static void nfc_scene_read_setup_view(NfcApp* instance) {
Popup* popup = instance->popup;
popup_reset(popup);
uint32_t state = scene_manager_get_scene_state(instance->scene_manager, NfcSceneRead);
if(state == NfcSceneReadMenuStateCardSearch) {
popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50);
popup_set_header(instance->popup, "Unlocking", 97, 15, AlignCenter, AlignTop);
popup_set_text(
instance->popup, "Hold card next\nto Flipper's back", 94, 27, AlignCenter, AlignTop);
} else {
popup_set_header(instance->popup, "Don't move", 85, 27, AlignCenter, AlignTop);
popup_set_icon(instance->popup, 12, 20, &A_Loading_24);
}
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup);
}
void nfc_unlock_helper_setup_from_state(NfcApp* instance) {
bool unlocking =
scene_manager_has_previous_scene(
instance->scene_manager, NfcSceneMfUltralightUnlockWarn) ||
scene_manager_has_previous_scene(instance->scene_manager, NfcSceneFelicaUnlockWarn);
uint32_t state = unlocking ? NfcSceneReadMenuStateCardSearch : NfcSceneReadMenuStateCardFound;
scene_manager_set_scene_state(instance->scene_manager, NfcSceneRead, state);
nfc_scene_read_setup_view(instance);
}
void nfc_unlock_helper_card_detected_handler(NfcApp* instance) {
scene_manager_set_scene_state(
instance->scene_manager, NfcSceneRead, NfcSceneReadMenuStateCardFound);
nfc_scene_read_setup_view(instance);
}

View File

@@ -0,0 +1,9 @@
#include "nfc/nfc_app_i.h"
typedef enum {
NfcSceneReadMenuStateCardSearch,
NfcSceneReadMenuStateCardFound,
} NfcSceneUnlockReadState;
void nfc_unlock_helper_setup_from_state(NfcApp* instance);
void nfc_unlock_helper_card_detected_handler(NfcApp* instance);

View File

@@ -1,22 +1,28 @@
#include "st25tb_render.h"
#include <nfc/protocols/st25tb/st25tb.h>
#include <machine/endian.h>
void nfc_render_st25tb_info(
const St25tbData* data,
NfcProtocolFormatType format_type,
FuriString* str) {
furi_string_cat_printf(str, "UID");
furi_string_cat_printf(str, "UID:");
for(size_t i = 0; i < ST25TB_UID_SIZE; i++) {
furi_string_cat_printf(str, " %02X", data->uid[i]);
}
if(format_type == NfcProtocolFormatTypeFull) {
furi_string_cat_printf(str, "\nSys. OTP: %08lX", data->system_otp_block);
furi_string_cat_printf(str, "\nBlocks:");
furi_string_cat_printf(
str, "\nSys. OTP: %08lX", (uint32_t)__bswap32(data->system_otp_block));
furi_string_cat_printf(str, "\n::::::::::::::::::::::[Blocks]::::::::::::::::::::::");
for(size_t i = 0; i < st25tb_get_block_count(data->type); i += 2) {
furi_string_cat_printf(
str, "\n %02X %08lX %08lX", i, data->blocks[i], data->blocks[i + 1]);
str,
"\n %02X %08lX %08lX",
i,
(uint32_t)__bswap32(data->blocks[i]),
(uint32_t)__bswap32(data->blocks[i + 1]));
}
}
}