fix(sync): force uvc descriptor refresh on codec changes

This commit is contained in:
Brad Stein 2026-04-27 15:50:29 -03:00
parent ff528bad1c
commit 36a198db4c
6 changed files with 53 additions and 29 deletions

6
Cargo.lock generated
View File

@ -1642,7 +1642,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]]
name = "lesavka_client"
version = "0.14.21"
version = "0.14.22"
dependencies = [
"anyhow",
"async-stream",
@ -1676,7 +1676,7 @@ dependencies = [
[[package]]
name = "lesavka_common"
version = "0.14.21"
version = "0.14.22"
dependencies = [
"anyhow",
"base64",
@ -1688,7 +1688,7 @@ dependencies = [
[[package]]
name = "lesavka_server"
version = "0.14.21"
version = "0.14.22"
dependencies = [
"anyhow",
"base64",

View File

@ -4,7 +4,7 @@ path = "src/main.rs"
[package]
name = "lesavka_client"
version = "0.14.21"
version = "0.14.22"
edition = "2024"
[dependencies]

View File

@ -1,6 +1,6 @@
[package]
name = "lesavka_common"
version = "0.14.21"
version = "0.14.22"
edition = "2024"
build = "build.rs"

View File

@ -21,6 +21,23 @@ manifest_package_version() {
' "$manifest"
}
render_uvc_env_file() {
cat <<EOF
# generated by lesavka/scripts/install/server.sh
# Edit only for local UVC hardware overrides; rerunning the installer refreshes defaults.
LESAVKA_UVC_DEBUG=${LESAVKA_UVC_DEBUG:-1}
LESAVKA_UVC_MAXPACKET=${LESAVKA_UVC_MAXPACKET:-256}
LESAVKA_UVC_LIMIT_PCT=${LESAVKA_UVC_LIMIT_PCT:-100}
LESAVKA_UVC_FPS=${LESAVKA_UVC_FPS:-20}
LESAVKA_UVC_INTERVAL=${LESAVKA_UVC_INTERVAL:-500000}
LESAVKA_UVC_WIDTH=${LESAVKA_UVC_WIDTH:-640}
LESAVKA_UVC_HEIGHT=${LESAVKA_UVC_HEIGHT:-480}
LESAVKA_UVC_CODEC=${LESAVKA_UVC_CODEC:-mjpeg}
LESAVKA_UVC_BLOCKING=${LESAVKA_UVC_BLOCKING:-1}
LESAVKA_UVC_MAXBURST=${LESAVKA_UVC_MAXBURST:-0}
EOF
}
udc_state() {
local udc=""
udc=$(ls /sys/class/udc 2>/dev/null | head -n1 || true)
@ -502,20 +519,14 @@ fi
printf 'LESAVKA_UVC_CODEC=%s\n' "${LESAVKA_UVC_CODEC:-mjpeg}"
} | sudo tee /etc/lesavka/server.env >/dev/null
{
echo "# generated by lesavka/scripts/install/server.sh"
echo "# Edit only for local UVC hardware overrides; rerunning the installer refreshes defaults."
printf 'LESAVKA_UVC_DEBUG=%s\n' "${LESAVKA_UVC_DEBUG:-1}"
printf 'LESAVKA_UVC_MAXPACKET=%s\n' "${LESAVKA_UVC_MAXPACKET:-256}"
printf 'LESAVKA_UVC_LIMIT_PCT=%s\n' "${LESAVKA_UVC_LIMIT_PCT:-100}"
printf 'LESAVKA_UVC_FPS=%s\n' "${LESAVKA_UVC_FPS:-20}"
printf 'LESAVKA_UVC_INTERVAL=%s\n' "${LESAVKA_UVC_INTERVAL:-500000}"
printf 'LESAVKA_UVC_WIDTH=%s\n' "${LESAVKA_UVC_WIDTH:-640}"
printf 'LESAVKA_UVC_HEIGHT=%s\n' "${LESAVKA_UVC_HEIGHT:-480}"
printf 'LESAVKA_UVC_CODEC=%s\n' "${LESAVKA_UVC_CODEC:-mjpeg}"
printf 'LESAVKA_UVC_BLOCKING=%s\n' "${LESAVKA_UVC_BLOCKING:-1}"
printf 'LESAVKA_UVC_MAXBURST=%s\n' "${LESAVKA_UVC_MAXBURST:-0}"
} | sudo tee /etc/lesavka/uvc.env >/dev/null
UVC_ENV_TMP=$(mktemp)
render_uvc_env_file >"$UVC_ENV_TMP"
UVC_ENV_CHANGED=1
if sudo test -f /etc/lesavka/uvc.env && sudo cmp -s "$UVC_ENV_TMP" /etc/lesavka/uvc.env; then
UVC_ENV_CHANGED=0
fi
sudo install -m 0644 "$UVC_ENV_TMP" /etc/lesavka/uvc.env
rm -f "$UVC_ENV_TMP"
echo "==> 6a. Systemd units - lesavka-core"
cat <<'UNIT' | sudo tee /etc/systemd/system/lesavka-core.service >/dev/null
@ -529,7 +540,6 @@ Type=oneshot
ExecStart=/usr/local/bin/lesavka-core.sh
RemainAfterExit=yes
Environment=LESAVKA_UVC_FALLBACK=0
Environment=LESAVKA_UVC_CODEC=mjpeg
EnvironmentFile=-/etc/lesavka/server.env
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_SYS_MODULE
AmbientCapabilities=CAP_SYS_MODULE
@ -557,7 +567,6 @@ Restart=always
Environment=RUST_LOG=lesavka_server=info,lesavka_server::audio=info,lesavka_server::video=debug,lesavka_server::gadget=info
Environment=RUST_BACKTRACE=1
Environment=GST_DEBUG="*:2,alsasink:6,alsasrc:6"
Environment=LESAVKA_UVC_CODEC=mjpeg
Environment=LESAVKA_UVC_EXTERNAL=1
Environment=LESAVKA_EYE_ADAPTIVE=1
Environment=LESAVKA_EYE_MIN_FPS=12
@ -565,6 +574,7 @@ Environment=LESAVKA_EYE_FPS=20
Environment=LESAVKA_MIC_INIT_ATTEMPTS=5
Environment=LESAVKA_MIC_INIT_DELAY_MS=250
Environment=LESAVKA_ALLOW_GADGET_CYCLE=1
EnvironmentFile=-/etc/lesavka/uvc.env
EnvironmentFile=-/etc/lesavka/server.env
Restart=always
RestartSec=5
@ -581,7 +591,12 @@ sudo systemctl daemon-reload
sudo systemctl enable lesavka-core lesavka-server
UDC_STATE=$(udc_state)
if [[ -n ${LESAVKA_ALLOW_GADGET_RESET:-} ]] || ! is_attached_state "$UDC_STATE"; then
FORCE_GADGET_REBUILD=0
if [[ "$UVC_ENV_CHANGED" == "1" ]] && is_attached_state "$UDC_STATE"; then
FORCE_GADGET_REBUILD=1
echo "⚠️ UVC runtime settings changed while the host is attached; forcing a gadget rebuild so the new descriptors take effect."
fi
if [[ -n ${LESAVKA_ALLOW_GADGET_RESET:-} ]] || [[ "$FORCE_GADGET_REBUILD" == "1" ]] || ! is_attached_state "$UDC_STATE"; then
echo "⚠️ UDC state is '$UDC_STATE' - forcing a Lesavka gadget rebuild before server start."
sudo env \
LESAVKA_ALLOW_GADGET_RESET=1 \
@ -635,7 +650,8 @@ sudo rm -f /etc/systemd/system/lesavka-watchdog.timer \
sudo systemctl daemon-reload
if systemctl is-active --quiet lesavka-uvc; then
echo "✅ lesavka-uvc is active (dependency-managed; manual restart disabled)."
sudo systemctl restart lesavka-uvc
echo "✅ lesavka-uvc restarted with the refreshed UVC runtime settings."
else
echo "⚠️ lesavka-uvc is not active; start via lesavka-core dependency path."
fi

View File

@ -10,7 +10,7 @@ bench = false
[package]
name = "lesavka_server"
version = "0.14.21"
version = "0.14.22"
edition = "2024"
autobins = false

View File

@ -24,11 +24,11 @@ fn server_install_pins_hdmi_camera_and_display_defaults() {
"LESAVKA_UPSTREAM_PAIR_SLACK_US=%s",
"LESAVKA_UPSTREAM_STALE_DROP_MS=%s",
"/etc/lesavka/uvc.env",
"LESAVKA_UVC_MAXPACKET=%s",
"LESAVKA_UVC_INTERVAL=%s",
"LESAVKA_UVC_WIDTH=%s",
"LESAVKA_UVC_HEIGHT=%s",
"LESAVKA_UVC_CODEC=%s",
"LESAVKA_UVC_MAXPACKET=",
"LESAVKA_UVC_INTERVAL=",
"LESAVKA_UVC_WIDTH=",
"LESAVKA_UVC_HEIGHT=",
"LESAVKA_UVC_CODEC=",
] {
assert!(
SERVER_INSTALL.contains(expected),
@ -49,6 +49,14 @@ fn server_install_pins_hdmi_camera_and_display_defaults() {
assert!(SERVER_INSTALL.contains("${LESAVKA_UVC_WIDTH:-640}"));
assert!(SERVER_INSTALL.contains("${LESAVKA_UVC_HEIGHT:-480}"));
assert!(SERVER_INSTALL.contains("${LESAVKA_UVC_CODEC:-mjpeg}"));
assert!(
SERVER_INSTALL.contains("EnvironmentFile=-/etc/lesavka/uvc.env"),
"install script should feed live UVC runtime settings into services"
);
assert!(
!SERVER_INSTALL.contains("Environment=LESAVKA_UVC_CODEC=mjpeg"),
"install script should not pin UVC codec to mjpeg in the systemd units"
);
}
#[test]