Files
sim-location-backend/main.py
2026-03-12 11:46:19 -04:00

96 lines
3.6 KiB
Python

import asyncio
import dataclasses
import json
import logging
import random
import sys
import socketio
import tempfile
from contextlib import nullcontext
from functools import partial
from pathlib import Path
from typing import Annotated, Optional, TextIO
import typer
from typer_injector import InjectingTyper
from pymobiledevice3.bonjour import DEFAULT_BONJOUR_TIMEOUT, browse_remotepairing_manual_pairing
from pymobiledevice3.cli.cli_common import (
RSDServiceProviderDep,
async_command,
print_json,
prompt_device_list,
sudo_required,
user_requested_colored_output,
)
from pymobiledevice3.common import get_home_folder
from pymobiledevice3.exceptions import NoDeviceConnectedError
from pymobiledevice3.pair_records import PAIRING_RECORD_EXT, get_remote_pairing_record_filename
from pymobiledevice3.remote.common import ConnectionType, TunnelProtocol
from pymobiledevice3.remote.module_imports import MAX_IDLE_TIMEOUT, start_tunnel, verify_tunnel_imports
from pymobiledevice3.remote.remote_service_discovery import RSD_PORT
from pymobiledevice3.remote.tunnel_service import (
RemotePairingManualPairingService,
get_core_device_tunnel_services,
get_remote_pairing_tunnel_services,
)
from pymobiledevice3.remote.utils import get_rsds
from pymobiledevice3.tunneld.api import TUNNELD_DEFAULT_ADDRESS
from pymobiledevice3.utils import run_in_loop
from server import TunneldRunnerSio, LocationSimulationState, logger
def main():
cli_tunneld(host="0.0.0.0", port=8000)
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()