dict_attack.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #include "dict_attack.h"
  2. #include <m-string.h>
  3. #include <gui/elements.h>
  4. typedef enum {
  5. DictAttackStateRead,
  6. DictAttackStateCardRemoved,
  7. } DictAttackState;
  8. struct DictAttack {
  9. View* view;
  10. DictAttackCallback callback;
  11. void* context;
  12. };
  13. typedef struct {
  14. DictAttackState state;
  15. MfClassicType type;
  16. string_t header;
  17. uint8_t sectors_total;
  18. uint8_t sectors_read;
  19. uint8_t sector_current;
  20. uint8_t keys_total;
  21. uint8_t keys_found;
  22. } DictAttackViewModel;
  23. static void dict_attack_draw_callback(Canvas* canvas, void* model) {
  24. DictAttackViewModel* m = model;
  25. if(m->state == DictAttackStateCardRemoved) {
  26. canvas_set_font(canvas, FontPrimary);
  27. canvas_draw_str_aligned(canvas, 64, 4, AlignCenter, AlignTop, "Lost the tag!");
  28. canvas_set_font(canvas, FontSecondary);
  29. elements_multiline_text_aligned(
  30. canvas, 64, 23, AlignCenter, AlignTop, "Make sure the tag is\npositioned correctly.");
  31. } else if(m->state == DictAttackStateRead) {
  32. char draw_str[32] = {};
  33. canvas_set_font(canvas, FontPrimary);
  34. canvas_draw_str_aligned(canvas, 64, 2, AlignCenter, AlignTop, string_get_cstr(m->header));
  35. canvas_set_font(canvas, FontSecondary);
  36. float progress =
  37. m->sectors_total == 0 ? 0 : (float)(m->sector_current) / (float)(m->sectors_total);
  38. elements_progress_bar(canvas, 5, 15, 120, progress);
  39. canvas_set_font(canvas, FontSecondary);
  40. snprintf(draw_str, sizeof(draw_str), "Keys found: %d/%d", m->keys_found, m->keys_total);
  41. canvas_draw_str_aligned(canvas, 1, 28, AlignLeft, AlignTop, draw_str);
  42. snprintf(
  43. draw_str, sizeof(draw_str), "Sectors Read: %d/%d", m->sectors_read, m->sectors_total);
  44. canvas_draw_str_aligned(canvas, 1, 40, AlignLeft, AlignTop, draw_str);
  45. }
  46. elements_button_center(canvas, "Skip");
  47. }
  48. static bool dict_attack_input_callback(InputEvent* event, void* context) {
  49. DictAttack* dict_attack = context;
  50. bool consumed = false;
  51. if(event->type == InputTypeShort && event->key == InputKeyOk) {
  52. if(dict_attack->callback) {
  53. dict_attack->callback(dict_attack->context);
  54. }
  55. consumed = true;
  56. }
  57. return consumed;
  58. }
  59. DictAttack* dict_attack_alloc() {
  60. DictAttack* dict_attack = malloc(sizeof(DictAttack));
  61. dict_attack->view = view_alloc();
  62. view_allocate_model(dict_attack->view, ViewModelTypeLocking, sizeof(DictAttackViewModel));
  63. view_set_draw_callback(dict_attack->view, dict_attack_draw_callback);
  64. view_set_input_callback(dict_attack->view, dict_attack_input_callback);
  65. view_set_context(dict_attack->view, dict_attack);
  66. with_view_model(
  67. dict_attack->view, (DictAttackViewModel * model) {
  68. string_init(model->header);
  69. return false;
  70. });
  71. return dict_attack;
  72. }
  73. void dict_attack_free(DictAttack* dict_attack) {
  74. furi_assert(dict_attack);
  75. with_view_model(
  76. dict_attack->view, (DictAttackViewModel * model) {
  77. string_clear(model->header);
  78. return false;
  79. });
  80. view_free(dict_attack->view);
  81. free(dict_attack);
  82. }
  83. void dict_attack_reset(DictAttack* dict_attack) {
  84. furi_assert(dict_attack);
  85. with_view_model(
  86. dict_attack->view, (DictAttackViewModel * model) {
  87. model->state = DictAttackStateRead;
  88. model->type = MfClassicType1k;
  89. model->sectors_total = 0;
  90. model->sectors_read = 0;
  91. model->sector_current = 0;
  92. model->keys_total = 0;
  93. model->keys_found = 0;
  94. string_reset(model->header);
  95. return false;
  96. });
  97. }
  98. View* dict_attack_get_view(DictAttack* dict_attack) {
  99. furi_assert(dict_attack);
  100. return dict_attack->view;
  101. }
  102. void dict_attack_set_callback(DictAttack* dict_attack, DictAttackCallback callback, void* context) {
  103. furi_assert(dict_attack);
  104. furi_assert(callback);
  105. dict_attack->callback = callback;
  106. dict_attack->context = context;
  107. }
  108. void dict_attack_set_header(DictAttack* dict_attack, const char* header) {
  109. furi_assert(dict_attack);
  110. furi_assert(header);
  111. with_view_model(
  112. dict_attack->view, (DictAttackViewModel * model) {
  113. string_set_str(model->header, header);
  114. return true;
  115. });
  116. }
  117. void dict_attack_set_card_detected(DictAttack* dict_attack, MfClassicType type) {
  118. furi_assert(dict_attack);
  119. with_view_model(
  120. dict_attack->view, (DictAttackViewModel * model) {
  121. model->state = DictAttackStateRead;
  122. model->sectors_total = mf_classic_get_total_sectors_num(type);
  123. model->keys_total = model->sectors_total * 2;
  124. return true;
  125. });
  126. }
  127. void dict_attack_set_card_removed(DictAttack* dict_attack) {
  128. furi_assert(dict_attack);
  129. with_view_model(
  130. dict_attack->view, (DictAttackViewModel * model) {
  131. model->state = DictAttackStateCardRemoved;
  132. return true;
  133. });
  134. }
  135. void dict_attack_set_sector_read(DictAttack* dict_attack, uint8_t sec_read) {
  136. furi_assert(dict_attack);
  137. with_view_model(
  138. dict_attack->view, (DictAttackViewModel * model) {
  139. model->sectors_read = sec_read;
  140. return true;
  141. });
  142. }
  143. void dict_attack_set_keys_found(DictAttack* dict_attack, uint8_t keys_found) {
  144. furi_assert(dict_attack);
  145. with_view_model(
  146. dict_attack->view, (DictAttackViewModel * model) {
  147. model->keys_found = keys_found;
  148. return true;
  149. });
  150. }
  151. void dict_attack_set_current_sector(DictAttack* dict_attack, uint8_t curr_sec) {
  152. furi_assert(dict_attack);
  153. with_view_model(
  154. dict_attack->view, (DictAttackViewModel * model) {
  155. model->sector_current = curr_sec;
  156. return true;
  157. });
  158. }
  159. void dict_attack_inc_current_sector(DictAttack* dict_attack) {
  160. furi_assert(dict_attack);
  161. with_view_model(
  162. dict_attack->view, (DictAttackViewModel * model) {
  163. if(model->sector_current < model->sectors_total) {
  164. model->sector_current++;
  165. }
  166. return true;
  167. });
  168. }
  169. void dict_attack_inc_keys_found(DictAttack* dict_attack) {
  170. furi_assert(dict_attack);
  171. with_view_model(
  172. dict_attack->view, (DictAttackViewModel * model) {
  173. if(model->keys_found < model->keys_total) {
  174. model->keys_found++;
  175. }
  176. return true;
  177. });
  178. }