hid_worker.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include "hid_worker.h"
  2. static const uint8_t hid_number_keys[10] = {
  3. HID_KEYBOARD_0,
  4. HID_KEYBOARD_1,
  5. HID_KEYBOARD_2,
  6. HID_KEYBOARD_3,
  7. HID_KEYBOARD_4,
  8. HID_KEYBOARD_5,
  9. HID_KEYBOARD_6,
  10. HID_KEYBOARD_7,
  11. HID_KEYBOARD_8,
  12. HID_KEYBOARD_9};
  13. static void totp_hid_worker_restore_usb_mode(TotpHidWorkerTypeContext* context) {
  14. if(context->usb_mode_prev != NULL) {
  15. furi_hal_usb_set_config(context->usb_mode_prev, NULL);
  16. context->usb_mode_prev = NULL;
  17. }
  18. }
  19. static inline bool totp_hid_worker_stop_requested() {
  20. return furi_thread_flags_get() & TotpHidWorkerEvtStop;
  21. }
  22. static void totp_hid_worker_type_code(TotpHidWorkerTypeContext* context) {
  23. context->usb_mode_prev = furi_hal_usb_get_config();
  24. furi_hal_usb_unlock();
  25. furi_check(furi_hal_usb_set_config(&usb_hid, NULL) == true);
  26. uint8_t i = 0;
  27. do {
  28. furi_delay_ms(500);
  29. i++;
  30. } while(!furi_hal_hid_is_connected() && i < 100 && !totp_hid_worker_stop_requested());
  31. if(furi_hal_hid_is_connected() &&
  32. furi_mutex_acquire(context->string_sync, 500) == FuriStatusOk) {
  33. furi_delay_ms(500);
  34. i = 0;
  35. while(i < context->string_length && context->string[i] != 0) {
  36. uint8_t digit = context->string[i] - '0';
  37. if(digit > 9) break;
  38. uint8_t hid_kb_key = hid_number_keys[digit];
  39. furi_hal_hid_kb_press(hid_kb_key);
  40. furi_delay_ms(30);
  41. furi_hal_hid_kb_release(hid_kb_key);
  42. i++;
  43. }
  44. furi_mutex_release(context->string_sync);
  45. furi_delay_ms(100);
  46. }
  47. totp_hid_worker_restore_usb_mode(context);
  48. }
  49. static int32_t totp_hid_worker_callback(void* context) {
  50. ValueMutex context_mutex;
  51. if(!init_mutex(&context_mutex, context, sizeof(TotpHidWorkerTypeContext))) {
  52. return 251;
  53. }
  54. while(true) {
  55. uint32_t flags = furi_thread_flags_wait(
  56. TotpHidWorkerEvtStop | TotpHidWorkerEvtType, FuriFlagWaitAny, FuriWaitForever);
  57. furi_check((flags & FuriFlagError) == 0); //-V562
  58. if(flags & TotpHidWorkerEvtStop) break;
  59. TotpHidWorkerTypeContext* h_context = acquire_mutex_block(&context_mutex);
  60. if(flags & TotpHidWorkerEvtType) {
  61. totp_hid_worker_type_code(h_context);
  62. }
  63. release_mutex(&context_mutex, h_context);
  64. }
  65. delete_mutex(&context_mutex);
  66. return 0;
  67. }
  68. TotpHidWorkerTypeContext* totp_hid_worker_start() {
  69. TotpHidWorkerTypeContext* context = malloc(sizeof(TotpHidWorkerTypeContext));
  70. furi_check(context != NULL);
  71. context->string_sync = furi_mutex_alloc(FuriMutexTypeNormal);
  72. context->thread = furi_thread_alloc();
  73. context->usb_mode_prev = NULL;
  74. furi_thread_set_name(context->thread, "TOTPHidWorker");
  75. furi_thread_set_stack_size(context->thread, 1024);
  76. furi_thread_set_context(context->thread, context);
  77. furi_thread_set_callback(context->thread, totp_hid_worker_callback);
  78. furi_thread_start(context->thread);
  79. return context;
  80. }
  81. void totp_hid_worker_stop(TotpHidWorkerTypeContext* context) {
  82. furi_assert(context != NULL);
  83. furi_thread_flags_set(furi_thread_get_id(context->thread), TotpHidWorkerEvtStop);
  84. furi_thread_join(context->thread);
  85. furi_thread_free(context->thread);
  86. furi_mutex_free(context->string_sync);
  87. totp_hid_worker_restore_usb_mode(context);
  88. free(context);
  89. }
  90. void totp_hid_worker_notify(TotpHidWorkerTypeContext* context, TotpHidWorkerEvtFlags event) {
  91. furi_assert(context != NULL);
  92. furi_thread_flags_set(furi_thread_get_id(context->thread), event);
  93. }