mirror of
git://f0xx.org/ac/ac-scripts
synced 2026-07-29 02:19:10 +03:00
feat(adb): improve wireless reconnect with pairing hints
Expand adb-reconnect.sh with TLS pairing guidance, dedupe, and safer cache handling for Android 11+ wireless debugging. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
168
adb-reconnect.sh
168
adb-reconnect.sh
@@ -8,8 +8,8 @@
|
||||
: "${ADB_TCP_PROBE:=yes}"
|
||||
: "${ADB_TCP_PROBE_SEC:=1}"
|
||||
: "${DEV_ADB_HTTP_PORT:=5039}"
|
||||
: "${ADB_CONNECT_CACHE:=$ROOT/.adb_connect_cache}"
|
||||
: "${ADB_HTTP_CACHE_DIR:=$ROOT/.adb_http_cache}"
|
||||
: "${ADB_CONNECT_CACHE:=${ROOT:-.}/.adb_connect_cache}"
|
||||
: "${ADB_HTTP_CACHE_DIR:=${ROOT:-.}/.adb_http_cache}"
|
||||
: "${ADB_RECONNECT_POKE_DELAY_SEC:=2}"
|
||||
: "${ADB_MDNS_AUTO_CONNECT:=adb-tls-connect,adb}"
|
||||
: "${ADB_KILL_SERVER:=no}"
|
||||
@@ -96,7 +96,7 @@ adb_json_connect_lines() {
|
||||
local json=${1}
|
||||
[[ -n "$json" ]] || return 0
|
||||
printf '%s' "$json" | python3 -c '
|
||||
import json, sys
|
||||
import json, sys, re
|
||||
raw = sys.stdin.read()
|
||||
if not raw.strip():
|
||||
raise SystemExit(0)
|
||||
@@ -104,23 +104,51 @@ try:
|
||||
data = json.loads(raw)
|
||||
except json.JSONDecodeError:
|
||||
raise SystemExit(0)
|
||||
IP_PORT = re.compile(r"^\d{1,3}(?:\.\d{1,3}){3}:\d+$")
|
||||
seen = set()
|
||||
def emit(ep):
|
||||
if ep and IP_PORT.match(ep) and ep not in seen:
|
||||
seen.add(ep)
|
||||
print(ep)
|
||||
tls = int(data.get("tls_port") or 0)
|
||||
if tls > 0:
|
||||
for ip in data.get("ips") or []:
|
||||
if ip:
|
||||
print(f"{ip}:{tls}")
|
||||
import re
|
||||
IP_PORT = re.compile(r"^\d{1,3}(?:\.\d{1,3}){3}:\d+$")
|
||||
def ok(ep):
|
||||
return bool(ep and IP_PORT.match(ep))
|
||||
emit(f"{ip}:{tls}")
|
||||
for item in data.get("connect") or []:
|
||||
if ok(item):
|
||||
print(item)
|
||||
emit(item)
|
||||
for item in data.get("commands") or []:
|
||||
if isinstance(item, str) and item.startswith("adb connect "):
|
||||
ep = item[len("adb connect "):]
|
||||
if ok(ep):
|
||||
emit(item[len("adb connect "):])
|
||||
' 2>/dev/null || true
|
||||
}
|
||||
|
||||
adb_json_pairing_lines() {
|
||||
local json=${1}
|
||||
[[ -n "$json" ]] || return 0
|
||||
printf '%s' "$json" | python3 -c '
|
||||
import json, sys, re
|
||||
raw = sys.stdin.read()
|
||||
if not raw.strip():
|
||||
raise SystemExit(0)
|
||||
try:
|
||||
data = json.loads(raw)
|
||||
except json.JSONDecodeError:
|
||||
raise SystemExit(0)
|
||||
IP_PORT = re.compile(r"^\d{1,3}(?:\.\d{1,3}){3}:\d+$")
|
||||
seen = set()
|
||||
def emit(ep):
|
||||
if ep and IP_PORT.match(ep) and ep not in seen:
|
||||
seen.add(ep)
|
||||
print(ep)
|
||||
pair = int(data.get("pairing_port") or 0)
|
||||
if pair > 0:
|
||||
for ip in data.get("ips") or []:
|
||||
if ip:
|
||||
emit(f"{ip}:{pair}")
|
||||
for item in data.get("pair_commands") or []:
|
||||
if isinstance(item, str) and item.startswith("adb pair "):
|
||||
emit(item[len("adb pair "):])
|
||||
' 2>/dev/null || true
|
||||
}
|
||||
|
||||
@@ -175,6 +203,14 @@ adb_discover_avahi_endpoints() {
|
||||
done
|
||||
}
|
||||
|
||||
adb_discover_avahi_pairing_endpoints() {
|
||||
command -v avahi-browse >/dev/null 2>&1 || return 0
|
||||
avahi-browse -rpt _adb-tls-pairing._tcp 2>/dev/null | awk -F';' '
|
||||
$1 == "=" && $3 == "IPv4" && $8 ~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/ && $9 ~ /^[0-9]+$/ {
|
||||
print $8 ":" $9
|
||||
}'
|
||||
}
|
||||
|
||||
adb_pull_device_json_endpoints() {
|
||||
local serial json tmp
|
||||
while IFS= read -r serial; do
|
||||
@@ -191,6 +227,60 @@ adb_pull_device_json_endpoints() {
|
||||
done < <(adb devices 2>/dev/null | awk 'NR > 1 && $2 == "device" { print $1 }')
|
||||
}
|
||||
|
||||
adb_connect_failure_hint() {
|
||||
local endpoint=${1}
|
||||
local out=${2}
|
||||
local host ip json pair_ep
|
||||
host="$(adb_endpoint_host "$endpoint")"
|
||||
[[ -n "$host" ]] || return 0
|
||||
if [[ "$out" != *"failed to connect"* && "$out" != *"failed to authenticate"* ]]; then
|
||||
return 0
|
||||
fi
|
||||
echo " hint: Android 11+ wireless adb requires one-time TLS pairing on this PC." >&2
|
||||
json="$(adb_curl_adb_json "$host" 2>/dev/null || true)"
|
||||
if [[ -n "$json" ]]; then
|
||||
while IFS= read -r pair_ep; do
|
||||
[[ -z "$pair_ep" ]] && continue
|
||||
echo " 1) On device: Developer options → Wireless debugging → Pair device with pairing code" >&2
|
||||
echo " 2) adb pair ${pair_ep} (enter 6-digit code when prompted)" >&2
|
||||
echo " 3) adb connect ${endpoint}" >&2
|
||||
return 0
|
||||
done < <(adb_json_pairing_lines "$json")
|
||||
fi
|
||||
while IFS= read -r pair_ep; do
|
||||
[[ -z "$pair_ep" ]] && continue
|
||||
echo " pairing (avahi): adb pair ${pair_ep}" >&2
|
||||
return 0
|
||||
done < <(adb_discover_avahi_pairing_endpoints | grep "^${host}:" || true)
|
||||
echo " Open Wireless debugging → Pair device; then: ADB_PAIR_CODE=123456 $0 adb_pair ${host}" >&2
|
||||
}
|
||||
|
||||
adb_pair_device() {
|
||||
local ip=${1}
|
||||
local code=${2:-${ADB_PAIR_CODE:-}}
|
||||
local pair_ep json
|
||||
[[ -n "$ip" ]] || { echo "usage: adb_pair IP [6-digit-code]" >&2; return 1; }
|
||||
json="$(adb_curl_adb_json "$ip" 2>/dev/null || true)"
|
||||
pair_ep="$(adb_json_pairing_lines "$json" 2>/dev/null | grep "^${ip}:" | head -1 || true)"
|
||||
if [[ -z "$pair_ep" ]]; then
|
||||
pair_ep="$(adb_discover_avahi_pairing_endpoints | grep "^${ip}:" | head -1 || true)"
|
||||
fi
|
||||
if [[ -z "$pair_ep" && -n "${ADB_PAIRING_PORT:-}" ]]; then
|
||||
pair_ep="${ip}:${ADB_PAIRING_PORT}"
|
||||
fi
|
||||
if [[ -z "$pair_ep" ]]; then
|
||||
echo "${ip}: no pairing port (open Wireless debugging → Pair device with pairing code on tablet)" >&2
|
||||
return 1
|
||||
fi
|
||||
if [[ -z "$code" ]]; then
|
||||
echo "${ip}: pair endpoint ${pair_ep}" >&2
|
||||
echo "Run: ADB_PAIR_CODE=123456 $0 adb_pair ${ip}" >&2
|
||||
return 1
|
||||
fi
|
||||
echo "==> adb pair ${pair_ep}" >&2
|
||||
adb pair "${pair_ep}" "$code"
|
||||
}
|
||||
|
||||
adb_endpoint_rank() {
|
||||
local e=${1}
|
||||
if [[ "$e" == *":5555" ]]; then
|
||||
@@ -396,6 +486,7 @@ adb_reconnect_endpoint() {
|
||||
fi
|
||||
done
|
||||
echo " ${endpoint} — not reachable (${out})" >&2
|
||||
adb_connect_failure_hint "$endpoint" "$out"
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -428,6 +519,13 @@ adb_reconnect_all() {
|
||||
sleep "$ADB_RECONNECT_POKE_DELAY_SEC"
|
||||
fi
|
||||
|
||||
if [[ -n "${ADB_PAIR_CODE:-}" ]]; then
|
||||
local _pair_ip
|
||||
for _pair_ip in $(adb_collect_candidate_ips | sort -u); do
|
||||
adb_pair_device "$_pair_ip" "$ADB_PAIR_CODE" && echo " paired ${_pair_ip}" >&2 || true
|
||||
done
|
||||
fi
|
||||
|
||||
local endpoint connected=0 host resolved
|
||||
declare -A connected_hosts=()
|
||||
while IFS= read -r serial; do
|
||||
@@ -486,7 +584,7 @@ adb_prepare_device_for_deploy() {
|
||||
|
||||
adb_http_status() {
|
||||
local ip=${1}
|
||||
local json
|
||||
local json note
|
||||
json="$(adb_curl_adb_json "$ip" 2>/dev/null || true)"
|
||||
if [[ -z "$json" ]]; then
|
||||
echo "${ip}: no response (app not running or port ${DEV_ADB_HTTP_PORT} closed)"
|
||||
@@ -494,4 +592,48 @@ adb_http_status() {
|
||||
fi
|
||||
echo "${ip}: ok"
|
||||
adb_json_connect_lines "$json" | sed 's/^/ connect /'
|
||||
if adb_json_pairing_lines "$json" | grep -q .; then
|
||||
adb_json_pairing_lines "$json" | sed 's/^/ pair /'
|
||||
fi
|
||||
note="$(printf '%s' "$json" | python3 -c 'import json,sys
|
||||
try:
|
||||
d=json.load(sys.stdin)
|
||||
print(d.get("connect_note") or d.get("hint") or "", end="")
|
||||
except Exception:
|
||||
pass' 2>/dev/null || true)"
|
||||
if [[ -n "$note" ]]; then
|
||||
echo " note: ${note}"
|
||||
fi
|
||||
}
|
||||
|
||||
# --- CLI (when executed, not sourced) ---
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
_ADB_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT="${ROOT:-$(cd "${_ADB_SCRIPT_DIR}/../ac-mobile-android" 2>/dev/null && pwd || pwd)}"
|
||||
export ROOT
|
||||
adb_reconnect_init_hints
|
||||
cmd=${1:-help}
|
||||
shift || true
|
||||
case "$cmd" in
|
||||
adb_http_status) adb_http_status "$@"; exit $? ;;
|
||||
adb_reconnect_all) adb_reconnect_all "$@"; exit $? ;;
|
||||
adb_pair) adb_pair_device "$@"; exit $? ;;
|
||||
help|-h|--help)
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") <command> [args]
|
||||
|
||||
Commands:
|
||||
adb_http_status IP curl :5039/adb.json and show connect/pair endpoints
|
||||
adb_reconnect_all [label] discover + adb connect (HTTP → avahi → cache)
|
||||
adb_pair IP [CODE] adb pair (CODE or env ADB_PAIR_CODE; port from JSON/avahi)
|
||||
|
||||
Env: DEV_ADB_HTTP_PORT=5039, ADB_PAIR_CODE=123456, ADB_PAIRING_PORT=NNNN, ROOT=project dir
|
||||
EOF
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown command: $cmd (try help)" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user