pymobiledevice3 7.2.0__py3-none-any.whl → 7.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '7.2.0'
32
- __version_tuple__ = version_tuple = (7, 2, 0)
31
+ __version__ = version = '7.3.0'
32
+ __version_tuple__ = version_tuple = (7, 3, 0)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -1,3 +1,4 @@
1
+ import ast
1
2
  import logging
2
3
 
3
4
  from typer_injector import InjectingTyper
@@ -30,7 +31,7 @@ def accessibility_settings_set(service_provider: ServiceProviderDep, setting: st
30
31
  in order to list all available use the "show" command
31
32
  """
32
33
  service = AccessibilityAudit(service_provider)
33
- service.set_setting(setting, eval(value))
34
+ service.set_setting(setting, ast.literal_eval(value))
34
35
  OSUTILS.wait_return()
35
36
 
36
37
 
@@ -51,7 +51,14 @@ def debugserver_applist(service_provider: ServiceProviderDep) -> None:
51
51
 
52
52
 
53
53
  @cli.command("start-server")
54
- def debugserver_start_server(service_provider: ServiceProviderDep, local_port: Optional[int] = None) -> None:
54
+ def debugserver_start_server(
55
+ service_provider: ServiceProviderDep,
56
+ local_port: Optional[int] = None,
57
+ host: Annotated[
58
+ str,
59
+ typer.Option(help="Address to bind the local port to."),
60
+ ] = "127.0.0.1",
61
+ ) -> None:
55
62
  """
56
63
  Start debugserver and print the LLDB connect string.
57
64
 
@@ -66,10 +73,10 @@ def debugserver_start_server(service_provider: ServiceProviderDep, local_port: O
66
73
  service_name = "com.apple.internal.dt.remote.debugproxy"
67
74
 
68
75
  if local_port is not None:
69
- print(DEBUGSERVER_CONNECTION_STEPS.format(host="127.0.0.1", port=local_port))
76
+ print(DEBUGSERVER_CONNECTION_STEPS.format(host=host, port=local_port))
70
77
  print("Started port forwarding. Press Ctrl-C to close this shell when done")
71
78
  sys.stdout.flush()
72
- LockdownTcpForwarder(service_provider, local_port, service_name).start()
79
+ LockdownTcpForwarder(service_provider, local_port, service_name).start(address=host)
73
80
  elif Version(service_provider.product_version) >= Version("17.0"):
74
81
  if not isinstance(service_provider, RemoteServiceDiscoveryService):
75
82
  raise RSDRequiredError(service_provider.identifier)
@@ -304,9 +304,10 @@ def netstat(service_provider: ServiceProviderDep) -> None:
304
304
  with DvtSecureSocketProxyService(lockdown=service_provider) as dvt, NetworkMonitor(dvt) as monitor:
305
305
  for event in monitor:
306
306
  if isinstance(event, ConnectionDetectionEvent):
307
- local_host, local_port = event.local_address.split(":")
308
- remote_host, remote_port = event.local_address.split(":")
309
- logger.info(f"Connection detected: {local_host}:{local_port} -> {remote_host}:{remote_port}")
307
+ logger.info(
308
+ f"Connection detected: {event.local_address.data.address}:{event.local_address.port} -> "
309
+ f"{event.remote_address.data.address}:{event.remote_address.port}"
310
+ )
310
311
 
311
312
 
312
313
  @cli.command("screenshot")
@@ -1,3 +1,4 @@
1
+ import ast
1
2
  import asyncio
2
3
  import logging
3
4
  import plistlib
@@ -61,8 +62,8 @@ def lockdown_set(
61
62
  domain: Optional[str] = None,
62
63
  key: Optional[str] = None,
63
64
  ) -> None:
64
- """set a lockdown value using python's eval()"""
65
- print_json(service_provider.set_value(value=eval(value), domain=domain, key=key))
65
+ """set a lockdown value using python's ast.literal_eval()"""
66
+ print_json(service_provider.set_value(value=ast.literal_eval(value), domain=domain, key=key))
66
67
 
67
68
 
68
69
  @cli.command("remove")
@@ -43,6 +43,10 @@ def usbmux_forward(
43
43
  Optional[str],
44
44
  typer.Option(help="Device serial/UDID to forward traffic to."),
45
45
  ] = None,
46
+ host: Annotated[
47
+ str,
48
+ typer.Option(help="Address to bind the local port to."),
49
+ ] = "127.0.0.1",
46
50
  daemonize: Annotated[
47
51
  bool,
48
52
  typer.Option("--daemonize", "-d", help="Run the forwarder in the background."),
@@ -58,10 +62,12 @@ def usbmux_forward(
58
62
  raise NotImplementedError("daemonizing is only supported on unix platforms") from e
59
63
 
60
64
  with tempfile.NamedTemporaryFile("wt") as pid_file:
61
- daemon = Daemonize(app=f"forwarder {src_port}->{dst_port}", pid=pid_file.name, action=forwarder.start)
65
+ daemon = Daemonize(
66
+ app=f"forwarder {src_port}->{dst_port}", pid=pid_file.name, action=lambda: forwarder.start(address=host)
67
+ )
62
68
  daemon.start()
63
69
  else:
64
- forwarder.start()
70
+ forwarder.start(address=host)
65
71
 
66
72
 
67
73
  @cli.command("list")
@@ -1,48 +1,78 @@
1
- import dataclasses
2
1
  import ipaddress
3
2
  import logging
3
+ from collections.abc import Iterator
4
+ from dataclasses import dataclass
5
+ from typing import Union
4
6
 
5
- from construct import Adapter, Bytes, Int8ul, Int16ub, Int32ul, Struct, Switch, this
7
+ from construct import Adapter, Bytes, Int8ul, Int16ub, Int32ul, Switch, this
8
+ from construct_typed import DataclassMixin, TStruct, csfield
9
+
10
+ from pymobiledevice3.services.dvt.dvt_secure_socket_proxy import DvtSecureSocketProxyService
6
11
 
7
12
 
8
13
  class IpAddressAdapter(Adapter):
14
+ """Decode raw address bytes into ipaddress objects."""
15
+
9
16
  def _decode(self, obj, context, path):
10
17
  return ipaddress.ip_address(obj)
11
18
 
12
19
 
13
- address_t = Struct(
14
- "len" / Int8ul,
15
- "family" / Int8ul,
16
- "port" / Int16ub,
17
- "data"
18
- / Switch(
19
- this.len,
20
- {
21
- 0x1C: Struct(
22
- "flow_info" / Int32ul,
23
- "address" / IpAddressAdapter(Bytes(16)),
24
- "scope_id" / Int32ul,
25
- ),
26
- 0x10: Struct("address" / IpAddressAdapter(Bytes(4)), "_zero" / Bytes(8)),
27
- },
28
- ),
29
- )
20
+ @dataclass
21
+ class AddressV6(DataclassMixin):
22
+ """IPv6 payload for a socket address."""
23
+
24
+ flow_info: int = csfield(Int32ul)
25
+ address: ipaddress.IPv6Address = csfield(IpAddressAdapter(Bytes(16)))
26
+ scope_id: int = csfield(Int32ul)
27
+
28
+
29
+ @dataclass
30
+ class AddressV4(DataclassMixin):
31
+ """IPv4 payload for a socket address."""
32
+
33
+ address: ipaddress.IPv4Address = csfield(IpAddressAdapter(Bytes(4)))
34
+ _zero: bytes = csfield(Bytes(8))
35
+
36
+
37
+ @dataclass
38
+ class SocketAddress(DataclassMixin):
39
+ """Parsed socket address with family-specific payload."""
40
+
41
+ length: int = csfield(Int8ul)
42
+ family: int = csfield(Int8ul)
43
+ port: int = csfield(Int16ub)
44
+ data: Union[AddressV4, AddressV6] = csfield(
45
+ Switch(
46
+ this.length,
47
+ {
48
+ 0x1C: TStruct(AddressV6),
49
+ 0x10: TStruct(AddressV4),
50
+ },
51
+ )
52
+ )
53
+
54
+
55
+ address_t = TStruct(SocketAddress)
30
56
 
31
57
  MESSAGE_TYPE_INTERFACE_DETECTION = 0
32
58
  MESSAGE_TYPE_CONNECTION_DETECTION = 1
33
59
  MESSAGE_TYPE_CONNECTION_UPDATE = 2
34
60
 
35
61
 
36
- @dataclasses.dataclass
62
+ @dataclass
37
63
  class InterfaceDetectionEvent:
64
+ """Interface detection event emitted by Instruments."""
65
+
38
66
  interface_index: int
39
67
  name: str
40
68
 
41
69
 
42
- @dataclasses.dataclass
70
+ @dataclass
43
71
  class ConnectionDetectionEvent:
44
- local_address: str
45
- remote_address: str
72
+ """Connection detection event emitted by Instruments."""
73
+
74
+ local_address: SocketAddress
75
+ remote_address: SocketAddress
46
76
  interface_index: int
47
77
  pid: int
48
78
  recv_buffer_size: int
@@ -51,8 +81,10 @@ class ConnectionDetectionEvent:
51
81
  kind: int
52
82
 
53
83
 
54
- @dataclasses.dataclass
84
+ @dataclass
55
85
  class ConnectionUpdateEvent:
86
+ """Connection update event emitted by Instruments."""
87
+
56
88
  rx_packets: int
57
89
  rx_bytes: int
58
90
  tx_packets: int
@@ -66,21 +98,28 @@ class ConnectionUpdateEvent:
66
98
  time: int
67
99
 
68
100
 
101
+ NetworkMonitorEvent = Union[InterfaceDetectionEvent, ConnectionDetectionEvent, ConnectionUpdateEvent]
102
+
103
+
69
104
  class NetworkMonitor:
105
+ """Iterate over network monitoring events from the Instruments service."""
106
+
70
107
  IDENTIFIER = "com.apple.instruments.server.services.networking"
71
108
 
72
- def __init__(self, dvt):
109
+ def __init__(self, dvt: DvtSecureSocketProxyService):
73
110
  self.logger = logging.getLogger(__name__)
74
111
  self._channel = dvt.make_channel(self.IDENTIFIER)
75
112
 
76
- def __enter__(self):
113
+ def __enter__(self) -> "NetworkMonitor":
77
114
  self._channel.startMonitoring(expects_reply=False)
78
115
  return self
79
116
 
80
- def __exit__(self, exc_type, exc_val, exc_tb):
117
+ def __exit__(self, exc_type, exc_val, exc_tb) -> None:
81
118
  self._channel.stopMonitoring()
82
119
 
83
- def __iter__(self):
120
+ def __iter__(self) -> Iterator[NetworkMonitorEvent]:
121
+ """Yield network events as they arrive from the service."""
122
+
84
123
  while True:
85
124
  message = self._channel.receive_plist()
86
125
 
@@ -92,9 +131,26 @@ class NetworkMonitor:
92
131
  if message[0] == MESSAGE_TYPE_INTERFACE_DETECTION:
93
132
  event = InterfaceDetectionEvent(*message[1])
94
133
  elif message[0] == MESSAGE_TYPE_CONNECTION_DETECTION:
95
- event = ConnectionDetectionEvent(*message[1])
96
- event.local_address = address_t.parse(event.local_address)
97
- event.remote_address = address_t.parse(event.remote_address)
134
+ (
135
+ local_address,
136
+ remote_address,
137
+ interface_index,
138
+ pid,
139
+ recv_buffer_size,
140
+ recv_buffer_used,
141
+ serial_number,
142
+ kind,
143
+ ) = message[1]
144
+ event = ConnectionDetectionEvent(
145
+ local_address=address_t.parse(local_address),
146
+ remote_address=address_t.parse(remote_address),
147
+ interface_index=interface_index,
148
+ pid=pid,
149
+ recv_buffer_size=recv_buffer_size,
150
+ recv_buffer_used=recv_buffer_used,
151
+ serial_number=serial_number,
152
+ kind=kind,
153
+ )
98
154
  elif message[0] == MESSAGE_TYPE_CONNECTION_UPDATE:
99
155
  event = ConnectionUpdateEvent(*message[1])
100
156
  else:
@@ -38,7 +38,7 @@ class TcpForwarderBase:
38
38
  # socket to its remote socket and vice versa
39
39
  self.connections = {}
40
40
 
41
- def start(self, address="0.0.0.0"):
41
+ def start(self, address="127.0.0.1"):
42
42
  """forward each connection from given local machine port to remote device port"""
43
43
  # create local tcp server socket
44
44
  self.server_socket = socket.socket()
@@ -191,10 +191,16 @@ class TunneldCore:
191
191
 
192
192
  @asyncio_print_traceback
193
193
  async def monitor_usbmux_task(self) -> None:
194
- try:
195
- while True:
196
- try:
197
- for mux_device in usbmux.list_devices():
194
+ while True:
195
+ mux = None
196
+ try:
197
+ mux = usbmux.create_mux()
198
+ mux.listen()
199
+
200
+ while True:
201
+ await asyncio.to_thread(mux.receive_device_state_update)
202
+
203
+ for mux_device in mux.devices:
198
204
  task_identifier = f"usbmux-{mux_device.serial}-{mux_device.connection_type}"
199
205
  if self.tunnel_exists_for_udid(mux_device.serial):
200
206
  # Skip if already established a tunnel for this udid
@@ -227,14 +233,19 @@ class TunneldCore:
227
233
  name=f"start-tunnel-task-{task_identifier}",
228
234
  ),
229
235
  )
230
- except ConnectionFailedToUsbmuxdError:
231
- # This is exception is expected to occur repeatedly on linux running usbmuxd
232
- # as long as there isn't any physical iDevice connected
233
- logger.debug("failed to connect to usbmux. waiting for it to restart")
234
- finally:
235
- await asyncio.sleep(USBMUX_INTERVAL)
236
- except asyncio.CancelledError:
237
- pass
236
+ except (BlockingIOError, StreamError, OSError) as e:
237
+ # Connection lost - will reconnect on next iteration
238
+ logger.debug(f"usbmux connection error: {e}, reconnecting...")
239
+ except ConnectionFailedToUsbmuxdError:
240
+ # This is exception is expected to occur repeatedly on linux running usbmuxd
241
+ # as long as there isn't any physical iDevice connected
242
+ logger.debug("failed to connect to usbmux. waiting for it to restart")
243
+ await asyncio.sleep(USBMUX_INTERVAL)
244
+ except asyncio.CancelledError:
245
+ break
246
+ finally:
247
+ if mux is not None:
248
+ mux.close()
238
249
 
239
250
  @asyncio_print_traceback
240
251
  async def monitor_mobdev2_task(self) -> None:
pymobiledevice3/usbmux.py CHANGED
@@ -258,6 +258,11 @@ class MuxConnection:
258
258
  """
259
259
  pass
260
260
 
261
+ @abc.abstractmethod
262
+ def listen(self):
263
+ """start listening for events of attached and detached devices"""
264
+ pass
265
+
261
266
  def connect(self, device: MuxDevice, port: int) -> socket.socket:
262
267
  """connect to a relay port on target machine and get a raw python socket object for the connection"""
263
268
  self._connect(device.devid, socket.htons(port))
@@ -273,6 +278,11 @@ class MuxConnection:
273
278
  if self._connected:
274
279
  raise MuxException("Mux is connected, cannot issue control packets")
275
280
 
281
+ @abc.abstractmethod
282
+ def receive_device_state_update(self):
283
+ """Block and wait for a device notification"""
284
+ pass
285
+
276
286
  def _raise_mux_exception(self, result: int, message: Optional[str] = None) -> None:
277
287
  exceptions = {
278
288
  int(usbmuxd_result.BADCOMMAND): BadCommandError,
@@ -306,7 +316,7 @@ class BinaryMuxConnection(MuxConnection):
306
316
  while time.time() < end:
307
317
  self._sock.settimeout(end - time.time())
308
318
  try:
309
- self._receive_device_state_update()
319
+ self.receive_device_state_update()
310
320
  except (BlockingIOError, StreamError):
311
321
  continue
312
322
  except OSError as e:
@@ -348,6 +358,16 @@ class BinaryMuxConnection(MuxConnection):
348
358
  raise MuxException(f"Reply tag mismatch: expected {expected_tag}, got {response.header.tag}")
349
359
  return response
350
360
 
361
+ def receive_device_state_update(self):
362
+ response = self._receive()
363
+ if response.header.message == usbmuxd_msgtype.ADD:
364
+ # old protocol only supported USB devices
365
+ self._add_device(MuxDevice(response.data.device_id, response.data.serial_number, "USB"))
366
+ elif response.header.message == usbmuxd_msgtype.REMOVE:
367
+ self._remove_device(response.data.device_id)
368
+ else:
369
+ raise MuxException(f"Invalid packet type received: {response}")
370
+
351
371
  def _send_receive(self, message_type: int):
352
372
  self._send({"header": {"version": self._version, "message": message_type, "tag": self._tag}, "data": b""})
353
373
  response = self._receive(self._tag - 1)
@@ -364,16 +384,6 @@ class BinaryMuxConnection(MuxConnection):
364
384
  def _remove_device(self, device_id: int):
365
385
  self.devices = [device for device in self.devices if device.devid != device_id]
366
386
 
367
- def _receive_device_state_update(self):
368
- response = self._receive()
369
- if response.header.message == usbmuxd_msgtype.ADD:
370
- # old protocol only supported USB devices
371
- self._add_device(MuxDevice(response.data.device_id, response.data.serial_number, "USB"))
372
- elif response.header.message == usbmuxd_msgtype.REMOVE:
373
- self._remove_device(response.data.device_id)
374
- else:
375
- raise MuxException(f"Invalid packet type received: {response}")
376
-
377
387
 
378
388
  class PlistMuxConnection(BinaryMuxConnection):
379
389
  def __init__(self, sock: SafeStreamSocket):
@@ -392,6 +402,20 @@ class PlistMuxConnection(BinaryMuxConnection):
392
402
  raise NotPairedError("device should be paired first")
393
403
  return plistlib.loads(pair_record)
394
404
 
405
+ def _process_device_state(self, response):
406
+ if response["MessageType"] == "Attached":
407
+ super()._add_device(
408
+ MuxDevice(
409
+ response["DeviceID"],
410
+ response["Properties"]["SerialNumber"],
411
+ response["Properties"]["ConnectionType"],
412
+ )
413
+ )
414
+ elif response["MessageType"] == "Detached":
415
+ super()._remove_device(response["DeviceID"])
416
+ else:
417
+ raise MuxException(f"Invalid packet type received: {response}")
418
+
395
419
  def get_device_list(self, timeout: Optional[float] = None) -> None:
396
420
  """get device list synchronously without waiting the timeout"""
397
421
  self.devices = []
@@ -401,18 +425,7 @@ class PlistMuxConnection(BinaryMuxConnection):
401
425
  if device_list is None:
402
426
  raise MuxException(f"Got an invalid response from usbmux: {response}")
403
427
  for response in device_list:
404
- if response["MessageType"] == "Attached":
405
- super()._add_device(
406
- MuxDevice(
407
- response["DeviceID"],
408
- response["Properties"]["SerialNumber"],
409
- response["Properties"]["ConnectionType"],
410
- )
411
- )
412
- elif response["MessageType"] == "Detached":
413
- super()._remove_device(response["DeviceID"])
414
- else:
415
- raise MuxException(f"Invalid packet type received: {response}")
428
+ self._process_device_state(response)
416
429
 
417
430
  def get_buid(self) -> str:
418
431
  """get SystemBUID"""
@@ -445,6 +458,10 @@ class PlistMuxConnection(BinaryMuxConnection):
445
458
  raise MuxException(f"Received non-plist type {response}")
446
459
  return plistlib.loads(response.data)
447
460
 
461
+ def receive_device_state_update(self):
462
+ response = self._receive()
463
+ self._process_device_state(response)
464
+
448
465
  def _send_receive(self, data: dict):
449
466
  self._send(data)
450
467
  response = self._receive(self._tag - 1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pymobiledevice3
3
- Version: 7.2.0
3
+ Version: 7.3.0
4
4
  Summary: Pure python3 implementation for working with iDevices (iPhone, etc...)
5
5
  Author-email: doronz88 <doron88@gmail.com>, matan <matan1008@gmail.com>
6
6
  Maintainer-email: doronz88 <doron88@gmail.com>, matan <matan1008@gmail.com>
@@ -8,7 +8,7 @@ misc/understanding_idevice_protocol_layers.md,sha256=FMJQ-ik2j9kFLPS15JzDZg62uk1
8
8
  misc/usbmux_sniff.sh,sha256=iWtbucOEQ9_UEFXk9x-2VNt48Jg5zrPsnUbZ_LfZxwA,212
9
9
  pymobiledevice3/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  pymobiledevice3/__main__.py,sha256=Ogsyro4MUVVSciEtg8kZufL81AHcjuphItnaL0BT10Q,16386
11
- pymobiledevice3/_version.py,sha256=6mGK2LZkwfh2g3gBQlsvmTFN5vd5BUVAxvH1FvJwE4I,704
11
+ pymobiledevice3/_version.py,sha256=BpXyl73xbe6_17dkPC-8-scRHBmLb8oS-aOvGbsktQs,704
12
12
  pymobiledevice3/bonjour.py,sha256=lmx3uCaiolF59AieftmTKqktNod5ZDyJ06oRZdYKHSE,13681
13
13
  pymobiledevice3/ca.py,sha256=5_Y4F-zDFX_KeDL-M_TRCKKyrRRb9h1lBE8MGTWv91o,10606
14
14
  pymobiledevice3/common.py,sha256=FZzF0BQYV5fCEUPbLo6jbt2Ig9s5YwR8AvX_iR124Ew,329
@@ -19,8 +19,8 @@ pymobiledevice3/lockdown.py,sha256=CgT3FApB3SLXbvbL3I7OFN7IkiPpSKjdxA1Zr0I6xIs,3
19
19
  pymobiledevice3/lockdown_service_provider.py,sha256=mj5Hf3fNWdVYYUayKnLO3NWNgvD0xDMAiSIXKDcXCuk,1814
20
20
  pymobiledevice3/pair_records.py,sha256=4T32UPcBuN_4e-QFzGLoDoUBg3k7hgQh72Yo3CTi18M,6001
21
21
  pymobiledevice3/service_connection.py,sha256=7-FxkycdgzAMcPqn5j5K4z8Zj5O_EOAj67j9DhkJcOY,15041
22
- pymobiledevice3/tcp_forwarder.py,sha256=imOTd76bh5bknOMJ4KAnWoe68eL3F3TpYlNM8eR7eXA,8971
23
- pymobiledevice3/usbmux.py,sha256=GmQTB3V5_6oYErBlZrFRi7XjPKVU1p0RUj147vT9-eg,16835
22
+ pymobiledevice3/tcp_forwarder.py,sha256=o3NyIWItt_eprILSCvZcT_rfjPEPJGSgiiM3CLgC2UU,8973
23
+ pymobiledevice3/usbmux.py,sha256=j8-ppwXv9d1czXBc-BGn7JlacrYkrBPPjal8T4vbmJs,17276
24
24
  pymobiledevice3/utils.py,sha256=Udx6xubsWYtJU9x7R-PrlSHseY438ua9_DPvzHd3XrQ,2210
25
25
  pymobiledevice3/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
26
  pymobiledevice3/cli/activation.py,sha256=FDqkBa1ew_d_8MLmq8nelF8D1eBcqm9kqTCAH03sTUU,1335
@@ -33,7 +33,7 @@ pymobiledevice3/cli/cli_common.py,sha256=FZJtZgnMZcCg2X2daJBvqOgbhiGbcG5aDFQ_pf5
33
33
  pymobiledevice3/cli/companion_proxy.py,sha256=Zp1PJKE36mNs2lbnmwevDoVC7jTX5FSuQApTcmvEhJg,611
34
34
  pymobiledevice3/cli/crash.py,sha256=wss34L3at8qwL_z5ExGabofBbQ99cP_CGJJm8vuF36g,3506
35
35
  pymobiledevice3/cli/idam.py,sha256=a_xnURhQlmfnrTGY5KwOIbl9f-1rAjuGG-q6QfOfSE4,1105
36
- pymobiledevice3/cli/lockdown.py,sha256=GoDnSiX2Ts8XFz3ZIVJLf3HBhiO5SuKBW3zOj63GjbU,6393
36
+ pymobiledevice3/cli/lockdown.py,sha256=p5bYYwR2HnXEU2jjotuYt3gSUVoVfzV9kBNTZr9eioU,6428
37
37
  pymobiledevice3/cli/mounter.py,sha256=wKFyn2liZspAVu7GWAfJiA_CyTLmDFeN9mg9YISMK_M,7930
38
38
  pymobiledevice3/cli/notification.py,sha256=rHC8z1RFpQpQAnsbqGC2ozqFjzvJ98FXw2WdAPJE0sw,2143
39
39
  pymobiledevice3/cli/pcap.py,sha256=50_jpjxC5GRJeD3PnrVnp5CkJhw1ZOM-LKxwsotif1E,2431
@@ -45,19 +45,19 @@ pymobiledevice3/cli/remote.py,sha256=tjoMjjUg32SPaIdZbwtu2Frno5Ly9is3p_E6FyjWxUU
45
45
  pymobiledevice3/cli/restore.py,sha256=j1T9-eZi2AsvQqJ0EKpXuaWPuttoVUPy0xbYYfH6B_s,7485
46
46
  pymobiledevice3/cli/springboard.py,sha256=S76Kth2DbqsjGRFVOns40-L4RCqFnuMFuy7bVHbmw9M,3111
47
47
  pymobiledevice3/cli/syslog.py,sha256=tqQLecHGcb0v_3Lq54XyEDojdxJSFpvMnQ8B7P_lU58,8945
48
- pymobiledevice3/cli/usbmux.py,sha256=1YopbLDgp34x3EfGM889H6UWch412hVWkDJp8OXdvb4,3009
48
+ pymobiledevice3/cli/usbmux.py,sha256=TTzVTftgipOS4ulHH9dfj7AG_GYZgKh8stl_4UXGS6o,3193
49
49
  pymobiledevice3/cli/version.py,sha256=59NxyLVJWcqNpoKo-XTc5RYGmweuJUmKgKnLwaLzD5o,326
50
50
  pymobiledevice3/cli/webinspector.py,sha256=grfwKDAQ1oh7WA_VWCM6qGQzo8osIOY2PjpYXJ1hzCs,17946
51
51
  pymobiledevice3/cli/developer/__init__.py,sha256=idQOgVsitt3nfolyhZuA6KHN2j44JNVq-d41I6ychpY,2015
52
52
  pymobiledevice3/cli/developer/arbitration.py,sha256=7Eod6-dlSjAMBljbsIGHL_QG9LFbOPIXqpS9Y_4-Q3Y,1576
53
53
  pymobiledevice3/cli/developer/condition.py,sha256=lb5BS8lVcgsb2yBgBsN2nK-j2u1_iVm_tBd1pSRHZB0,1294
54
54
  pymobiledevice3/cli/developer/core_device.py,sha256=QzMVfghq3fKLI2NQ2Kg7r_zyFIWGCBt7ZS-GTLWDZs4,10895
55
- pymobiledevice3/cli/developer/debugserver.py,sha256=0hP6-x3xChcYCacxI7CuEWEsM8-u4i4GNYa1HeSMPXg,10464
55
+ pymobiledevice3/cli/developer/debugserver.py,sha256=gIUBiJx8e2h3u8QDJvR0rsQnmaPlY8eeEp6iVEhasjE,10600
56
56
  pymobiledevice3/cli/developer/fetch_symbols.py,sha256=57HzVyUJPXL_I8EiqWArJ2Fczb2yX9y6nDMgjZcADo0,4353
57
57
  pymobiledevice3/cli/developer/simulate_location.py,sha256=IVJQPYKUrQcsdpCxf2D2sgy6Nb3mUOFvK-Og_y5lfDM,1555
58
58
  pymobiledevice3/cli/developer/accessibility/__init__.py,sha256=VpJSdnkEZhUuJXWy08wqgqObXv1PgZ2Ht4qy-560QRk,2271
59
- pymobiledevice3/cli/developer/accessibility/settings.py,sha256=QKgQ7XK6LNrlE-1nnWVGL2Mix385Huf-diptgY91apA,1170
60
- pymobiledevice3/cli/developer/dvt/__init__.py,sha256=N2IZJR6pYerLtzCsNQL8TTSy6X1ktduLuYDT0Ld5tIo,15828
59
+ pymobiledevice3/cli/developer/accessibility/settings.py,sha256=2aTAFSslD9Lc2yqW7l7x2IiRTOYxfOX_T_xYwkgHBvk,1193
60
+ pymobiledevice3/cli/developer/dvt/__init__.py,sha256=deQPWmFzdsJ5iw2CktCIssjbcTZ0VVrxuFZ1Osbgfac,15816
61
61
  pymobiledevice3/cli/developer/dvt/core_profile_session.py,sha256=Ni6znP0mg-XKLu0aXm8ZZDEKziKokQYMjwbTu2TzFxk,9968
62
62
  pymobiledevice3/cli/developer/dvt/simulate_location.py,sha256=QLjjllbjuM205joFlRXdo7cIjvkFdXJ2f5pKzT9sHOY,1816
63
63
  pymobiledevice3/cli/developer/dvt/sysmon/__init__.py,sha256=PSTruXzQQLGvVuc1j7aKEafXFYgFMOCuNiMjbtDqKrM,2283
@@ -159,7 +159,7 @@ pymobiledevice3/services/dvt/instruments/energy_monitor.py,sha256=7zVLliaWoAtiH_
159
159
  pymobiledevice3/services/dvt/instruments/graphics.py,sha256=hkX8_kLStRf9pliLSJUO2Vk7KG9gqSo55Ydntm6S9Xw,588
160
160
  pymobiledevice3/services/dvt/instruments/location_simulation.py,sha256=A04YrB8ptP_t2ImEY4Gj8168-q-Hh-emzWKzVSGSL1U,703
161
161
  pymobiledevice3/services/dvt/instruments/location_simulation_base.py,sha256=LQJO1aa50Duue4ZrRpoZyjwnV4qsLw4nge0oWuhm_yY,1543
162
- pymobiledevice3/services/dvt/instruments/network_monitor.py,sha256=T8KFbrdqXinbluGqH5Fe_piS_mZt1hcHBOL47jRKFUE,2621
162
+ pymobiledevice3/services/dvt/instruments/network_monitor.py,sha256=e138eqB4-p-nRQBfGWZpwTHVl7g4wgmqW-jLM03U3Ak,4485
163
163
  pymobiledevice3/services/dvt/instruments/notifications.py,sha256=IDFtGKWxOoicAyPmE4FADEn84-B-OTrP0k_6kKKMlXU,829
164
164
  pymobiledevice3/services/dvt/instruments/process_control.py,sha256=9S4ck7MLRmMIiaO9x-LczVUENh0l6GtdlF4QDb51gsA,3864
165
165
  pymobiledevice3/services/dvt/instruments/screenshot.py,sha256=JKz8UFWTkroMTIEnXBqCMI4AupKIjhwDpuZaxy98Ouw,476
@@ -179,10 +179,10 @@ pymobiledevice3/services/web_protocol/session_protocol.py,sha256=CMqFeIjsse0qkFq
179
179
  pymobiledevice3/services/web_protocol/switch_to.py,sha256=TCdVrMfsvd18o-vZ0owVrEFYeoGbwF3jZ1iDaPslV9U,2944
180
180
  pymobiledevice3/tunneld/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
181
181
  pymobiledevice3/tunneld/api.py,sha256=Lwl1OdhPTgX6Zqezy8T4dEcXRfaEPwyGNClioTx3fUc,2338
182
- pymobiledevice3/tunneld/server.py,sha256=dMEZAv_X-76l0vSalpq4x0IVkbE-MNGR77T-u1TiHuE,25752
183
- pymobiledevice3-7.2.0.dist-info/licenses/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
184
- pymobiledevice3-7.2.0.dist-info/METADATA,sha256=YusNp-ay7Vex8lHFZBXuHoN8PQQzQnIO-kXyl16qq6s,17500
185
- pymobiledevice3-7.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
186
- pymobiledevice3-7.2.0.dist-info/entry_points.txt,sha256=jJMlOanHlVwUxcY__JwvKeWPrvBJr_wJyEq4oHIZNKE,66
187
- pymobiledevice3-7.2.0.dist-info/top_level.txt,sha256=MjZoRqcWPOh5banG-BbDOnKEfsS3kCxqV9cv-nzyg2Q,21
188
- pymobiledevice3-7.2.0.dist-info/RECORD,,
182
+ pymobiledevice3/tunneld/server.py,sha256=kxz6Jea5l47Fv_-O2PbteyXOaHIcbqkL58pZE2LnCbo,26188
183
+ pymobiledevice3-7.3.0.dist-info/licenses/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
184
+ pymobiledevice3-7.3.0.dist-info/METADATA,sha256=7pFRO6aE7xTxkDctW5r6ubzyxGbGL5XwuGCsdBB6A60,17500
185
+ pymobiledevice3-7.3.0.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
186
+ pymobiledevice3-7.3.0.dist-info/entry_points.txt,sha256=jJMlOanHlVwUxcY__JwvKeWPrvBJr_wJyEq4oHIZNKE,66
187
+ pymobiledevice3-7.3.0.dist-info/top_level.txt,sha256=MjZoRqcWPOh5banG-BbDOnKEfsS3kCxqV9cv-nzyg2Q,21
188
+ pymobiledevice3-7.3.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5