From 60cee23d08c54f532783667b6fcffdea0e41fe11 Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Sat, 28 Jun 2025 17:07:39 -0500 Subject: [PATCH] fixes --- scripts/install-server.sh | 130 -------------------------------------- scripts/install/server.sh | 2 +- scripts/lesavka-core.sh | 114 --------------------------------- server/src/main.rs | 2 +- 4 files changed, 2 insertions(+), 246 deletions(-) delete mode 100644 scripts/install-server.sh delete mode 100644 scripts/lesavka-core.sh diff --git a/scripts/install-server.sh b/scripts/install-server.sh deleted file mode 100644 index 09c088b..0000000 --- a/scripts/install-server.sh +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env bash -# install-server.sh - install and setup all server related apps and environments -set -euo pipefail -ORIG_USER=${SUDO_USER:-$(id -un)} - -echo "==> 1a. Base packages" -sudo pacman -Syq --needed --noconfirm git rustup protobuf gcc pipewire pipewire-pulse tailscale base-devel gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav -if ! command -v yay >/dev/null 2>&1; then - echo "==> 1b. installing yay from AUR ..." - sudo -u "$ORIG_USER" bash -c ' - cd /tmp && git clone --depth 1 https://aur.archlinux.org/yay.git && - cd yay && makepkg -si --noconfirm' -fi -yay -S --noconfirm grpcurl-bin - -echo "==> 2a. Kernel-driver tweaks" -cat <<'EOF' | sudo tee /etc/modprobe.d/gc311-stream.conf >/dev/null -options uvcvideo quirks=0x200 timeout=10000 -EOF - -echo "==> 2b. Predictable /dev names for each capture card" -# probe all v4l2 devices, keep only the two GC311 capture cards -mapfile -t GC_VIDEOS < <( - sudo v4l2-ctl --list-devices | - awk '/Live Gamer MINI/{getline; print $1}' -) - -if [ "${#GC_VIDEOS[@]}" -ne 2 ]; then - echo "❌ Exactly two GC311 capture cards (index0) must be attached!" >&2 - printf ' Detected: %s\n' "${GC_VIDEOS[@]}" - exit 1 -fi - -mapfile -t TAGS < <( - for v in "${GC_VIDEOS[@]}"; do - sudo udevadm info -q property -n "$v" | - awk -F= '/^ID_PATH_TAG=/{print $2}' - done -) - -printf ' ↪ Left card: %s (%s)\n' "${GC_VIDEOS[0]}" "${TAGS[0]}" -printf ' ↪ Right card: %s (%s)\n' "${GC_VIDEOS[1]}" "${TAGS[1]}" - -LEFT_TAG=${TAGS[0]} -RIGHT_TAG=${TAGS[1]} - -sudo tee /etc/udev/rules.d/85-gc311.rules >/dev/null < 3. Rust toolchain" -sudo rustup default stable -sudo -u "$ORIG_USER" rustup default stable - -echo "==> 4a. Source checkout" -SRC_DIR=/var/src/lesavka -REPO_URL=ssh://git@scm.bstein.dev:2242/brad_stein/lesavka.git -if [[ ! -d $SRC_DIR ]]; then - sudo mkdir -p /var/src - sudo chown "$ORIG_USER":"$ORIG_USER" /var/src -fi -if [[ -d $SRC_DIR/.git ]]; then - sudo -u "$ORIG_USER" git -C "$SRC_DIR" pull --ff-only -else - sudo -u "$ORIG_USER" git clone "$REPO_URL" "$SRC_DIR" -fi - -echo "==> 4b. Source build" -sudo -u "$ORIG_USER" bash -c "cd '$SRC_DIR/server' && cargo clean && cargo build --release" - -echo "==> 5. Install binaries" -sudo install -Dm755 "$SRC_DIR/server/target/release/lesavka-server" /usr/local/bin/lesavka-server -sudo install -Dm755 "$SRC_DIR/scripts/lesavka-core.sh" /usr/local/bin/lesavka-core.sh - -echo "==> 6a. Systemd units - lesavka-core" -cat <<'UNIT' | sudo tee /etc/systemd/system/lesavka-core.service >/dev/null -[Unit] -Description=lesavka USB gadget bring-up -After=sys-kernel-config.mount -Requires=sys-kernel-config.mount - -[Service] -Type=oneshot -ExecStart=/usr/local/bin/lesavka-core.sh -RemainAfterExit=yes -CapabilityBoundingSet=CAP_SYS_ADMIN -MountFlags=slave - -[Install] -WantedBy=multi-user.target -UNIT - -echo "==> 6b. Systemd units - lesavka-server" -cat <<'UNIT' | sudo tee /etc/systemd/system/lesavka-server.service >/dev/null -[Unit] -Description=lesavka gRPC relay -After=network.target lesavka-core.service - -[Service] -ExecStart=/usr/local/bin/lesavka-server -Restart=always -Environment=RUST_LOG=lesavka_server=debug,lesavka_server::usb_gadget=info -Environment=RUST_BACKTRACE=1 -Restart=always -RestartSec=5 -StandardError=append:/tmp/lesavka-server.log -StartLimitIntervalSec=30 -StartLimitBurst=10 -User=root - -[Install] -WantedBy=multi-user.target -UNIT - -echo "==> 6c. Systemd units - initialization" -sudo truncate -s 0 /tmp/lesavka-server.log -sudo systemctl daemon-reload -sudo systemctl enable --now lesavka-core -sudo systemctl restart lesavka-core -echo "✅ lesavka-core installed and restarted..." - -sudo systemctl enable --now lesavka-server -sudo systemctl restart lesavka-server -echo "✅ lesavka-server installed and restarted..." diff --git a/scripts/install/server.sh b/scripts/install/server.sh index a357a97..bc632b3 100755 --- a/scripts/install/server.sh +++ b/scripts/install/server.sh @@ -105,7 +105,7 @@ After=network.target lesavka-core.service [Service] ExecStart=/usr/local/bin/lesavka-server Restart=always -Environment=RUST_LOG=lesavka_server=info,lesavka_server::video=trace,lesavka_server::usb_gadget=info +Environment=RUST_LOG=lesavka_server=trace,lesavka_server::video=trace,lesavka_server::usb_gadget=info Environment=RUST_BACKTRACE=1 Restart=always RestartSec=5 diff --git a/scripts/lesavka-core.sh b/scripts/lesavka-core.sh deleted file mode 100644 index dd2009a..0000000 --- a/scripts/lesavka-core.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env bash -# lesavka-core.sh - background stealth daemon to present gadget as usb hub of genuine devices -# Proven Pi-5 configfs gadget: HID keyboard+mouse -# Still need Web Cam Support + stereo UAC2 - -# lesavka-core - one-shot gadget bring-up for Pi-5 / Arch-ARM -set -euo pipefail - -# 1) Ensure the dwc2 peripheral overlay is active exactly once -CFG=/boot/config.txt -grep -q 'dtoverlay=dwc2,dr_mode=peripheral' "$CFG" || echo 'dtoverlay=dwc2,dr_mode=peripheral' >> "$CFG" - -# 2) Load kernel modules (idempotent) -modprobe dwc2 || { echo "dwc2 not in kernel; abort" >&2; exit 1; } -modprobe libcomposite || { echo "libcomposite not in kernel; abort" >&2; exit 1; } - -modprobe -r uvcvideo 2>/dev/null || true -modprobe uvcvideo || { echo "uvcvideo not in kernel; abort" >&2; exit 1; } - -udevadm control --reload -udevadm trigger --subsystem-match=video4linux -udevadm settle - -echo "[lesavka-core] ⏳ waiting for UDC to register ..." -UDC="" -for _ in {1..100}; do # 100 × 100ms = 10s - UDC=$(ls /sys/class/udc 2>/dev/null | head -n1) && [[ -n $UDC ]] && break - sleep 0.1 -done - -if [[ -z $UDC ]]; then - echo "[lesavka-core] ⚠️ UDC still absent - trying manual bind" - for drv in dwc2 dwc3; do - drv_root="/sys/bus/platform/drivers/$drv" - [[ -d $drv_root ]] || continue - for node in /sys/bus/platform/devices/*usb*; do - node=${node##*/} # strip path → “1000480000.usb” - echo "$node" >"$drv_root/bind" 2>/dev/null || continue - done - done - # re-check for another 5 s - for i in {1..50}; do - UDC=$(ls /sys/class/udc 2>/dev/null | head -n1) && [[ -n $UDC ]] && break - sleep 0.1 - done -fi - -[[ -n $UDC ]] || { echo "❌ UDC not present after manual bind"; exit 1; } -echo "[lesavka-core] ✅ UDC detected: $UDC" - -# 3) Mount configfs once -mountpoint -q /sys/kernel/config || mount -t configfs none /sys/kernel/config -G=/sys/kernel/config/usb_gadget/lesavka - -# 4) Tear down any previous half-built gadget -if [[ -d $G ]]; then - echo '' >"$G/UDC" 2>/dev/null || true - sleep 0.2 - find "$G/configs" -type l -delete 2>/dev/null || true - rm -rf "$G" 2>/dev/null || true -fi - -# 5) Create gadget (boot-keyboard + UAC2 mic/spkr, 500 mA max) -mkdir -p "$G" -echo 0x1d6b >"$G/idVendor" # Linux Foundation -echo 0x0104 >"$G/idProduct" # Multifunction Composite Gadget -echo 0x0200 >"$G/bcdUSB" - -mkdir -p "$G/strings/0x409" -echo "$(cat /proc/sys/kernel/random/uuid)" >"$G/strings/0x409/serialnumber" -echo "Lesavka" >"$G/strings/0x409/manufacturer" -echo "Lesavka Composite" >"$G/strings/0x409/product" - -# ----------------------- HID keyboard (usb0) ----------------------- -mkdir -p "$G/functions/hid.usb0" -echo 1 >"$G/functions/hid.usb0/protocol" -echo 1 >"$G/functions/hid.usb0/subclass" -echo 8 >"$G/functions/hid.usb0/report_length" -printf '\x05\x01\x09\x06\xa1\x01\x05\x07\x19\xe0\x29\xe7\x15\x00\x25\x01'\ -'\x75\x01\x95\x08\x81\x02\x95\x01\x75\x08\x81\x01\x95\x05\x75\x01\x05'\ -'\x08\x19\x01\x29\x05\x91\x02\x95\x01\x75\x03\x91\x01\x95\x06\x75\x08'\ -'\x15\x00\x25\x65\x05\x07\x19\x00\x29\x65\x81\x00\xc0' \ - >"$G/functions/hid.usb0/report_desc" - -# ----------------------- HID mouse (usb1) -------------------------- -mkdir -p "$G/functions/hid.usb1" -echo 2 > "$G/functions/hid.usb1/protocol" # Boot mouse -echo 1 > "$G/functions/hid.usb1/subclass" -echo 4 > "$G/functions/hid.usb1/report_length" -printf '\x05\x01\x09\x02\xa1\x01\x09\x01\xa1\x00'\ -'\x05\x09\x19\x01\x29\x03\x15\x00\x25\x01\x95\x03\x75\x01\x81\x02'\ -'\x95\x01\x75\x05\x81\x03'\ -'\x05\x01\x09\x30\x09\x31\x09\x38\x15\x81\x25\x7f\x75\x08\x95\x03\x81\x06'\ -'\xc0\xc0' >"$G/functions/hid.usb1/report_desc" - -# # -- UAC2 Audio -# mkdir -p $G/functions/uac2.usb0 -# echo 48000 > $G/functions/uac2.usb0/c_srate -# echo 2 > $G/functions/uac2.usb0/c_ssize -# echo 2 > $G/functions/uac2.usb0/p_chmask - -# ----------------------- configuration ----------------------------- -mkdir -p "$G/configs/c.1/strings/0x409" -echo 500 > "$G/configs/c.1/MaxPower" -echo "Config 1" > "$G/configs/c.1/strings/0x409/configuration" - -# 6) Finally bind to first available UDC -ln -s $G/functions/hid.usb0 $G/configs/c.1/ -ln -s $G/functions/hid.usb1 $G/configs/c.1/ -# ln -s $G/functions/uac2.usb0 $G/configs/c.1/ - -# 7) Finally bind to first available UDC -echo "$UDC" > "$G/UDC" -echo "[lesavka-core] 🎉 gadget ready on $UDC (keyboard: hidg0, mouse: hidg1)" diff --git a/server/src/main.rs b/server/src/main.rs index eb06437..f9968de 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -34,7 +34,7 @@ const AUTO_CYCLE: bool = false; /*──────────────── logging ───────────────────*/ fn init_tracing() -> anyhow::Result { let file = std::fs::OpenOptions::new() - .create(true).append(true).write(true) + .create(true).truncate(true).write(true) .open("/tmp/lesavka-server.log")?; let (file_writer, guard) = tracing_appender::non_blocking(file);