Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 71 additions & 25 deletions applications/main/bad_usb/helpers/ducky_script.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
(((uint8_t)x < 128) ? (script->layout[(uint8_t)x]) : HID_KEYBOARD_NONE)

typedef enum {
WorkerEvtToggle = (1 << 0),
WorkerEvtEnd = (1 << 1),
WorkerEvtConnect = (1 << 2),
WorkerEvtDisconnect = (1 << 3),
WorkerEvtStartStop = (1 << 0),
WorkerEvtPauseResume = (1 << 1),
WorkerEvtEnd = (1 << 2),
WorkerEvtConnect = (1 << 3),
WorkerEvtDisconnect = (1 << 4),
} WorkerEvtFlags;

static const char ducky_cmd_id[] = {"ID"};
Expand Down Expand Up @@ -372,6 +373,7 @@ static int32_t bad_usb_worker(void* context) {
BadUsbScript* bad_usb = context;

BadUsbWorkerState worker_state = BadUsbStateInit;
BadUsbWorkerState pause_state = BadUsbStateRunning;
int32_t delay_val = 0;

FURI_LOG_I(WORKER_TAG, "Init");
Expand Down Expand Up @@ -406,24 +408,24 @@ static int32_t bad_usb_worker(void* context) {

} else if(worker_state == BadUsbStateNotConnected) { // State: USB not connected
uint32_t flags = bad_usb_flags_get(
WorkerEvtEnd | WorkerEvtConnect | WorkerEvtToggle, FuriWaitForever);
WorkerEvtEnd | WorkerEvtConnect | WorkerEvtStartStop, FuriWaitForever);

if(flags & WorkerEvtEnd) {
break;
} else if(flags & WorkerEvtConnect) {
worker_state = BadUsbStateIdle; // Ready to run
} else if(flags & WorkerEvtToggle) {
} else if(flags & WorkerEvtStartStop) {
worker_state = BadUsbStateWillRun; // Will run when USB is connected
}
bad_usb->st.state = worker_state;

} else if(worker_state == BadUsbStateIdle) { // State: ready to start
uint32_t flags = bad_usb_flags_get(
WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, FuriWaitForever);
WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtDisconnect, FuriWaitForever);

if(flags & WorkerEvtEnd) {
break;
} else if(flags & WorkerEvtToggle) { // Start executing script
} else if(flags & WorkerEvtStartStop) { // Start executing script
DOLPHIN_DEED(DolphinDeedBadUsbPlayScript);
delay_val = 0;
bad_usb->buf_len = 0;
Expand All @@ -442,7 +444,7 @@ static int32_t bad_usb_worker(void* context) {

} else if(worker_state == BadUsbStateWillRun) { // State: start on connection
uint32_t flags = bad_usb_flags_get(
WorkerEvtEnd | WorkerEvtConnect | WorkerEvtToggle, FuriWaitForever);
WorkerEvtEnd | WorkerEvtConnect | WorkerEvtStartStop, FuriWaitForever);

if(flags & WorkerEvtEnd) {
break;
Expand All @@ -458,36 +460,41 @@ static int32_t bad_usb_worker(void* context) {
storage_file_seek(script_file, 0, true);
// extra time for PC to recognize Flipper as keyboard
flags = furi_thread_flags_wait(
WorkerEvtEnd | WorkerEvtDisconnect | WorkerEvtToggle,
WorkerEvtEnd | WorkerEvtDisconnect | WorkerEvtStartStop,
FuriFlagWaitAny | FuriFlagNoClear,
1500);
if(flags == (unsigned)FuriFlagErrorTimeout) {
// If nothing happened - start script execution
worker_state = BadUsbStateRunning;
} else if(flags & WorkerEvtToggle) {
} else if(flags & WorkerEvtStartStop) {
worker_state = BadUsbStateIdle;
furi_thread_flags_clear(WorkerEvtToggle);
furi_thread_flags_clear(WorkerEvtStartStop);
}
} else if(flags & WorkerEvtToggle) { // Cancel scheduled execution
} else if(flags & WorkerEvtStartStop) { // Cancel scheduled execution
worker_state = BadUsbStateNotConnected;
}
bad_usb->st.state = worker_state;

} else if(worker_state == BadUsbStateRunning) { // State: running
uint16_t delay_cur = (delay_val > 1000) ? (1000) : (delay_val);
uint32_t flags = furi_thread_flags_wait(
WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, FuriFlagWaitAny, delay_cur);
WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtDisconnect,
FuriFlagWaitAny,
delay_cur);

delay_val -= delay_cur;
if(!(flags & FuriFlagError)) {
if(flags & WorkerEvtEnd) {
break;
} else if(flags & WorkerEvtToggle) {
} else if(flags & WorkerEvtStartStop) {
worker_state = BadUsbStateIdle; // Stop executing script
furi_hal_hid_kb_release_all();
} else if(flags & WorkerEvtDisconnect) {
worker_state = BadUsbStateNotConnected; // USB disconnected
furi_hal_hid_kb_release_all();
} else if(flags & WorkerEvtPauseResume) {
pause_state = BadUsbStateRunning;
worker_state = BadUsbStatePaused; // Pause
}
bad_usb->st.state = worker_state;
continue;
Expand Down Expand Up @@ -526,13 +533,13 @@ static int32_t bad_usb_worker(void* context) {
furi_check((flags & FuriFlagError) == 0);
}
} else if(worker_state == BadUsbStateWaitForBtn) { // State: Wait for button Press
uint16_t delay_cur = (delay_val > 1000) ? (1000) : (delay_val);
uint32_t flags = furi_thread_flags_wait(
WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, FuriFlagWaitAny, delay_cur);
uint32_t flags = bad_usb_flags_get(
WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtDisconnect,
FuriWaitForever);
if(!(flags & FuriFlagError)) {
if(flags & WorkerEvtEnd) {
break;
} else if(flags & WorkerEvtToggle) {
} else if(flags & WorkerEvtStartStop) {
delay_val = 0;
worker_state = BadUsbStateRunning;
} else if(flags & WorkerEvtDisconnect) {
Expand All @@ -542,21 +549,55 @@ static int32_t bad_usb_worker(void* context) {
bad_usb->st.state = worker_state;
continue;
}
} else if(worker_state == BadUsbStatePaused) { // State: Paused
uint32_t flags = bad_usb_flags_get(
WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtDisconnect,
FuriWaitForever);
if(!(flags & FuriFlagError)) {
if(flags & WorkerEvtEnd) {
break;
} else if(flags & WorkerEvtStartStop) {
worker_state = BadUsbStateIdle; // Stop executing script
bad_usb->st.state = worker_state;
furi_hal_hid_kb_release_all();
} else if(flags & WorkerEvtDisconnect) {
worker_state = BadUsbStateNotConnected; // USB disconnected
bad_usb->st.state = worker_state;
furi_hal_hid_kb_release_all();
} else if(flags & WorkerEvtPauseResume) {
if(pause_state == BadUsbStateRunning) {
if(delay_val > 0) {
bad_usb->st.state = BadUsbStateDelay;
bad_usb->st.delay_remain = delay_val / 1000;
} else {
bad_usb->st.state = BadUsbStateRunning;
delay_val = 0;
}
worker_state = BadUsbStateRunning; // Resume
} else if(pause_state == BadUsbStateStringDelay) {
bad_usb->st.state = BadUsbStateRunning;
worker_state = BadUsbStateStringDelay; // Resume
}
}
continue;
}
} else if(worker_state == BadUsbStateStringDelay) { // State: print string with delays
uint32_t flags = furi_thread_flags_wait(
WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect,
FuriFlagWaitAny,
uint32_t flags = bad_usb_flags_get(
WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtDisconnect,
bad_usb->stringdelay);

if(!(flags & FuriFlagError)) {
if(flags & WorkerEvtEnd) {
break;
} else if(flags & WorkerEvtToggle) {
} else if(flags & WorkerEvtStartStop) {
worker_state = BadUsbStateIdle; // Stop executing script
furi_hal_hid_kb_release_all();
} else if(flags & WorkerEvtDisconnect) {
worker_state = BadUsbStateNotConnected; // USB disconnected
furi_hal_hid_kb_release_all();
} else if(flags & WorkerEvtPauseResume) {
pause_state = BadUsbStateStringDelay;
worker_state = BadUsbStatePaused; // Pause
}
bad_usb->st.state = worker_state;
continue;
Expand Down Expand Up @@ -651,9 +692,14 @@ void bad_usb_script_set_keyboard_layout(BadUsbScript* bad_usb, FuriString* layou
storage_file_free(layout_file);
}

void bad_usb_script_toggle(BadUsbScript* bad_usb) {
void bad_usb_script_start_stop(BadUsbScript* bad_usb) {
furi_assert(bad_usb);
furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtStartStop);
}

void bad_usb_script_pause_resume(BadUsbScript* bad_usb) {
furi_assert(bad_usb);
furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtToggle);
furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtPauseResume);
}

BadUsbState* bad_usb_script_get_state(BadUsbScript* bad_usb) {
Expand Down
5 changes: 4 additions & 1 deletion applications/main/bad_usb/helpers/ducky_script.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ typedef enum {
BadUsbStateDelay,
BadUsbStateStringDelay,
BadUsbStateWaitForBtn,
BadUsbStatePaused,
BadUsbStateDone,
BadUsbStateScriptError,
BadUsbStateFileError,
Expand All @@ -42,7 +43,9 @@ void bad_usb_script_start(BadUsbScript* bad_usb);

void bad_usb_script_stop(BadUsbScript* bad_usb);

void bad_usb_script_toggle(BadUsbScript* bad_usb);
void bad_usb_script_start_stop(BadUsbScript* bad_usb);

void bad_usb_script_pause_resume(BadUsbScript* bad_usb);

BadUsbState* bad_usb_script_get_state(BadUsbScript* bad_usb);

Expand Down
5 changes: 4 additions & 1 deletion applications/main/bad_usb/scenes/bad_usb_scene_work.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ bool bad_usb_scene_work_on_event(void* context, SceneManagerEvent event) {
}
consumed = true;
} else if(event.event == InputKeyOk) {
bad_usb_script_toggle(app->bad_usb_script);
bad_usb_script_start_stop(app->bad_usb_script);
consumed = true;
} else if(event.event == InputKeyRight) {
bad_usb_script_pause_resume(app->bad_usb_script);
consumed = true;
}
} else if(event.type == SceneManagerEventTypeTick) {
Expand Down
Loading