gen1a_poller.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. #include "gen1a_poller_i.h"
  2. #include <nfc/protocols/iso14443_3a/iso14443_3a.h>
  3. #include <nfc/protocols/iso14443_3a/iso14443_3a_poller.h>
  4. #include <nfc/helpers/nfc_data_generator.h>
  5. #include <furi/furi.h>
  6. #define GEN1A_POLLER_THREAD_FLAG_DETECTED (1U << 0)
  7. typedef NfcCommand (*Gen1aPollerStateHandler)(Gen1aPoller* instance);
  8. typedef struct {
  9. Nfc* nfc;
  10. BitBuffer* tx_buffer;
  11. BitBuffer* rx_buffer;
  12. FuriThreadId thread_id;
  13. bool detected;
  14. } Gen1aPollerDetectContext;
  15. Gen1aPollerError gen1a_poller_parse_block0(MfClassicBlock* block, MfClassicData* mf_data) {
  16. furi_assert(mf_data);
  17. furi_assert(block);
  18. Gen1aPollerError ret = Gen1aPollerErrorNone;
  19. // Get UID, SAK, and ATQA from block 0
  20. memcpy(mf_data->iso14443_3a_data->uid, block->data, 4);
  21. mf_data->iso14443_3a_data->uid_len = 4;
  22. mf_data->iso14443_3a_data->sak = block->data[5];
  23. memcpy(mf_data->iso14443_3a_data->atqa, &block->data[6], 2);
  24. // Gen1 tags are always 1k
  25. mf_data->type = MfClassicType1k;
  26. return ret;
  27. }
  28. Gen1aPoller* gen1a_poller_alloc(Nfc* nfc) {
  29. furi_assert(nfc);
  30. Gen1aPoller* instance = malloc(sizeof(Gen1aPoller));
  31. instance->nfc = nfc;
  32. nfc_config(instance->nfc, NfcModePoller, NfcTechIso14443a);
  33. nfc_set_guard_time_us(instance->nfc, ISO14443_3A_GUARD_TIME_US);
  34. nfc_set_fdt_poll_fc(instance->nfc, ISO14443_3A_FDT_POLL_FC);
  35. nfc_set_fdt_poll_poll_us(instance->nfc, ISO14443_3A_POLL_POLL_MIN_US);
  36. instance->tx_buffer = bit_buffer_alloc(GEN1A_POLLER_MAX_BUFFER_SIZE);
  37. instance->rx_buffer = bit_buffer_alloc(GEN1A_POLLER_MAX_BUFFER_SIZE);
  38. instance->mfc_device = nfc_device_alloc();
  39. instance->gen1a_event.data = &instance->gen1a_event_data;
  40. return instance;
  41. }
  42. void gen1a_poller_free(Gen1aPoller* instance) {
  43. furi_assert(instance);
  44. bit_buffer_free(instance->tx_buffer);
  45. bit_buffer_free(instance->rx_buffer);
  46. nfc_device_free(instance->mfc_device);
  47. free(instance);
  48. }
  49. NfcCommand gen1a_poller_detect_callback(NfcEvent event, void* context) {
  50. furi_assert(context);
  51. NfcCommand command = NfcCommandStop;
  52. Gen1aPollerDetectContext* gen1a_poller_detect_ctx = context;
  53. if(event.type == NfcEventTypePollerReady) {
  54. do {
  55. bit_buffer_set_size(gen1a_poller_detect_ctx->tx_buffer, 7);
  56. bit_buffer_set_byte(gen1a_poller_detect_ctx->tx_buffer, 0, 0x40);
  57. NfcError error = nfc_poller_trx(
  58. gen1a_poller_detect_ctx->nfc,
  59. gen1a_poller_detect_ctx->tx_buffer,
  60. gen1a_poller_detect_ctx->rx_buffer,
  61. GEN1A_POLLER_MAX_FWT);
  62. if(error != NfcErrorNone) break;
  63. if(bit_buffer_get_size(gen1a_poller_detect_ctx->rx_buffer) != 4) break;
  64. if(bit_buffer_get_byte(gen1a_poller_detect_ctx->rx_buffer, 0) != 0x0A) break;
  65. gen1a_poller_detect_ctx->detected = true;
  66. } while(false);
  67. }
  68. furi_thread_flags_set(gen1a_poller_detect_ctx->thread_id, GEN1A_POLLER_THREAD_FLAG_DETECTED);
  69. return command;
  70. }
  71. bool gen1a_poller_detect(Nfc* nfc) {
  72. furi_assert(nfc);
  73. nfc_config(nfc, NfcModePoller, NfcTechIso14443a);
  74. nfc_set_guard_time_us(nfc, ISO14443_3A_GUARD_TIME_US);
  75. nfc_set_fdt_poll_fc(nfc, ISO14443_3A_FDT_POLL_FC);
  76. nfc_set_fdt_poll_poll_us(nfc, ISO14443_3A_POLL_POLL_MIN_US);
  77. Gen1aPollerDetectContext gen1a_poller_detect_ctx = {};
  78. gen1a_poller_detect_ctx.nfc = nfc;
  79. gen1a_poller_detect_ctx.tx_buffer = bit_buffer_alloc(GEN1A_POLLER_MAX_BUFFER_SIZE);
  80. gen1a_poller_detect_ctx.rx_buffer = bit_buffer_alloc(GEN1A_POLLER_MAX_BUFFER_SIZE);
  81. gen1a_poller_detect_ctx.thread_id = furi_thread_get_current_id();
  82. gen1a_poller_detect_ctx.detected = false;
  83. nfc_start(nfc, gen1a_poller_detect_callback, &gen1a_poller_detect_ctx);
  84. uint32_t flags = furi_thread_flags_wait(
  85. GEN1A_POLLER_THREAD_FLAG_DETECTED, FuriFlagWaitAny, FuriWaitForever);
  86. if(flags & GEN1A_POLLER_THREAD_FLAG_DETECTED) {
  87. furi_thread_flags_clear(GEN1A_POLLER_THREAD_FLAG_DETECTED);
  88. }
  89. nfc_stop(nfc);
  90. bit_buffer_free(gen1a_poller_detect_ctx.tx_buffer);
  91. bit_buffer_free(gen1a_poller_detect_ctx.rx_buffer);
  92. return gen1a_poller_detect_ctx.detected;
  93. }
  94. static void gen1a_poller_reset(Gen1aPoller* instance) {
  95. instance->current_block = 0;
  96. nfc_data_generator_fill_data(NfcDataGeneratorTypeMfClassic1k_4b, instance->mfc_device);
  97. }
  98. NfcCommand gen1a_poller_idle_handler(Gen1aPoller* instance) {
  99. NfcCommand command = NfcCommandContinue;
  100. gen1a_poller_reset(instance);
  101. Gen1aPollerError error = gen1a_poller_wupa(instance);
  102. if(error == Gen1aPollerErrorNone) {
  103. instance->state = Gen1aPollerStateRequestMode;
  104. instance->gen1a_event.type = Gen1aPollerEventTypeDetected;
  105. command = instance->callback(instance->gen1a_event, instance->context);
  106. }
  107. return command;
  108. }
  109. NfcCommand gen1a_poller_request_mode_handler(Gen1aPoller* instance) {
  110. NfcCommand command = NfcCommandContinue;
  111. instance->gen1a_event.type = Gen1aPollerEventTypeRequestMode;
  112. command = instance->callback(instance->gen1a_event, instance->context);
  113. if(instance->gen1a_event_data.request_mode.mode == Gen1aPollerModeWipe) {
  114. instance->state = Gen1aPollerStateWipe;
  115. } else if(instance->gen1a_event_data.request_mode.mode == Gen1aPollerModeDump) {
  116. instance->state = Gen1aPollerStateDumpDataRequest;
  117. } else {
  118. instance->state = Gen1aPollerStateWriteDataRequest;
  119. }
  120. return command;
  121. }
  122. NfcCommand gen1a_poller_wipe_handler(Gen1aPoller* instance) {
  123. NfcCommand command = NfcCommandContinue;
  124. Gen1aPollerError error = Gen1aPollerErrorNone;
  125. const MfClassicData* mfc_data =
  126. nfc_device_get_data(instance->mfc_device, NfcProtocolMfClassic);
  127. uint16_t total_block_num = mf_classic_get_total_block_num(mfc_data->type);
  128. if(instance->current_block == total_block_num) {
  129. instance->state = Gen1aPollerStateSuccess;
  130. } else {
  131. do {
  132. if(instance->current_block == 0) {
  133. error = gen1a_poller_data_access(instance);
  134. if(error != Gen1aPollerErrorNone) {
  135. instance->state = Gen1aPollerStateFail;
  136. break;
  137. }
  138. }
  139. error = gen1a_poller_write_block(
  140. instance, instance->current_block, &mfc_data->block[instance->current_block]);
  141. if(error != Gen1aPollerErrorNone) {
  142. instance->state = Gen1aPollerStateFail;
  143. break;
  144. }
  145. instance->current_block++;
  146. } while(false);
  147. }
  148. return command;
  149. }
  150. NfcCommand gen1a_poller_write_data_request_handler(Gen1aPoller* instance) {
  151. NfcCommand command = NfcCommandContinue;
  152. instance->gen1a_event.type = Gen1aPollerEventTypeRequestDataToWrite;
  153. command = instance->callback(instance->gen1a_event, instance->context);
  154. instance->state = Gen1aPollerStateWrite;
  155. return command;
  156. }
  157. NfcCommand gen1a_poller_write_handler(Gen1aPoller* instance) {
  158. NfcCommand command = NfcCommandContinue;
  159. Gen1aPollerError error = Gen1aPollerErrorNone;
  160. const MfClassicData* mfc_data = instance->gen1a_event_data.data_to_write.mfc_data;
  161. uint16_t total_block_num = mf_classic_get_total_block_num(mfc_data->type);
  162. if(instance->current_block == total_block_num) {
  163. instance->state = Gen1aPollerStateSuccess;
  164. } else {
  165. do {
  166. if(instance->current_block == 0) {
  167. error = gen1a_poller_data_access(instance);
  168. if(error != Gen1aPollerErrorNone) {
  169. instance->state = Gen1aPollerStateFail;
  170. break;
  171. }
  172. }
  173. error = gen1a_poller_write_block(
  174. instance, instance->current_block, &mfc_data->block[instance->current_block]);
  175. if(error != Gen1aPollerErrorNone) {
  176. instance->state = Gen1aPollerStateFail;
  177. break;
  178. }
  179. instance->current_block++;
  180. } while(false);
  181. }
  182. return command;
  183. }
  184. NfcCommand gen1a_poller_dump_data_request_handler(Gen1aPoller* instance) {
  185. NfcCommand command = NfcCommandContinue;
  186. instance->gen1a_event.type = Gen1aPollerEventTypeRequestDataToDump;
  187. command = instance->callback(instance->gen1a_event, instance->context);
  188. instance->state = Gen1aPollerStateDump;
  189. return command;
  190. }
  191. NfcCommand gen1a_poller_dump_handler(Gen1aPoller* instance) {
  192. NfcCommand command = NfcCommandContinue;
  193. Gen1aPollerError error = Gen1aPollerErrorNone;
  194. MfClassicData* mfc_data = instance->gen1a_event_data.data_to_dump.mfc_data;
  195. MfClassicBlock block = {};
  196. uint16_t total_block_num =
  197. mf_classic_get_total_block_num(MfClassicType1k); // Gen1 can only be 1k
  198. while(instance->current_block < total_block_num) {
  199. if(instance->current_block == 0) {
  200. error = gen1a_poller_data_access(instance);
  201. if(error != Gen1aPollerErrorNone) {
  202. instance->state = Gen1aPollerStateFail;
  203. break;
  204. }
  205. }
  206. error = gen1a_poller_read_block(instance, instance->current_block, &block);
  207. if(error != Gen1aPollerErrorNone) {
  208. instance->state = Gen1aPollerStateFail;
  209. break;
  210. } else {
  211. mf_classic_set_block_read(mfc_data, instance->current_block, &block);
  212. if(mf_classic_is_sector_trailer(instance->current_block)) {
  213. mf_classic_set_sector_trailer_read(
  214. mfc_data, instance->current_block, (MfClassicSectorTrailer*)&block);
  215. }
  216. }
  217. if(instance->current_block == 0) {
  218. error = gen1a_poller_parse_block0(&mfc_data->block[instance->current_block], mfc_data);
  219. if(error != Gen1aPollerErrorNone) {
  220. instance->state = Gen1aPollerStateFail;
  221. break;
  222. }
  223. }
  224. instance->current_block++;
  225. }
  226. if(instance->current_block == total_block_num) {
  227. instance->state = Gen1aPollerStateSuccess;
  228. }
  229. return command;
  230. }
  231. NfcCommand gen1a_poller_success_handler(Gen1aPoller* instance) {
  232. NfcCommand command = NfcCommandContinue;
  233. instance->gen1a_event.type = Gen1aPollerEventTypeSuccess;
  234. command = instance->callback(instance->gen1a_event, instance->context);
  235. instance->state = Gen1aPollerStateIdle;
  236. return command;
  237. }
  238. NfcCommand gen1a_poller_fail_handler(Gen1aPoller* instance) {
  239. NfcCommand command = NfcCommandContinue;
  240. instance->gen1a_event.type = Gen1aPollerEventTypeFail;
  241. command = instance->callback(instance->gen1a_event, instance->context);
  242. instance->state = Gen1aPollerStateIdle;
  243. return command;
  244. }
  245. static const Gen1aPollerStateHandler gen1a_poller_state_handlers[Gen1aPollerStateNum] = {
  246. [Gen1aPollerStateIdle] = gen1a_poller_idle_handler,
  247. [Gen1aPollerStateRequestMode] = gen1a_poller_request_mode_handler,
  248. [Gen1aPollerStateWipe] = gen1a_poller_wipe_handler,
  249. [Gen1aPollerStateWriteDataRequest] = gen1a_poller_write_data_request_handler,
  250. [Gen1aPollerStateWrite] = gen1a_poller_write_handler,
  251. [Gen1aPollerStateDumpDataRequest] = gen1a_poller_dump_data_request_handler,
  252. [Gen1aPollerStateDump] = gen1a_poller_dump_handler,
  253. [Gen1aPollerStateSuccess] = gen1a_poller_success_handler,
  254. [Gen1aPollerStateFail] = gen1a_poller_fail_handler,
  255. };
  256. NfcCommand gen1a_poller_run(NfcEvent event, void* context) {
  257. NfcCommand command = NfcCommandContinue;
  258. Gen1aPoller* instance = context;
  259. if(event.type == NfcEventTypePollerReady) {
  260. command = gen1a_poller_state_handlers[instance->state](instance);
  261. }
  262. if(instance->session_state == Gen1aPollerSessionStateStopRequest) {
  263. command = NfcCommandStop;
  264. }
  265. return command;
  266. }
  267. void gen1a_poller_start(Gen1aPoller* instance, Gen1aPollerCallback callback, void* context) {
  268. furi_assert(instance);
  269. furi_assert(callback);
  270. instance->callback = callback;
  271. instance->context = context;
  272. instance->session_state = Gen1aPollerSessionStateStarted;
  273. nfc_start(instance->nfc, gen1a_poller_run, instance);
  274. }
  275. void gen1a_poller_stop(Gen1aPoller* instance) {
  276. furi_assert(instance);
  277. instance->session_state = Gen1aPollerSessionStateStopRequest;
  278. nfc_stop(instance->nfc);
  279. instance->session_state = Gen1aPollerSessionStateIdle;
  280. }