detect_reader.c 4.8 KB

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