1# Copyright 2024 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14"""Launch a simulated device subprocess under pw_console.""" 15 16import argparse 17from pathlib import Path 18import subprocess 19import sys 20from types import ModuleType 21 22from pw_system.console import console, get_parser 23from pw_system.device_connection import DeviceConnection 24 25 26def _parse_args() -> tuple[argparse.Namespace, list[str]]: 27 parser = argparse.ArgumentParser(description=__doc__) 28 parser.add_argument( 29 '--sim-binary', 30 type=Path, 31 help='Path to a simulated device binary to run on the host', 32 ) 33 return parser.parse_known_args() 34 35 36def launch_sim( 37 sim_binary: Path, 38 remaining_args: list[str], 39 compiled_protos: list[ModuleType] | None = None, 40 device_connection: DeviceConnection | None = None, 41) -> int: 42 """Launches a host-device-sim binary, and attaches a console to it.""" 43 if '-s' not in remaining_args and '--socket-addr' not in remaining_args: 44 remaining_args.extend(['--socket-addr', 'default']) 45 46 # Pass the remaining arguments on to pw_system console. 47 console_args = get_parser().parse_args(remaining_args) 48 49 sim_process = subprocess.Popen( 50 sim_binary, 51 stdin=subprocess.DEVNULL, 52 stdout=subprocess.DEVNULL, 53 stderr=subprocess.STDOUT, 54 ) 55 56 try: 57 retval = console( 58 **vars(console_args), 59 compiled_protos=compiled_protos, 60 device_connection=device_connection, 61 ) 62 finally: 63 sim_process.terminate() 64 65 return retval 66 67 68def main( 69 compiled_protos: list[ModuleType] | None = None, 70 device_connection: DeviceConnection | None = None, 71) -> int: 72 sim_args, remaining_args = _parse_args() 73 return launch_sim( 74 **vars(sim_args), 75 remaining_args=remaining_args, 76 compiled_protos=compiled_protos, 77 device_connection=device_connection, 78 ) 79 80 81# TODO(b/353327855): Deprecated function, remove when no longer used. 82def main_with_compiled_protos( 83 compiled_protos: list[ModuleType] | None = None, 84 device_connection: DeviceConnection | None = None, 85) -> int: 86 return main( 87 compiled_protos=compiled_protos, 88 device_connection=device_connection, 89 ) 90 91 92if __name__ == '__main__': 93 sys.exit(main()) 94