This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

machines.coaxmetal: strom-pair re-pairs controllers with a stale bond

A pad paired to another device in the meantime still shows Bonded here, so the
old script skipped it and it never reconnected (kept shutting down / rejoining
the other host). Target pads by what actually shows up in the scan (present and
advertising in pairing mode) rather than the bonded-device list, and clear any
stale bond before re-pairing. Pads already connected and working are left
alone.

+41 -28
+41 -28
machines/coaxmetal/strom.nix
··· 66 66 # `ssh root@coaxmetal.r strom-pair`): put the pad in pairing mode (hold the 67 67 # Xbox button to power on, then hold the small round sync button on the top 68 68 # edge until the light flashes rapidly) and the script blocks until it pairs 69 - # that one fresh pad, then exits. Already-bonded pads are skipped, so just run 70 - # it again for the next controller. Bonded+trusted pads reconnect on their own 71 - # on every later boot. Pass a MAC (`strom-pair AA:BB:...`) to pair just one. 69 + # that one pad, then exits. A pad currently paired to another device is 70 + # re-paired here (its stale bond is cleared); a pad already connected and 71 + # working is left alone. Run once per controller. Bonded+trusted pads 72 + # reconnect on their own on every later boot. Pass a MAC to pair just one. 72 73 strom-pair = pkgs.writeShellApplication { 73 74 name = "strom-pair"; 74 75 runtimeInputs = [ pkgs.bluez ]; 75 76 text = '' 76 - # Find one not-yet-bonded Xbox pad, echoing its MAC (empty if none). A 77 - # foreground timed scan is reliable; a backgrounded `scan on` exits at once 78 - # without a tty and never actually scans. 79 - find_unpaired() { 80 - local m 81 - bluetoothctl --timeout 12 scan on >/dev/null 2>&1 || true 82 - mapfile -t cand < <(bluetoothctl devices 2>/dev/null | grep -i xbox | awk '{print $2}') 83 - for m in "''${cand[@]:-}"; do 77 + # Find one Xbox pad that is here right now (advertising in pairing mode) 78 + # and not already connected; echo its MAC (empty if none). We key off what 79 + # actually shows up in THIS scan, not the bonded-device list: a pad that 80 + # was since re-paired to another host still lingers as "bonded" here but 81 + # only appears in a scan when it is genuinely present and pairable. 82 + find_target() { 83 + local sl m 84 + local -a bonded present 85 + sl=$(mktemp) 86 + bluetoothctl --timeout 12 scan on > "$sl" 2>&1 || true 87 + mapfile -t bonded < <(bluetoothctl devices 2>/dev/null | grep -i xbox | awk '{print $2}') 88 + # MACs of xbox pads that showed up in this scan (present + advertising). 89 + mapfile -t present < <( 90 + { 91 + # freshly discovered pads announce their name 92 + grep -i xbox "$sl" | grep -oiE '([0-9a-f]{2}:){5}[0-9a-f]{2}' 93 + # known/bonded pads emit nameless RSSI lines; match their MAC in-scan 94 + for m in "''${bonded[@]:-}"; do 95 + [ -n "$m" ] && grep -qiF "$m" "$sl" && printf '%s\n' "$m" 96 + done 97 + } | sort -uf 98 + ) 99 + rm -f "$sl" 100 + for m in "''${present[@]:-}"; do 84 101 [ -n "$m" ] || continue 85 - bluetoothctl info "$m" 2>/dev/null | grep -q "Bonded: yes" && continue 102 + bluetoothctl info "$m" 2>/dev/null | grep -q "Connected: yes" && continue 86 103 printf '%s\n' "$m" 87 104 return 0 88 105 done ··· 91 108 92 109 # Pair one pad. Xbox controllers use JustWorks pairing, which needs a 93 110 # NoInputNoOutput agent held in the SAME bluetoothctl session as `pair` 94 - # (plus disable_ertm, set system-wide below). `connect` succeeds even when 95 - # pairing fails, so success is judged by "Bonded: yes", not by connect. 111 + # (plus disable_ertm, set system-wide below). Remove any existing bond 112 + # first: a pad re-paired to another host still shows bonded here but never 113 + # reconnects, and bluez refuses a fresh pair while that stale bond exists. 114 + # `connect` succeeds even when pairing fails, so success is judged by 115 + # "Bonded: yes", not by connect. 96 116 pair_one() { 97 117 local mac="$1" 118 + bluetoothctl remove "$mac" >/dev/null 2>&1 || true 98 119 { 99 120 echo "power on" 100 121 echo "agent NoInputNoOutput" ··· 119 140 120 141 bluetoothctl power on >/dev/null 2>&1 || true 121 142 122 - # Single-pad mode: pair exactly the given MAC and exit. 143 + # Single-pad mode: (re)pair exactly the given MAC and exit. 123 144 if [ -n "''${1:-}" ]; then 124 145 if pair_one "$1"; then 125 146 echo ">> paired, trusted, connected: $1" ··· 129 150 exit 1 130 151 fi 131 152 132 - # Default: wait for one fresh (unbonded) pad, pair it, then exit. Run once 133 - # per controller; already-bonded pads are ignored so each run grabs the 134 - # next one. 153 + # Default: wait for a pad that is present and in pairing mode, (re)pair it, 154 + # then exit. Run once per controller. A pad that was paired to another 155 + # device in the meantime is re-paired here (its stale bond is cleared) 156 + # rather than skipped; a pad already connected and working is left alone. 135 157 echo ">> put a controller in pairing mode: hold the Xbox button to power" 136 158 echo " on, then hold the small round sync button on the top edge until" 137 159 echo " the light flashes rapidly. Waiting... (Ctrl-C to abort)" 138 160 while true; do 139 161 echo ">> scanning..." 140 - mac=$(find_unpaired) 141 - # Show which Xbox pads are visible and whether they are already bonded, 142 - # so it's obvious if the pad is being detected at all. 143 - bluetoothctl devices 2>/dev/null | grep -i xbox | while read -r _ m _; do 144 - if bluetoothctl info "$m" 2>/dev/null | grep -q "Bonded: yes"; then 145 - echo " seen $m (already bonded, skipping)" 146 - else 147 - echo " seen $m (pairable)" 148 - fi 149 - done 162 + mac=$(find_target) 150 163 if [ -n "$mac" ]; then 151 164 printf '>> pairing %s ... ' "$mac" 152 165 if pair_one "$mac"; then