uhf_worker.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. #include "uhf_worker.h"
  2. #include "uhf_tag.h"
  3. // yrm100 module commands
  4. UHFWorkerEvent verify_module_connected(UHFWorker* uhf_worker) {
  5. // FuriString* ts = furi_string_alloc();
  6. char* hw_version = m100_get_hardware_version(uhf_worker->module);
  7. char* sw_version = m100_get_software_version(uhf_worker->module);
  8. char* manufacturer = m100_get_manufacturers(uhf_worker->module);
  9. // verify all data exists
  10. if(hw_version == NULL || sw_version == NULL || manufacturer == NULL) return UHFWorkerEventFail;
  11. FURI_LOG_E("TAG", "hw=%s", hw_version);
  12. FURI_LOG_E("TAG", "sw=%s", sw_version);
  13. FURI_LOG_E("TAG", "mf=%s", manufacturer);
  14. return UHFWorkerEventSuccess;
  15. }
  16. uint8_t get_epc_length_in_bits(uint8_t pc) {
  17. uint8_t epc_length = pc;
  18. epc_length >>= 3;
  19. return (uint8_t)epc_length * 16; // x-words * 16 bits
  20. }
  21. // bool read_bank(UHFData* read_bank_cmd, UHFData* response_bank, UHFBank bank) {
  22. // furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, response_bank);
  23. // read_bank_cmd->data[9] = bank;
  24. // read_bank_cmd->data[read_bank_cmd->length - 2] = uhf_data_calculate_checksum(read_bank_cmd);
  25. // uhf_data_reset(response_bank);
  26. // furi_hal_uart_tx(FuriHalUartIdUSART1, read_bank_cmd->data, read_bank_cmd->length);
  27. // furi_delay_ms(CB_DELAY);
  28. // return response_bank->data[2] == read_bank_cmd->data[2];
  29. // }
  30. // bool write_bank(UHFData* write_bank_cmd, UHFBank bank, uint8_t* bank_data, size_t bank_len) {
  31. // UHFData* rp_data = uhf_data_alloc();
  32. // write_bank_cmd->end = false;
  33. // for(size_t i = 0; i < write_bank_cmd->length; i++) {
  34. // continue;
  35. // }
  36. // furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, rp_data);
  37. // for(int i = 5; i < 9; i++) { // no access password for now
  38. // write_bank_cmd->data[i] = 0;
  39. // }
  40. // write_bank_cmd->data[9] = bank;
  41. // size_t word_len = bank_len / 2;
  42. // write_bank_cmd->data[13] = word_len;
  43. // write_bank_cmd->length = 14;
  44. // write_bank_cmd->start = true;
  45. // for(size_t i = 0; i < bank_len; i++) {
  46. // uhf_data_append(write_bank_cmd, bank_data[i]);
  47. // }
  48. // uhf_data_append(write_bank_cmd, 00);
  49. // uhf_data_append(write_bank_cmd, FRAME_END);
  50. // write_bank_cmd->data[4] = write_bank_cmd->length - 7;
  51. // write_bank_cmd->data[write_bank_cmd->length - 2] = uhf_data_calculate_checksum(write_bank_cmd);
  52. // furi_hal_uart_tx(FuriHalUartIdUSART1, write_bank_cmd->data, write_bank_cmd->length);
  53. // furi_delay_ms(CB_DELAY);
  54. // bool success = rp_data->data[2] == write_bank_cmd->data[2];
  55. // uhf_data_free(rp_data);
  56. // return success;
  57. // }
  58. UHFTag* send_polling_command(UHFWorker* uhf_worker) {
  59. // read epc bank
  60. UHFTag* uhf_tag;
  61. while(true) {
  62. uhf_tag = m100_send_single_poll(uhf_worker->module);
  63. furi_delay_ms(100);
  64. if(uhf_worker->state == UHFWorkerStateStop) {
  65. return NULL;
  66. }
  67. if(uhf_tag != NULL) break;
  68. }
  69. return uhf_tag;
  70. }
  71. UHFWorkerEvent read_single_card(UHFWorker* uhf_worker) {
  72. UHFTag* uhf_tag = send_polling_command(uhf_worker);
  73. if(uhf_tag == NULL) return UHFWorkerEventAborted;
  74. uhf_tag_wrapper_set_tag(uhf_worker->uhf_tag_wrapper, uhf_tag);
  75. // Todo : set select here
  76. bool select_success = m100_set_select(uhf_worker->module, uhf_tag);
  77. FURI_LOG_E("TAG", "select success = %d", select_success);
  78. // Todo : read rfu
  79. m100_read_label_data_storage(uhf_worker->module, uhf_tag, ReservedBank, 0);
  80. // Todo : read epc
  81. m100_read_label_data_storage(uhf_worker->module, uhf_tag, EPCBank, 0);
  82. // Todo : read tid
  83. m100_read_label_data_storage(uhf_worker->module, uhf_tag, TIDBank, 0);
  84. // Todo : read user
  85. m100_read_label_data_storage(uhf_worker->module, uhf_tag, UserBank, 0);
  86. // add to tag object
  87. // UHFData* raw_bank_data = uhf_data_alloc();
  88. // size_t epc_length = (size_t)get_epc_length_in_bits(raw_read_data->data[6]) / 8;
  89. // size_t offset = (size_t)(8 + epc_length);
  90. // UHFData* read_bank_cmd = uhf_data_alloc();
  91. // read_bank_cmd->length = CMD_READ_LABEL_DATA_STORAGE.length;
  92. // memcpy(
  93. // (void*)&read_bank_cmd->data[0],
  94. // (void*)&CMD_READ_LABEL_DATA_STORAGE.cmd[0],
  95. // read_bank_cmd->length);
  96. // if(!send_set_select_command(raw_read_data, EPC_BANK)) return UHFWorkerEventFail;
  97. // int retry = 3;
  98. // do {
  99. // if(read_bank(read_bank_cmd, raw_bank_data, EPC_BANK)) {
  100. // uhf_tag_set_epc(uhf_tag, raw_bank_data->data + offset, epc_length + 2);
  101. // break;
  102. // }
  103. // } while(retry--);
  104. // // // debug
  105. // // furi_string_reset(temp_str);
  106. // // for(size_t i = 0; i < raw_bank_data->length; i++) {
  107. // // furi_string_cat_printf(temp_str, "%02x ", raw_bank_data->data[i]);
  108. // // }
  109. // // FURI_LOG_E("TAG", "data = %s", furi_string_get_cstr(temp_str));
  110. // // // e-debug
  111. // uhf_data_reset(raw_bank_data);
  112. // retry = 3;
  113. // do {
  114. // if(read_bank(read_bank_cmd, raw_bank_data, TID_BANK)) {
  115. // uhf_tag_set_tid(uhf_tag, raw_bank_data->data + offset, 16);
  116. // break;
  117. // }
  118. // } while(retry--);
  119. // // // debug
  120. // // furi_string_reset(temp_str);
  121. // // for(size_t i = 0; i < raw_bank_data->length; i++) {
  122. // // furi_string_cat_printf(temp_str, "%02x ", raw_bank_data->data[i]);
  123. // // }
  124. // // FURI_LOG_E("TAG", "data = %s", furi_string_get_cstr(temp_str));
  125. // // // e-debug
  126. // uhf_data_reset(raw_bank_data);
  127. // retry = 3;
  128. // if(raw_read_data->data[6] & 0x04) {
  129. // do {
  130. // if(read_bank(read_bank_cmd, raw_bank_data, USER_BANK)) {
  131. // uhf_tag_set_user(uhf_tag, raw_bank_data->data + offset, 16);
  132. // break;
  133. // }
  134. // } while(retry--);
  135. // }
  136. // // // debug
  137. // // furi_string_reset(temp_str);
  138. // // for(size_t i = 0; i < raw_bank_data->length; i++) {
  139. // // furi_string_cat_printf(temp_str, "%02x ", raw_bank_data->data[i]);
  140. // // }
  141. // // FURI_LOG_E("TAG", "data = %s", furi_string_get_cstr(temp_str));
  142. // // // e-debug
  143. // uhf_data_reset(raw_bank_data);
  144. // uhf_data_free(raw_bank_data);
  145. // uhf_data_free(read_bank_cmd);
  146. // // debug
  147. // // furi_string_free(temp_str);
  148. // // e-debug
  149. return UHFWorkerEventSuccess;
  150. }
  151. // UHFWorkerEvent write_single_card(UHFWorker* uhf_worker) {
  152. // UHFResponseData* uhf_response_data = uhf_worker->response_data;
  153. // uhf_response_data_reset(uhf_response_data);
  154. // UHFData* raw_read_data = uhf_response_data_get_uhf_data(uhf_response_data, 0);
  155. // furi_hal_uart_set_br(FuriHalUartIdUSART1, DEFAULT_BAUD_RATE);
  156. // send_polling_command(uhf_worker, raw_read_data);
  157. // // todo : rfu ?
  158. // UHFTag* uhf_tag = uhf_worker->uhf_tag;
  159. // UHFData* write_bank_cmd = uhf_data_alloc();
  160. // write_bank_cmd->length = CMD_WRITE_LABEL_DATA_STORAGE.length;
  161. // memcpy(
  162. // (void*)&write_bank_cmd->data[0],
  163. // (void*)&CMD_WRITE_LABEL_DATA_STORAGE.cmd[0],
  164. // write_bank_cmd->length);
  165. // if(!send_set_select_command(raw_read_data, EPC_BANK)) return UHFWorkerEventFail;
  166. // if(raw_read_data->data[6] & 0x04) {
  167. // if(!write_bank(write_bank_cmd, USER_BANK, uhf_tag->user, uhf_tag->user_length))
  168. // return UHFWorkerEventFail;
  169. // }
  170. // uint8_t write_data[uhf_tag->epc_length + 2];
  171. // memcpy(&write_data, &raw_read_data->data[raw_read_data->length - 4], 2);
  172. // memcpy(&write_data[2], &uhf_tag->epc, uhf_tag->epc_length);
  173. // write_data[10] = 0xF1;
  174. // if(!write_bank(write_bank_cmd, EPC_BANK, write_data, uhf_tag->epc_length + 2)) {
  175. // return UHFWorkerEventFail;
  176. // }
  177. // return UHFWorkerEventSuccess;
  178. // }
  179. int32_t uhf_worker_task(void* ctx) {
  180. UHFWorker* uhf_worker = ctx;
  181. if(uhf_worker->state == UHFWorkerStateVerify) {
  182. UHFWorkerEvent event = verify_module_connected(uhf_worker);
  183. uhf_worker->callback(event, uhf_worker->ctx);
  184. } else if(uhf_worker->state == UHFWorkerStateDetectSingle) {
  185. UHFWorkerEvent event = read_single_card(uhf_worker);
  186. uhf_worker->callback(event, uhf_worker->ctx);
  187. }
  188. // else if(uhf_worker->state == UHFWorkerStateWriteSingle) {
  189. // UHFWorkerEvent event = write_single_card(uhf_worker);
  190. // uhf_worker->callback(event, uhf_worker->ctx);
  191. // }
  192. return 0;
  193. }
  194. UHFWorker* uhf_worker_alloc() {
  195. UHFWorker* uhf_worker = (UHFWorker*)malloc(sizeof(UHFWorker));
  196. uhf_worker->thread = furi_thread_alloc_ex("UHFWorker", 8 * 1024, uhf_worker_task, uhf_worker);
  197. uhf_worker->module = m100_module_alloc();
  198. uhf_worker->callback = NULL;
  199. uhf_worker->ctx = NULL;
  200. return uhf_worker;
  201. }
  202. void uhf_worker_change_state(UHFWorker* worker, UHFWorkerState state) {
  203. worker->state = state;
  204. }
  205. void uhf_worker_start(
  206. UHFWorker* uhf_worker,
  207. UHFWorkerState state,
  208. UHFWorkerCallback callback,
  209. void* ctx) {
  210. uhf_worker->state = state;
  211. uhf_worker->callback = callback;
  212. uhf_worker->ctx = ctx;
  213. furi_thread_start(uhf_worker->thread);
  214. }
  215. void uhf_worker_stop(UHFWorker* uhf_worker) {
  216. furi_assert(uhf_worker);
  217. furi_assert(uhf_worker->thread);
  218. if(furi_thread_get_state(uhf_worker->thread) != FuriThreadStateStopped) {
  219. uhf_worker_change_state(uhf_worker, UHFWorkerStateStop);
  220. furi_thread_join(uhf_worker->thread);
  221. }
  222. }
  223. void uhf_worker_free(UHFWorker* uhf_worker) {
  224. furi_assert(uhf_worker);
  225. furi_thread_free(uhf_worker->thread);
  226. m100_module_free(uhf_worker->module);
  227. free(uhf_worker);
  228. }