uhf_worker.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. #include "uhf_worker.h"
  2. #include "uhf_cmd.h"
  3. // inner functions
  4. uint8_t calculate_checksum(uint8_t* arr, size_t length) {
  5. // CheckSum8 Modulo 256
  6. // Sum of Bytes % 256
  7. uint8_t sum_val = 0x00;
  8. for(size_t i = 0; i < length; i++) {
  9. sum_val += arr[i];
  10. }
  11. return sum_val % 256;
  12. }
  13. // uart callback functions
  14. void module_rx_callback(UartIrqEvent event, uint8_t data, void* ctx) {
  15. UNUSED(event);
  16. UHFData* uhf_data = ctx;
  17. uhf_data_append(uhf_data, data);
  18. // FURI_LOG_E("module_rx_callback", "%02x", data);
  19. }
  20. // yrm100 module commands
  21. UHFWorkerEvent verify_module_connected(UHFWorker* uhf_worker) {
  22. UHFResponseData* uhf_response_data = uhf_worker->response_data;
  23. uhf_response_data_reset(uhf_response_data);
  24. // FURI_LOG_E("log", "freeing done");
  25. UHFData* hardware_version = uhf_response_data->head;
  26. UHFData* software_version = uhf_response_data_add_new_uhf_data(uhf_response_data);
  27. UHFData* manufacturer = uhf_response_data_add_new_uhf_data(uhf_response_data);
  28. // FURI_LOG_E("log", "alloc done");
  29. furi_hal_uart_set_br(FuriHalUartIdUSART1, DEFAULT_BAUD_RATE);
  30. // read hardware version
  31. furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, hardware_version);
  32. furi_hal_uart_tx(FuriHalUartIdUSART1, CMD_HARDWARE_VERSION.cmd, CMD_HARDWARE_VERSION.length);
  33. furi_delay_ms(50);
  34. // read software version
  35. furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, software_version);
  36. furi_hal_uart_tx(FuriHalUartIdUSART1, CMD_SOFTWARE_VERSION.cmd, CMD_SOFTWARE_VERSION.length);
  37. furi_delay_ms(50);
  38. // read manufacturer
  39. furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, manufacturer);
  40. furi_hal_uart_tx(FuriHalUartIdUSART1, CMD_MANUFACTURERS.cmd, CMD_MANUFACTURERS.length);
  41. furi_delay_ms(50);
  42. // FURI_LOG_E("log", "done sending tx");
  43. if(!hardware_version->end || !software_version->end || !manufacturer->end) {
  44. return UHFWorkerEventFail;
  45. }
  46. return UHFWorkerEventSuccess;
  47. }
  48. UHFWorkerEvent read_single_card(UHFWorker* uhf_worker) {
  49. UHFResponseData* uhf_response_data = uhf_worker->response_data;
  50. uhf_response_data_reset(uhf_response_data);
  51. UHFData* raw_read_data = uhf_response_data_get_uhf_data(uhf_response_data, 0);
  52. furi_hal_uart_set_br(FuriHalUartIdUSART1, DEFAULT_BAUD_RATE);
  53. furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, raw_read_data);
  54. uhf_data_reset(raw_read_data);
  55. // read epc bank
  56. while(true) {
  57. furi_hal_uart_tx(FuriHalUartIdUSART1, CMD_SINGLE_POLLING.cmd, CMD_SINGLE_POLLING.length);
  58. furi_delay_ms(100);
  59. if(uhf_worker->state == UHFWorkerStateStop) {
  60. return UHFWorkerEventAborted;
  61. }
  62. if(raw_read_data->end) {
  63. if(raw_read_data->data[1] == 0x01 && raw_read_data->data[5] == 0x15) {
  64. uhf_data_reset(raw_read_data);
  65. continue;
  66. } else if(raw_read_data->data[1] == 0x02)
  67. break; // read success
  68. }
  69. }
  70. // Set select
  71. uint8_t* select_cmd = (uint8_t*)malloc(sizeof(uint8_t) * CMD_SET_SELECT_PARAMETER.length);
  72. memcpy(select_cmd, (void*)&CMD_SET_SELECT_PARAMETER.cmd[0], CMD_SET_SELECT_PARAMETER.length);
  73. // set select param
  74. select_cmd[5] = 0x01; // 0x00=rfu, 0x01=epc, 0x10=tid, 0x11=user
  75. // set ptr
  76. select_cmd[9] = 0x20;
  77. // set mask
  78. for(int i = 0; i < 12; i++) // 96 bits, 12 bytes
  79. {
  80. select_cmd[12 + i] = raw_read_data->data[8 + i];
  81. }
  82. // checksum
  83. select_cmd[CMD_SET_SELECT_PARAMETER.length - 2] =
  84. calculate_checksum(select_cmd + 1, CMD_SET_SELECT_PARAMETER.length - 3);
  85. UHFData* select_response = uhf_response_data_add_new_uhf_data(uhf_response_data);
  86. furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, select_response);
  87. furi_hal_uart_tx(FuriHalUartIdUSART1, select_cmd, CMD_SET_SELECT_PARAMETER.length);
  88. furi_delay_ms(50);
  89. if(select_response->data[5] != 0x00) return UHFWorkerEventFail;
  90. uint8_t* read_bank_cmd =
  91. (uint8_t*)malloc(sizeof(uint8_t) * CMD_READ_LABEL_DATA_STORAGE.length);
  92. memcpy(
  93. read_bank_cmd,
  94. (void*)&CMD_READ_LABEL_DATA_STORAGE.cmd[0],
  95. CMD_READ_LABEL_DATA_STORAGE.length);
  96. // read rfu bank
  97. UHFData* rfu_bank = select_response;
  98. uhf_data_reset(rfu_bank);
  99. furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, rfu_bank);
  100. read_bank_cmd[9] = 0x00;
  101. furi_hal_uart_tx(FuriHalUartIdUSART1, read_bank_cmd, CMD_READ_LABEL_DATA_STORAGE.length);
  102. furi_delay_ms(50);
  103. // for(int i = 0; i < (int)rfu_bank->length; i++) {
  104. // FURI_LOG_E("rfu_bank", "data[%d]=%02x", i, rfu_bank->data[i]);
  105. // }
  106. // read epc bank
  107. UHFData* epc_bank = uhf_response_data_add_new_uhf_data(uhf_response_data);
  108. furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, epc_bank);
  109. read_bank_cmd[9] = 0x01;
  110. furi_hal_uart_tx(FuriHalUartIdUSART1, read_bank_cmd, CMD_READ_LABEL_DATA_STORAGE.length);
  111. furi_delay_ms(50);
  112. // for(int i = 0; i < (int)epc_bank->length; i++) {
  113. // FURI_LOG_E("epc_bank", "data[%d]=%02x", i, epc_bank->data[i]);
  114. // }
  115. // read tid bank
  116. UHFData* tid_bank = uhf_response_data_add_new_uhf_data(uhf_response_data);
  117. furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, tid_bank);
  118. read_bank_cmd[9] = 0x02;
  119. furi_hal_uart_tx(FuriHalUartIdUSART1, read_bank_cmd, CMD_READ_LABEL_DATA_STORAGE.length);
  120. furi_delay_ms(50);
  121. // for(int i = 0; i < (int)tid_bank->length; i++) {
  122. // FURI_LOG_E("tid_bank", "data[%d]=%02x", i, tid_bank->data[i]);
  123. // }
  124. // read user bank
  125. UHFData* user_bank = uhf_response_data_add_new_uhf_data(uhf_response_data);
  126. furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, user_bank);
  127. read_bank_cmd[9] = 0x03;
  128. furi_hal_uart_tx(FuriHalUartIdUSART1, read_bank_cmd, CMD_READ_LABEL_DATA_STORAGE.length);
  129. furi_delay_ms(50);
  130. // for(int i = 0; i < (int)user_bank->length; i++) {
  131. // FURI_LOG_E("user_bank", "data[%d]=%02x", i, user_bank->data[i]);
  132. // }
  133. free(select_cmd);
  134. free(read_bank_cmd);
  135. return UHFWorkerEventSuccess;
  136. }
  137. int32_t uhf_worker_task(void* ctx) {
  138. UHFWorker* uhf_worker = ctx;
  139. if(uhf_worker->state == UHFWorkerStateVerify) {
  140. UHFWorkerEvent event = verify_module_connected(uhf_worker);
  141. uhf_worker->callback(event, uhf_worker->ctx);
  142. }
  143. if(uhf_worker->state == UHFWorkerStateDetectSingle) {
  144. UHFWorkerEvent event = read_single_card(uhf_worker);
  145. uhf_worker->callback(event, uhf_worker->ctx);
  146. }
  147. return 0;
  148. }
  149. UHFWorker* uhf_worker_alloc() {
  150. UHFWorker* uhf_worker = (UHFWorker*)malloc(sizeof(UHFWorker));
  151. uhf_worker->thread = furi_thread_alloc_ex("UHFWorker", 8 * 1024, uhf_worker_task, uhf_worker);
  152. uhf_worker->response_data = uhf_response_data_alloc();
  153. uhf_worker->callback = NULL;
  154. uhf_worker->ctx = NULL;
  155. return uhf_worker;
  156. }
  157. void uhf_worker_change_state(UHFWorker* worker, UHFWorkerState state) {
  158. worker->state = state;
  159. }
  160. void uhf_worker_start(
  161. UHFWorker* uhf_worker,
  162. UHFWorkerState state,
  163. UHFWorkerCallback callback,
  164. void* ctx) {
  165. uhf_worker->state = state;
  166. uhf_worker->callback = callback;
  167. uhf_worker->ctx = ctx;
  168. furi_thread_start(uhf_worker->thread);
  169. }
  170. void uhf_worker_stop(UHFWorker* uhf_worker) {
  171. furi_assert(uhf_worker);
  172. furi_assert(uhf_worker->thread);
  173. if(furi_thread_get_state(uhf_worker->thread) != FuriThreadStateStopped) {
  174. uhf_worker_change_state(uhf_worker, UHFWorkerStateStop);
  175. furi_thread_join(uhf_worker->thread);
  176. }
  177. }
  178. void uhf_worker_free(UHFWorker* uhf_worker) {
  179. furi_assert(uhf_worker);
  180. furi_thread_free(uhf_worker->thread);
  181. uhf_response_data_free(uhf_worker->response_data);
  182. free(uhf_worker);
  183. }