picopass_poller.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #include "picopass_poller_i.h"
  2. #include <furi/furi.h>
  3. #define TAG "Picopass"
  4. typedef NfcCommand (*PicopassPollerStateHandler)(PicopassPoller* instance);
  5. static void picopass_poller_reset(PicopassPoller* instance) {
  6. UNUSED(instance);
  7. }
  8. NfcCommand picopass_poller_request_mode_handler(PicopassPoller* instance) {
  9. NfcCommand command = NfcCommandContinue;
  10. instance->event.type = PicopassPollerEventTypeRequestMode;
  11. command = instance->callback(instance->event, instance->context);
  12. instance->mode = instance->event_data.req_mode.mode;
  13. instance->state = PicopassPollerStateDetect;
  14. return command;
  15. }
  16. NfcCommand picopass_poller_detect_handler(PicopassPoller* instance) {
  17. NfcCommand command = NfcCommandContinue;
  18. PicopassError error = picopass_poller_actall(instance);
  19. if(error == PicopassErrorNone) {
  20. instance->state = PicopassPollerStateSelect;
  21. instance->event.type = PicopassPollerEventTypeCardDetected;
  22. command = instance->callback(instance->event, instance->context);
  23. } else {
  24. furi_delay_ms(100);
  25. }
  26. return command;
  27. }
  28. NfcCommand picopass_poller_select_handler(PicopassPoller* instance) {
  29. NfcCommand command = NfcCommandContinue;
  30. do {
  31. PicopassError error = picopass_poller_identify(instance, &instance->col_res_serial_num);
  32. if(error != PicopassErrorNone) {
  33. instance->state = PicopassPollerStateFail;
  34. break;
  35. }
  36. error =
  37. picopass_poller_select(instance, &instance->col_res_serial_num, &instance->serial_num);
  38. if(error != PicopassErrorNone) {
  39. instance->state = PicopassPollerStateFail;
  40. break;
  41. }
  42. instance->state = PicopassPollerStateSuccess;
  43. } while(false);
  44. return command;
  45. }
  46. NfcCommand picopass_poller_success_handler(PicopassPoller* instance) {
  47. NfcCommand command = NfcCommandContinue;
  48. instance->event.type = PicopassPollerEventTypeSuccess;
  49. command = instance->callback(instance->event, instance->context);
  50. furi_delay_ms(100);
  51. return command;
  52. }
  53. NfcCommand picopass_poller_fail_handler(PicopassPoller* instance) {
  54. NfcCommand command = NfcCommandReset;
  55. instance->event.type = PicopassPollerEventTypeFail;
  56. command = instance->callback(instance->event, instance->context);
  57. picopass_poller_reset(instance);
  58. instance->state = PicopassPollerStateDetect;
  59. return command;
  60. }
  61. static const PicopassPollerStateHandler picopass_poller_state_handler[PicopassPollerStateNum] = {
  62. [PicopassPollerStateRequestMode] = picopass_poller_request_mode_handler,
  63. [PicopassPollerStateDetect] = picopass_poller_detect_handler,
  64. [PicopassPollerStateSelect] = picopass_poller_select_handler,
  65. [PicopassPollerStateSuccess] = picopass_poller_success_handler,
  66. [PicopassPollerStateFail] = picopass_poller_fail_handler,
  67. };
  68. static NfcCommand picopass_poller_callback(NfcEvent event, void* context) {
  69. furi_assert(context);
  70. PicopassPoller* instance = context;
  71. NfcCommand command = NfcCommandContinue;
  72. if(event.type == NfcEventTypePollerReady) {
  73. command = picopass_poller_state_handler[instance->state](instance);
  74. }
  75. if(instance->session_state == PicopassPollerSessionStateStopRequest) {
  76. command = NfcCommandStop;
  77. }
  78. return command;
  79. }
  80. void picopass_poller_start(
  81. PicopassPoller* instance,
  82. PicopassPollerCallback callback,
  83. void* context) {
  84. furi_assert(instance);
  85. furi_assert(instance->session_state == PicopassPollerSessionStateIdle);
  86. instance->callback = callback;
  87. instance->context = context;
  88. instance->session_state = PicopassPollerSessionStateActive;
  89. nfc_start(instance->nfc, picopass_poller_callback, instance);
  90. }
  91. void picopass_poller_stop(PicopassPoller* instance) {
  92. furi_assert(instance);
  93. instance->session_state = PicopassPollerSessionStateStopRequest;
  94. nfc_stop(instance->nfc);
  95. instance->session_state = PicopassPollerSessionStateIdle;
  96. }
  97. PicopassPoller* picopass_poller_alloc(Nfc* nfc) {
  98. furi_assert(nfc);
  99. PicopassPoller* instance = malloc(sizeof(PicopassPoller));
  100. instance->nfc = nfc;
  101. nfc_config(instance->nfc, NfcModePoller, NfcTechIso15693);
  102. nfc_set_guard_time_us(instance->nfc, 10000);
  103. nfc_set_fdt_poll_fc(instance->nfc, 5000);
  104. nfc_set_fdt_poll_poll_us(instance->nfc, 1000);
  105. instance->event.data = &instance->event_data;
  106. instance->tx_buffer = bit_buffer_alloc(PICOPASS_POLLER_BUFFER_SIZE);
  107. instance->rx_buffer = bit_buffer_alloc(PICOPASS_POLLER_BUFFER_SIZE);
  108. instance->tmp_buffer = bit_buffer_alloc(PICOPASS_POLLER_BUFFER_SIZE);
  109. return instance;
  110. }
  111. void picopass_poller_free(PicopassPoller* instance) {
  112. furi_assert(instance);
  113. bit_buffer_free(instance->tx_buffer);
  114. bit_buffer_free(instance->rx_buffer);
  115. bit_buffer_free(instance->tmp_buffer);
  116. free(instance);
  117. }
  118. uint8_t* picopass_poller_get_csn(PicopassPoller* instance) {
  119. furi_assert(instance);
  120. return instance->serial_num.data;
  121. }