#!/usr/bin/env bash # navka-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 # navka-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; } # 3) Mount configfs once mountpoint -q /sys/kernel/config || mount -t configfs none /sys/kernel/config G=/sys/kernel/config/usb_gadget/navka # 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 "Navka" >"$G/strings/0x409/manufacturer" echo "Navka Composite" >"$G/strings/0x409/product" # HID (boot keyboard) 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" # usb1 = mouse mkdir -p "$G/functions/hid.usb1" echo 2 > "$G/functions/hid.usb1/protocol" echo 1 > "$G/functions/hid.usb1/subclass" echo 4 > "$G/functions/hid.usb1/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' \ > 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 # -- Config 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" # -- Bindings ln -s $G/functions/hid.usb0 $G/configs/c.1/ # ln -s $G/functions/uac2.usb0 $G/configs/c.1/ # 6) Finally bind to first available UDC echo $(ls /sys/class/udc | head -n1) > $G/UDC echo "[navka-core] gadget ready on USB-C port"