mfc_editor_scene_data_view.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include "../mfc_editor_app_i.h"
  2. void mfc_editor_scene_data_view_dialog_ex_callback(DialogExResult result, void* context) {
  3. MfcEditorApp* instance = context;
  4. view_dispatcher_send_custom_event(instance->view_dispatcher, result);
  5. }
  6. void mfc_editor_scene_data_view_on_enter(void* context) {
  7. MfcEditorApp* instance = context;
  8. DialogEx* dialog_ex = instance->dialog_ex;
  9. dialog_ex_set_context(instance->dialog_ex, instance);
  10. MfcEditorBlockView block_view =
  11. scene_manager_get_scene_state(instance->scene_manager, MfcEditorSceneDataView);
  12. const MfClassicData* mf_classic_data = instance->mf_classic_data;
  13. Iso14443_3aData* iso14443_3a_data = mf_classic_data->iso14443_3a_data;
  14. furi_string_reset(instance->data_view_text);
  15. if(block_view == MfcEditorBlockViewUID) {
  16. dialog_ex_set_header(dialog_ex, "UID", 63, 3, AlignCenter, AlignTop);
  17. for(int i = 0; i < iso14443_3a_data->uid_len; i++) {
  18. furi_string_cat_printf(instance->data_view_text, "%02X ", iso14443_3a_data->uid[i]);
  19. }
  20. // Remove trailing space
  21. furi_string_trim(instance->data_view_text);
  22. } else if(block_view == MfcEditorBlockViewBCC) {
  23. dialog_ex_set_header(dialog_ex, "Block Check Character", 63, 3, AlignCenter, AlignTop);
  24. uint8_t stored_bcc = mf_classic_data->block[0].data[4];
  25. uint8_t calculated_bcc =
  26. mfc_editor_calculate_uid_bcc(iso14443_3a_data->uid, iso14443_3a_data->uid_len);
  27. if(mf_classic_is_block_read(mf_classic_data, 0)) {
  28. furi_string_printf(
  29. instance->data_view_text,
  30. "Stored BCC: %02X\nActual BCC: %02X",
  31. stored_bcc,
  32. calculated_bcc);
  33. if(stored_bcc != calculated_bcc) {
  34. furi_string_cat(instance->data_view_text, "\n(Mismatch!)");
  35. }
  36. } else {
  37. furi_string_printf(
  38. instance->data_view_text,
  39. "Actual BCC: %02X\nStored BCC is unavailable\nas Block 0 has not been read.",
  40. calculated_bcc);
  41. }
  42. } else if(block_view == MfcEditorBlockViewManufacturerBytes) {
  43. dialog_ex_set_header(dialog_ex, "Manufacturer Bytes", 63, 3, AlignCenter, AlignTop);
  44. if(mf_classic_is_block_read(mf_classic_data, 0)) {
  45. // Skip BCC byte (not present on 7B UID cards)
  46. bool skip_byte = iso14443_3a_data->uid_len == 4;
  47. uint8_t byte_num = MF_CLASSIC_BLOCK_SIZE - iso14443_3a_data->uid_len - skip_byte;
  48. for(int i = iso14443_3a_data->uid_len + skip_byte; i < MF_CLASSIC_BLOCK_SIZE; i++) {
  49. furi_string_cat_printf(
  50. instance->data_view_text, "%02X", mf_classic_data->block[0].data[i]);
  51. // Go onto next line when halfway through
  52. if(MF_CLASSIC_BLOCK_SIZE - i - 1 == byte_num / 2) {
  53. furi_string_push_back(instance->data_view_text, '\n');
  54. } else {
  55. furi_string_push_back(instance->data_view_text, ' ');
  56. }
  57. }
  58. // Remove trailing space
  59. furi_string_trim(instance->data_view_text);
  60. } else {
  61. furi_string_set(
  62. instance->data_view_text, "Data unavailable.\nBlock 0 has not been read.");
  63. }
  64. } else if(block_view == MfcEditorBlockViewKeyA) {
  65. dialog_ex_set_header(dialog_ex, "Key A", 63, 3, AlignCenter, AlignTop);
  66. if(mf_classic_is_key_found(mf_classic_data, instance->current_sector, MfClassicKeyTypeA)) {
  67. MfClassicSectorTrailer* sector_trailer =
  68. mf_classic_get_sector_trailer_by_sector(mf_classic_data, instance->current_sector);
  69. MfClassicKey key_a = sector_trailer->key_a;
  70. furi_string_printf(
  71. instance->data_view_text,
  72. "%02X %02X %02X %02X %02X %02X",
  73. key_a.data[0],
  74. key_a.data[1],
  75. key_a.data[2],
  76. key_a.data[3],
  77. key_a.data[4],
  78. key_a.data[5]);
  79. } else {
  80. furi_string_set(
  81. instance->data_view_text, "Key A has not been found\nfor this sector.");
  82. }
  83. } else if(block_view == MfcEditorBlockViewKeyB) {
  84. dialog_ex_set_header(dialog_ex, "Key B", 63, 3, AlignCenter, AlignTop);
  85. if(mf_classic_is_key_found(mf_classic_data, instance->current_sector, MfClassicKeyTypeB)) {
  86. MfClassicSectorTrailer* sector_trailer =
  87. mf_classic_get_sector_trailer_by_sector(mf_classic_data, instance->current_sector);
  88. MfClassicKey key_b = sector_trailer->key_b;
  89. furi_string_printf(
  90. instance->data_view_text,
  91. "%02X %02X %02X %02X %02X %02X",
  92. key_b.data[0],
  93. key_b.data[1],
  94. key_b.data[2],
  95. key_b.data[3],
  96. key_b.data[4],
  97. key_b.data[5]);
  98. } else {
  99. furi_string_set(
  100. instance->data_view_text, "Key B has not been found\nfor this sector.");
  101. }
  102. } else if(block_view == MfcEditorBlockViewAccessBits) {
  103. dialog_ex_set_header(dialog_ex, "Access Bits", 63, 3, AlignCenter, AlignTop);
  104. } else if(block_view == MfcEditorBlockViewUserByte) {
  105. dialog_ex_set_header(dialog_ex, "User Byte", 63, 3, AlignCenter, AlignTop);
  106. uint8_t sector_trailer_num =
  107. mf_classic_get_sector_trailer_num_by_sector(instance->current_sector);
  108. if(mf_classic_is_block_read(mf_classic_data, sector_trailer_num)) {
  109. furi_string_printf(
  110. instance->data_view_text,
  111. "Free byte between\nAccess Bits and Key B:\n%02X",
  112. mf_classic_data->block[sector_trailer_num].data[9]);
  113. } else {
  114. furi_string_printf(
  115. instance->data_view_text,
  116. "Data unavailable.\nBlock %u has not been read.",
  117. sector_trailer_num);
  118. }
  119. } else {
  120. furi_string_printf(instance->data_view_header, "Block %u Data", instance->current_block);
  121. dialog_ex_set_header(
  122. dialog_ex,
  123. furi_string_get_cstr(instance->data_view_header),
  124. 63,
  125. 3,
  126. AlignCenter,
  127. AlignTop);
  128. }
  129. dialog_ex_set_text(
  130. dialog_ex,
  131. furi_string_get_cstr(instance->data_view_text),
  132. 63,
  133. 31,
  134. AlignCenter,
  135. AlignCenter);
  136. dialog_ex_set_left_button_text(instance->dialog_ex, "Back");
  137. dialog_ex_set_result_callback(
  138. instance->dialog_ex, mfc_editor_scene_data_view_dialog_ex_callback);
  139. view_dispatcher_switch_to_view(instance->view_dispatcher, MfcEditorAppViewDialogEx);
  140. }
  141. bool mfc_editor_scene_data_view_on_event(void* context, SceneManagerEvent event) {
  142. MfcEditorApp* instance = context;
  143. bool consumed = false;
  144. if(event.type == SceneManagerEventTypeCustom) {
  145. if(event.event == DialogExResultLeft) {
  146. scene_manager_previous_scene(instance->scene_manager);
  147. consumed = true;
  148. }
  149. }
  150. return consumed;
  151. }
  152. void mfc_editor_scene_data_view_on_exit(void* context) {
  153. MfcEditorApp* instance = context;
  154. dialog_ex_reset(instance->dialog_ex);
  155. }