import tempfile from functools import partial from typing import Annotated import typer from pymobiledevice3.remote.common import TunnelProtocol from pymobiledevice3.remote.module_imports import verify_tunnel_imports from pymobiledevice3.tunneld.api import TUNNELD_DEFAULT_ADDRESS from src.pymd3_vue_location_sim.server import TunneldRunnerSio, LocationSimulationState from src.pymd3_vue_location_sim.json_formatter import logger def main(): cli_tunneld(host="0.0.0.0", port=49151) def cli_tunneld( host: Annotated[str, typer.Option(help="Address to bind the tunneld server to.")] = TUNNELD_DEFAULT_ADDRESS[0], port: Annotated[int, typer.Option(help="Port to bind the tunneld server to.")] = TUNNELD_DEFAULT_ADDRESS[1], daemonize: Annotated[bool, typer.Option("--daemonize", "-d", help="Run tunneld in the background.")] = False, protocol: Annotated[ TunnelProtocol, typer.Option( "--protocol", "-p", case_sensitive=False, help="Transport protocol for tunneld (default: TCP on Python >=3.13, otherwise QUIC).", ), ] = TunnelProtocol.DEFAULT, usb: Annotated[bool, typer.Option(help="Enable USB monitoring")] = True, wifi: Annotated[bool, typer.Option(help="Enable WiFi monitoring")] = True, usbmux: Annotated[bool, typer.Option(help="Enable usbmux monitoring")] = True, mobdev2: Annotated[bool, typer.Option(help="Enable mobdev2 monitoring")] = True, context: Annotated[LocationSimulationState, typer.Option( help="Location simulation context to use for the server.")] = LocationSimulationState(), ) -> None: """Start Tunneld service for remote tunneling""" if not verify_tunnel_imports(): return tunneld_runner = partial( TunneldRunnerSio.create, host, port, protocol=protocol, usb_monitor=usb, wifi_monitor=wifi, usbmux_monitor=usbmux, mobdev2_monitor=mobdev2, context=context, ) if daemonize: try: from daemonize import Daemonize except ImportError as e: raise NotImplementedError("daemonizing is only supported on unix platforms") from e with tempfile.NamedTemporaryFile("wt") as pid_file: daemon = Daemonize(app=f"Tunneld {host}:{port}", pid=pid_file.name, action=tunneld_runner) logger.info(f"starting Tunneld {host}:{port}") daemon.start() else: tunneld_runner() # 4. Entry point (always last) if __name__ == "__main__": main()