lfrfid_reader.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include "lfrfid_reader.h"
  2. #include <lfrfid/protocols/lfrfid_protocols.h>
  3. #include <toolbox/protocols/protocol_dict.h>
  4. #include <lib/lfrfid/lfrfid_worker.h>
  5. #define TAG "LfRfid_Reader"
  6. typedef enum {
  7. LFRFIDReaderEventTagRead = (1 << 0),
  8. LFRFIDReaderEventStopThread = (1 << 1),
  9. LFRFIDReaderEventAll = (LFRFIDReaderEventTagRead | LFRFIDReaderEventStopThread),
  10. } LFRFIDReaderEventType;
  11. struct LFRFIDReader {
  12. char* requested_protocol;
  13. ProtocolId protocol;
  14. ProtocolDict* dict;
  15. LFRFIDWorker* worker;
  16. FuriThread* thread;
  17. LFRFIDReaderTagCallback callback;
  18. void* callback_context;
  19. };
  20. static void lfrfid_cli_read_callback(LFRFIDWorkerReadResult result, ProtocolId proto, void* ctx) {
  21. furi_assert(ctx);
  22. LFRFIDReader* context = ctx;
  23. if(result == LFRFIDWorkerReadDone) {
  24. context->protocol = proto;
  25. furi_thread_flags_set(furi_thread_get_id(context->thread), LFRFIDReaderEventTagRead);
  26. }
  27. }
  28. LFRFIDReader* lfrfid_reader_alloc() {
  29. LFRFIDReader* reader = malloc(sizeof(LFRFIDReader));
  30. reader->protocol = PROTOCOL_NO;
  31. reader->dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax);
  32. reader->worker = lfrfid_worker_alloc(reader->dict);
  33. return reader;
  34. }
  35. void lfrfid_reader_set_tag_callback(
  36. LFRFIDReader* reader,
  37. char* requested_protocol,
  38. LFRFIDReaderTagCallback callback,
  39. void* context) {
  40. furi_assert(reader);
  41. furi_assert(requested_protocol);
  42. reader->requested_protocol = requested_protocol;
  43. reader->callback = callback;
  44. reader->callback_context = context;
  45. }
  46. static int32_t lfrfid_reader_start_thread(void* ctx) {
  47. LFRFIDReader* reader = (LFRFIDReader*)ctx;
  48. furi_thread_flags_clear(LFRFIDReaderEventAll);
  49. lfrfid_worker_start_thread(reader->worker);
  50. lfrfid_worker_read_start(
  51. reader->worker, LFRFIDWorkerReadTypeASKOnly, lfrfid_cli_read_callback, reader);
  52. while(true) {
  53. uint32_t flags = furi_thread_flags_wait(LFRFIDReaderEventAll, FuriFlagWaitAny, 100);
  54. if(flags != (unsigned)FuriFlagErrorTimeout) {
  55. if((flags & LFRFIDReaderEventTagRead) == LFRFIDReaderEventTagRead) {
  56. furi_thread_flags_clear(LFRFIDReaderEventTagRead);
  57. if(reader->protocol != PROTOCOL_NO) {
  58. const char* protocol_name =
  59. protocol_dict_get_name(reader->dict, reader->protocol);
  60. if(strcmp(protocol_name, reader->requested_protocol) == 0) {
  61. size_t size = protocol_dict_get_data_size(reader->dict, reader->protocol);
  62. uint8_t* data = malloc(size);
  63. protocol_dict_get_data(reader->dict, reader->protocol, data, size);
  64. if(reader->callback) {
  65. FURI_LOG_D(TAG, "Tag %s detected", protocol_name);
  66. reader->callback(data, size, reader->callback_context);
  67. } else {
  68. FURI_LOG_W(TAG, "No callback set for tag %s", protocol_name);
  69. }
  70. free(data);
  71. } else {
  72. FURI_LOG_W(TAG, "Unsupported tag %s, expected EM4100", protocol_name);
  73. }
  74. }
  75. reader->protocol = PROTOCOL_NO;
  76. lfrfid_worker_read_start(
  77. reader->worker, LFRFIDWorkerReadTypeASKOnly, lfrfid_cli_read_callback, reader);
  78. } else if((flags & LFRFIDReaderEventStopThread) == LFRFIDReaderEventStopThread) {
  79. break;
  80. }
  81. }
  82. }
  83. lfrfid_worker_stop(reader->worker);
  84. lfrfid_worker_stop_thread(reader->worker);
  85. FURI_LOG_D(TAG, "LfRfidReader thread exiting");
  86. return 0;
  87. }
  88. void lfrfid_reader_start(LFRFIDReader* reader) {
  89. reader->thread =
  90. furi_thread_alloc_ex("lfrfid_reader", 2048, lfrfid_reader_start_thread, reader);
  91. furi_thread_start(reader->thread);
  92. }
  93. void lfrfid_reader_stop(LFRFIDReader* reader) {
  94. if(reader->thread) {
  95. furi_thread_flags_set(furi_thread_get_id(reader->thread), LFRFIDReaderEventStopThread);
  96. furi_thread_join(reader->thread);
  97. reader->thread = NULL;
  98. }
  99. }
  100. void lfrfid_reader_free(LFRFIDReader* reader) {
  101. lfrfid_reader_stop(reader);
  102. protocol_dict_free(reader->dict);
  103. lfrfid_worker_free(reader->worker);
  104. free(reader);
  105. }