detect_reader.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #include "detect_reader.h"
  2. #include <gui/elements.h>
  3. struct DetectReader {
  4. View* view;
  5. DetectReaderDoneCallback callback;
  6. void* context;
  7. };
  8. typedef struct {
  9. uint16_t nonces;
  10. uint16_t nonces_max;
  11. DetectReaderState state;
  12. } DetectReaderViewModel;
  13. static void detect_reader_draw_callback(Canvas* canvas, void* model) {
  14. DetectReaderViewModel* m = model;
  15. char text[32] = {};
  16. // Draw header and icon
  17. canvas_draw_icon(canvas, 0, 16, &I_Modern_reader_18x34);
  18. if(m->state == DetectReaderStateStart) {
  19. snprintf(text, sizeof(text), "Touch the reader");
  20. canvas_draw_icon(canvas, 21, 13, &I_Move_flipper_26x39);
  21. } else if(m->state == DetectReaderStateReaderDetected) {
  22. snprintf(text, sizeof(text), "Move the Flipper away");
  23. canvas_draw_icon(canvas, 24, 25, &I_Release_arrow_18x15);
  24. } else if(m->state == DetectReaderStateReaderLost) {
  25. snprintf(text, sizeof(text), "Touch the reader again");
  26. canvas_draw_icon(canvas, 21, 13, &I_Move_flipper_26x39);
  27. }
  28. canvas_draw_str_aligned(canvas, 64, 0, AlignCenter, AlignTop, text);
  29. // Draw collected nonces
  30. if(m->state == DetectReaderStateStart) {
  31. canvas_set_font(canvas, FontPrimary);
  32. canvas_draw_str_aligned(canvas, 51, 22, AlignLeft, AlignTop, "Emulating...");
  33. canvas_set_font(canvas, FontSecondary);
  34. canvas_draw_str_aligned(canvas, 51, 35, AlignLeft, AlignTop, "MIFARE MFkey32");
  35. } else {
  36. if(m->state == DetectReaderStateDone) {
  37. canvas_set_font(canvas, FontPrimary);
  38. canvas_draw_str_aligned(canvas, 51, 22, AlignLeft, AlignTop, "Completed!");
  39. } else {
  40. canvas_set_font(canvas, FontPrimary);
  41. canvas_draw_str_aligned(canvas, 51, 22, AlignLeft, AlignTop, "Collecting...");
  42. }
  43. canvas_set_font(canvas, FontSecondary);
  44. snprintf(text, sizeof(text), "Nonce pairs: %d/%d", m->nonces, m->nonces_max);
  45. canvas_draw_str_aligned(canvas, 51, 35, AlignLeft, AlignTop, text);
  46. }
  47. // Draw button
  48. if(m->nonces > 0) {
  49. elements_button_center(canvas, "Done");
  50. }
  51. }
  52. static bool detect_reader_input_callback(InputEvent* event, void* context) {
  53. DetectReader* detect_reader = context;
  54. furi_assert(detect_reader->callback);
  55. bool consumed = false;
  56. uint8_t nonces = 0;
  57. with_view_model(
  58. detect_reader->view, DetectReaderViewModel * model, { nonces = model->nonces; }, false);
  59. if(event->type == InputTypeShort) {
  60. if(event->key == InputKeyOk) {
  61. if(nonces > 0) {
  62. detect_reader->callback(detect_reader->context);
  63. consumed = true;
  64. }
  65. }
  66. }
  67. return consumed;
  68. }
  69. DetectReader* detect_reader_alloc() {
  70. DetectReader* detect_reader = malloc(sizeof(DetectReader));
  71. detect_reader->view = view_alloc();
  72. view_allocate_model(detect_reader->view, ViewModelTypeLocking, sizeof(DetectReaderViewModel));
  73. view_set_draw_callback(detect_reader->view, detect_reader_draw_callback);
  74. view_set_input_callback(detect_reader->view, detect_reader_input_callback);
  75. view_set_context(detect_reader->view, detect_reader);
  76. return detect_reader;
  77. }
  78. void detect_reader_free(DetectReader* detect_reader) {
  79. furi_assert(detect_reader);
  80. view_free(detect_reader->view);
  81. free(detect_reader);
  82. }
  83. void detect_reader_reset(DetectReader* detect_reader) {
  84. furi_assert(detect_reader);
  85. with_view_model(
  86. detect_reader->view,
  87. DetectReaderViewModel * model,
  88. {
  89. model->nonces = 0;
  90. model->nonces_max = 0;
  91. model->state = DetectReaderStateStart;
  92. },
  93. false);
  94. }
  95. View* detect_reader_get_view(DetectReader* detect_reader) {
  96. furi_assert(detect_reader);
  97. return detect_reader->view;
  98. }
  99. void detect_reader_set_callback(
  100. DetectReader* detect_reader,
  101. DetectReaderDoneCallback callback,
  102. void* context) {
  103. furi_assert(detect_reader);
  104. furi_assert(callback);
  105. detect_reader->callback = callback;
  106. detect_reader->context = context;
  107. }
  108. void detect_reader_set_nonces_max(DetectReader* detect_reader, uint16_t nonces_max) {
  109. furi_assert(detect_reader);
  110. with_view_model(
  111. detect_reader->view,
  112. DetectReaderViewModel * model,
  113. { model->nonces_max = nonces_max; },
  114. false);
  115. }
  116. void detect_reader_set_nonces_collected(DetectReader* detect_reader, uint16_t nonces_collected) {
  117. furi_assert(detect_reader);
  118. with_view_model(
  119. detect_reader->view,
  120. DetectReaderViewModel * model,
  121. { model->nonces = nonces_collected; },
  122. false);
  123. }
  124. void detect_reader_set_state(DetectReader* detect_reader, DetectReaderState state) {
  125. furi_assert(detect_reader);
  126. with_view_model(
  127. detect_reader->view, DetectReaderViewModel * model, { model->state = state; }, true);
  128. }