Skip to content

feat: support start-tunnel over Wi-Fi #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions tidevice3/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,16 @@
if is_port_open("localhost", 49151):
tunneld_url = "http://localhost:49151"
else:
tunneld_url = "http://localhost:5555" # for backward compatibility
tunneld_url = "http://localhost:5555" # for backward compatibility

Check warning on line 109 in tidevice3/api.py

View check run for this annotation

Codecov / codecov/patch

tidevice3/api.py#L109

Added line #L109 was not covered by tests

try:
resp = requests.get(tunneld_url, timeout=DEFAULT_TIMEOUT)
tunnels: Dict[str, Any] = resp.json()
ipv6_address = tunnels.get(udid)
ipv6_address = tunnels.get("usb_" + udid)

Check warning on line 114 in tidevice3/api.py

View check run for this annotation

Codecov / codecov/patch

tidevice3/api.py#L114

Added line #L114 was not covered by tests
if ipv6_address is None:
raise FatalError("tunneld not ready for device", udid)
ipv6_address = tunnels.get("wifi_" + udid)

Check warning on line 116 in tidevice3/api.py

View check run for this annotation

Codecov / codecov/patch

tidevice3/api.py#L116

Added line #L116 was not covered by tests
if ipv6_address is None:
raise FatalError("tunneld not ready for device", udid)

Check warning on line 118 in tidevice3/api.py

View check run for this annotation

Codecov / codecov/patch

tidevice3/api.py#L118

Added line #L118 was not covered by tests
rsd = EnterableRemoteServiceDiscoveryService(ipv6_address)
return rsd
except requests.RequestException:
Expand Down
48 changes: 32 additions & 16 deletions tidevice3/cli/tunneld.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,18 @@
port: int


def get_connected_devices() -> list[str]:
def get_connected_devices(wifi: bool) -> list[str]:
"""return list of udid"""
try:
devices = list_devices(usb=True, network=False)
usb_devices = list_devices(usb=True, network=False)

Check warning on line 40 in tidevice3/cli/tunneld.py

View check run for this annotation

Codecov / codecov/patch

tidevice3/cli/tunneld.py#L40

Added line #L40 was not covered by tests
devices = ["usb_" + d.Identifier for d in usb_devices if Version(d.ProductVersion) >= Version("17")]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里感觉不太好,udid加上前缀 usb_, wifi_ 感觉不如直接定义一个新的类型,比如

get_connected_devices(usb: bool, network: bool) -> List[DeviceInfo]

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

以提交新版本

if wifi:
wifi_devices = list_devices(usb=False, network=True)

Check warning on line 43 in tidevice3/cli/tunneld.py

View check run for this annotation

Codecov / codecov/patch

tidevice3/cli/tunneld.py#L43

Added line #L43 was not covered by tests
devices.extend(["wifi_" + d.Identifier for d in wifi_devices if Version(d.ProductVersion) >= Version("17")])
except MuxException as e:
logger.error("list_devices failed: %s", e)
return []
return [d.Identifier for d in devices if Version(d.ProductVersion) >= Version("17")]
return devices

Check warning on line 48 in tidevice3/cli/tunneld.py

View check run for this annotation

Codecov / codecov/patch

tidevice3/cli/tunneld.py#L48

Added line #L48 was not covered by tests


def get_need_lockdown_devices() -> list[str]:
Expand Down Expand Up @@ -74,11 +78,16 @@
TunnelError
"""
# cmd = ["bash", "-c", "echo ::1 1234; sleep 10001"]
log_prefix = f"[{udid}]"
device_type, _udid = udid.split("_")[0], udid.split("_")[1]
log_prefix = f"[{_udid}]"

Check warning on line 82 in tidevice3/cli/tunneld.py

View check run for this annotation

Codecov / codecov/patch

tidevice3/cli/tunneld.py#L81-L82

Added lines #L81 - L82 were not covered by tests
start_tunnel_cmd = "remote"
if udid in get_need_lockdown_devices():
start_tunnel_cmd = "lockdown"
cmdargs = pmd3_path + f"{start_tunnel_cmd} start-tunnel --script-mode --udid {udid}".split()
lockdown_devices = get_need_lockdown_devices()

Check warning on line 84 in tidevice3/cli/tunneld.py

View check run for this annotation

Codecov / codecov/patch

tidevice3/cli/tunneld.py#L84

Added line #L84 was not covered by tests
if device_type == "wifi" and _udid not in lockdown_devices:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

=17.0 < 17.4 的设备不包含这这里面?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

17.4以下,Wi-Fi模式,用remote加-t wifi;17.4以上,Wi-Fi模式和USB模式都用lockdown,没有-t wifi选项

cmdargs = pmd3_path + f"{start_tunnel_cmd} start-tunnel --script-mode --udid {_udid} -t wifi".split()

Check warning on line 86 in tidevice3/cli/tunneld.py

View check run for this annotation

Codecov / codecov/patch

tidevice3/cli/tunneld.py#L86

Added line #L86 was not covered by tests
else:
if _udid in lockdown_devices:
start_tunnel_cmd = "lockdown"
cmdargs = pmd3_path + f"{start_tunnel_cmd} start-tunnel --script-mode --udid {_udid}".split()

Check warning on line 90 in tidevice3/cli/tunneld.py

View check run for this annotation

Codecov / codecov/patch

tidevice3/cli/tunneld.py#L89-L90

Added lines #L89 - L90 were not covered by tests
logger.info("%s cmd: %s", log_prefix, shlex.join(cmdargs))
process = subprocess.Popen(
cmdargs, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE
Expand All @@ -100,12 +109,16 @@
self.addresses: Mapping[str, Address] = {}
self.pmd3_cmd = ["pymobiledevice3"]

def update_devices(self):
current_devices = set(get_connected_devices())
active_udids = set(self.active_monitors.keys())
def update_devices(self, wifi: bool):
current_devices = get_connected_devices(wifi)
active_udids = self.active_monitors.keys()

Check warning on line 114 in tidevice3/cli/tunneld.py

View check run for this annotation

Codecov / codecov/patch

tidevice3/cli/tunneld.py#L113-L114

Added lines #L113 - L114 were not covered by tests

# Start monitors for new devices
for udid in current_devices - active_udids:
for udid in current_devices:
if udid in active_udids:
continue

Check warning on line 119 in tidevice3/cli/tunneld.py

View check run for this annotation

Codecov / codecov/patch

tidevice3/cli/tunneld.py#L119

Added line #L119 was not covered by tests
if udid.replace("wifi", "usb") in active_udids: # skip if device already monitered by usb
continue

Check warning on line 121 in tidevice3/cli/tunneld.py

View check run for this annotation

Codecov / codecov/patch

tidevice3/cli/tunneld.py#L121

Added line #L121 was not covered by tests
self.active_monitors[udid] = None
try:
threading.Thread(name=f"{udid} keeper",
Expand All @@ -116,7 +129,9 @@
logger.error("udid: %s start-tunnel failed: %s", udid, e)

# Stop monitors for disconnected devices
for udid in active_udids - current_devices:
for udid in active_udids:
if udid in current_devices:
continue

Check warning on line 134 in tidevice3/cli/tunneld.py

View check run for this annotation

Codecov / codecov/patch

tidevice3/cli/tunneld.py#L134

Added line #L134 was not covered by tests
logger.info("udid: %s quit, terminate related process", udid)
process = self.active_monitors[udid]
if process:
Expand Down Expand Up @@ -152,10 +167,10 @@
process.terminate()
self.running = False

def run_forever(self):
def run_forever(self, wifi: bool):
while self.running:
try:
self.update_devices()
self.update_devices(wifi)

Check warning on line 173 in tidevice3/cli/tunneld.py

View check run for this annotation

Codecov / codecov/patch

tidevice3/cli/tunneld.py#L173

Added line #L173 was not covered by tests
except Exception as e:
logger.exception("update_devices failed: %s", e)
time.sleep(1)
Expand All @@ -169,7 +184,8 @@
default=None,
)
@click.option("--port", "port", help="listen port", default=5555)
def tunneld(pmd3_path: str, port: int):
@click.option("--wifi", is_flag=True, help="start-tunnel for network devices")
def tunneld(pmd3_path: str, port: int, wifi: bool):
"""start server for iOS >= 17 auto start-tunnel, function like pymobiledevice3 remote tunneld"""
if not os_utils.is_admin:
logger.error("Please run as root(Mac) or administrator(Windows)")
Expand All @@ -194,7 +210,7 @@
manager.pmd3_cmd = [pmd3_path]

threading.Thread(
target=manager.run_forever, daemon=True, name="device_manager"
target=manager.run_forever, args=(wifi,), daemon=True, name="device_manager"
).start()
try:
uvicorn.run(app, host="0.0.0.0", port=port)
Expand Down
Loading