@@ -32,6 +32,7 @@ struct BadUsbScript {
32
32
FuriString * file_path ;
33
33
uint32_t defdelay ;
34
34
uint16_t layout [128 ];
35
+ uint32_t stringdelay ;
35
36
FuriThread * thread ;
36
37
uint8_t file_buf [FILE_BUFFER_LEN + 1 ];
37
38
uint8_t buf_start ;
@@ -113,6 +114,8 @@ static const char ducky_cmd_delay[] = {"DELAY "};
113
114
static const char ducky_cmd_string [] = {"STRING " };
114
115
static const char ducky_cmd_defdelay_1 [] = {"DEFAULT_DELAY " };
115
116
static const char ducky_cmd_defdelay_2 [] = {"DEFAULTDELAY " };
117
+ static const char ducky_cmd_stringdelay_1 [] = {"STRINGDELAY " };
118
+ static const char ducky_cmd_stringdelay_2 [] = {"STRING_DELAY " };
116
119
static const char ducky_cmd_repeat [] = {"REPEAT " };
117
120
static const char ducky_cmd_sysrq [] = {"SYSRQ " };
118
121
@@ -211,14 +214,19 @@ static bool ducky_altstring(const char* param) {
211
214
212
215
static bool ducky_string (BadUsbScript * bad_usb , const char * param ) {
213
216
uint32_t i = 0 ;
217
+
214
218
while (param [i ] != '\0' ) {
215
219
uint16_t keycode = BADUSB_ASCII_TO_KEY (bad_usb , param [i ]);
216
220
if (keycode != HID_KEYBOARD_NONE ) {
217
221
furi_hal_hid_kb_press (keycode );
218
222
furi_hal_hid_kb_release (keycode );
223
+ if (bad_usb -> stringdelay > 0 ) {
224
+ furi_delay_ms (bad_usb -> stringdelay );
225
+ }
219
226
}
220
227
i ++ ;
221
228
}
229
+ bad_usb -> stringdelay = 0 ;
222
230
return true;
223
231
}
224
232
@@ -277,6 +285,20 @@ static int32_t
277
285
snprintf (error , error_len , "Invalid number %s" , line_tmp );
278
286
}
279
287
return (state ) ? (0 ) : SCRIPT_STATE_ERROR ;
288
+ } else if (
289
+ (strncmp (line_tmp , ducky_cmd_stringdelay_1 , strlen (ducky_cmd_stringdelay_1 )) == 0 ) ||
290
+ (strncmp (line_tmp , ducky_cmd_stringdelay_2 , strlen (ducky_cmd_stringdelay_2 )) == 0 )) {
291
+ //STRINGDELAY, finally it's here
292
+ line_tmp = & line_tmp [ducky_get_command_len (line_tmp ) + 1 ];
293
+ state = ducky_get_number (line_tmp , & bad_usb -> stringdelay );
294
+ if ((state ) && (bad_usb -> stringdelay > 0 )) {
295
+ return state ;
296
+ }
297
+ if (error != NULL ) {
298
+ snprintf (error , error_len , "Invalid number %s" , line_tmp );
299
+ }
300
+ return SCRIPT_STATE_ERROR ;
301
+
280
302
} else if (strncmp (line_tmp , ducky_cmd_string , strlen (ducky_cmd_string )) == 0 ) {
281
303
// STRING
282
304
line_tmp = & line_tmp [ducky_get_command_len (line_tmp ) + 1 ];
@@ -484,6 +506,19 @@ static void bad_usb_hid_state_callback(bool state, void* context) {
484
506
furi_thread_flags_set (furi_thread_get_id (bad_usb -> thread ), WorkerEvtDisconnect );
485
507
}
486
508
509
+ static uint32_t bad_usb_flags_get (uint32_t flags_mask , uint32_t timeout ) {
510
+ uint32_t flags = furi_thread_flags_get ();
511
+ furi_check ((flags & FuriFlagError ) == 0 );
512
+ if (flags == 0 ) {
513
+ flags = furi_thread_flags_wait (flags_mask , FuriFlagWaitAny , timeout );
514
+ furi_check (((flags & FuriFlagError ) == 0 ) || (flags == FuriFlagErrorTimeout ));
515
+ } else {
516
+ uint32_t state = furi_thread_flags_clear (flags );
517
+ furi_check ((state & FuriFlagError ) == 0 );
518
+ }
519
+ return flags ;
520
+ }
521
+
487
522
static int32_t bad_usb_worker (void * context ) {
488
523
BadUsbScript * bad_usb = context ;
489
524
@@ -520,11 +555,9 @@ static int32_t bad_usb_worker(void* context) {
520
555
bad_usb -> st .state = worker_state ;
521
556
522
557
} else if (worker_state == BadUsbStateNotConnected ) { // State: USB not connected
523
- uint32_t flags = furi_thread_flags_wait (
524
- WorkerEvtEnd | WorkerEvtConnect | WorkerEvtToggle ,
525
- FuriFlagWaitAny ,
526
- FuriWaitForever );
527
- furi_check ((flags & FuriFlagError ) == 0 );
558
+ uint32_t flags = bad_usb_flags_get (
559
+ WorkerEvtEnd | WorkerEvtConnect | WorkerEvtToggle , FuriWaitForever );
560
+
528
561
if (flags & WorkerEvtEnd ) {
529
562
break ;
530
563
} else if (flags & WorkerEvtConnect ) {
@@ -535,11 +568,9 @@ static int32_t bad_usb_worker(void* context) {
535
568
bad_usb -> st .state = worker_state ;
536
569
537
570
} else if (worker_state == BadUsbStateIdle ) { // State: ready to start
538
- uint32_t flags = furi_thread_flags_wait (
539
- WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect ,
540
- FuriFlagWaitAny ,
541
- FuriWaitForever );
542
- furi_check ((flags & FuriFlagError ) == 0 );
571
+ uint32_t flags = bad_usb_flags_get (
572
+ WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect , FuriWaitForever );
573
+
543
574
if (flags & WorkerEvtEnd ) {
544
575
break ;
545
576
} else if (flags & WorkerEvtToggle ) { // Start executing script
@@ -548,6 +579,7 @@ static int32_t bad_usb_worker(void* context) {
548
579
bad_usb -> buf_len = 0 ;
549
580
bad_usb -> st .line_cur = 0 ;
550
581
bad_usb -> defdelay = 0 ;
582
+ bad_usb -> stringdelay = 0 ;
551
583
bad_usb -> repeat_cnt = 0 ;
552
584
bad_usb -> file_end = false;
553
585
storage_file_seek (script_file , 0 , true);
@@ -558,11 +590,9 @@ static int32_t bad_usb_worker(void* context) {
558
590
bad_usb -> st .state = worker_state ;
559
591
560
592
} else if (worker_state == BadUsbStateWillRun ) { // State: start on connection
561
- uint32_t flags = furi_thread_flags_wait (
562
- WorkerEvtEnd | WorkerEvtConnect | WorkerEvtToggle ,
563
- FuriFlagWaitAny ,
564
- FuriWaitForever );
565
- furi_check ((flags & FuriFlagError ) == 0 );
593
+ uint32_t flags = bad_usb_flags_get (
594
+ WorkerEvtEnd | WorkerEvtConnect | WorkerEvtToggle , FuriWaitForever );
595
+
566
596
if (flags & WorkerEvtEnd ) {
567
597
break ;
568
598
} else if (flags & WorkerEvtConnect ) { // Start executing script
@@ -571,12 +601,22 @@ static int32_t bad_usb_worker(void* context) {
571
601
bad_usb -> buf_len = 0 ;
572
602
bad_usb -> st .line_cur = 0 ;
573
603
bad_usb -> defdelay = 0 ;
604
+ bad_usb -> stringdelay = 0 ;
574
605
bad_usb -> repeat_cnt = 0 ;
575
606
bad_usb -> file_end = false;
576
607
storage_file_seek (script_file , 0 , true);
577
608
// extra time for PC to recognize Flipper as keyboard
578
- furi_thread_flags_wait (0 , FuriFlagWaitAny , 1500 );
579
- worker_state = BadUsbStateRunning ;
609
+ flags = furi_thread_flags_wait (
610
+ WorkerEvtEnd | WorkerEvtDisconnect | WorkerEvtToggle ,
611
+ FuriFlagWaitAny | FuriFlagNoClear ,
612
+ 1500 );
613
+ if (flags == FuriFlagErrorTimeout ) {
614
+ // If nothing happened - start script execution
615
+ worker_state = BadUsbStateRunning ;
616
+ } else if (flags & WorkerEvtToggle ) {
617
+ worker_state = BadUsbStateIdle ;
618
+ furi_thread_flags_clear (WorkerEvtToggle );
619
+ }
580
620
} else if (flags & WorkerEvtToggle ) { // Cancel scheduled execution
581
621
worker_state = BadUsbStateNotConnected ;
582
622
}
@@ -586,6 +626,7 @@ static int32_t bad_usb_worker(void* context) {
586
626
uint16_t delay_cur = (delay_val > 1000 ) ? (1000 ) : (delay_val );
587
627
uint32_t flags = furi_thread_flags_wait (
588
628
WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect , FuriFlagWaitAny , delay_cur );
629
+
589
630
delay_val -= delay_cur ;
590
631
if (!(flags & FuriFlagError )) {
591
632
if (flags & WorkerEvtEnd ) {
@@ -629,9 +670,9 @@ static int32_t bad_usb_worker(void* context) {
629
670
} else if (
630
671
(worker_state == BadUsbStateFileError ) ||
631
672
(worker_state == BadUsbStateScriptError )) { // State: error
632
- uint32_t flags = furi_thread_flags_wait (
633
- WorkerEvtEnd , FuriFlagWaitAny , FuriWaitForever ); // Waiting for exit command
634
- furi_check (( flags & FuriFlagError ) == 0 );
673
+ uint32_t flags =
674
+ bad_usb_flags_get ( WorkerEvtEnd , FuriWaitForever ); // Waiting for exit command
675
+
635
676
if (flags & WorkerEvtEnd ) {
636
677
break ;
637
678
}
0 commit comments