lfrfid_worker_modes.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. #include <furi.h>
  2. #include <furi_hal.h>
  3. #include "lfrfid_worker_i.h"
  4. #include "tools/t5577.h"
  5. #include <toolbox/pulse_protocols/pulse_glue.h>
  6. #include <toolbox/buffer_stream.h>
  7. #include "tools/varint_pair.h"
  8. #include "tools/bit_lib.h"
  9. #define TAG "LFRFIDWorker"
  10. /**
  11. * if READ_DEBUG_GPIO is defined:
  12. * gpio_ext_pa7 will repeat signal coming from the comparator
  13. * gpio_ext_pa6 will show load on the decoder
  14. */
  15. // #define LFRFID_WORKER_READ_DEBUG_GPIO 1
  16. #ifdef LFRFID_WORKER_READ_DEBUG_GPIO
  17. #define LFRFID_WORKER_READ_DEBUG_GPIO_VALUE &gpio_ext_pa7
  18. #define LFRFID_WORKER_READ_DEBUG_GPIO_LOAD &gpio_ext_pa6
  19. #endif
  20. #define LFRFID_WORKER_READ_AVERAGE_COUNT 64
  21. #define LFRFID_WORKER_READ_MIN_TIME_US 16
  22. #define LFRFID_WORKER_READ_DROP_TIME_MS 50
  23. #define LFRFID_WORKER_READ_STABILIZE_TIME_MS 450
  24. #define LFRFID_WORKER_READ_SWITCH_TIME_MS 2000
  25. #define LFRFID_WORKER_WRITE_VERIFY_TIME_MS 2000
  26. #define LFRFID_WORKER_WRITE_DROP_TIME_MS 50
  27. #define LFRFID_WORKER_WRITE_TOO_LONG_TIME_MS 10000
  28. #define LFRFID_WORKER_WRITE_MAX_UNSUCCESSFUL_READS 5
  29. #define LFRFID_WORKER_READ_BUFFER_SIZE 512
  30. #define LFRFID_WORKER_READ_BUFFER_COUNT 16
  31. #define LFRFID_WORKER_EMULATE_BUFFER_SIZE 1024
  32. #define LFRFID_WORKER_DELAY_QUANT 50
  33. void lfrfid_worker_delay(LFRFIDWorker* worker, uint32_t milliseconds) {
  34. for(uint32_t i = 0; i < (milliseconds / LFRFID_WORKER_DELAY_QUANT); i++) {
  35. if(lfrfid_worker_check_for_stop(worker)) break;
  36. furi_delay_ms(LFRFID_WORKER_DELAY_QUANT);
  37. }
  38. }
  39. /**************************************************************************************************/
  40. /********************************************** READ **********************************************/
  41. /**************************************************************************************************/
  42. typedef struct {
  43. BufferStream* stream;
  44. VarintPair* pair;
  45. bool ignore_next_pulse;
  46. } LFRFIDWorkerReadContext;
  47. static void lfrfid_worker_read_capture(bool level, uint32_t duration, void* context) {
  48. LFRFIDWorkerReadContext* ctx = context;
  49. // ignore pulse if last pulse was noise
  50. if(ctx->ignore_next_pulse) {
  51. ctx->ignore_next_pulse = false;
  52. return;
  53. }
  54. // ignore noise spikes
  55. if(duration <= LFRFID_WORKER_READ_MIN_TIME_US) {
  56. if(level) {
  57. ctx->ignore_next_pulse = true;
  58. }
  59. varint_pair_reset(ctx->pair);
  60. return;
  61. }
  62. #ifdef LFRFID_WORKER_READ_DEBUG_GPIO
  63. furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_VALUE, level);
  64. #endif
  65. bool need_to_send = varint_pair_pack(ctx->pair, level, duration);
  66. if(need_to_send) {
  67. buffer_stream_send_from_isr(
  68. ctx->stream, varint_pair_get_data(ctx->pair), varint_pair_get_size(ctx->pair));
  69. varint_pair_reset(ctx->pair);
  70. }
  71. }
  72. typedef enum {
  73. LFRFIDWorkerReadOK,
  74. LFRFIDWorkerReadExit,
  75. LFRFIDWorkerReadTimeout,
  76. } LFRFIDWorkerReadState;
  77. static LFRFIDWorkerReadState lfrfid_worker_read_internal(
  78. LFRFIDWorker* worker,
  79. LFRFIDFeature feature,
  80. uint32_t timeout,
  81. ProtocolId* result_protocol) {
  82. LFRFIDWorkerReadState state = LFRFIDWorkerReadTimeout;
  83. furi_hal_rfid_pins_read();
  84. if(feature & LFRFIDFeatureASK) {
  85. furi_hal_rfid_tim_read(125000, 0.5);
  86. FURI_LOG_D(TAG, "Start ASK");
  87. if(worker->read_cb) {
  88. worker->read_cb(LFRFIDWorkerReadStartASK, PROTOCOL_NO, worker->cb_ctx);
  89. }
  90. } else {
  91. furi_hal_rfid_tim_read(62500, 0.25);
  92. FURI_LOG_D(TAG, "Start PSK");
  93. if(worker->read_cb) {
  94. worker->read_cb(LFRFIDWorkerReadStartPSK, PROTOCOL_NO, worker->cb_ctx);
  95. }
  96. }
  97. furi_hal_rfid_tim_read_start();
  98. // stabilize detector
  99. lfrfid_worker_delay(worker, LFRFID_WORKER_READ_STABILIZE_TIME_MS);
  100. protocol_dict_decoders_start(worker->protocols);
  101. #ifdef LFRFID_WORKER_READ_DEBUG_GPIO
  102. furi_hal_gpio_init_simple(LFRFID_WORKER_READ_DEBUG_GPIO_VALUE, GpioModeOutputPushPull);
  103. furi_hal_gpio_init_simple(LFRFID_WORKER_READ_DEBUG_GPIO_LOAD, GpioModeOutputPushPull);
  104. furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_VALUE, false);
  105. furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_LOAD, false);
  106. #endif
  107. LFRFIDWorkerReadContext ctx;
  108. ctx.pair = varint_pair_alloc();
  109. ctx.stream =
  110. buffer_stream_alloc(LFRFID_WORKER_READ_BUFFER_SIZE, LFRFID_WORKER_READ_BUFFER_COUNT);
  111. furi_hal_rfid_tim_read_capture_start(lfrfid_worker_read_capture, &ctx);
  112. *result_protocol = PROTOCOL_NO;
  113. ProtocolId last_protocol = PROTOCOL_NO;
  114. size_t last_size = protocol_dict_get_max_data_size(worker->protocols);
  115. uint8_t* last_data = malloc(last_size);
  116. uint8_t* protocol_data = malloc(last_size);
  117. size_t last_read_count = 0;
  118. uint32_t switch_os_tick_last = furi_get_tick();
  119. uint32_t average_duration = 0;
  120. uint32_t average_pulse = 0;
  121. size_t average_index = 0;
  122. bool card_detected = false;
  123. FURI_LOG_D(TAG, "Read started");
  124. while(true) {
  125. if(lfrfid_worker_check_for_stop(worker)) {
  126. state = LFRFIDWorkerReadExit;
  127. break;
  128. }
  129. Buffer* buffer = buffer_stream_receive(ctx.stream, 100);
  130. #ifdef LFRFID_WORKER_READ_DEBUG_GPIO
  131. furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_LOAD, true);
  132. #endif
  133. if(buffer_stream_get_overrun_count(ctx.stream) > 0) {
  134. FURI_LOG_E(TAG, "Read overrun, recovering");
  135. buffer_stream_reset(ctx.stream);
  136. #ifdef LFRFID_WORKER_READ_DEBUG_GPIO
  137. furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_LOAD, false);
  138. #endif
  139. continue;
  140. }
  141. if(buffer == NULL) {
  142. #ifdef LFRFID_WORKER_READ_DEBUG_GPIO
  143. furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_LOAD, false);
  144. #endif
  145. continue;
  146. }
  147. size_t size = buffer_get_size(buffer);
  148. uint8_t* data = buffer_get_data(buffer);
  149. size_t index = 0;
  150. while(index < size) {
  151. uint32_t duration;
  152. uint32_t pulse;
  153. size_t tmp_size;
  154. if(!varint_pair_unpack(&data[index], size - index, &pulse, &duration, &tmp_size)) {
  155. FURI_LOG_E(TAG, "can't unpack varint pair");
  156. break;
  157. } else {
  158. index += tmp_size;
  159. average_duration += duration;
  160. average_pulse += pulse;
  161. average_index++;
  162. if(average_index >= LFRFID_WORKER_READ_AVERAGE_COUNT) {
  163. float average = (float)average_pulse / (float)average_duration;
  164. average_pulse = 0;
  165. average_duration = 0;
  166. average_index = 0;
  167. if(worker->read_cb) {
  168. if(average > 0.2 && average < 0.8) {
  169. if(!card_detected) {
  170. card_detected = true;
  171. worker->read_cb(
  172. LFRFIDWorkerReadSenseStart, PROTOCOL_NO, worker->cb_ctx);
  173. }
  174. } else {
  175. if(card_detected) {
  176. card_detected = false;
  177. worker->read_cb(
  178. LFRFIDWorkerReadSenseEnd, PROTOCOL_NO, worker->cb_ctx);
  179. }
  180. }
  181. }
  182. }
  183. ProtocolId protocol = PROTOCOL_NO;
  184. protocol = protocol_dict_decoders_feed_by_feature(
  185. worker->protocols, feature, true, pulse);
  186. if(protocol == PROTOCOL_NO) {
  187. protocol = protocol_dict_decoders_feed_by_feature(
  188. worker->protocols, feature, false, duration - pulse);
  189. }
  190. if(protocol != PROTOCOL_NO) {
  191. // reset switch timer
  192. switch_os_tick_last = furi_get_tick();
  193. size_t protocol_data_size =
  194. protocol_dict_get_data_size(worker->protocols, protocol);
  195. protocol_dict_get_data(
  196. worker->protocols, protocol, protocol_data, protocol_data_size);
  197. // validate protocol
  198. if(protocol == last_protocol &&
  199. memcmp(last_data, protocol_data, protocol_data_size) == 0) {
  200. last_read_count = last_read_count + 1;
  201. size_t validation_count =
  202. protocol_dict_get_validate_count(worker->protocols, protocol);
  203. if(last_read_count >= validation_count) {
  204. state = LFRFIDWorkerReadOK;
  205. *result_protocol = protocol;
  206. break;
  207. }
  208. } else {
  209. if(last_protocol == PROTOCOL_NO && worker->read_cb) {
  210. worker->read_cb(
  211. LFRFIDWorkerReadSenseCardStart, protocol, worker->cb_ctx);
  212. }
  213. last_protocol = protocol;
  214. memcpy(last_data, protocol_data, protocol_data_size);
  215. last_read_count = 0;
  216. }
  217. if(furi_log_get_level() >= FuriLogLevelDebug) {
  218. FuriString* string_info;
  219. string_info = furi_string_alloc();
  220. for(uint8_t i = 0; i < protocol_data_size; i++) {
  221. if(i != 0) {
  222. furi_string_cat_printf(string_info, " ");
  223. }
  224. furi_string_cat_printf(string_info, "%02X", protocol_data[i]);
  225. }
  226. FURI_LOG_D(
  227. TAG,
  228. "%s, %d, [%s]",
  229. protocol_dict_get_name(worker->protocols, protocol),
  230. last_read_count,
  231. furi_string_get_cstr(string_info));
  232. furi_string_free(string_info);
  233. }
  234. protocol_dict_decoders_start(worker->protocols);
  235. }
  236. }
  237. }
  238. buffer_reset(buffer);
  239. #ifdef LFRFID_WORKER_READ_DEBUG_GPIO
  240. furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_LOAD, false);
  241. #endif
  242. if(*result_protocol != PROTOCOL_NO) {
  243. break;
  244. }
  245. if((furi_get_tick() - switch_os_tick_last) > timeout) {
  246. state = LFRFIDWorkerReadTimeout;
  247. break;
  248. }
  249. }
  250. FURI_LOG_D(TAG, "Read stopped");
  251. if(last_protocol != PROTOCOL_NO && worker->read_cb) {
  252. worker->read_cb(LFRFIDWorkerReadSenseCardEnd, last_protocol, worker->cb_ctx);
  253. }
  254. if(card_detected && worker->read_cb) {
  255. worker->read_cb(LFRFIDWorkerReadSenseEnd, last_protocol, worker->cb_ctx);
  256. }
  257. furi_hal_rfid_tim_read_capture_stop();
  258. furi_hal_rfid_tim_read_stop();
  259. furi_hal_rfid_pins_reset();
  260. varint_pair_free(ctx.pair);
  261. buffer_stream_free(ctx.stream);
  262. free(protocol_data);
  263. free(last_data);
  264. #ifdef LFRFID_WORKER_READ_DEBUG_GPIO
  265. furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_VALUE, false);
  266. furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_LOAD, false);
  267. furi_hal_gpio_init_simple(LFRFID_WORKER_READ_DEBUG_GPIO_VALUE, GpioModeAnalog);
  268. furi_hal_gpio_init_simple(LFRFID_WORKER_READ_DEBUG_GPIO_LOAD, GpioModeAnalog);
  269. #endif
  270. return state;
  271. }
  272. static void lfrfid_worker_mode_read_process(LFRFIDWorker* worker) {
  273. LFRFIDFeature feature = LFRFIDFeatureASK;
  274. ProtocolId read_result = PROTOCOL_NO;
  275. LFRFIDWorkerReadState state;
  276. if(worker->read_type == LFRFIDWorkerReadTypePSKOnly) {
  277. feature = LFRFIDFeaturePSK;
  278. } else {
  279. feature = LFRFIDFeatureASK;
  280. }
  281. if(worker->read_type == LFRFIDWorkerReadTypeAuto) {
  282. while(1) {
  283. // read for a while
  284. state = lfrfid_worker_read_internal(
  285. worker, feature, LFRFID_WORKER_READ_SWITCH_TIME_MS, &read_result);
  286. if(state == LFRFIDWorkerReadOK || state == LFRFIDWorkerReadExit) {
  287. break;
  288. }
  289. // switch to next feature
  290. if(feature == LFRFIDFeatureASK) {
  291. feature = LFRFIDFeaturePSK;
  292. } else {
  293. feature = LFRFIDFeatureASK;
  294. }
  295. lfrfid_worker_delay(worker, LFRFID_WORKER_READ_DROP_TIME_MS);
  296. }
  297. } else {
  298. while(1) {
  299. if(worker->read_type == LFRFIDWorkerReadTypeASKOnly) {
  300. state = lfrfid_worker_read_internal(worker, feature, UINT32_MAX, &read_result);
  301. } else {
  302. state = lfrfid_worker_read_internal(
  303. worker, feature, LFRFID_WORKER_READ_SWITCH_TIME_MS, &read_result);
  304. }
  305. if(state == LFRFIDWorkerReadOK || state == LFRFIDWorkerReadExit) {
  306. break;
  307. }
  308. lfrfid_worker_delay(worker, LFRFID_WORKER_READ_DROP_TIME_MS);
  309. }
  310. }
  311. if(state == LFRFIDWorkerReadOK && worker->read_cb) {
  312. worker->read_cb(LFRFIDWorkerReadDone, read_result, worker->cb_ctx);
  313. }
  314. }
  315. /**************************************************************************************************/
  316. /******************************************** EMULATE *********************************************/
  317. /**************************************************************************************************/
  318. typedef struct {
  319. uint32_t duration[LFRFID_WORKER_EMULATE_BUFFER_SIZE];
  320. uint32_t pulse[LFRFID_WORKER_EMULATE_BUFFER_SIZE];
  321. } LFRFIDWorkerEmulateBuffer;
  322. typedef enum {
  323. HalfTransfer,
  324. TransferComplete,
  325. } LFRFIDWorkerEmulateDMAEvent;
  326. static void lfrfid_worker_emulate_dma_isr(bool half, void* context) {
  327. FuriStreamBuffer* stream = context;
  328. uint32_t flag = half ? HalfTransfer : TransferComplete;
  329. furi_stream_buffer_send(stream, &flag, sizeof(uint32_t), 0);
  330. }
  331. static void lfrfid_worker_mode_emulate_process(LFRFIDWorker* worker) {
  332. LFRFIDWorkerEmulateBuffer* buffer = malloc(sizeof(LFRFIDWorkerEmulateBuffer));
  333. FuriStreamBuffer* stream = furi_stream_buffer_alloc(sizeof(uint32_t), sizeof(uint32_t));
  334. LFRFIDProtocol protocol = worker->protocol;
  335. PulseGlue* pulse_glue = pulse_glue_alloc();
  336. protocol_dict_encoder_start(worker->protocols, protocol);
  337. for(size_t i = 0; i < LFRFID_WORKER_EMULATE_BUFFER_SIZE; i++) {
  338. bool pulse_pop = false;
  339. while(!pulse_pop) {
  340. LevelDuration level_duration =
  341. protocol_dict_encoder_yield(worker->protocols, protocol);
  342. pulse_pop = pulse_glue_push(
  343. pulse_glue,
  344. level_duration_get_level(level_duration),
  345. level_duration_get_duration(level_duration));
  346. }
  347. uint32_t duration, pulse;
  348. pulse_glue_pop(pulse_glue, &duration, &pulse);
  349. buffer->duration[i] = duration - 1;
  350. buffer->pulse[i] = pulse;
  351. }
  352. #ifdef LFRFID_WORKER_READ_DEBUG_GPIO
  353. furi_hal_gpio_init_simple(LFRFID_WORKER_READ_DEBUG_GPIO_LOAD, GpioModeOutputPushPull);
  354. #endif
  355. furi_hal_rfid_tim_emulate_dma_start(
  356. buffer->duration,
  357. buffer->pulse,
  358. LFRFID_WORKER_EMULATE_BUFFER_SIZE,
  359. lfrfid_worker_emulate_dma_isr,
  360. stream);
  361. while(true) {
  362. uint32_t flag = 0;
  363. size_t size = furi_stream_buffer_receive(stream, &flag, sizeof(uint32_t), 100);
  364. #ifdef LFRFID_WORKER_READ_DEBUG_GPIO
  365. furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_LOAD, true);
  366. #endif
  367. if(size == sizeof(uint32_t)) {
  368. size_t start = 0;
  369. if(flag == HalfTransfer) {
  370. start = 0;
  371. } else if(flag == TransferComplete) {
  372. start = (LFRFID_WORKER_EMULATE_BUFFER_SIZE / 2);
  373. }
  374. for(size_t i = 0; i < (LFRFID_WORKER_EMULATE_BUFFER_SIZE / 2); i++) {
  375. bool pulse_pop = false;
  376. while(!pulse_pop) {
  377. LevelDuration level_duration =
  378. protocol_dict_encoder_yield(worker->protocols, protocol);
  379. pulse_pop = pulse_glue_push(
  380. pulse_glue,
  381. level_duration_get_level(level_duration),
  382. level_duration_get_duration(level_duration));
  383. }
  384. uint32_t duration, pulse;
  385. pulse_glue_pop(pulse_glue, &duration, &pulse);
  386. buffer->duration[start + i] = duration - 1;
  387. buffer->pulse[start + i] = pulse;
  388. }
  389. }
  390. if(lfrfid_worker_check_for_stop(worker)) {
  391. break;
  392. }
  393. #ifdef LFRFID_WORKER_READ_DEBUG_GPIO
  394. furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_LOAD, false);
  395. #endif
  396. }
  397. furi_hal_rfid_tim_emulate_dma_stop();
  398. #ifdef LFRFID_WORKER_READ_DEBUG_GPIO
  399. furi_hal_gpio_init_simple(LFRFID_WORKER_READ_DEBUG_GPIO_LOAD, GpioModeAnalog);
  400. #endif
  401. free(buffer);
  402. furi_stream_buffer_free(stream);
  403. pulse_glue_free(pulse_glue);
  404. }
  405. /**************************************************************************************************/
  406. /********************************************* WRITE **********************************************/
  407. /**************************************************************************************************/
  408. static void lfrfid_worker_mode_write_process(LFRFIDWorker* worker) {
  409. LFRFIDProtocol protocol = worker->protocol;
  410. LFRFIDWriteRequest* request = malloc(sizeof(LFRFIDWriteRequest));
  411. request->write_type = LFRFIDWriteTypeT5577;
  412. bool can_be_written = protocol_dict_get_write_data(worker->protocols, protocol, request);
  413. uint32_t write_start_time = furi_get_tick();
  414. bool too_long = false;
  415. size_t unsuccessful_reads = 0;
  416. size_t data_size = protocol_dict_get_data_size(worker->protocols, protocol);
  417. uint8_t* verify_data = malloc(data_size);
  418. uint8_t* read_data = malloc(data_size);
  419. protocol_dict_get_data(worker->protocols, protocol, verify_data, data_size);
  420. if(can_be_written) {
  421. while(!lfrfid_worker_check_for_stop(worker)) {
  422. FURI_LOG_D(TAG, "Data write");
  423. t5577_write(&request->t5577);
  424. ProtocolId read_result = PROTOCOL_NO;
  425. LFRFIDWorkerReadState state = lfrfid_worker_read_internal(
  426. worker,
  427. protocol_dict_get_features(worker->protocols, protocol),
  428. LFRFID_WORKER_WRITE_VERIFY_TIME_MS,
  429. &read_result);
  430. if(state == LFRFIDWorkerReadOK) {
  431. bool read_success = false;
  432. if(read_result == protocol) {
  433. protocol_dict_get_data(worker->protocols, protocol, read_data, data_size);
  434. if(memcmp(read_data, verify_data, data_size) == 0) {
  435. read_success = true;
  436. }
  437. }
  438. if(read_success) {
  439. if(worker->write_cb) {
  440. worker->write_cb(LFRFIDWorkerWriteOK, worker->cb_ctx);
  441. }
  442. break;
  443. } else {
  444. unsuccessful_reads++;
  445. if(unsuccessful_reads == LFRFID_WORKER_WRITE_MAX_UNSUCCESSFUL_READS) {
  446. if(worker->write_cb) {
  447. worker->write_cb(LFRFIDWorkerWriteFobCannotBeWritten, worker->cb_ctx);
  448. }
  449. }
  450. }
  451. } else if(state == LFRFIDWorkerReadExit) {
  452. break;
  453. }
  454. if(!too_long &&
  455. (furi_get_tick() - write_start_time) > LFRFID_WORKER_WRITE_TOO_LONG_TIME_MS) {
  456. too_long = true;
  457. if(worker->write_cb) {
  458. worker->write_cb(LFRFIDWorkerWriteTooLongToWrite, worker->cb_ctx);
  459. }
  460. }
  461. lfrfid_worker_delay(worker, LFRFID_WORKER_WRITE_DROP_TIME_MS);
  462. }
  463. } else {
  464. if(worker->write_cb) {
  465. worker->write_cb(LFRFIDWorkerWriteProtocolCannotBeWritten, worker->cb_ctx);
  466. }
  467. }
  468. free(request);
  469. free(verify_data);
  470. free(read_data);
  471. }
  472. /**************************************************************************************************/
  473. /******************************************* READ RAW *********************************************/
  474. /**************************************************************************************************/
  475. static void lfrfid_worker_mode_read_raw_process(LFRFIDWorker* worker) {
  476. LFRFIDRawWorker* raw_worker = lfrfid_raw_worker_alloc();
  477. switch(worker->read_type) {
  478. case LFRFIDWorkerReadTypePSKOnly:
  479. lfrfid_raw_worker_start_read(
  480. raw_worker, worker->raw_filename, 62500, 0.25, worker->read_raw_cb, worker->cb_ctx);
  481. break;
  482. case LFRFIDWorkerReadTypeASKOnly:
  483. lfrfid_raw_worker_start_read(
  484. raw_worker, worker->raw_filename, 125000, 0.5, worker->read_raw_cb, worker->cb_ctx);
  485. break;
  486. default:
  487. furi_crash("RAW can be only PSK or ASK");
  488. break;
  489. }
  490. while(!lfrfid_worker_check_for_stop(worker)) {
  491. furi_delay_ms(100);
  492. }
  493. lfrfid_raw_worker_stop(raw_worker);
  494. lfrfid_raw_worker_free(raw_worker);
  495. }
  496. /**************************************************************************************************/
  497. /***************************************** EMULATE RAW ********************************************/
  498. /**************************************************************************************************/
  499. static void lfrfid_worker_mode_emulate_raw_process(LFRFIDWorker* worker) {
  500. LFRFIDRawWorker* raw_worker = lfrfid_raw_worker_alloc();
  501. lfrfid_raw_worker_start_emulate(
  502. raw_worker, worker->raw_filename, worker->emulate_raw_cb, worker->cb_ctx);
  503. while(!lfrfid_worker_check_for_stop(worker)) {
  504. furi_delay_ms(100);
  505. }
  506. lfrfid_raw_worker_stop(raw_worker);
  507. lfrfid_raw_worker_free(raw_worker);
  508. }
  509. /**************************************************************************************************/
  510. /******************************************** MODES ***********************************************/
  511. /**************************************************************************************************/
  512. const LFRFIDWorkerModeType lfrfid_worker_modes[] = {
  513. [LFRFIDWorkerIdle] = {.process = NULL},
  514. [LFRFIDWorkerRead] = {.process = lfrfid_worker_mode_read_process},
  515. [LFRFIDWorkerWrite] = {.process = lfrfid_worker_mode_write_process},
  516. [LFRFIDWorkerEmulate] = {.process = lfrfid_worker_mode_emulate_process},
  517. [LFRFIDWorkerReadRaw] = {.process = lfrfid_worker_mode_read_raw_process},
  518. [LFRFIDWorkerEmulateRaw] = {.process = lfrfid_worker_mode_emulate_raw_process},
  519. };