hid_worker.c 3.4 KB

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