uhf_worker.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include "uhf_worker.h"
  2. #include "uhf_tag.h"
  3. // yrm100 module commands
  4. UHFWorkerEvent verify_module_connected(UHFWorker* uhf_worker) {
  5. char* hw_version = m100_get_hardware_version(uhf_worker->module);
  6. char* sw_version = m100_get_software_version(uhf_worker->module);
  7. char* manufacturer = m100_get_manufacturers(uhf_worker->module);
  8. // verify all data exists
  9. if(hw_version == NULL || sw_version == NULL || manufacturer == NULL) return UHFWorkerEventFail;
  10. return UHFWorkerEventSuccess;
  11. }
  12. UHFTag* send_polling_command(UHFWorker* uhf_worker) {
  13. // read epc bank
  14. UHFTag* uhf_tag = uhf_tag_alloc();
  15. M100ResponseType status;
  16. do {
  17. if(uhf_worker->state == UHFWorkerStateStop) {
  18. uhf_tag_free(uhf_tag);
  19. return NULL;
  20. }
  21. status = m100_single_poll(uhf_worker->module, uhf_tag);
  22. } while(status != M100SuccessResponse);
  23. return uhf_tag;
  24. }
  25. UHFWorkerEvent read_bank_till_max_length(UHFWorker* uhf_worker, UHFTag* uhf_tag, BankType bank) {
  26. unsigned int word_low = 0, word_high = 64;
  27. unsigned int word_size;
  28. M100ResponseType status;
  29. do {
  30. if(uhf_worker->state == UHFWorkerStateStop) return UHFWorkerEventAborted;
  31. if(word_low >= word_high) return UHFWorkerEventSuccess;
  32. word_size = (word_low + word_high) / 2;
  33. status = m100_read_label_data_storage(uhf_worker->module, uhf_tag, bank, 0, word_size);
  34. if(status == M100SuccessResponse) {
  35. word_low = word_size + 1;
  36. } else if(status == M100MemoryOverrun) {
  37. word_high = word_size - 1;
  38. }
  39. } while(true);
  40. return UHFWorkerEventSuccess;
  41. }
  42. UHFWorkerEvent read_single_card(UHFWorker* uhf_worker) {
  43. UHFTag* uhf_tag = send_polling_command(uhf_worker);
  44. if(uhf_tag == NULL) return UHFWorkerEventAborted;
  45. uhf_tag_wrapper_set_tag(uhf_worker->uhf_tag_wrapper, uhf_tag);
  46. // set select
  47. while(m100_set_select(uhf_worker->module, uhf_tag) != M100SuccessResponse) {
  48. }
  49. // read tid
  50. UHFWorkerEvent event;
  51. event = read_bank_till_max_length(uhf_worker, uhf_tag, TIDBank);
  52. if(event != UHFWorkerEventSuccess) return event;
  53. // read user
  54. event = read_bank_till_max_length(uhf_worker, uhf_tag, UserBank);
  55. if(event != UHFWorkerEventSuccess) return event;
  56. return UHFWorkerEventSuccess;
  57. }
  58. UHFWorkerEvent write_single_card(UHFWorker* uhf_worker) {
  59. UHFTag* uhf_tag_des = send_polling_command(uhf_worker);
  60. if(uhf_tag_des == NULL) return UHFWorkerEventAborted;
  61. UHFTag* uhf_tag_from = uhf_worker->uhf_tag_wrapper->uhf_tag;
  62. M100ResponseType rp_type;
  63. do {
  64. rp_type = m100_set_select(uhf_worker->module, uhf_tag_des);
  65. if(uhf_worker->state == UHFWorkerStateStop) return UHFWorkerEventAborted;
  66. if(rp_type == M100SuccessResponse) break;
  67. } while(true);
  68. while(m100_is_write_mask_enabled(uhf_worker->module, WRITE_USER)) {
  69. rp_type = m100_write_label_data_storage(
  70. uhf_worker->module, uhf_tag_from, uhf_tag_des, UserBank, 0, 0);
  71. if(uhf_worker->state == UHFWorkerStateStop) return UHFWorkerEventAborted;
  72. if(rp_type == M100SuccessResponse) break;
  73. }
  74. while(m100_is_write_mask_enabled(uhf_worker->module, WRITE_TID)) {
  75. rp_type = m100_write_label_data_storage(
  76. uhf_worker->module, uhf_tag_from, uhf_tag_des, TIDBank, 0, 0);
  77. if(uhf_worker->state == UHFWorkerStateStop) return UHFWorkerEventAborted;
  78. if(rp_type == M100SuccessResponse) break;
  79. }
  80. while(m100_is_write_mask_enabled(uhf_worker->module, WRITE_EPC)) {
  81. rp_type = m100_write_label_data_storage(
  82. uhf_worker->module, uhf_tag_from, uhf_tag_des, EPCBank, 0, 0);
  83. if(uhf_worker->state == UHFWorkerStateStop) return UHFWorkerEventAborted;
  84. if(rp_type == M100SuccessResponse) break;
  85. }
  86. return UHFWorkerEventSuccess;
  87. }
  88. int32_t uhf_worker_task(void* ctx) {
  89. UHFWorker* uhf_worker = ctx;
  90. if(uhf_worker->state == UHFWorkerStateVerify) {
  91. UHFWorkerEvent event = verify_module_connected(uhf_worker);
  92. uhf_worker->callback(event, uhf_worker->ctx);
  93. } else if(uhf_worker->state == UHFWorkerStateDetectSingle) {
  94. UHFWorkerEvent event = read_single_card(uhf_worker);
  95. uhf_worker->callback(event, uhf_worker->ctx);
  96. } else if(uhf_worker->state == UHFWorkerStateWriteSingle) {
  97. UHFWorkerEvent event = write_single_card(uhf_worker);
  98. uhf_worker->callback(event, uhf_worker->ctx);
  99. }
  100. return 0;
  101. }
  102. UHFWorker* uhf_worker_alloc() {
  103. UHFWorker* uhf_worker = (UHFWorker*)malloc(sizeof(UHFWorker));
  104. uhf_worker->thread =
  105. furi_thread_alloc_ex("UHFWorker", UHF_WORKER_STACK_SIZE, uhf_worker_task, uhf_worker);
  106. uhf_worker->module = m100_module_alloc();
  107. uhf_worker->callback = NULL;
  108. uhf_worker->ctx = NULL;
  109. return uhf_worker;
  110. }
  111. void uhf_worker_change_state(UHFWorker* worker, UHFWorkerState state) {
  112. worker->state = state;
  113. }
  114. void uhf_worker_start(
  115. UHFWorker* uhf_worker,
  116. UHFWorkerState state,
  117. UHFWorkerCallback callback,
  118. void* ctx) {
  119. uhf_worker->state = state;
  120. uhf_worker->callback = callback;
  121. uhf_worker->ctx = ctx;
  122. furi_thread_start(uhf_worker->thread);
  123. }
  124. void uhf_worker_stop(UHFWorker* uhf_worker) {
  125. furi_assert(uhf_worker);
  126. furi_assert(uhf_worker->thread);
  127. if(furi_thread_get_state(uhf_worker->thread) != FuriThreadStateStopped) {
  128. uhf_worker_change_state(uhf_worker, UHFWorkerStateStop);
  129. furi_thread_join(uhf_worker->thread);
  130. }
  131. }
  132. void uhf_worker_free(UHFWorker* uhf_worker) {
  133. furi_assert(uhf_worker);
  134. furi_thread_free(uhf_worker->thread);
  135. m100_module_free(uhf_worker->module);
  136. free(uhf_worker);
  137. }