lfrfid_worker_modes.c 23 KB

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