| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- #include "../mfc_editor_app_i.h"
- void mfc_editor_scene_data_view_dialog_ex_callback(DialogExResult result, void* context) {
- MfcEditorApp* instance = context;
- view_dispatcher_send_custom_event(instance->view_dispatcher, result);
- }
- void mfc_editor_scene_data_view_update_display(MfcEditorApp* instance) {
- DialogEx* dialog_ex = instance->dialog_ex;
- dialog_ex_reset(instance->dialog_ex);
- dialog_ex_set_context(instance->dialog_ex, instance);
- dialog_ex_set_result_callback(
- instance->dialog_ex, mfc_editor_scene_data_view_dialog_ex_callback);
- MfcEditorBlockView block_view =
- scene_manager_get_scene_state(instance->scene_manager, MfcEditorSceneDataView);
- MfClassicData* mf_classic_data = instance->mf_classic_data;
- Iso14443_3aData* iso14443_3a_data = mf_classic_data->iso14443_3a_data;
- furi_string_reset(instance->data_view_text);
- if(block_view == MfcEditorBlockViewUID) {
- dialog_ex_set_header(dialog_ex, "UID", 63, 3, AlignCenter, AlignTop);
- mfc_editor_furi_string_render_bytes(
- instance->data_view_text, iso14443_3a_data->uid, iso14443_3a_data->uid_len);
- if(memcmp(
- iso14443_3a_data->uid, mf_classic_data->block[0].data, iso14443_3a_data->uid_len)) {
- // ISO-14443 UID does not match first bytes of block 0
- furi_string_cat_printf(instance->data_view_text, "\nBlock 0 does not match UID!\n(");
- mfc_editor_furi_string_render_bytes(
- instance->data_view_text,
- mf_classic_data->block[0].data,
- iso14443_3a_data->uid_len);
- furi_string_push_back(instance->data_view_text, ')');
- dialog_ex_set_center_button_text(dialog_ex, "Fix");
- }
- if(mf_classic_is_block_read(mf_classic_data, 0)) {
- dialog_ex_set_right_button_text(dialog_ex, "Edit");
- }
- } else if(block_view == MfcEditorBlockViewBCC) {
- dialog_ex_set_header(dialog_ex, "Block Check Character", 63, 3, AlignCenter, AlignTop);
- uint8_t stored_bcc = mf_classic_data->block[0].data[4];
- uint8_t calculated_bcc =
- mfc_editor_calculate_uid_bcc(iso14443_3a_data->uid, iso14443_3a_data->uid_len);
- if(mf_classic_is_block_read(mf_classic_data, 0)) {
- furi_string_printf(
- instance->data_view_text,
- "Stored BCC: %02X\nActual BCC: %02X",
- stored_bcc,
- calculated_bcc);
- if(stored_bcc != calculated_bcc) {
- furi_string_cat(instance->data_view_text, "\n(Mismatch!)");
- dialog_ex_set_center_button_text(dialog_ex, "Fix");
- }
- } else {
- furi_string_printf(
- instance->data_view_text,
- "Actual BCC: %02X\nStored BCC is unavailable\nas Block 0 has not been read.",
- calculated_bcc);
- }
- } else if(block_view == MfcEditorBlockViewManufacturerBytes) {
- dialog_ex_set_header(dialog_ex, "Manufacturer Bytes", 63, 3, AlignCenter, AlignTop);
- if(mf_classic_is_block_read(mf_classic_data, 0)) {
- // Skip BCC byte (not present on 7B UID cards)
- bool skip_byte = iso14443_3a_data->uid_len == 4;
- uint8_t start_index = iso14443_3a_data->uid_len + skip_byte;
- uint8_t byte_num = MF_CLASSIC_BLOCK_SIZE - iso14443_3a_data->uid_len - skip_byte;
- uint8_t line_len = byte_num / 2;
- mfc_editor_furi_string_render_bytes(
- instance->data_view_text, mf_classic_data->block[0].data + start_index, line_len);
- furi_string_push_back(instance->data_view_text, '\n');
- mfc_editor_furi_string_render_bytes(
- instance->data_view_text,
- mf_classic_data->block[0].data + start_index + line_len,
- byte_num - line_len);
- dialog_ex_set_right_button_text(dialog_ex, "Edit");
- } else {
- furi_string_set(
- instance->data_view_text, "Data unavailable.\nBlock 0 has not been read.");
- }
- } else if(block_view == MfcEditorBlockViewKeyA) {
- dialog_ex_set_header(dialog_ex, "Key A", 63, 3, AlignCenter, AlignTop);
- if(mf_classic_is_key_found(mf_classic_data, instance->current_sector, MfClassicKeyTypeA)) {
- MfClassicSectorTrailer* sector_trailer =
- mf_classic_get_sector_trailer_by_sector(mf_classic_data, instance->current_sector);
- mfc_editor_furi_string_render_bytes(
- instance->data_view_text, sector_trailer->key_a.data, MF_CLASSIC_KEY_SIZE);
- dialog_ex_set_right_button_text(dialog_ex, "Edit");
- } else {
- furi_string_set(
- instance->data_view_text, "Key A has not been found\nfor this sector.");
- }
- } else if(block_view == MfcEditorBlockViewKeyB) {
- dialog_ex_set_header(dialog_ex, "Key B", 63, 3, AlignCenter, AlignTop);
- if(mf_classic_is_key_found(mf_classic_data, instance->current_sector, MfClassicKeyTypeB)) {
- MfClassicSectorTrailer* sector_trailer =
- mf_classic_get_sector_trailer_by_sector(mf_classic_data, instance->current_sector);
- mfc_editor_furi_string_render_bytes(
- instance->data_view_text, sector_trailer->key_b.data, MF_CLASSIC_KEY_SIZE);
- dialog_ex_set_right_button_text(dialog_ex, "Edit");
- } else {
- furi_string_set(
- instance->data_view_text, "Key B has not been found\nfor this sector.");
- }
- } else if(block_view == MfcEditorBlockViewAccessBits) {
- uint8_t sector_trailer_num =
- mf_classic_get_sector_trailer_num_by_sector(instance->current_sector);
- if(mf_classic_is_block_read(mf_classic_data, sector_trailer_num)) {
- furi_string_printf(
- instance->data_view_header, "Access Bits (Block %u)", instance->current_block);
- dialog_ex_set_header(
- dialog_ex,
- furi_string_get_cstr(instance->data_view_header),
- 63,
- 3,
- AlignCenter,
- AlignTop);
- MfcEditorAccessBits access_bits =
- mfc_editor_get_block_access_bits(mf_classic_data, instance->current_block);
- furi_string_printf(
- instance->data_view_text,
- "C1: %i(%i), C2: %i(%i), C3: %i(%i)\n",
- FURI_BIT(access_bits.bits, 0),
- FURI_BIT(access_bits.check_bits, 0),
- FURI_BIT(access_bits.bits, 1),
- FURI_BIT(access_bits.check_bits, 1),
- FURI_BIT(access_bits.bits, 2),
- FURI_BIT(access_bits.check_bits, 2));
- if(access_bits.bits != access_bits.check_bits) {
- furi_string_cat(
- instance->data_view_text,
- "Access Bits are invalid.\nEntire sector inaccessible.");
- } else if(instance->current_block == sector_trailer_num) {
- furi_string_cat(
- instance->data_view_text, access_sector_trailer_labels[access_bits.bits]);
- } else {
- furi_string_cat(
- instance->data_view_text, access_data_block_labels[access_bits.bits]);
- }
- dialog_ex_set_center_button_text(dialog_ex, "Next");
- dialog_ex_set_left_button_text(dialog_ex, "Prev");
- dialog_ex_set_right_button_text(dialog_ex, "Edit");
- } else {
- dialog_ex_set_header(dialog_ex, "Access Bits", 63, 3, AlignCenter, AlignTop);
- furi_string_printf(
- instance->data_view_text,
- "Access Bits unavailable.\nBlock %u has not been read.",
- sector_trailer_num);
- }
- } else if(block_view == MfcEditorBlockViewUserByte) {
- dialog_ex_set_header(dialog_ex, "User Byte", 63, 3, AlignCenter, AlignTop);
- uint8_t sector_trailer_num =
- mf_classic_get_sector_trailer_num_by_sector(instance->current_sector);
- if(mf_classic_is_block_read(mf_classic_data, sector_trailer_num)) {
- furi_string_printf(
- instance->data_view_text,
- "Free byte between\nAccess Bits and Key B:\n%02X",
- mf_classic_data->block[sector_trailer_num].data[9]);
- dialog_ex_set_right_button_text(dialog_ex, "Edit");
- } else {
- furi_string_printf(
- instance->data_view_text,
- "Data unavailable.\nBlock %u has not been read.",
- sector_trailer_num);
- }
- } else {
- uint8_t current_block = instance->current_block;
- furi_string_printf(instance->data_view_header, "Block %u Data", current_block);
- dialog_ex_set_header(
- dialog_ex,
- furi_string_get_cstr(instance->data_view_header),
- 63,
- 3,
- AlignCenter,
- AlignTop);
- // Only display a block if it is fully read, and, if it is a sector trailer, both keys are found
- if(mf_classic_is_block_read(mf_classic_data, current_block) &&
- (!mf_classic_is_sector_trailer(current_block) ||
- (mf_classic_is_key_found(
- mf_classic_data, instance->current_sector, MfClassicKeyTypeA) &&
- mf_classic_is_key_found(
- mf_classic_data, instance->current_sector, MfClassicKeyTypeB)))) {
- // Split block data across 2 even lines
- const uint8_t* block_data = mf_classic_data->block[current_block].data;
- mfc_editor_furi_string_render_bytes(
- instance->data_view_text, block_data, MF_CLASSIC_BLOCK_SIZE / 2);
- furi_string_push_back(instance->data_view_text, '\n');
- mfc_editor_furi_string_render_bytes(
- instance->data_view_text,
- block_data + MF_CLASSIC_BLOCK_SIZE / 2,
- MF_CLASSIC_BLOCK_SIZE / 2);
- dialog_ex_set_right_button_text(dialog_ex, "Edit");
- } else {
- furi_string_set(
- instance->data_view_text, "Data unavailable.\nBlock has not been fully read.");
- }
- }
- dialog_ex_set_text(
- dialog_ex,
- furi_string_get_cstr(instance->data_view_text),
- 63,
- 31,
- AlignCenter,
- AlignCenter);
- }
- void mfc_editor_scene_data_view_on_enter(void* context) {
- MfcEditorApp* instance = context;
- mfc_editor_scene_data_view_update_display(instance);
- view_dispatcher_switch_to_view(instance->view_dispatcher, MfcEditorAppViewDialogEx);
- }
- bool mfc_editor_scene_data_view_on_event(void* context, SceneManagerEvent event) {
- MfcEditorApp* instance = context;
- bool consumed = false;
- if(event.type == SceneManagerEventTypeCustom) {
- MfcEditorBlockView block_view =
- scene_manager_get_scene_state(instance->scene_manager, MfcEditorSceneDataView);
- if(block_view == MfcEditorBlockViewNormal) {
- if(event.event == DialogExResultRight) {
- // Block 0 and sector trailer blocks are risky edits
- bool risky_block =
- instance->current_block == 0 ||
- instance->current_block ==
- mf_classic_get_sector_trailer_num_by_block(instance->current_block);
- if(!risky_block || mfc_editor_warn_risky_operation(instance)) {
- scene_manager_set_scene_state(
- instance->scene_manager, MfcEditorSceneDataEdit, block_view);
- scene_manager_next_scene(instance->scene_manager, MfcEditorSceneDataEdit);
- }
- consumed = true;
- }
- } else if(block_view == MfcEditorBlockViewUID) {
- if(event.event == DialogExResultRight) {
- if(mfc_editor_warn_risky_operation(instance)) {
- scene_manager_set_scene_state(
- instance->scene_manager, MfcEditorSceneDataEdit, block_view);
- scene_manager_next_scene(instance->scene_manager, MfcEditorSceneDataEdit);
- }
- consumed = true;
- } else if(event.event == DialogExResultCenter) {
- if(mfc_editor_warn_risky_operation(instance)) {
- memcpy(
- instance->mf_classic_data->block[0].data,
- instance->mf_classic_data->iso14443_3a_data->uid,
- instance->mf_classic_data->iso14443_3a_data->uid_len);
- instance->is_unsaved_changes = true;
- mfc_editor_scene_data_view_update_display(instance);
- }
- consumed = true;
- }
- } else if(
- block_view == MfcEditorBlockViewManufacturerBytes ||
- block_view == MfcEditorBlockViewKeyA || block_view == MfcEditorBlockViewKeyB) {
- if(event.event == DialogExResultRight) {
- if(mfc_editor_warn_risky_operation(instance)) {
- scene_manager_set_scene_state(
- instance->scene_manager, MfcEditorSceneDataEdit, block_view);
- scene_manager_next_scene(instance->scene_manager, MfcEditorSceneDataEdit);
- }
- consumed = true;
- }
- } else if(block_view == MfcEditorBlockViewBCC) {
- if(event.event == DialogExResultCenter) {
- if(mfc_editor_warn_risky_operation(instance)) {
- // Fix BCC byte by setting it to calculated one
- instance->mf_classic_data->block[0].data[4] = mfc_editor_calculate_uid_bcc(
- instance->mf_classic_data->iso14443_3a_data->uid,
- instance->mf_classic_data->iso14443_3a_data->uid_len);
- instance->is_unsaved_changes = true;
- mfc_editor_scene_data_view_update_display(instance);
- }
- consumed = true;
- }
- } else if(block_view == MfcEditorBlockViewAccessBits) {
- if(event.event == DialogExResultLeft) {
- uint8_t new_sector = mf_classic_get_sector_by_block(--instance->current_block);
- if(new_sector != instance->current_sector) {
- instance->current_block =
- mf_classic_get_sector_trailer_num_by_sector(instance->current_sector);
- }
- mfc_editor_scene_data_view_update_display(instance);
- consumed = true;
- } else if(event.event == DialogExResultCenter) {
- uint8_t new_sector = mf_classic_get_sector_by_block(++instance->current_block);
- if(new_sector != instance->current_sector) {
- instance->current_block =
- mf_classic_get_first_block_num_of_sector(instance->current_sector);
- }
- mfc_editor_scene_data_view_update_display(instance);
- consumed = true;
- } else if(event.event == DialogExResultRight) {
- if(mfc_editor_warn_risky_operation(instance)) {
- scene_manager_next_scene(
- instance->scene_manager, MfcEditorSceneDataEditAccessBits);
- }
- consumed = true;
- }
- } else if(block_view == MfcEditorBlockViewUserByte) {
- scene_manager_set_scene_state(
- instance->scene_manager, MfcEditorSceneDataEdit, block_view);
- scene_manager_next_scene(instance->scene_manager, MfcEditorSceneDataEdit);
- consumed = true;
- }
- }
- return consumed;
- }
- void mfc_editor_scene_data_view_on_exit(void* context) {
- MfcEditorApp* instance = context;
- dialog_ex_reset(instance->dialog_ex);
- }
|