1
mirror of https://github.com/flipperdevices/flipperzero-firmware.git synced 2025-12-12 20:59:50 +04:00

CLI: Fix long delay with quick connect/disconnect (#4251)

* CLI: Fix long delay with quick connect/disconnect

noticeable with qflipper, for some reason it sets DTR on/off/on again
so flipper starts CLI, stops it, then starts again
but cli shell is trying to print motd, and pipe is already broken
so each character of motd times out for 100ms
changing pipe timeout to 10ms works too, but is just a workaround

it didnt always happen, i think that variable time of loading ext cmds
made it so on ofw it usually manages to print motd before pipe is broken
on cfw with more ext commands it always hung, on ofw only sometimes

important part is bailing early in cli shell
in cli vcp i made it cleanup cli shell on disconnect so it doesnt stay
around after disconnecting usb, might free a little ram maybe

* cli_shell: possibly more robust fix?

* Fix use after free crash

* cli_shell: waste even less time

Co-Authored-By: WillyJL <me@willyjl.dev>

---------

Co-authored-by: Anna Antonenko <portasynthinca3@gmail.com>
Co-authored-by: hedger <hedger@users.noreply.github.com>
This commit is contained in:
WillyJL
2025-09-24 11:19:18 +02:00
committed by GitHub
parent 8bd66c9920
commit ad94694fbd
2 changed files with 16 additions and 13 deletions

View File

@@ -16,7 +16,8 @@
#define TAG "CliShell"
#define ANSI_TIMEOUT_MS 10
#define ANSI_TIMEOUT_MS 10
#define TRANSIENT_SESSION_WINDOW_MS 100
typedef enum {
CliShellComponentCompletions,
@@ -415,10 +416,15 @@ static void cli_shell_deinit(CliShell* shell) {
static int32_t cli_shell_thread(void* context) {
CliShell* shell = context;
// Sometimes, the other side closes the pipe even before our thread is started. Although the
// rest of the code will eventually find this out if this check is removed, there's no point in
// wasting time.
if(pipe_state(shell->pipe) == PipeStateBroken) return 0;
// Sometimes, the other side (e.g. qFlipper) closes the pipe even before our thread is started.
// Although the rest of the code will eventually find this out if this check is removed,
// there's no point in wasting time. This gives qFlipper a chance to quickly close and re-open
// the session.
const size_t delay_step = 10;
for(size_t i = 0; i < TRANSIENT_SESSION_WINDOW_MS / delay_step; i++) {
furi_delay_ms(delay_step);
if(pipe_state(shell->pipe) == PipeStateBroken) return 0;
}
cli_shell_init(shell);
FURI_LOG_D(TAG, "Started");