#!/usr/bin/env bash # HPOS — ADB über WLAN verbinden, ohne USB-Kabel. # # Android 11 und neuer bringen "Wireless Debugging" mit: einmal per sechsstelligem # Code koppeln, danach verbindet sich adb über das Netz. Ein Kabel wird nie gebraucht. # # Zwei Dinge, die regelmäßig für Verwirrung sorgen und die dieses Skript deshalb # auseinanderhält: # # · Die KOPPLUNG bleibt dauerhaft bestehen. Nur die VERBINDUNG geht verloren, # und der Port wechselt bei jedem Einschalten. Ein zweiter Kopplungscode wird # daher nie gebraucht — deshalb wird immer erst ein Verbindungsversuch gemacht. # · Kopplungsport und Verbindungsport sind VERSCHIEDEN. Der eine steht im # Kopplungsfenster, der andere auf der Hauptseite von "Drahtloses Debugging". # # Aufruf: ./provision/adb-wireless.sh # Umgebung: HPOS_ADB_MANUELL=1 überspringt die mDNS-Suche und fragt direkt nach # der Adresse (nützlich, wenn das Netz kein # Multicast durchlässt) set -uo pipefail source "$(dirname "$0")/lib.sh" # Das Skript lebt von Rückfragen und liest bewusst aus /dev/tty statt von stdin — # sonst würde eine Pipe die Antworten wegfressen. Ohne Terminal ist das aussichtslos, # und ein klarer Hinweis ist besser als eine Kette von /dev/tty-Fehlern. # Umleitungen wertet bash von links nach rechts aus — 2>/dev/null muss deshalb VOR # dem Schreibversuch stehen, sonst landet der Fehler trotzdem auf dem Bildschirm. if ! { : 2>/dev/null >/dev/tty; }; then fehl "Dieses Skript braucht ein Terminal für die Rückfragen." hinweis "Bitte direkt in einer Shell aufrufen, nicht in einer Pipe oder aus einem Dienst." exit 1 fi kopf "Werkzeug" if adb_einrichten; then ok "adb $(adb_version "$ADB_BIN") — kann WLAN-Kopplung" hinweis "$ADB_BIN" else fehl "Ohne 'adb pair' ist eine Kopplung über WLAN nicht möglich." hinweis "Entweder aktuelle platform-tools installieren, oder doch ein Kabel besorgen." exit 1 fi adb start-server >/dev/null 2>&1 # ── Hilfsmittel ────────────────────────────────────────────────────────────── ist_verbunden() { adb devices | grep -qw 'device$'; } # Sucht einen mDNS-Dienst und gibt HOST:PORT zurück. Der Kopplungsdienst wird nur # angekündigt, solange der Kopplungsdialog auf dem Telefon offen ist — deshalb wird # wiederholt gesucht statt einmal. suche_dienst() { local typ="$1" versuche="${2:-15}" i zeile for ((i = 1; i <= versuche; i++)); do zeile=$(adb mdns services 2>/dev/null | awk -v t="$typ" '$2 == t {print $3; exit}') if [ -n "$zeile" ]; then printf '%s' "$zeile"; return 0; fi printf '.' >&2 sleep 1 done return 1 } plausibel() { case "$1" in *:[0-9]*) return 0 ;; *) return 1 ;; esac } # Wie die Adresse ermittelt wird — einmal gefragt, dann für beide Schritte gemerkt. # mDNS ist bequem, scheitert aber in Netzen, die Multicast filtern. Das ist keine # Seltenheit und kein Fehler des Nutzers, deshalb steht die manuelle Eingabe # gleichberechtigt daneben statt nur als Notnagel nach einer Wartezeit. ADRESS_MODUS="${HPOS_ADB_MANUELL:+manuell}" modus_erfragen() { [ -n "$ADRESS_MODUS" ] && return 0 { printf '\n Wie soll die Adresse ermittelt werden?\n\n' printf ' [m] automatisch per mDNS (bequem, scheitert in manchen Netzen)\n' printf ' [e] von Hand eingeben (Adresse steht auf dem Telefon)\n\n' printf ' Auswahl [m] > ' } >&2 local wahl read -r wahl &2 if ziel=$(suche_dienst "$typ" "$wartezeit"); then printf '\n' >&2 ok "gefunden: $ziel" >&2 printf '%s' "$ziel" return 0 fi printf '\n' >&2 warn "Per mDNS nichts gefunden." >&2 hinweis "Viele Netze filtern Multicast — dann hilft nur die Eingabe von Hand." >&2 ADRESS_MODUS=manuell continue fi hinweis "$wo" >&2 printf ' Adresse eingeben (IP:PORT), [m] für mDNS, leer für Abbruch > ' >&2 read -r ziel &2 hinweis "Beispiel: 192.168.178.42:37123" >&2 done } weiter_mit_provision() { adb devices | grep -w 'device$' | sed 's/^/ /' kopf "Fertig" cat <<'TEXT' Weiter mit: ./provision/provision.sh Für später: die Kopplung bleibt bestehen. Nach einem Neustart oder nach dem Aus- und Einschalten von "Drahtloses Debugging" ändert sich nur der Port — dann genügt dieses Skript erneut, ohne neuen Code. ADB wird in diesem Projekt nur für die Ersteinrichtung gebraucht. Im Dauerbetrieb kommt HPOS ohne Privilegienkanal aus. Trennen mit: adb disconnect TEXT } WO_VERBINDUNG="Auf dem Telefon: Drahtloses Debugging → 'IP-Adresse und Port' (Hauptseite)" WO_KOPPLUNG="Auf dem Telefon: im Fenster 'Mit Kopplungscode koppeln' (ANDERER Port!)" # ── Schon verbunden? ───────────────────────────────────────────────────────── kopf "Aktueller Stand" if ist_verbunden; then ok "Es ist bereits ein Gerät verbunden." weiter_mit_provision exit 0 fi # ── Erst verbinden, dann erst koppeln ──────────────────────────────────────── # Wer schon einmal gekoppelt hat, braucht keinen neuen Code, sondern nur ein neues # connect. Ohne diesen Schritt landet man bei jedem Aufruf wieder im Kopplungsdialog. hinweis "Kein Gerät verbunden." printf '\n Wurde dieses Telefon hier schon einmal gekoppelt? [j/N] > ' read -r SCHON_GEKOPPELT ' read -r _ ' read -r CODE