#!/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$'; } anzahl_geraete() { adb_geraete | wc -l | tr -d ' '; } # Nach dem Koppeln reicht "irgendein Gerät verbunden" als Erfolgsnachweis nicht: # beim Hinzufügen eines zweiten Telefons wäre das erste ja noch da. Es zählt nur, # ob EIN GERÄT DAZUGEKOMMEN ist. GERAETE_VORHER=0 neues_geraet() { [ "$(anzahl_geraete)" -gt "$GERAETE_VORHER" ]; } # 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? ───────────────────────────────────────────────────────── # Ein bereits verbundenes Gerät darf kein Grund sein auszusteigen: ein zweites # Telefon dazuzunehmen ist ein völlig normaler Wunsch, etwa beim Gerätewechsel, # wenn altes und neues Gerät gleichzeitig erreichbar sein müssen. kopf "Aktueller Stand" if ist_verbunden; then ok "Verbundene Geräte:" while IFS= read -r S; do [ -n "$S" ] && printf ' %-24s %s\n' "$S" "$(geraet_beschreiben "$S")" done < <(adb_geraete) cat <<'TEXT' Was möchtest du tun? [w] weiter zur Einrichtung (provision.sh übernimmt die Auswahl) [n] ein weiteres Gerät hinzufügen (Kopplung oder Verbindung) [t] ein verbundenes Gerät trennen [a] abbrechen TEXT printf '\n Auswahl [w] > ' read -r AKTION ' read -r TRENNEN ' read -r SCHON_GEKOPPELT ' read -r _ ' read -r CODE