fix(server): map eye links from distinct capture nodes
This commit is contained in:
parent
76a6df4f60
commit
97abb938c5
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -1642,7 +1642,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lesavka_client"
|
name = "lesavka_client"
|
||||||
version = "0.13.15"
|
version = "0.13.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-stream",
|
"async-stream",
|
||||||
@ -1676,7 +1676,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lesavka_common"
|
name = "lesavka_common"
|
||||||
version = "0.13.15"
|
version = "0.13.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
@ -1688,7 +1688,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lesavka_server"
|
name = "lesavka_server"
|
||||||
version = "0.13.15"
|
version = "0.13.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
|
|||||||
@ -4,7 +4,7 @@ path = "src/main.rs"
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "lesavka_client"
|
name = "lesavka_client"
|
||||||
version = "0.13.15"
|
version = "0.13.16"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "lesavka_common"
|
name = "lesavka_common"
|
||||||
version = "0.13.15"
|
version = "0.13.16"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
|
|||||||
@ -320,49 +320,43 @@ if systemctl list-unit-files | grep -q '^relay.service'; then
|
|||||||
sleep 2
|
sleep 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# probe v4l2 devices for GC311s (07ca:3311)
|
mapfile -t GC_CAPTURE_PAIRS < <(
|
||||||
mapfile -t GC_VIDEOS < <(
|
for dev in /dev/video*; do
|
||||||
sudo v4l2-ctl --list-devices 2>/dev/null |
|
props=$(sudo udevadm info -q property -n "$dev" 2>/dev/null || true)
|
||||||
awk '/Live Gamer MINI/{getline; print $1}'
|
index=$(cat "/sys/class/video4linux/$(basename "$dev")/index" 2>/dev/null || true)
|
||||||
|
if echo "$props" | grep -q 'ID_VENDOR_ID=07ca' \
|
||||||
|
&& echo "$props" | grep -q 'ID_MODEL_ID=3311' \
|
||||||
|
&& [ "$index" = "0" ]; then
|
||||||
|
tag=$(printf '%s\n' "$props" | awk -F= '/^ID_PATH_TAG=/{print $2}')
|
||||||
|
if [ -n "$tag" ]; then
|
||||||
|
printf '%s %s\n' "$tag" "$dev"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done | sort -u
|
||||||
)
|
)
|
||||||
|
|
||||||
# fallback via udev if v4l2-ctl output is empty/partial
|
if [ "${#GC_CAPTURE_PAIRS[@]}" -ne 2 ]; then
|
||||||
if [ "${#GC_VIDEOS[@]}" -ne 2 ]; then
|
|
||||||
mapfile -t GC_VIDEOS < <(
|
|
||||||
for dev in /dev/video*; do
|
|
||||||
props=$(sudo udevadm info -q property -n "$dev" 2>/dev/null || true)
|
|
||||||
if echo "$props" | grep -q 'ID_VENDOR_ID=07ca' && echo "$props" | grep -q 'ID_MODEL_ID=3311'; then
|
|
||||||
echo "$dev"
|
|
||||||
fi
|
|
||||||
done | sort -u
|
|
||||||
)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${#GC_VIDEOS[@]}" -ne 2 ]; then
|
|
||||||
echo "⚠️ GC311 capture cards not fully present; skipping udev eye-link refresh." >&2
|
echo "⚠️ GC311 capture cards not fully present; skipping udev eye-link refresh." >&2
|
||||||
if [ "${#GC_VIDEOS[@]}" -eq 0 ]; then
|
if [ "${#GC_CAPTURE_PAIRS[@]}" -eq 0 ]; then
|
||||||
echo " Detected: none" >&2
|
echo " Detected: none" >&2
|
||||||
else
|
else
|
||||||
printf ' Detected: %s\n' "${GC_VIDEOS[@]}" >&2
|
printf ' Detected: %s\n' "${GC_CAPTURE_PAIRS[@]}" >&2
|
||||||
fi
|
fi
|
||||||
echo " The server install will continue, and existing /dev/lesavka_* links stay untouched." >&2
|
echo " The server install will continue, and existing /dev/lesavka_* links stay untouched." >&2
|
||||||
else
|
else
|
||||||
mapfile -t TAGS < <(
|
LEFT_TAG=${GC_CAPTURE_PAIRS[0]%% *}
|
||||||
for v in "${GC_VIDEOS[@]}"; do
|
LEFT_DEV=${GC_CAPTURE_PAIRS[0]#* }
|
||||||
sudo udevadm info -q property -n "$v" |
|
RIGHT_TAG=${GC_CAPTURE_PAIRS[1]%% *}
|
||||||
awk -F= '/^ID_PATH_TAG=/{print $2}'
|
RIGHT_DEV=${GC_CAPTURE_PAIRS[1]#* }
|
||||||
done
|
|
||||||
)
|
|
||||||
|
|
||||||
if [ -z "${TAGS[0]:-}" ] || [ -z "${TAGS[1]:-}" ]; then
|
if [ -z "$LEFT_TAG" ] || [ -z "$RIGHT_TAG" ] || [ "$LEFT_TAG" = "$RIGHT_TAG" ]; then
|
||||||
echo "⚠️ GC311 cards were detected, but ID_PATH_TAG lookup was incomplete." >&2
|
echo "⚠️ GC311 cards were detected, but the capture path tags are incomplete or duplicated." >&2
|
||||||
|
printf ' Left candidate: %s\n' "${GC_CAPTURE_PAIRS[0]:-missing}" >&2
|
||||||
|
printf ' Right candidate: %s\n' "${GC_CAPTURE_PAIRS[1]:-missing}" >&2
|
||||||
echo " Skipping udev eye-link refresh and preserving any existing /dev/lesavka_* links." >&2
|
echo " Skipping udev eye-link refresh and preserving any existing /dev/lesavka_* links." >&2
|
||||||
else
|
else
|
||||||
printf ' ↪ Left card: %s (%s)\n' "${GC_VIDEOS[0]}" "${TAGS[0]}"
|
printf ' ↪ Left card: %s (%s)\n' "$LEFT_DEV" "$LEFT_TAG"
|
||||||
printf ' ↪ Right card: %s (%s)\n' "${GC_VIDEOS[1]}" "${TAGS[1]}"
|
printf ' ↪ Right card: %s (%s)\n' "$RIGHT_DEV" "$RIGHT_TAG"
|
||||||
|
|
||||||
LEFT_TAG=${TAGS[0]}
|
|
||||||
RIGHT_TAG=${TAGS[1]}
|
|
||||||
|
|
||||||
sudo tee /etc/udev/rules.d/85-gc311.rules >/dev/null <<EOF
|
sudo tee /etc/udev/rules.d/85-gc311.rules >/dev/null <<EOF
|
||||||
# auto-generated by lesavka/scripts/daemon/install-server.sh - DO NOT EDIT
|
# auto-generated by lesavka/scripts/daemon/install-server.sh - DO NOT EDIT
|
||||||
|
|||||||
@ -10,7 +10,7 @@ bench = false
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "lesavka_server"
|
name = "lesavka_server"
|
||||||
version = "0.13.15"
|
version = "0.13.16"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
autobins = false
|
autobins = false
|
||||||
|
|
||||||
|
|||||||
@ -55,3 +55,19 @@ fn server_install_grants_operator_audio_group_access() {
|
|||||||
"install script should target the sudo-invoking operator instead of a hard-coded account"
|
"install script should target the sudo-invoking operator instead of a hard-coded account"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn server_install_builds_eye_links_from_capture_nodes_only() {
|
||||||
|
assert!(
|
||||||
|
SERVER_INSTALL.contains("/sys/class/video4linux/$(basename \"$dev\")/index"),
|
||||||
|
"install script should inspect the kernel video index so it only links real capture nodes"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
SERVER_INSTALL.contains("GC_CAPTURE_PAIRS"),
|
||||||
|
"install script should assemble eye-link candidates from udev-tagged capture devices"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
SERVER_INSTALL.contains("[ \"$LEFT_TAG\" = \"$RIGHT_TAG\" ]"),
|
||||||
|
"install script should refuse duplicated path tags instead of assigning both eyes to one card"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user