mirror of
git://f0xx.org/ac/ac-scripts
synced 2026-07-29 06:18:32 +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:=yes}"
|
||||||
: "${ADB_TCP_PROBE_SEC:=1}"
|
: "${ADB_TCP_PROBE_SEC:=1}"
|
||||||
: "${DEV_ADB_HTTP_PORT:=5039}"
|
: "${DEV_ADB_HTTP_PORT:=5039}"
|
||||||
: "${ADB_CONNECT_CACHE:=$ROOT/.adb_connect_cache}"
|
: "${ADB_CONNECT_CACHE:=${ROOT:-.}/.adb_connect_cache}"
|
||||||
: "${ADB_HTTP_CACHE_DIR:=$ROOT/.adb_http_cache}"
|
: "${ADB_HTTP_CACHE_DIR:=${ROOT:-.}/.adb_http_cache}"
|
||||||
: "${ADB_RECONNECT_POKE_DELAY_SEC:=2}"
|
: "${ADB_RECONNECT_POKE_DELAY_SEC:=2}"
|
||||||
: "${ADB_MDNS_AUTO_CONNECT:=adb-tls-connect,adb}"
|
: "${ADB_MDNS_AUTO_CONNECT:=adb-tls-connect,adb}"
|
||||||
: "${ADB_KILL_SERVER:=no}"
|
: "${ADB_KILL_SERVER:=no}"
|
||||||
@@ -96,7 +96,7 @@ adb_json_connect_lines() {
|
|||||||
local json=${1}
|
local json=${1}
|
||||||
[[ -n "$json" ]] || return 0
|
[[ -n "$json" ]] || return 0
|
||||||
printf '%s' "$json" | python3 -c '
|
printf '%s' "$json" | python3 -c '
|
||||||
import json, sys
|
import json, sys, re
|
||||||
raw = sys.stdin.read()
|
raw = sys.stdin.read()
|
||||||
if not raw.strip():
|
if not raw.strip():
|
||||||
raise SystemExit(0)
|
raise SystemExit(0)
|
||||||
@@ -104,23 +104,51 @@ try:
|
|||||||
data = json.loads(raw)
|
data = json.loads(raw)
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
raise SystemExit(0)
|
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)
|
tls = int(data.get("tls_port") or 0)
|
||||||
if tls > 0:
|
if tls > 0:
|
||||||
for ip in data.get("ips") or []:
|
for ip in data.get("ips") or []:
|
||||||
if ip:
|
if ip:
|
||||||
print(f"{ip}:{tls}")
|
emit(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))
|
|
||||||
for item in data.get("connect") or []:
|
for item in data.get("connect") or []:
|
||||||
if ok(item):
|
emit(item)
|
||||||
print(item)
|
|
||||||
for item in data.get("commands") or []:
|
for item in data.get("commands") or []:
|
||||||
if isinstance(item, str) and item.startswith("adb connect "):
|
if isinstance(item, str) and item.startswith("adb connect "):
|
||||||
ep = item[len("adb connect "):]
|
emit(item[len("adb connect "):])
|
||||||
if ok(ep):
|
' 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)
|
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
|
' 2>/dev/null || true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,6 +203,14 @@ adb_discover_avahi_endpoints() {
|
|||||||
done
|
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() {
|
adb_pull_device_json_endpoints() {
|
||||||
local serial json tmp
|
local serial json tmp
|
||||||
while IFS= read -r serial; do
|
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 }')
|
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() {
|
adb_endpoint_rank() {
|
||||||
local e=${1}
|
local e=${1}
|
||||||
if [[ "$e" == *":5555" ]]; then
|
if [[ "$e" == *":5555" ]]; then
|
||||||
@@ -396,6 +486,7 @@ adb_reconnect_endpoint() {
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
echo " ${endpoint} — not reachable (${out})" >&2
|
echo " ${endpoint} — not reachable (${out})" >&2
|
||||||
|
adb_connect_failure_hint "$endpoint" "$out"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,6 +519,13 @@ adb_reconnect_all() {
|
|||||||
sleep "$ADB_RECONNECT_POKE_DELAY_SEC"
|
sleep "$ADB_RECONNECT_POKE_DELAY_SEC"
|
||||||
fi
|
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
|
local endpoint connected=0 host resolved
|
||||||
declare -A connected_hosts=()
|
declare -A connected_hosts=()
|
||||||
while IFS= read -r serial; do
|
while IFS= read -r serial; do
|
||||||
@@ -486,7 +584,7 @@ adb_prepare_device_for_deploy() {
|
|||||||
|
|
||||||
adb_http_status() {
|
adb_http_status() {
|
||||||
local ip=${1}
|
local ip=${1}
|
||||||
local json
|
local json note
|
||||||
json="$(adb_curl_adb_json "$ip" 2>/dev/null || true)"
|
json="$(adb_curl_adb_json "$ip" 2>/dev/null || true)"
|
||||||
if [[ -z "$json" ]]; then
|
if [[ -z "$json" ]]; then
|
||||||
echo "${ip}: no response (app not running or port ${DEV_ADB_HTTP_PORT} closed)"
|
echo "${ip}: no response (app not running or port ${DEV_ADB_HTTP_PORT} closed)"
|
||||||
@@ -494,4 +592,48 @@ adb_http_status() {
|
|||||||
fi
|
fi
|
||||||
echo "${ip}: ok"
|
echo "${ip}: ok"
|
||||||
adb_json_connect_lines "$json" | sed 's/^/ connect /'
|
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