nfc.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #include "nfc.h"
  2. #include "nfc_i.h"
  3. #include "nfc_worker.h"
  4. void nfc_draw_callback(CanvasApi* canvas, void* context) {
  5. furi_assert(canvas);
  6. furi_assert(context);
  7. Nfc* nfc = context;
  8. dispatcher_lock(nfc->dispatcher);
  9. canvas->clear(canvas);
  10. canvas->set_color(canvas, ColorBlack);
  11. canvas->set_font(canvas, FontPrimary);
  12. if(nfc->screen == 0) {
  13. char status[128 / 8];
  14. if(nfc->ret == ERR_WRONG_STATE)
  15. canvas->draw_str(canvas, 2, 16, "NFC Wrong State");
  16. else if(nfc->ret == ERR_PARAM)
  17. canvas->draw_str(canvas, 2, 16, "NFC Wrong Param");
  18. else if(nfc->ret == ERR_IO)
  19. canvas->draw_str(canvas, 2, 16, "NFC IO Error");
  20. else if(nfc->ret == ERR_NONE)
  21. canvas->draw_str(canvas, 2, 16, "NFC Device Found");
  22. else if(nfc->ret == ERR_TIMEOUT)
  23. canvas->draw_str(canvas, 2, 16, "NFC Timeout");
  24. else
  25. canvas->draw_str(canvas, 2, 16, "NFC error");
  26. canvas->set_font(canvas, FontSecondary);
  27. snprintf(status, sizeof(status), "Found: %d", nfc->devCnt);
  28. if(nfc->devCnt > 0) {
  29. canvas->draw_str(canvas, 2, 32, status);
  30. canvas->draw_str(canvas, 2, 42, nfc->current);
  31. snprintf(
  32. status,
  33. sizeof(status),
  34. "ATQA:%d SAK:%d",
  35. nfc->first_atqa.anticollisionInfo,
  36. nfc->first_sak.sak);
  37. canvas->draw_str(canvas, 2, 52, status);
  38. }
  39. } else {
  40. canvas->draw_str(canvas, 2, 16, "Not implemented");
  41. }
  42. dispatcher_unlock(nfc->dispatcher);
  43. }
  44. void nfc_input_callback(InputEvent* event, void* context) {
  45. furi_assert(event);
  46. furi_assert(context);
  47. Nfc* nfc = context;
  48. if(!event->state || event->input != InputBack) return;
  49. widget_enabled_set(nfc->widget, false);
  50. }
  51. void nfc_test_callback(void* context) {
  52. furi_assert(context);
  53. Nfc* nfc = context;
  54. dispatcher_lock(nfc->dispatcher);
  55. nfc->screen = 0;
  56. widget_enabled_set(nfc->widget, true);
  57. // TODO only for workaround
  58. if(nfc->ret != ERR_NONE) {
  59. nfc->ret = rfalNfcInitialize();
  60. rfalLowPowerModeStart();
  61. }
  62. if(nfc->ret == ERR_NONE && !nfc->worker) {
  63. // TODO change to fuirac_start
  64. nfc->worker = osThreadNew(nfc_worker_task, nfc, &nfc->worker_attr);
  65. }
  66. dispatcher_unlock(nfc->dispatcher);
  67. }
  68. void nfc_field_on_callback(void* context) {
  69. furi_assert(context);
  70. Nfc* nfc = context;
  71. // TODO only for workaround
  72. if(nfc->ret != ERR_NONE) {
  73. nfc->ret = rfalNfcInitialize();
  74. rfalLowPowerModeStart();
  75. }
  76. st25r3916OscOn();
  77. st25r3916TxRxOn();
  78. }
  79. void nfc_field_off_callback(void* context) {
  80. furi_assert(context);
  81. Nfc* nfc = context;
  82. // TODO only for workaround
  83. if(nfc->ret != ERR_NONE) {
  84. nfc->ret = rfalNfcInitialize();
  85. rfalLowPowerModeStart();
  86. }
  87. st25r3916TxRxOff();
  88. }
  89. void nfc_read_callback(void* context) {
  90. furi_assert(context);
  91. Nfc* nfc = context;
  92. nfc->screen = 1;
  93. widget_enabled_set(nfc->widget, true);
  94. }
  95. void nfc_write_callback(void* context) {
  96. furi_assert(context);
  97. Nfc* nfc = context;
  98. nfc->screen = 1;
  99. widget_enabled_set(nfc->widget, true);
  100. }
  101. void nfc_bridge_callback(void* context) {
  102. furi_assert(context);
  103. Nfc* nfc = context;
  104. nfc->screen = 1;
  105. widget_enabled_set(nfc->widget, true);
  106. }
  107. Nfc* nfc_alloc() {
  108. Nfc* nfc = furi_alloc(sizeof(Nfc));
  109. nfc->dispatcher = dispatcher_alloc(32, sizeof(NfcMessage));
  110. nfc->icon = assets_icons_get(A_NFC_14);
  111. nfc->widget = widget_alloc();
  112. widget_draw_callback_set(nfc->widget, nfc_draw_callback, nfc);
  113. widget_input_callback_set(nfc->widget, nfc_input_callback, nfc);
  114. nfc->menu_vm = furi_open("menu");
  115. furi_check(nfc->menu_vm);
  116. nfc->menu = menu_item_alloc_menu("NFC", nfc->icon);
  117. menu_item_subitem_add(
  118. nfc->menu, menu_item_alloc_function("Test", NULL, nfc_test_callback, nfc));
  119. menu_item_subitem_add(
  120. nfc->menu, menu_item_alloc_function("Field On", NULL, nfc_field_on_callback, nfc));
  121. menu_item_subitem_add(
  122. nfc->menu, menu_item_alloc_function("Field Off", NULL, nfc_field_off_callback, nfc));
  123. menu_item_subitem_add(
  124. nfc->menu, menu_item_alloc_function("Read", NULL, nfc_read_callback, nfc));
  125. menu_item_subitem_add(
  126. nfc->menu, menu_item_alloc_function("Write", NULL, nfc_write_callback, nfc));
  127. menu_item_subitem_add(
  128. nfc->menu, menu_item_alloc_function("Brdige", NULL, nfc_bridge_callback, nfc));
  129. nfc->worker_attr.name = "nfc_worker";
  130. // nfc->worker_attr.attr_bits = osThreadJoinable;
  131. nfc->worker_attr.stack_size = 4096;
  132. return nfc;
  133. }
  134. void nfc_task(void* p) {
  135. Nfc* nfc = nfc_alloc();
  136. FuriRecordSubscriber* gui_record = furi_open_deprecated("gui", false, false, NULL, NULL, NULL);
  137. furi_check(gui_record);
  138. GuiApi* gui = furi_take(gui_record);
  139. furi_check(gui);
  140. widget_enabled_set(nfc->widget, false);
  141. gui->add_widget(gui, nfc->widget, GuiLayerFullscreen);
  142. furi_commit(gui_record);
  143. with_value_mutex(
  144. nfc->menu_vm, (Menu * menu) { menu_item_add(menu, nfc->menu); });
  145. if(!furi_create("nfc", nfc)) {
  146. printf("[nfc_task] cannot create nfc record\n");
  147. furiac_exit(NULL);
  148. }
  149. // TODO only for workaround
  150. nfc->ret = ERR_WRONG_STATE;
  151. furiac_ready();
  152. NfcMessage message;
  153. while(1) {
  154. dispatcher_recieve(nfc->dispatcher, (Message*)&message);
  155. if(message.base.type == MessageTypeExit) {
  156. break;
  157. }
  158. }
  159. }