Remove IDT (#33054)
* Remove IDT
* Remove idt readme from docs index
diff --git a/docs/tools/index.md b/docs/tools/index.md
index 14ab864..003573e 100644
--- a/docs/tools/index.md
+++ b/docs/tools/index.md
@@ -28,7 +28,6 @@
../scripts/tools/memory/README
../scripts/tools/spake2p/README
-../src/tools/interop/idt/README
```
diff --git a/src/tools/interop/idt/.gitignore b/src/tools/interop/idt/.gitignore
deleted file mode 100644
index 55da2a8..0000000
--- a/src/tools/interop/idt/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-*~
-.DS_Store
-.idea/
-IDT_ARTIFACTS/
-OUT/
-__pycache__/
-pycache/
-venv/
-.zip
-BUILD
diff --git a/src/tools/interop/idt/Dockerfile b/src/tools/interop/idt/Dockerfile
deleted file mode 100644
index 29036c3..0000000
--- a/src/tools/interop/idt/Dockerfile
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-FROM debian:bookworm
-RUN apt-get update && \
- apt-get install -y \
- adb \
- aircrack-ng \
- apt-utils \
- bison \
- byacc \
- dnsutils \
- flex \
- gcc-aarch64-linux-gnu \
- gcc-arm-linux-gnueabi \
- git \
- glib-2.0 \
- kmod \
- libbluetooth-dev \
- libboost-python-dev \
- libboost-thread-dev \
- libglib2.0-dev \
- net-tools \
- pciutils \
- pkg-config \
- python3-pip \
- python3.11 \
- python3.11-venv \
- tcpdump \
- usbutils \
- wget && \
- echo "wireshark-common wireshark-common/install-setuid boolean true" | debconf-set-selections && \
- DEBIAN_FRONTEND=noninteractive apt-get -y install wireshark && \
- rm -rf /var/lib/apt/lists/*
-RUN usermod -aG plugdev $(whoami)
-RUN git clone https://github.com/openthread/ot-br-posix
-COPY requirements.txt /
-RUN /bin/bash -c "python3 -m venv /env && source /env/bin/activate && pip install -r requirements.txt"
-RUN echo "source /env/bin/activate; pip -V; source /idt/scripts/alias.sh;" >> /root/.bashrc
-ENTRYPOINT ["/bin/bash"]
diff --git a/src/tools/interop/idt/README.md b/src/tools/interop/idt/README.md
deleted file mode 100644
index acc0c25..0000000
--- a/src/tools/interop/idt/README.md
+++ /dev/null
@@ -1,365 +0,0 @@
-# Interoperability Debugging Tool
-
-## Overview
-
-The “Interoperability Debugging Tool” (IDT) is a python-based tool that supports
-a variety of commands that are useful in the context of interoperability testing
-of Matter devices and app controllers.
-
-### Discovery
-
-While in discovery mode, the tool displays all Matter devices that are in
-commission and/or operational mode. This is useful to have a clear understanding
-of all Matter devices currently “active” in the testing environment.
-
-See section “4.3. Discovery” of the Matter spec for official documentation.
-
-When run interactively, discovery functions in one of two modes: BLE and DNS-SD.
-
-### Capture
-
-While in capture mode, the tool starts capturing all data of interest (e.g.
-video recording of interactions with the mobile app, logs from all components
-involved, network packets capture, etc.) while a test is being conducted
-manually. It also provides feedback to the user on test setup and execution.
-
-When the test completes, capture mode is stopped and all captured data is zipped
-in a file that can then be sent to all parties involved in investigating any
-issue uncovered via the manual test. Each ecosystem may implement an analysis
-that analyzes capture data, displays info to the user, probes the local
-environment and generates additional artifacts.
-
-## Single host installation (no Raspberry Pi)
-
-All features of `idt` are available on macOS and Linux (tested with Debian based
-systems).
-If you would prefer to execute capture and discovery from a Raspberry Pi, read
-the next section instead.
-
-The machine running `idt` should be connected to the same Wi-Fi network used for
-testing.
-Follow the steps below to execute capture and discovery without a Raspberry Pi:
-
-- From the parent directory of `idt`, run `source idt/scripts/alias.sh`.
-- Optionally, run `source idt/scripts/setup_shell.sh` to install aliases
- permanently.
-- After `idt` aliases are available in your environment, calling any `idt`
- command will automatically create a new virtual environment and install
- python dependencies.
- - If you're missing non-Python dependencies, you'll be prompted to install
- them until they're available.
-- Bluetooth discovery on macOS will require granting the program where `idt`
- is run, e.g. terminal emulator or IDE permission to access bluetooth in
- macOS settings.
- - Failure to do so may result in any of the following:
- - A single `abort` message and no further output in the terminal.
- - Failure with a relevant stack trace in the terminal.
- - A prompt to allow the application access to bluetooth.
-
-## Raspberry Pi installation
-
-### Environment overview
-
-The execution environment of IDT when using Raspberry Pi is shown in the figure
-below.
-
-[TODO] add figure.
-
-The Raspberry Pi is where "discovery" and "capture" are executed.
-
-The "admin" computer is the machine used to connect to and control the RPi, and
-to fetch artifacts which were created during capture from the RPi.
-
-This directory contains tools for use on both the admin computer and the RPi.
-
-### Environment details
-
-1. `idt` will be used on both the admin computer and the RPi.
-1. `scripts` only points to one installation location at a time. It is ideal to
- maintain a single `idt` directory on each (admin and RPi) system accordingly.
-1. The expected install location on the RPi is the home directory of the user
- specified in `idt/scripts/vars.sh`, which will be generated by running a
- script in the next section.
-1. Helper scripts may be used on admin computers that support `zsh` and `bash`
- (Linux and macOS).
-1. Windows may be used as the admin computer via tools like `PowerShell`,
- `MobaXterm` and `FileZilla`.
-1. This setup is intended to work with the admin computer and RPi connected to
- the same Wi-Fi network, which is also the Wi-Fi network used for testing.
-1. Corporate networks are not expected to be used as test networks.
-
-### Prepare the RPi
-
-1. A >= 128 GB SD card is recommended.
-1. Flash the RPi SD with the debian based distribution of your choice.
-1. Plug the SD into the RPi.
-1. Ensure the RPi is connected to your network, either via ethernet or with
- Wi-Fi configured in the disk image.
-1. Boot the RPi.
-
-### Configure admin computer and push to the RPi
-
-#### Linux and macOS admin computers
-
-1. On your admin computer, source the `alias` script from the parent directory
- of `idt` to get `idt` commands in your current shell.
- ```
- source idt/scripts/alias.sh
- ```
- - To avoid having to repeat this step for each session, optionally configure
- automatic aliases permanently.
- - **_NOTE:_** Once run, `idt` commands will be globally and automatically
- available. If you need to remove the installation, edit the `.rc` files
- mentioned in `setup_shell`.
- ```
- source idt/scripts/setup_shell.sh
- ```
-1. Run `idt_create_vars` and follow the prompts to set IDs for the target RPi.
-1. Send `idt` to the RPi:
- ```
- idt_push
- ```
-1. `ssh` to the RPi:
- - **_NOTE:_** You may need to wait a few minutes after boot for the `ssh`
- server to be available on the RPi. Retry if needed!
- ```
- idt_connect
- ```
-
-#### Windows admin computers
-
-1. Open `PowerShell`, cd to the directory containing `idt` and send `idt` to the
- RPi:
- ```
- scp -r ./idt/* $PIUSER@$PIHOST:/home/$PIUSER/idt
- ```
-1. `ssh` to the RPi, e.g. with `MobaXterm`
- - **_NOTE:_** You may need to wait a few minutes after boot for the `ssh`
- server to be available on the RPi. Retry if needed!
- - Use `$PIUSER@$PIHOST` or `$PIUSER@$ip` where `$ip` is the RPi's IP found
- in your router admin panel.
-
-### Configure the RPi
-
-1. Configure passwords or ssh keys.
-1. Configure Wi-Fi networks if needed.
-1. Set up `idt`:
- ```
- cd ~ # Go to idt parent dir
- source idt/scripts/setup_shell.sh # Setup atuo aliases
- source idt/scripts/alias.sh # Get aliases now
- idt_bootstrap # Initial configuration
- idt_build # Build the container image
- ```
-
-### Install updates
-
-SCP may not overwrite all files. To clear the `idt` dir off of the RPi safely
-between pushes, exit the container and:
-
-```
-idt_clean
-```
-
-NOTE the idt artifacts directory is contained in idt, so running this will
-delete any artifacts.
-
-Then from the admin computer:
-
-```
-idt_push
-```
-
-## User guide
-
-> **_IMPORTANT_**
-> `idt_` commands are shell aliases helpful for administrative commands.
-> `idt` invokes the `idt` python package.
-> Output from `idt` will generally be colorized while output from sub processes
-> is generally not.
-
-RPi users, as needed:
-
-- For users with Windows admin computers, reconnect e.g., using `MobaXterm`
-- Other users reconnect `ssh` to the RPi (from your admin computer):
- ```
- idt_connect
- ```
-- Run the `idt` container (from the RPi):
- ```
- idt_activate
- ```
-
-### Capture
-
-> **_IMPORTANT_**
-> Ensure you've made it to the log line "Starting real time analysis, press
-> enter to stop!" before launching the app under test.
-
-```
-idt capture -h
-
-usage: idt capture [-h] [--platform {Android}] [--ecosystem {PlayServicesUser,PlayServices,ALL}] [--pcap {t,f}] [--interface {wlp0s20f3,lo,docker0,any}]
-
-options:
- -h, --help show this help message and exit
- --platform {Android}, -p {Android}
- Run capture for a particular platform (default Android)
- --ecosystem {PlayServicesUser,PlayServices,ALL}, -e {PlayServicesUser,PlayServices,ALL}
- Run capture for a particular ecosystem or ALL ecosystems (default ALL)
- --pcap {t,f}, -c {t,f}
- Run packet capture (default t)
- --interface {wlp0s20f3,lo,docker0,any}, -i {wlp0s20f3,lo,docker0,any}
- Specify packet capture interface (default any)
-```
-
-For packet capture interface (`-i`/`--interface`:
-
-- On macOS, the only available interface is `any`.
-- On Linux, `idt` checks available interfaces from `/sys/class/net/` as well
- as allowing `any`.
-
-#### Artifacts
-
-Each ecosystem and platform involved in the capture will have their own
-subdirectory in the root artifact dir.
-
-### Discovery
-
-```
-idt discover -h
-
-usage: idt discover [-h] --type {ble,b,dnssd,d}
-
-options:
- -h, --help show this help message and exit
- --type {ble,b,dnssd,d}, -t {ble,b,dnssd,d}
- Specify the type of discovery to execute
-```
-
-#### BLE
-
-```
-idt discover -t b
-```
-
-#### mDNS
-
-```
-idt discover -t d
-```
-
-#### Artifacts
-
-There is a per device log in `ble` and `dnssd` subdirectory of the root artifact
-dir.
-
-### Probe
-
-```
-usage: idt probe [-h]
-
-options:
- -h, --help show this help message and exit
-```
-
-Collect contextually relevant networking info from the local environment and
-provide artifacts.
-
-## Troubleshooting
-
-- Wireless `adb` may fail to connect indefinitely depending on network
- configuration. Use a wired connection if wireless fails repeatedly.
-- Change log level from `INFO` to `DEBUG` in root `config.py` for additional
- logging.
-- Compiling `tcpdump` for android may require additional dependencies.
- - If the build script fails for you, try
- `idt_go && source idt/scripts/compilers.sh`.
-- You may disable colors and splash by setting `enable_color` in `config.py`
- to `False`.
-- `idt_clean_child` will kill any stray `tcpdump` and `adb` commands.
- - `idt_check_child` will look for leftover processes.
- - Not expected to be needed outside of development scenarios.
-
-## Project overview
-
-- The entry point is in `idt.py` which contains simple CLI parsing with
- `argparse`.
-
-### `capture`
-
-- `base` contains the base classes for ecosystems and platforms.
-- `controller` contains the ecosystem and platform producer and controller
-- `loader` is a generic class loader that dynamically imports classes matching
- a given super class from a given directory.
-- `/platform` and `/ecosystem` contain one package for each platform and
- ecosystem, which should each contain one implementation of the respective
- base class.
-
-### `discovery`
-
-- `matter_ble` provides a simple ble scanner that shows matter devices being
- discovered and lost, as well as their VID/PID, RSSI, etc.
-- `matter_dnssd` provides a simple DNS-SD browser that searches for matter
- devices and thread border routers.
-
-### `probe`
-
-- `probe` contains the base class for (`idt`'s) host platform specific
- implementation.
- - Reuses the dnssd discovery implementation to build probe targets.
- - Calls platform + addr type specific probe methods for each target.
-- `linux` and `mac` contain `probe` implementations for each host platform.
-
-### `utils`
-
-- `log` contains logging utilities used by everything in the project.
-- `artifact` contains helper functions for managing artifacts.
-- `shell` contains a simple helper class for background and foreground Bash
- commands.
-- `host_platform` contains helper functions for the interacting with the host
- running `idt`.
-
-### Conventions
-
-- `config.py` should be used to hold development configs within the directory
- where they are needed.
- - It may also hold configs for flaky/cumbersome features that might need
- to be disabled in an emergency.
- - `config.py` **should not** be used for everyday operation.
-- When needed, execute builds in a folder called `BUILD` within the source
- tree.
- - `idt_clean_all` deletes all `BUILD` dirs and `BUILD` is in `.gitignore`.
-
-## Extending functionality
-
-### Capture
-
-Ecosystem and Platform implementations are dynamically loaded.
-
-For each package in `capture/ecosystem`, the ecosystem loader expects a module
-name matching the package name.
-This module must contain a single class which is a subclass of
-`capture.base.EcosystemCapture`.
-
-`/capture/ecosystem/play_services_user` contains a minimal example
-implementation.
-
-As another example, link `/res/plugin_demo/ecosystem/demo_ext_ecosystem`.
-
-```
-$ idt_go && ln -s $PWD/idt/res/plugin_demo/ecosystem/demo_ext_ecosystem/ idt/capture/ecosystem
-$ idt capture -h
-usage: idt capture [-h] [--platform {Android}] [--ecosystem {DemoExtEcosystem...
-```
-
-> **IMPORTANT:** Note the following runtime expectations of ecosystems:
-> `analyze_capture()` must not block the async event loop excessively and must
-> not interact with standard in
-
-The platform loader functions the same as `capture/ecosystem`.
-
-For each package in `capture/platform`, the platform loader expects a module
-name matching the package name.
-This module must contain a single class which is a subclass of
-`capture.base.PlatformLogStreamer`.
diff --git a/src/tools/interop/idt/__main__.py b/src/tools/interop/idt/__main__.py
deleted file mode 100644
index b927d05..0000000
--- a/src/tools/interop/idt/__main__.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from idt import InteropDebuggingTool
-from utils.host_platform import verify_py_version
-
-if __name__ == "__main__":
- verify_py_version()
- InteropDebuggingTool()
diff --git a/src/tools/interop/idt/capture/__init__.py b/src/tools/interop/idt/capture/__init__.py
deleted file mode 100644
index 18069e7..0000000
--- a/src/tools/interop/idt/capture/__init__.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from capture import ecosystem, platform
-
-from .controller import EcosystemCapture, PlatformLogStreamer
-from .pcap import PacketCaptureRunner
-
-__all__ = [
- 'ecosystem',
- 'platform',
- 'controller',
- 'EcosystemCapture',
- 'PacketCaptureRunner',
- 'PlatformLogStreamer',
-]
diff --git a/src/tools/interop/idt/capture/base.py b/src/tools/interop/idt/capture/base.py
deleted file mode 100644
index b905710..0000000
--- a/src/tools/interop/idt/capture/base.py
+++ /dev/null
@@ -1,114 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from abc import ABC, abstractmethod
-
-
-class PlatformLogStreamer(ABC):
- """
- The abstract base class for a platform transport, subclassed by sub packages of platform
- """
-
- @abstractmethod
- def __init__(self, artifact_dir: str) -> None:
- """
- artifact_dir: the fully qualified path of the output directory. This directory already exists
- """
- raise NotImplementedError
-
- @abstractmethod
- async def connect(self) -> None:
- """
- Establish connections to log targets for this platform
- """
- raise NotImplementedError
-
- @abstractmethod
- async def start_streaming(self) -> None:
- """
- Begin streaming logs
- """
- raise NotImplementedError
-
- @abstractmethod
- async def run_observers(self) -> None:
- """
- Observe log procs and restart as needed
- Must be async aware and not interact with stdin
- """
- raise NotImplementedError
-
- @abstractmethod
- async def stop_streaming(self) -> None:
- """
- Stop the capture and pull any artifacts from remote devices
- Write artifacts to artifact_dir passed on instantiation
- """
- raise NotImplementedError
-
-
-class UnsupportedCapturePlatformException(Exception):
- """EcosystemCapture should raise this for unsupported platform"""
-
- def __init__(self, message: str):
- super().__init__(message)
-
-
-class EcosystemCapture(ABC):
-
- @abstractmethod
- def __init__(
- self,
- platform: PlatformLogStreamer,
- artifact_dir: str) -> None:
- """
- platform: the instance of the log streamer for the selected platform
- artifact_dir: the fully qualified path of the output directory. This directory already exists.
- """
- raise NotImplementedError
-
- @abstractmethod
- async def start_capture(self) -> None:
- """
- Start the capture
- Platform is already started
- """
- raise NotImplementedError
-
- @abstractmethod
- async def stop_capture(self) -> None:
- """
- Stop the capture and pull any artifacts from remote devices
- Write artifacts to artifact_dir passed on instantiation
- Platform is already stopped
- """
- raise NotImplementedError
-
- @abstractmethod
- async def analyze_capture(self) -> None:
- """
- Parse the capture and create + display helpful analysis artifacts that are unique to the ecosystem
- Must be async aware and not interact with stdin
- """
- raise NotImplementedError
-
- @abstractmethod
- async def probe_capture(self) -> None:
- """
- Probe the local environment, e.g. ping relevant remote services and write respective artifacts
- """
- raise NotImplementedError
diff --git a/src/tools/interop/idt/capture/config.py b/src/tools/interop/idt/capture/config.py
deleted file mode 100644
index 12ce985..0000000
--- a/src/tools/interop/idt/capture/config.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""
-The timeout time used by Orchestrator in capture/controller
-
-Used when calling:
-- Platform.connect() - if timeout, then halt
-- Ecosystem.start(), .stop(), .probe() - if timeout, then continue execution and log error
-
-This is an async timeout, so dependent on event loop being released to work.
-To illustrate, consider this example where no timeout is thrown despite the awaited task running for twice the timeout:
-----
-sleep_time = 2
-
-async def not_actually_async():
- time.sleep(sleep_time * 2) # Blocking the EL!
-
-async def try_timeout():
- async with asyncio.timeout(sleep_time):
- await not_actually_async()
- print("Timeout was NOT thrown!")
-
-asyncio.run(try_timeout())
-----
-Result: Timeout was NOT thrown!
-
-Update the example
-----
-async def not_actually_async(): # Now it is_actually_async because we
- await asyncio.sleep(sleep_time * 2) # change to something that isn't blocking the EL
-----
-Result: The timeout error will be raised.
-
-"""
-orchestrator_async_step_timeout_seconds = 240
diff --git a/src/tools/interop/idt/capture/controller.py b/src/tools/interop/idt/capture/controller.py
deleted file mode 100644
index 624a6f2..0000000
--- a/src/tools/interop/idt/capture/controller.py
+++ /dev/null
@@ -1,183 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import asyncio
-import copy
-import os
-import sys
-import traceback
-import typing
-from dataclasses import dataclass
-
-import capture
-from capture.base import EcosystemCapture, PlatformLogStreamer, UnsupportedCapturePlatformException
-from utils.artifact import create_standard_log_name, log, safe_mkdir
-from utils.log import add_border, border_print
-
-from . import config
-
-
-@dataclass(repr=True)
-class ErrorRecord:
- ecosystem: str
- help_message: str
- stack_trace: str
-
-
-_PLATFORM_MAP: typing.Dict[str, PlatformLogStreamer] = {}
-_ECOSYSTEM_MAP: typing.Dict[str, PlatformLogStreamer] = {}
-_ERROR_REPORT: typing.Dict[str, ErrorRecord] = {}
-
-logger = log.get_logger(__file__)
-
-
-def track_error(ecosystem: str, help_message: str) -> None:
- if ecosystem not in _ERROR_REPORT:
- _ERROR_REPORT[ecosystem] = []
- record = ErrorRecord(ecosystem, help_message, traceback.format_exc())
- logger.error(record)
- _ERROR_REPORT[ecosystem].append(record)
-
-
-def list_available_platforms() -> typing.List[str]:
- return copy.deepcopy(capture.platform.__all__)
-
-
-async def get_platform_impl(
- platform: str,
- artifact_dir: str) -> PlatformLogStreamer:
- if platform in _PLATFORM_MAP:
- return _PLATFORM_MAP[platform]
- border_print(f"Initializing platform {platform}")
- platform_class = getattr(capture.platform, platform)
- platform_artifact_dir = os.path.join(artifact_dir, platform)
- safe_mkdir(platform_artifact_dir)
- platform_inst = platform_class(platform_artifact_dir)
- _PLATFORM_MAP[platform] = platform_inst
- async with asyncio.timeout(config.orchestrator_async_step_timeout_seconds):
- await platform_inst.connect()
- return platform_inst
-
-
-def list_available_ecosystems() -> typing.List[str]:
- return copy.deepcopy(capture.ecosystem.__all__)
-
-
-async def get_ecosystem_impl(
- ecosystem: str,
- platform: PlatformLogStreamer,
- artifact_dir: str) -> EcosystemCapture:
- if ecosystem in _ECOSYSTEM_MAP:
- return _ECOSYSTEM_MAP[ecosystem]
- ecosystem_class = getattr(capture.ecosystem, ecosystem)
- ecosystem_artifact_dir = os.path.join(artifact_dir, ecosystem)
- safe_mkdir(ecosystem_artifact_dir)
- ecosystem_instance = ecosystem_class(platform, ecosystem_artifact_dir)
- _ECOSYSTEM_MAP[ecosystem] = ecosystem_instance
- return ecosystem_instance
-
-
-async def init_ecosystems(platform, ecosystem, artifact_dir):
- platform = await get_platform_impl(platform, artifact_dir)
- ecosystems_to_load = list_available_ecosystems() \
- if ecosystem == 'ALL' \
- else [ecosystem]
- for ecosystem in ecosystems_to_load:
- try:
- await get_ecosystem_impl(
- ecosystem, platform, artifact_dir)
- except UnsupportedCapturePlatformException:
- help_message = f"Unsupported platform {ecosystem} {platform}"
- logger.error(help_message)
- track_error(ecosystem, help_message)
- except Exception:
- help_message = f"Unknown error instantiating ecosystem {ecosystem} {platform}"
- logger.error(help_message)
- track_error(ecosystem, help_message)
-
-
-async def handle_capture(attr):
- attr = f"{attr}_capture"
- for ecosystem in _ECOSYSTEM_MAP:
- try:
- border_print(f"{attr} for {ecosystem}")
- async with asyncio.timeout(config.orchestrator_async_step_timeout_seconds):
- await getattr(_ECOSYSTEM_MAP[ecosystem], attr)()
- except TimeoutError:
- help_message = f"Timeout after {config.orchestrator_async_step_timeout_seconds} seconds {attr} {ecosystem}"
- logger.error(help_message)
- track_error(ecosystem, help_message)
- except Exception:
- help_message = f"Unexpected error {attr} {ecosystem}"
- logger.error(help_message)
- track_error(ecosystem, help_message)
-
-
-async def start():
- for platform_name, platform, in _PLATFORM_MAP.items():
- # TODO: Write error log if halt here
- border_print(f"Starting streaming for platform {platform_name}")
- await platform.start_streaming()
- await handle_capture("start")
-
-
-async def stop():
- for platform_name, platform, in _PLATFORM_MAP.items():
- # TODO: Write error log if halt here
- border_print(f"Stopping streaming for platform {platform_name}")
- await platform.stop_streaming()
- await handle_capture("stop")
-
-
-async def run_analyzers():
- border_print("Starting real time analysis, press enter to stop!", important=True)
- analysis_tasks = []
- monitor_tasks = []
- for platform_name, platform in _PLATFORM_MAP.items():
- logger.info(f"Creating monitor task for {platform_name}")
- monitor_tasks.append(asyncio.create_task(platform.run_observers()))
- for ecosystem_name, ecosystem in _ECOSYSTEM_MAP.items():
- logger.info(f"Creating analysis task for {ecosystem_name}")
- analysis_tasks.append(asyncio.create_task(ecosystem.analyze_capture()))
- logger.info("Done creating analysis tasks")
- await asyncio.get_event_loop().run_in_executor(
- None, sys.stdin.readline)
- border_print("Cancelling monitor tasks")
- for task in monitor_tasks:
- task.cancel()
- logger.info("Done cancelling monitor tasks")
- border_print("Cancelling analysis tasks")
- for task in analysis_tasks:
- task.cancel()
- logger.info("Done cancelling analysis tasks")
-
-
-async def probe():
- await handle_capture("probe")
-
-
-def write_error_report(artifact_dir: str):
- if _ERROR_REPORT:
- logger.critical("DETECTED ERRORS THIS RUN!")
- error_report_file_name = create_standard_log_name("error_report", "txt", parent=artifact_dir)
- with open(error_report_file_name, "a+") as error_report_file:
- for ecosystem in _ERROR_REPORT:
- log.print_and_write(add_border(f"Errors for {ecosystem}"), error_report_file)
- for record in _ERROR_REPORT[ecosystem]:
- log.print_and_write(str(record), error_report_file)
- else:
- logger.info("No errors seen this run!")
diff --git a/src/tools/interop/idt/capture/ecosystem/__init__.py b/src/tools/interop/idt/capture/ecosystem/__init__.py
deleted file mode 100644
index 432af96..0000000
--- a/src/tools/interop/idt/capture/ecosystem/__init__.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from capture.base import EcosystemCapture
-from capture.loader import CaptureImplsLoader
-
-impl_loader = CaptureImplsLoader(
- __path__[0],
- "capture.ecosystem",
- EcosystemCapture
-)
-
-for impl_name, impl in impl_loader.impls.items():
- globals()[impl_name] = impl
-
-__all__ = impl_loader.impl_names
diff --git a/src/tools/interop/idt/capture/ecosystem/play_services/__init__.py b/src/tools/interop/idt/capture/ecosystem/play_services/__init__.py
deleted file mode 100644
index ea3a466..0000000
--- a/src/tools/interop/idt/capture/ecosystem/play_services/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from .play_services import PlayServices
-
-__all__ = [
- 'PlayServices'
-]
diff --git a/src/tools/interop/idt/capture/ecosystem/play_services/command_map.py b/src/tools/interop/idt/capture/ecosystem/play_services/command_map.py
deleted file mode 100644
index 4adf9b5..0000000
--- a/src/tools/interop/idt/capture/ecosystem/play_services/command_map.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-getprop = {
- 'ro.product.model': 'android_model',
- 'ro.build.version.release': 'android_version',
- 'ro.build.version.sdk': 'android_api',
- 'ro.build.fingerprint': 'build_fingerprint',
- 'ro.odm.build.fingerprint': 'odm_build_fingerprint',
- 'ro.product.build.fingerprint': 'product_build_fingerprint',
- 'ro.ecosystem.build.fingerprint': 'vendor_build_fingerprint',
-}
-
-_ap = 'activity provider com.google.android.gms.chimera.container.GmsModuleProvider'
-dumpsys = {
- 'display_width': 'display | grep StableDisplayWidth | awk -F\'=\' \'{print $2}\'',
- 'display_height': 'display | grep StableDisplayHeight | awk -F\'=\' \'{print $2}\'',
- 'gha_info': ' package com.google.android.apps.chromecast.app | grep versionName',
- 'container_info': 'package com.google.android.gms | grep "versionName"',
- 'home_module_info': f'{_ap} | grep "com.google.android.gms.home" | grep -v graph',
- 'optional_home_module_info': f'{_ap} | grep "com.google.android.gms.optional_home" | grep -v graph',
- 'policy_home_module_info': f'{_ap} | grep "com.google.android.gms.policy_home" | grep -v graph',
- 'thread_info': f'{_ap} | grep "com.google.android.gms.threadnetwork"',
- 'mdns_info': f'{_ap} | grep -i com.google.android.gms.mdns',
-}
diff --git a/src/tools/interop/idt/capture/ecosystem/play_services/config.py b/src/tools/interop/idt/capture/ecosystem/play_services/config.py
deleted file mode 100644
index 2daacb3..0000000
--- a/src/tools/interop/idt/capture/ecosystem/play_services/config.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-enable_foyer_probers = True
-foyer_prober_traceroute_limit = 32
diff --git a/src/tools/interop/idt/capture/ecosystem/play_services/play_services.py b/src/tools/interop/idt/capture/ecosystem/play_services/play_services.py
deleted file mode 100644
index e94a10f..0000000
--- a/src/tools/interop/idt/capture/ecosystem/play_services/play_services.py
+++ /dev/null
@@ -1,117 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import asyncio
-import json
-import os
-from typing import IO, Dict
-
-from capture.base import EcosystemCapture, UnsupportedCapturePlatformException
-from capture.platform.android import Android
-from capture.platform.android.streams.logcat import LogcatStreamer
-from utils.artifact import create_standard_log_name, log
-
-from . import config
-from .command_map import dumpsys, getprop
-from .play_services_analysis import PlayServicesAnalysis
-from .prober import PlayServicesProber
-
-logger = log.get_logger(__file__)
-
-
-class PlayServices(EcosystemCapture):
- """
- Implementation of capture and analysis for Play Services
- """
-
- def __init__(self, platform: Android, artifact_dir: str) -> None:
- self.artifact_dir = artifact_dir
-
- if not isinstance(platform, Android):
- raise UnsupportedCapturePlatformException(
- 'only platform=android is supported for ecosystem=play_services')
- self.platform = platform
-
- self.standard_info_file_path = os.path.join(
- self.artifact_dir, create_standard_log_name(
- 'phone_info', 'json'))
- self.standard_info_data: Dict[str, str] = {}
-
- self.analysis = PlayServicesAnalysis(self.platform, self.artifact_dir)
-
- self.service_ids = ['336', # Home
- '305', # Thread
- '168', # mDNS
- ]
- self.logcat_stream: LogcatStreamer = self.platform.streams["LogcatStreamer"]
- self.logcat_file: IO = None
-
- def _write_standard_info_file(self) -> None:
- for k, v in self.standard_info_data.items():
- logger.info(f"{k}: {v}")
- standard_info_data_json = json.dumps(self.standard_info_data, indent=2)
- with open(self.standard_info_file_path, mode='w+') as standard_info_file:
- standard_info_file.write(standard_info_data_json)
-
- def _parse_get_prop(self) -> None:
- get_prop = self.platform.run_adb_command(
- "shell getprop",
- capture_output=True).get_captured_output()
- for output in get_prop.split("\n"):
- for prop in getprop:
- if prop in output:
- self.standard_info_data[prop] = output[output.rindex("["):]
-
- def _parse_dumpsys(self) -> None:
- for attr_name, command in dumpsys.items():
- command = f"shell dumpsys {command}"
- command_output = self.platform.run_adb_command(
- command,
- capture_output=True).get_captured_output()
- self.standard_info_data[attr_name] = command_output
-
- def _get_standard_info(self) -> None:
- self._parse_get_prop()
- self._parse_dumpsys()
- self._write_standard_info_file()
-
- async def start_capture(self) -> None:
- for service_id in self.service_ids:
- verbose_command = f"shell setprop log.tag.gms_svc_id:{service_id} VERBOSE"
- self.platform.run_adb_command(verbose_command)
- self._get_standard_info()
-
- async def analyze_capture(self):
- try:
- self.logcat_file = open(self.logcat_stream.logcat_artifact, "r")
- while True:
- self.analysis.do_analysis(self.logcat_file.readlines())
- # Releasing async event loop for other analysis / monitor topics
- await asyncio.sleep(0.5)
- except asyncio.CancelledError:
- logger.info("Closing logcat stream")
- if self.logcat_file:
- self.logcat_file.close()
-
- async def stop_capture(self) -> None:
- self.analysis.show_analysis()
-
- async def probe_capture(self) -> None:
- if config.enable_foyer_probers:
- await PlayServicesProber(self.platform, self.artifact_dir).probe_services()
- else:
- logger.critical("Foyer probers disabled in config!")
diff --git a/src/tools/interop/idt/capture/ecosystem/play_services/play_services_analysis.py b/src/tools/interop/idt/capture/ecosystem/play_services/play_services_analysis.py
deleted file mode 100644
index e6ebb8f..0000000
--- a/src/tools/interop/idt/capture/ecosystem/play_services/play_services_analysis.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import os
-
-from capture.platform.android import Android
-from utils.artifact import create_standard_log_name, log
-from utils.log import add_border, print_and_write
-
-logger = log.get_logger(__file__)
-
-
-class PlayServicesAnalysis:
-
- def __init__(self, platform: Android, artifact_dir: str) -> None:
- self.logger = logger
- self.artifact_dir = artifact_dir
- self.analysis_file_name = os.path.join(
- self.artifact_dir, create_standard_log_name(
- 'commissioning_logcat', 'txt'))
-
- self.platform = platform
-
- self.matter_commissioner_logs = ''
- self.failure_stack_trace = ''
- self.pake_logs = ''
- self.resolver_logs = ''
- self.sigma_logs = ''
- self.fail_trace_line_counter = -1
-
- def _log_proc_matter_commissioner(self, line: str) -> None:
- """Core commissioning flow"""
- if 'MatterCommissioner' in line:
- self.logger.info(line)
- self.matter_commissioner_logs += line
-
- def _log_proc_commissioning_failed(self, line: str) -> None:
- parsed_stack_trace_max_depth = 15
- if self.fail_trace_line_counter > parsed_stack_trace_max_depth:
- self.fail_trace_line_counter = -1
- if self.fail_trace_line_counter > -1 and 'SetupDevice' in line:
- self.failure_stack_trace += line
- self.fail_trace_line_counter += 1
- if 'SetupDeviceView' and 'Commissioning failed' in line:
- self.logger.info(line)
- self.fail_trace_line_counter = 0
- self.failure_stack_trace += line
-
- def _log_proc_pake(self, line: str) -> None:
- """Three logs for pake 1-3 expected"""
- if "Pake" in line and "chip_logging" in line:
- self.logger.info(line)
- self.pake_logs += line
-
- def _log_proc_mdns(self, line: str) -> None:
- if "_matter" in line and "ServiceResolverAdapter" in line:
- self.logger.info(line)
- self.resolver_logs += line
-
- def _log_proc_sigma(self, line: str) -> None:
- """Three logs expected for sigma 1-3"""
- if "Sigma" in line and "chip_logging" in line:
- self.logger.info(line)
- self.sigma_logs += line
-
- def show_analysis(self) -> None:
- analysis_file = open(self.analysis_file_name, mode="w+")
- print_and_write(add_border('Matter commissioner logs'), analysis_file)
- print_and_write(self.matter_commissioner_logs, analysis_file)
- print_and_write(
- add_border('Commissioning failure stack trace'),
- analysis_file)
- print_and_write(self.failure_stack_trace, analysis_file)
- print_and_write(add_border('PASE Handshake'), analysis_file)
- print_and_write(self.pake_logs, analysis_file)
- print_and_write(add_border('DNS-SD resolution'), analysis_file)
- print_and_write(self.resolver_logs, analysis_file)
- print_and_write(add_border('CASE handshake'), analysis_file)
- print_and_write(self.sigma_logs, analysis_file)
- analysis_file.close()
-
- def process_line(self, line: str) -> None:
- for line_func in [s for s in dir(self) if s.startswith('_log')]:
- getattr(self, line_func)(line)
-
- def do_analysis(self, batch: [str]) -> None:
- for line in batch:
- self.process_line(line)
diff --git a/src/tools/interop/idt/capture/ecosystem/play_services/prober.py b/src/tools/interop/idt/capture/ecosystem/play_services/prober.py
deleted file mode 100644
index 8dcda80..0000000
--- a/src/tools/interop/idt/capture/ecosystem/play_services/prober.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import os
-
-from utils.shell import Bash, log
-
-from . import config
-
-logger = log.get_logger(__file__)
-
-
-class PlayServicesProber:
-
- def __init__(self, platform, artifact_dir):
- # TODO: Handle all resolved addresses
- self.platform = platform
- self.artifact_dir = artifact_dir
- self.logger = logger
- self.probe_artifact = os.path.join(self.artifact_dir, "net_probes.txt")
- self.command_suffix = f" 2>&1 | tee -a {self.probe_artifact}"
- self.target = "googlehomefoyer-pa.googleapis.com"
- self.tracert_limit = config.foyer_prober_traceroute_limit
-
- def run_command(self, command):
- Bash(f"{command} {self.command_suffix}", sync=True).start_command()
-
- async def _probe_tracert_icmp_foyer(self) -> None:
- self.logger.info(f"icmp traceroute to {self.target}")
- self.run_command(f"traceroute -m {self.tracert_limit} {self.target}")
-
- async def _probe_tracert_udp_foyer(self) -> None:
- # TODO: Per-host-platform impl
- self.logger.info(f"udp traceroute to {self.target}")
- self.run_command(f"traceroute -m {self.tracert_limit} -U -p 443 {self.target}")
-
- async def _probe_tracert_tcp_foyer(self) -> None:
- # TODO: Per-host-platform impl
- self.logger.info(f"tcp traceroute to {self.target}")
- self.run_command(f"traceroute -m {self.tracert_limit} -T -p 443 {self.target}")
-
- async def _probe_ping_foyer(self) -> None:
- self.logger.info(f"ping {self.target}")
- self.run_command(f"ping -c 4 {self.target}")
-
- async def _probe_dns_foyer(self) -> None:
- self.logger.info(f"dig {self.target}")
- self.run_command(f"dig {self.target}")
-
- async def _probe_from_phone_ping_foyer(self) -> None:
- self.logger.info(f"ping {self.target} from phone")
- self.platform.run_adb_command(f"shell ping -c 4 {self.target} {self.command_suffix}")
-
- async def probe_services(self) -> None:
- self.logger.info(f"Probing {self.target}")
- for probe_func in [s for s in dir(self) if s.startswith('_probe')]:
- await getattr(self, probe_func)()
diff --git a/src/tools/interop/idt/capture/ecosystem/play_services_user/__init__.py b/src/tools/interop/idt/capture/ecosystem/play_services_user/__init__.py
deleted file mode 100644
index ea02f9d..0000000
--- a/src/tools/interop/idt/capture/ecosystem/play_services_user/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from .play_services_user import PlayServicesUser
-
-__all__ = [
- 'PlayServicesUser'
-]
diff --git a/src/tools/interop/idt/capture/ecosystem/play_services_user/play_services_user.py b/src/tools/interop/idt/capture/ecosystem/play_services_user/play_services_user.py
deleted file mode 100644
index 2fdac62..0000000
--- a/src/tools/interop/idt/capture/ecosystem/play_services_user/play_services_user.py
+++ /dev/null
@@ -1,90 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import asyncio
-import os
-
-from capture.base import EcosystemCapture, UnsupportedCapturePlatformException
-from capture.platform.android.android import Android
-from capture.platform.android.streams.logcat import LogcatStreamer
-from utils.artifact import create_standard_log_name
-from utils.log import get_logger, print_and_write
-
-logger = get_logger(__file__)
-
-
-class PlayServicesUser(EcosystemCapture):
- """
- Implementation of capture and analysis for Play Services 3P
- """
-
- def __init__(self, platform: Android, artifact_dir: str) -> None:
- self.logger = logger
- self.artifact_dir = artifact_dir
- self.analysis_file = os.path.join(
- self.artifact_dir, create_standard_log_name(
- 'commissioning_boundaries', 'txt'))
-
- if not isinstance(platform, Android):
- raise UnsupportedCapturePlatformException(
- 'only platform=android is supported for '
- 'ecosystem=PlayServicesUser')
- self.platform = platform
- self.logcat_fd = None
- self.output = ""
- self.logcat_stream: LogcatStreamer = self.platform.streams["LogcatStreamer"]
-
- async def start_capture(self) -> None:
- pass
-
- async def stop_capture(self) -> None:
- self.show_analysis()
-
- def proc_line(self, line) -> None:
- if "CommissioningServiceBin: Binding to service" in line:
- s = f"3P commissioner initiated Play Services commissioning\n{line}"
- logger.info(s)
- self.output += f"{s}\n"
- elif "CommissioningServiceBin: Sending commissioning request to bound service" in line:
- s = f"Play Services commissioning complete; passing back to 3P\n{line}"
- logger.info(s)
- self.output += f"{s}\n"
- elif "CommissioningServiceBin: Received commissioning complete from bound service" in line:
- s = f"3P commissioning complete!\n{line}"
- logger.info(s)
- self.output += f"{s}\n"
-
- async def analyze_capture(self) -> None:
- """"Show the start and end times of commissioning boundaries"""
- try:
- self.logcat_fd = open(self.logcat_stream.logcat_artifact, "r")
- while True:
- for line in self.logcat_fd.readlines():
- self.proc_line(line)
- # Releasing async event loop for other analysis / monitor tasks
- await asyncio.sleep(0.5)
- except asyncio.CancelledError:
- self.logger.info("Closing logcat stream")
- if self.logcat_fd is not None:
- self.logcat_fd.close()
-
- def show_analysis(self) -> None:
- with open(self.analysis_file, "w") as analysis_file:
- print_and_write(self.output, analysis_file)
-
- async def probe_capture(self) -> None:
- pass
diff --git a/src/tools/interop/idt/capture/loader.py b/src/tools/interop/idt/capture/loader.py
deleted file mode 100644
index 8e02e9d..0000000
--- a/src/tools/interop/idt/capture/loader.py
+++ /dev/null
@@ -1,104 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import importlib
-import inspect
-import os
-import traceback
-from typing import Any
-
-from utils import log
-
-logger = log.get_logger(__file__)
-
-
-class CaptureImplsLoader:
-
- def __init__(self, root_dir: str, root_package: str, search_type: type):
- self.logger = logger
- self.root_dir = root_dir
- self.root_package = root_package
- self.search_type = search_type
- self.impl_names = []
- self.impls = {}
- self.fetch_impls()
-
- @staticmethod
- def is_package(potential_package: str) -> bool:
- init_path = os.path.join(potential_package,
- "__init__.py")
- return os.path.exists(init_path)
-
- def verify_coroutines(self, subclass) -> bool:
- # ABC does not verify coroutines on subclass instantiation, it merely checks the presence of methods
- for item in dir(self.search_type):
- item_attr = getattr(self.search_type, item)
- if inspect.iscoroutinefunction(item_attr):
- if not hasattr(subclass, item):
- self.logger.warning(f"Missing coroutine in {subclass}")
- return False
- if not inspect.iscoroutinefunction(getattr(subclass, item)):
- self.logger.warning(f"Missing coroutine in {subclass}")
- return False
- for item in dir(subclass):
- item_attr = getattr(subclass, item)
- if inspect.iscoroutinefunction(item_attr) and hasattr(self.search_type, item):
- if not inspect.iscoroutinefunction(getattr(self.search_type, item)):
- self.logger.warning(f"Unexpected coroutine in {subclass}")
- return False
- return True
-
- def is_type_match(self, potential_class_match: Any) -> bool:
- if inspect.isclass(potential_class_match):
- self.logger.debug(f"Checking {self.search_type} match against {potential_class_match}")
- if issubclass(potential_class_match, self.search_type):
- self.logger.debug(f"Found type match search: {self.search_type} match: {potential_class_match}")
- if self.verify_coroutines(potential_class_match):
- return True
- return False
-
- def load_module(self, to_load):
- self.logger.debug(f"Loading module {to_load}")
- saw_more_than_one_impl = False
- saw_one_impl = False
- found_class = None
- for module_item in dir(to_load):
- loaded_item = getattr(to_load, module_item)
- if self.is_type_match(loaded_item):
- found_class = module_item
- found_impl = loaded_item
- if not saw_one_impl:
- saw_one_impl = True
- else:
- saw_more_than_one_impl = True
- if saw_one_impl and not saw_more_than_one_impl:
- self.impl_names.append(found_class)
- self.impls[found_class] = found_impl
- elif saw_more_than_one_impl:
- self.logger.warning(f"more than one impl in {module_item}")
-
- def fetch_impls(self):
- self.logger.debug(f"Searching for implementations in {self.root_dir}")
- for item in os.listdir(self.root_dir):
- dir_content = os.path.join(self.root_dir, item)
- if self.is_package(dir_content):
- self.logger.debug(f"Found package in {dir_content}")
- try:
- module = importlib.import_module("." + item, self.root_package)
- self.load_module(module)
- except ModuleNotFoundError:
- self.logger.warning(f"No module matching package name for {item}\n{traceback.format_exc()}")
diff --git a/src/tools/interop/idt/capture/pcap/__init__.py b/src/tools/interop/idt/capture/pcap/__init__.py
deleted file mode 100644
index b536056..0000000
--- a/src/tools/interop/idt/capture/pcap/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from .pcap import PacketCaptureRunner
-
-__all__ = [
- 'PacketCaptureRunner'
-]
diff --git a/src/tools/interop/idt/capture/pcap/pcap.py b/src/tools/interop/idt/capture/pcap/pcap.py
deleted file mode 100644
index 2cb2285..0000000
--- a/src/tools/interop/idt/capture/pcap/pcap.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import os
-import time
-
-from utils.artifact import create_standard_log_name, log
-from utils.shell import Bash
-
-logger = log.get_logger(__file__)
-
-
-class PacketCaptureRunner:
-
- def __init__(self, artifact_dir: str, interface: str) -> None:
- self.logger = logger
- self.artifact_dir = artifact_dir
- self.output_path = str(
- os.path.join(
- self.artifact_dir,
- create_standard_log_name(
- "pcap",
- "pcap")))
- self.start_delay_seconds = 2
- self.interface = interface
- self.pcap_command = f"tcpdump -i {self.interface} -n -w {self.output_path}"
- self.pcap_proc = Bash(self.pcap_command)
-
- def start_pcap(self) -> None:
- self.pcap_proc.start_command()
- self.logger.info("Pausing to check if pcap started...")
- time.sleep(self.start_delay_seconds)
- if not self.pcap_proc.command_is_running():
- self.logger.error(
- "Pcap did not start, you might need root; please authorize if prompted.")
- Bash("sudo echo \"\"", sync=True).start_command()
- self.logger.warning("Retrying pcap with sudo...")
- self.pcap_command = f"sudo {self.pcap_command}"
- self.pcap_proc = Bash(self.pcap_command)
- self.pcap_proc.start_command()
- time.sleep(self.start_delay_seconds)
- if not self.pcap_proc.command_is_running():
- self.logger.error("Failed to start pcap!")
- else:
- self.logger.info(f"Pcap output path {self.output_path}")
-
- def stop_pcap(self) -> None:
- self.logger.info("Stopping pcap proc")
- self.pcap_proc.stop_command()
diff --git a/src/tools/interop/idt/capture/platform/__init__.py b/src/tools/interop/idt/capture/platform/__init__.py
deleted file mode 100644
index 92c1efc..0000000
--- a/src/tools/interop/idt/capture/platform/__init__.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from capture.base import PlatformLogStreamer
-from capture.loader import CaptureImplsLoader
-
-impl_loader = CaptureImplsLoader(
- __path__[0],
- "capture.platform",
- PlatformLogStreamer
-)
-
-for impl_name, impl in impl_loader.impls.items():
- globals()[impl_name] = impl
-
-__all__ = impl_loader.impl_names
diff --git a/src/tools/interop/idt/capture/platform/android/__init__.py b/src/tools/interop/idt/capture/platform/android/__init__.py
deleted file mode 100644
index 021ec15..0000000
--- a/src/tools/interop/idt/capture/platform/android/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from .android import Android
-
-__all__ = [
- 'Android',
-]
diff --git a/src/tools/interop/idt/capture/platform/android/android.py b/src/tools/interop/idt/capture/platform/android/android.py
deleted file mode 100644
index 4ca8b26..0000000
--- a/src/tools/interop/idt/capture/platform/android/android.py
+++ /dev/null
@@ -1,226 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-import asyncio
-import ipaddress
-import os
-import traceback
-import typing
-from asyncio import Task
-
-from capture.base import PlatformLogStreamer
-from utils.shell import Bash, log
-
-from . import config, streams
-from .capabilities import Capabilities
-
-logger = log.get_logger(__file__)
-
-
-class Android(PlatformLogStreamer):
-
- def __init__(self, artifact_dir: str) -> None:
- self.logger = logger
- self.artifact_dir = artifact_dir
- self.device_id: str | None = None
- self.adb_devices: typing.Dict[str, bool] = {}
- self.capabilities: None | Capabilities = None
- self.streams = {}
- self.connected = False
-
- def run_adb_command(
- self,
- command: str,
- capture_output: bool = False,
- cwd=None) -> Bash:
- """
- Run an adb command synchronously
- Capture_output must be true to call get_captured_output() later
- """
- bash_command = Bash(
- f'adb -s {self.device_id} {command}',
- sync=True,
- capture_output=capture_output,
- cwd=cwd)
- bash_command.start_command()
- return bash_command
-
- def get_adb_background_command(
- self,
- command: str,
- cwd=None) -> Bash:
- return Bash(f'adb -s {self.device_id} {command}', cwd=cwd)
-
- def get_adb_devices(self) -> typing.Dict[str, bool]:
- """Returns a dict of device ids and whether they are authorized"""
- adb_devices = Bash('adb devices', sync=True, capture_output=True)
- adb_devices.start_command()
- adb_devices_output = adb_devices.get_captured_output().split('\n')
- devices_auth = {}
- header_done = False
- for line in adb_devices_output:
- if header_done:
- line_parsed = line.split("\t")
- device_id = line_parsed[0]
- device_is_auth = line_parsed[1] == "device"
- if line_parsed[1] == "offline":
- disconnect_command = f"adb disconnect {device_id}"
- self.logger.warning(f"Device {device_id} is offline, trying disconnect!")
- Bash(
- disconnect_command,
- sync=True,
- capture_output=False).start_command()
- else:
- devices_auth[device_id] = device_is_auth
- header_done = True
- self.adb_devices = devices_auth
- return self.adb_devices
-
- def _only_one_device_connected(self) -> bool:
- return len(self.adb_devices) == 1
-
- def _get_first_connected_device(self) -> str:
- return list(self.adb_devices.keys())[0]
-
- def _set_device_if_only_one_connected(self) -> None:
- if self._only_one_device_connected():
- self.device_id = self._get_first_connected_device()
- self.logger.warning(f'Only one device detected; using {self.device_id}')
-
- def _log_adb_devices(self) -> None:
- for dev in self.adb_devices:
- self.logger.info(dev)
-
- @staticmethod
- def _is_connection_str(adb_input_str: str) -> bool:
- valid_ipv4 = False
- port_entered = False
- valid_port = False
- split_on_colon = adb_input_str.split(":")
- try:
- ipaddress.IPv4Network(split_on_colon[0])
- valid_ipv4 = True
- except ValueError:
- pass
- if len(split_on_colon) > 1:
- port_entered = True
- try:
- port = int(split_on_colon[1])
- valid_port = port < 65535
- except ValueError:
- pass
- valid_ip_no_port = valid_ipv4 and not port_entered
- valid_ip_valid_port = valid_ipv4 and valid_port
- return valid_ip_no_port or valid_ip_valid_port
-
- def _check_connect_wireless_adb(self, temp_device_id: str) -> None:
- if Android._is_connection_str(temp_device_id):
- connect_command = f"adb connect {temp_device_id}"
- self.logger.warning(
- f"Detected connection string; attempting to connect: {connect_command}")
- Bash(connect_command, sync=True, capture_output=False).start_command()
- self.get_adb_devices()
-
- def _device_id_user_input(self) -> None:
- self.logger.error('Connect additional android devices via USB and press enter OR')
- self.logger.error('Enter (copy paste) the target device id from the list of available devices below OR')
- self.logger.error('Enter $IP4:$PORT to connect wireless debugging.')
- self._log_adb_devices()
- temp_device_id = input('').strip()
- self._check_connect_wireless_adb(temp_device_id)
- self.get_adb_devices()
- if self._only_one_device_connected():
- self._set_device_if_only_one_connected()
- elif temp_device_id not in self.adb_devices:
- self.logger.warning('Entered device not in adb devices!')
- else:
- self.device_id = temp_device_id
-
- def _choose_device_id(self) -> None:
- """
- Prompts the user to select a single device ID for this transport
- If only one device is ever connected, use it.
- """
- self._set_device_if_only_one_connected()
- while self.device_id not in self.get_adb_devices():
- self._device_id_user_input()
- self.logger.info(f'Selected device {self.device_id}')
-
- def _authorize_adb(self) -> None:
- """
- Prompts the user until a single device is selected and adb is auth'd
- """
- self.get_adb_devices()
- self._choose_device_id()
- while not self.get_adb_devices()[self.device_id]:
- self.logger.info('Confirming authorization, press enter after auth')
- input('')
- self.logger.info(f'Target android device ID is authorized: {self.device_id}')
-
- async def connect(self) -> None:
- if not self.connected:
- self._authorize_adb()
- self.capabilities = Capabilities(self)
- self.capabilities.check_capabilities()
- for stream in streams.__all__:
- self.streams[stream] = getattr(streams, stream)(self)
- self.connected = True
-
- async def handle_stream_action(self, action: str) -> None:
- had_error = False
- for stream_name, stream in self.streams.items():
- self.logger.info(f"Doing {action} for {stream_name}!")
- try:
- await getattr(stream, action)()
- except Exception:
- self.logger.error(traceback.format_exc())
- had_error = True
- if had_error:
- raise Exception("Propagating to controller!")
-
- async def start_streaming(self) -> None:
- await self.handle_stream_action("start")
-
- async def run_observers(self) -> None:
- try:
- observer_tasks: [Task] = []
- for stream_name, stream in self.streams.items():
- observer_tasks.append(asyncio.create_task(stream.run_observer()))
- while True:
- self.logger.info("Android root observer task checking sub tasks")
- for task in observer_tasks:
- if task.done() or task.cancelled():
- self.logger.error(f"An android monitoring task has died, consider restarting! {task.__str__()}")
- await asyncio.sleep(30)
- except asyncio.CancelledError:
- self.logger.info("Cancelling observer tasks")
- for observer_tasks in observer_tasks:
- observer_tasks.cancel()
-
- async def stop_streaming(self) -> None:
- await self.handle_stream_action("stop")
- if config.enable_bug_report:
- found = False
- for item in os.listdir(self.artifact_dir):
- if "bugreport" in item and ".zip" in item:
- found = True
- if not found:
- self.logger.info("Taking bugreport")
- self.run_adb_command("bugreport", cwd=self.artifact_dir)
- else:
- self.logger.warning("bugreport already taken")
- else:
- self.logger.critical("bugreport disabled in settings!")
diff --git a/src/tools/interop/idt/capture/platform/android/capabilities.py b/src/tools/interop/idt/capture/platform/android/capabilities.py
deleted file mode 100644
index cd2f7f6..0000000
--- a/src/tools/interop/idt/capture/platform/android/capabilities.py
+++ /dev/null
@@ -1,60 +0,0 @@
-from typing import TYPE_CHECKING
-
-from utils.artifact import create_standard_log_name, log
-from utils.shell import Bash
-
-if TYPE_CHECKING:
- from capture.platform.android import Android
-
-from . import config
-
-logger = log.get_logger(__file__)
-
-
-class Capabilities:
-
- def __init__(self, platform: "Android"):
- self.logger = logger
- self.platform = platform
- self.c_has_tcpdump = False
- self.c_has_root = False
- self.c_is_64 = False
- self.c_hci_snoop_enabled = False
- self.artifact = create_standard_log_name("capabilities", "txt", parent=platform.artifact_dir)
-
- def __repr__(self):
- s = "Detected capabilities:\n"
- for item in [x for x in dir(self) if x.startswith("c_")]:
- s += f"{item}: {getattr(self, item)}\n"
- return s
-
- def check_snoop_log(self) -> bool:
- return config.hci_log_level in self.platform.run_adb_command("shell getprop persist.bluetooth.btsnooplogmode",
- capture_output=True).get_captured_output()
-
- def check_capabilities(self):
- self.logger.info("Checking if device has root")
- self.c_has_root = self.platform.run_adb_command(
- "shell which su", capture_output=True).finished_success()
- if self.c_has_root:
- self.logger.warning("adb root!")
- Bash("adb root", sync=True).start_command()
- self.logger.info("Checking if device has tcpdump")
- self.c_has_tcpdump = self.platform.run_adb_command(
- "shell which tcpdump", capture_output=True).finished_success()
- self.logger.info("Checking device CPU arch")
- self.c_is_64 = "8" in self.platform.run_adb_command("shell cat /proc/cpuinfo | grep rch",
- capture_output=True).get_captured_output()
- self.c_hci_snoop_enabled = self.check_snoop_log()
- if not self.c_hci_snoop_enabled:
- self.logger.info("HCI not enabled, attempting to enable!")
- self.platform.run_adb_command(
- f"shell setprop persist.bluetooth.btsnooplogmode {config.hci_log_level}")
- self.platform.run_adb_command("shell svc bluetooth disable")
- self.platform.run_adb_command("shell svc bluetooth enable")
- self.c_hci_snoop_enabled = self.check_snoop_log()
- if not self.c_hci_snoop_enabled:
- self.logger.error("Failed to enabled HCI snoop log")
- self.logger.info(self)
- with open(self.artifact, "w") as artifact:
- artifact.write(str(self))
diff --git a/src/tools/interop/idt/capture/platform/android/config.py b/src/tools/interop/idt/capture/platform/android/config.py
deleted file mode 100644
index a0b05cd..0000000
--- a/src/tools/interop/idt/capture/platform/android/config.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-enable_build_push_tcpdump = True
-enable_bug_report = True
-hci_log_level = "full"
diff --git a/src/tools/interop/idt/capture/platform/android/streams/__init__.py b/src/tools/interop/idt/capture/platform/android/streams/__init__.py
deleted file mode 100644
index 9f48b1f..0000000
--- a/src/tools/interop/idt/capture/platform/android/streams/__init__.py
+++ /dev/null
@@ -1,14 +0,0 @@
-from capture.loader import CaptureImplsLoader
-
-from .base import AndroidStream
-
-impl_loader = CaptureImplsLoader(
- __path__[0],
- "capture.platform.android.streams",
- AndroidStream
-)
-
-for impl_name, impl in impl_loader.impls.items():
- globals()[impl_name] = impl
-
-__all__ = impl_loader.impl_names
diff --git a/src/tools/interop/idt/capture/platform/android/streams/base.py b/src/tools/interop/idt/capture/platform/android/streams/base.py
deleted file mode 100644
index 6468131..0000000
--- a/src/tools/interop/idt/capture/platform/android/streams/base.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from abc import ABC, abstractmethod
-
-
-class AndroidStream(ABC):
-
- @abstractmethod
- async def start(self) -> None:
- raise NotImplementedError
-
- @abstractmethod
- async def run_observer(self) -> None:
- raise NotImplementedError
-
- @abstractmethod
- async def stop(self) -> None:
- raise NotImplementedError
diff --git a/src/tools/interop/idt/capture/platform/android/streams/logcat/__init__.py b/src/tools/interop/idt/capture/platform/android/streams/logcat/__init__.py
deleted file mode 100644
index eebc071..0000000
--- a/src/tools/interop/idt/capture/platform/android/streams/logcat/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from .logcat import LogcatStreamer
-
-__all__ = ["LogcatStreamer"]
diff --git a/src/tools/interop/idt/capture/platform/android/streams/logcat/logcat.py b/src/tools/interop/idt/capture/platform/android/streams/logcat/logcat.py
deleted file mode 100644
index 78670bf..0000000
--- a/src/tools/interop/idt/capture/platform/android/streams/logcat/logcat.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import asyncio
-import os
-from typing import TYPE_CHECKING
-
-from utils.artifact import create_standard_log_name, log
-
-from ..base import AndroidStream
-
-logger = log.get_logger(__file__)
-
-if TYPE_CHECKING:
- from capture.platform.android import Android
-
-
-class LogcatStreamer(AndroidStream):
-
- def __init__(self, platform: "Android"):
- self.logger = logger
- self.platform = platform
- self.logcat_artifact = create_standard_log_name("logcat", "txt", parent=platform.artifact_dir)
- self.logcat_command = f"logcat -T 1 >> {self.logcat_artifact}"
- self.logcat_proc = platform.get_adb_background_command(self.logcat_command)
- self.was_ever_running = False
-
- async def run_observer(self) -> None:
- last_size = 0
- if not os.path.exists(self.logcat_artifact):
- self.logger.warning("Logcat artifact does not exist yes, this might be normal at the start of execution")
- asyncio.sleep(15)
- while True:
- try:
- new_size = os.path.getsize(self.logcat_artifact)
- if not (new_size > last_size):
- self.logger.warning(f"Logcat file not growing for {self.platform.device_id}, check connection!")
- last_size = new_size
- except OSError:
- self.logger.error(f"Logcat file does not exist for {self.platfrom.device_id}, check connection!")
- if not self.logcat_proc.command_is_running():
- self.logger.error("Logcat proc is not running, trying to restart!")
- self.logcat_proc = self.platform.get_adb_background_command(self.logcat_command)
- self.logcat_proc.start_command()
- await asyncio.sleep(4)
-
- async def start(self):
- self.logcat_proc.start_command()
-
- async def stop(self):
- self.logcat_proc.stop_command()
diff --git a/src/tools/interop/idt/capture/platform/android/streams/pcap/__init__.py b/src/tools/interop/idt/capture/platform/android/streams/pcap/__init__.py
deleted file mode 100644
index 8462107..0000000
--- a/src/tools/interop/idt/capture/platform/android/streams/pcap/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from .pcap import AndroidPcap
-
-__all__ = ["AndroidPcap"]
diff --git a/src/tools/interop/idt/capture/platform/android/streams/pcap/linux_build_tcpdump_64.sh b/src/tools/interop/idt/capture/platform/android/streams/pcap/linux_build_tcpdump_64.sh
deleted file mode 100755
index c82141b..0000000
--- a/src/tools/interop/idt/capture/platform/android/streams/pcap/linux_build_tcpdump_64.sh
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-set -e
-export TCPDUMP=4.99.4
-export LIBPCAP=1.10.4
-
-wget https://www.tcpdump.org/release/tcpdump-"$TCPDUMP".tar.gz
-wget https://www.tcpdump.org/release/libpcap-"$LIBPCAP".tar.gz
-
-tar zxvf tcpdump-"$TCPDUMP".tar.gz
-tar zxvf libpcap-"$LIBPCAP".tar.gz
-export CC=aarch64-linux-gnu-gcc
-cd libpcap-"$LIBPCAP"
-./configure --host=arm-linux --with-pcap=linux
-make
-cd ..
-
-cd tcpdump-"$TCPDUMP"
-export ac_cv_linux_vers=2
-export CFLAGS=-static
-export CPPFLAGS=-static
-export LDFLAGS=-static
-
-./configure --host=arm-linux
-make
-
-aarch64-linux-gnu-strip tcpdump
-cp tcpdump ..
-cd ..
-rm -R libpcap-"$LIBPCAP"
-rm -R tcpdump-"$TCPDUMP"
-rm libpcap-"$LIBPCAP".tar.gz
-rm tcpdump-"$TCPDUMP".tar.gz
diff --git a/src/tools/interop/idt/capture/platform/android/streams/pcap/mac_build_tcpdump_64.sh b/src/tools/interop/idt/capture/platform/android/streams/pcap/mac_build_tcpdump_64.sh
deleted file mode 100644
index 15d9119..0000000
--- a/src/tools/interop/idt/capture/platform/android/streams/pcap/mac_build_tcpdump_64.sh
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/usr/bin/env bash
-
-# This script cross-compiles libpcap and tcpdump for a specified architecture (default: ARM64)
-
-# Set bash script to exit immediately if any commands fail, any variables are unexpanded, or any commands in a pipeline fail.
-set -o errexit
-set -o nounset
-set -o pipefail
-
-# Check for optional target architecture argument, default to aarch64-linux-gnu if not provided
-TARGET_ARCH="${1:-aarch64-linux-gnu}"
-
-# Create a random temporary directory using mktemp
-TMP_DIR=$(mktemp -d)
-OUT_DIR=$TMP_DIR/out
-
-# Function to download and extract archives
-download_and_extract() {
- local url="$1"
- local filepath="$2"
- local tar_dir="$3"
-
- wget -O "$filepath" "$url"
- tar -C "$tar_dir" -zxvf "$filepath"
-}
-
-# Function to clean up downloaded and extracted files
-cleanup() {
- local filepath="$1"
- local dirpath="$2"
-
- rm -rf "$filepath" "$dirpath"
-}
-
-# Cross-compile libpcap
-LIBPCAP_VERSION=1.10.4
-LIBPCAP_DIR=$TMP_DIR/libpcap-$LIBPCAP_VERSION
-LIBPCAP_ARCHIVE=$TMP_DIR/libpcap-$LIBPCAP_VERSION.tar.gz
-
-download_and_extract "https://www.tcpdump.org/release/libpcap-$LIBPCAP_VERSION.tar.gz" "$LIBPCAP_ARCHIVE" "$TMP_DIR"
-(cd "$LIBPCAP_DIR" && ./configure --prefix="$OUT_DIR" --host="$TARGET_ARCH" --with-pcap=linux)
-make -C "$LIBPCAP_DIR" -j"$(nproc)"
-make -C "$LIBPCAP_DIR" install
-cleanup "$LIBPCAP_ARCHIVE" "$LIBPCAP_DIR"
-
-# Cross-compile tcpdump
-TCPDUMP_VERSION=4.99.4
-TCPDUMP_DIR=$TMP_DIR/tcpdump-$TCPDUMP_VERSION
-TCPDUMP_ARCHIVE=$TMP_DIR/tcpdump-$TCPDUMP_VERSION.tar.gz
-
-download_and_extract "https://www.tcpdump.org/release/tcpdump-$TCPDUMP_VERSION.tar.gz" "$TCPDUMP_ARCHIVE" "$TMP_DIR"
-(cd "$TCPDUMP_DIR" && CFLAGS="-static -I$OUT_DIR/include" CPPFLAGS="-static" LDFLAGS="-static -L$OUT_DIR/lib" ./configure --prefix="$OUT_DIR" --host="$TARGET_ARCH")
-make -C "$TCPDUMP_DIR"
-make -C "$TCPDUMP_DIR" install
-cleanup "$TCPDUMP_ARCHIVE" "$TCPDUMP_DIR"
-
-# Prepare the artifact
-strip "$OUT_DIR/bin/tcpdump"
-mv "$OUT_DIR/bin/tcpdump" .
-rm -rf "$TMP_DIR"
diff --git a/src/tools/interop/idt/capture/platform/android/streams/pcap/pcap.py b/src/tools/interop/idt/capture/platform/android/streams/pcap/pcap.py
deleted file mode 100644
index 8eab53b..0000000
--- a/src/tools/interop/idt/capture/platform/android/streams/pcap/pcap.py
+++ /dev/null
@@ -1,99 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import asyncio
-import os
-from typing import TYPE_CHECKING
-
-from utils.artifact import create_standard_log_name, log, safe_mkdir
-from utils.host_platform import is_mac
-from utils.shell import Bash
-
-from ... import config
-from ..base import AndroidStream
-
-if TYPE_CHECKING:
- from capture.platform.android import Android
-
-logger = log.get_logger(__file__)
-
-
-class AndroidPcap(AndroidStream):
-
- def __init__(self, platform: "Android"):
- self.logger = logger
- self.platform = platform
- self.target_dir = "/sdcard/Download"
- self.pcap_artifact = create_standard_log_name("android_tcpdump", "pcap", parent=self.platform.artifact_dir)
- self.pcap_phone_out_path = f"{self.target_dir}/{os.path.basename(self.pcap_artifact)}"
- self.pcap_phone_bin_location = "tcpdump" if platform.capabilities.c_has_tcpdump \
- else f"{self.target_dir}/tcpdump"
- self.pcap_command = f"shell {self.pcap_phone_bin_location} -w {self.pcap_phone_out_path}"
- self.pcap_proc = platform.get_adb_background_command(self.pcap_command)
- self.pcap_pull = False
- self.pcap_pull_command = f"pull {self.pcap_phone_out_path} {self.pcap_artifact}"
- self.build_dir = os.path.join(os.path.dirname(__file__), "BUILD")
-
- async def pull_packet_capture(self) -> None:
- if self.pcap_pull:
- self.logger.info("Attempting to pull android pcap")
- await asyncio.sleep(3)
- self.platform.run_adb_command(self.pcap_pull_command)
- self.pcap_pull = False
-
- async def start(self):
- if not self.platform.capabilities.c_has_root:
- self.logger.warning("Phone is not rooted, cannot take pcap!")
- return
- if self.platform.capabilities.c_has_tcpdump:
- self.logger.info("tcpdump already available; using!")
- self.pcap_proc.start_command()
- self.pcap_pull = True
- return
- if not config.enable_build_push_tcpdump:
- self.logger.critical("Android TCP Dump build and push disabled in configs!")
- return
- if not os.path.exists(os.path.join(self.build_dir, "tcpdump")):
- self.logger.warning("tcpdump bin not found, attempting to build, please wait a few moments!")
- safe_mkdir(self.build_dir)
- if is_mac():
- build_script = os.path.join(os.path.dirname(__file__), "mac_build_tcpdump_64.sh")
- Bash(f"{build_script} 2>&1 >> BUILD_LOG.txt", sync=True, cwd=self.build_dir).start_command()
- else:
- build_script = os.path.join(os.path.dirname(__file__), "linux_build_tcpdump_64.sh")
- Bash(f"{build_script} 2>&1 >> BUILD_LOG.txt", sync=True, cwd=self.build_dir).start_command()
- else:
- self.logger.warning("Reusing existing tcpdump build")
- if not self.platform.run_adb_command(f"shell ls {self.target_dir}/tcpdump").finished_success():
- self.logger.warning("Pushing tcpdump to device")
- self.platform.run_adb_command(f"push {os.path.join(self.build_dir, 'tcpdump')} f{self.target_dir}")
- self.platform.run_adb_command(f"chmod +x {self.target_dir}/tcpdump")
- else:
- self.logger.info("tcpdump already in the expected location, not pushing!")
- self.logger.info("Starting Android pcap command")
- self.pcap_proc.start_command()
- self.pcap_pull = True
-
- async def run_observer(self) -> None:
- while True:
- # TODO: Implement, need to restart w/ new out file (no append) and keep pull manifest, much like `screen`
- await asyncio.sleep(120)
-
- async def stop(self):
- self.logger.info("Stopping android pcap proc")
- self.pcap_proc.stop_command()
- await self.pull_packet_capture()
diff --git a/src/tools/interop/idt/capture/platform/android/streams/screen/__init__.py b/src/tools/interop/idt/capture/platform/android/streams/screen/__init__.py
deleted file mode 100644
index 1170a57..0000000
--- a/src/tools/interop/idt/capture/platform/android/streams/screen/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from .screen import ScreenRecorder
-
-__all__ = ["ScreenRecorder"]
diff --git a/src/tools/interop/idt/capture/platform/android/streams/screen/screen.py b/src/tools/interop/idt/capture/platform/android/streams/screen/screen.py
deleted file mode 100644
index e190e7c..0000000
--- a/src/tools/interop/idt/capture/platform/android/streams/screen/screen.py
+++ /dev/null
@@ -1,100 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import asyncio
-import os
-from typing import TYPE_CHECKING
-
-from utils.artifact import create_standard_log_name, log
-
-from ..base import AndroidStream
-
-if TYPE_CHECKING:
- from capture.platform.android import Android
-
-logger = log.get_logger(__file__)
-
-
-class ScreenRecorder(AndroidStream):
-
- def __init__(self, platform: "Android"):
- self.screen_artifact = None
- self.screen_phone_out_path = None
- self.screen_command = None
- self.screen_proc = None
- self.logger = logger
- self.platform = platform
- self.screen_check_command = "shell dumpsys deviceidle | grep mScreenOn"
- self.screen_pull = False
- self.file_counter = 0
- self.pull_commands: [str] = []
- self.manifest_file = os.path.join(platform.artifact_dir, "screen_manifest.txt")
-
- def check_screen(self) -> bool:
- screen_cmd_output = self.platform.run_adb_command(
- self.screen_check_command, capture_output=True)
- return "mScreenOn=true" == screen_cmd_output.get_captured_output().strip()
-
- async def prepare_screen_recording(self) -> None:
- screen_on = self.check_screen()
- while not screen_on:
- await asyncio.sleep(3)
- screen_on = self.check_screen()
- if not screen_on:
- self.logger.error("Please turn the screen on so screen recording can start or check connection!")
-
- def update_commands(self) -> None:
- self.screen_artifact = create_standard_log_name("screencast" + str(self.file_counter),
- "mp4",
- parent=self.platform.artifact_dir)
- self.screen_phone_out_path = f"/sdcard/Movies/{os.path.basename(self.screen_artifact)}"
- self.screen_command = f"shell screenrecord --bugreport {self.screen_phone_out_path}"
- screen_pull_command = f"pull {self.screen_phone_out_path} {self.screen_artifact}\n"
- self.pull_commands.append(screen_pull_command)
- with open(self.manifest_file, "a+") as manifest:
- manifest.write(screen_pull_command)
- self.file_counter += 1
-
- async def start(self):
- await self.prepare_screen_recording()
- if self.check_screen():
- self.screen_pull = True
- self.update_commands()
- self.screen_proc = self.platform.get_adb_background_command(self.screen_command)
- self.screen_proc.start_command()
- self.logger.info(f"New screen recording file started {self.screen_phone_out_path} {self.screen_artifact}")
-
- async def run_observer(self) -> None:
- while True:
- if not self.screen_proc.command_is_running():
- self.logger.warning(f"Screen recording proc needs restart (may be normal) {self.platform.device_id}")
- await self.start()
- await asyncio.sleep(4)
-
- async def pull_screen_recording(self) -> None:
- if self.screen_pull:
- self.logger.info("Attempting to pull screen recording")
- await asyncio.sleep(3)
- with open(self.manifest_file) as manifest:
- for line in manifest:
- self.platform.run_adb_command(line)
- self.screen_pull = False
-
- async def stop(self):
- self.logger.info("Stopping screen proc")
- self.screen_proc.stop_command()
- await self.pull_screen_recording()
diff --git a/src/tools/interop/idt/config.py b/src/tools/interop/idt/config.py
deleted file mode 100644
index f084d49..0000000
--- a/src/tools/interop/idt/config.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-import logging
-
-enable_color = True
-log_level = logging.INFO
-py_major_version = 3
-py_minor_version = 11
diff --git a/src/tools/interop/idt/discovery/__init__.py b/src/tools/interop/idt/discovery/__init__.py
deleted file mode 100644
index b83e5df..0000000
--- a/src/tools/interop/idt/discovery/__init__.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-from .ble import MatterBleScanner
-from .dnssd import MatterDnssdListener
-
-__all__ = [
- 'MatterBleScanner',
- 'MatterDnssdListener'
-]
diff --git a/src/tools/interop/idt/discovery/ble.py b/src/tools/interop/idt/discovery/ble.py
deleted file mode 100644
index 9549c74..0000000
--- a/src/tools/interop/idt/discovery/ble.py
+++ /dev/null
@@ -1,118 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import asyncio
-import datetime
-import os
-import sys
-import time
-
-from bleak import AdvertisementData, BleakScanner, BLEDevice
-from bleak.exc import BleakDBusError
-from utils import log
-from utils.log import border_print
-
-logger = log.get_logger(__file__)
-
-
-class MatterBleScanner:
-
- def __init__(self, artifact_dir: str):
- self.artifact_dir = artifact_dir
- self.logger = logger
- self.devices_seen_last_time: set[str] = set()
- self.devices_seen_this_time: set[str] = set()
- self.throttle_seconds = 1
- self.error_seconds = 5
-
- def parse_vid_pid(self, loggable_data: str) -> str:
- try:
- vid = loggable_data[8:10] + loggable_data[6:8]
- pid = loggable_data[12:14] + loggable_data[10:12]
- except IndexError:
- self.logger.warning("Error parsing vid / pid from BLE ad data")
- return ""
- return f"VID: {vid} PID: {pid}"
-
- def write_device_log(self, device_name: str, to_write: str) -> None:
- log_file_name = os.path.join(self.artifact_dir, f"{device_name}.txt")
- with open(log_file_name, "a+") as log_file:
- ts = datetime.datetime.now().isoformat(sep=' ', timespec='milliseconds')
- to_write = f"{ts}\n{to_write}\n\n"
- log_file.write(to_write)
- self.logger.info(to_write)
-
- @staticmethod
- def is_matter_device(service_uuid: str) -> bool:
- is_matter_device = service_uuid.startswith("0000fff6")
- return is_matter_device
-
- def handle_device_states(self) -> None:
- for device_id in self.devices_seen_last_time - self.devices_seen_this_time:
- to_log = f"LOST {device_id}\n"
- self.write_device_log(device_id, to_log)
- self.devices_seen_last_time = self.devices_seen_this_time
- self.devices_seen_this_time = set()
-
- def log_ble_discovery(
- self,
- name: str,
- bin_service_data: bytes,
- ble_device: BLEDevice,
- rssi: int) -> None:
- hex_service_data = bin_service_data.hex()
- if self.is_matter_device(name):
- device_id = f"{ble_device.name}_{ble_device.address}"
- self.devices_seen_this_time.add(device_id)
- if device_id not in self.devices_seen_last_time:
- to_log = "DISCOVERED\n"
- to_log += f"BLE DEVICE NAME: {ble_device.name}\n"
- to_log += f"BLE ADDR: {ble_device.address}\n"
- to_log += f"NAME: {name}\n"
- to_log += f"HEX SERVICE DATA: {hex_service_data}\n"
- to_log += f"RSSI {rssi}\n"
- to_log += self.parse_vid_pid(hex_service_data)
- self.write_device_log(device_id, to_log)
-
- async def browse(self, scanner: BleakScanner) -> None:
- devices: dict[str, tuple[BLEDevice, AdvertisementData]] = await scanner.discover(return_adv=True)
- for device in devices.values():
- ble_device = device[0]
- ad_data = device[1]
- for name, bin_service_data in ad_data.service_data.items():
- self.log_ble_discovery(
- name, bin_service_data, ble_device, ad_data.rssi)
- self.handle_device_states()
-
- async def browser_task(self, scanner) -> None:
- while True:
- try:
- await asyncio.sleep(self.throttle_seconds)
- await self.browse(scanner)
- except BleakDBusError as e:
- self.logger.critical(e)
- time.sleep(self.error_seconds)
-
- async def browse_interactive(self) -> None:
- scanner = BleakScanner()
- self.logger.warning(
- "Scanning BLE\nDCL Lookup: https://webui.dcl.csa-iot.org/\n")
- border_print("Press enter to stop!", important=True)
- task = asyncio.create_task(self.browser_task(scanner))
- await asyncio.get_event_loop().run_in_executor(
- None, sys.stdin.readline)
- task.cancel()
diff --git a/src/tools/interop/idt/discovery/dnssd.py b/src/tools/interop/idt/discovery/dnssd.py
deleted file mode 100644
index 04dd8de..0000000
--- a/src/tools/interop/idt/discovery/dnssd.py
+++ /dev/null
@@ -1,354 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import asyncio
-import os
-import traceback
-from dataclasses import dataclass
-from textwrap import dedent
-from typing import Callable
-
-from probe.ip_utils import get_addr_type
-from utils.artifact import create_standard_log_name, log
-from utils.log import add_border, border_print
-from zeroconf import ServiceBrowser, ServiceInfo, ServiceListener, Zeroconf
-
-logger = log.get_logger(__file__)
-
-
-@dataclass()
-class MdnsTypeInfo:
- type: str
- description: str
-
-
-commissioner = MdnsTypeInfo(
- "COMMISSIONER",
- "This is a service for a Matter commissioner aka. controller"
-)
-commissionable = MdnsTypeInfo(
- "COMMISSIONABLE / EXTENDED DISCOVERY",
- "This is a service to be used in the commissioning process and provides more info about the device."
-)
-operational = MdnsTypeInfo(
- "OPERATIONAL",
- "This is a service for a commissioned Matter device. It exposes limited info about the device."
-)
-border_router = MdnsTypeInfo(
- "THREAD BORDER ROUTER",
- "This is a service for a thread border router; may be used for thread+Matter devices."
-)
-
-_MDNS_TYPES = {
- "_matterd._udp.local.": commissioner,
- "_matterc._udp.local.": commissionable,
- "_matter._tcp.local.": operational,
- "_meshcop._udp.local.": border_router,
-}
-
-
-@dataclass()
-class RecordParser:
- readable_name: str
- explanation: str
- parse: Callable[[str], str]
-
-
-# TODO: Meshcop parser
-
-class MatterTxtRecordParser:
-
- def __init__(self):
- self.parsers = {
- "D": RecordParser("Discriminator",
- dedent("\
- Differentiates this instance of the device from others w/ same VID/PID that might be \n\
- in the environment."),
- MatterTxtRecordParser.parse_d), # To hex
- "VP": RecordParser("VID/PID",
- "The Vendor ID and Product ID (each are two bytes of hex) that identify this product.",
- MatterTxtRecordParser.parse_vp), # Split + to hex
- "CM": RecordParser("Commissioning mode",
- "Whether the device is in commissioning mode or not.",
- MatterTxtRecordParser.parse_cm), # Decode
- "DT": RecordParser("Device type",
- "Application type for this end device.",
- MatterTxtRecordParser.parse_dt), # Decode
- "DN": RecordParser("Device name",
- "Manufacturer provided device name. MAY match NodeLabel in Basic info cluster.",
- MatterTxtRecordParser.parse_pass_through), # None
- "RI": RecordParser("Rotating identifier",
- "Vendor specific, non-trackable per-device ID.",
- MatterTxtRecordParser.parse_pass_through), # None
- "PH": RecordParser("Pairing hint",
- dedent("\
- Given the current device state, follow these instructions to make the device \n\
- commissionable."),
- MatterTxtRecordParser.parse_ph), # Decode
- "PI": RecordParser("Pairing instructions",
- dedent("\
- Used with the Pairing hint. If the Pairing hint mentions N, this is the \n\
- value of N."),
- MatterTxtRecordParser.parse_pass_through), # None
- # General records
- "SII": RecordParser("Session idle interval",
- "Message Reliability Protocol retry interval while the device is idle in milliseconds.",
- MatterTxtRecordParser.parse_pass_through), # None
- "SAI": RecordParser("Session active interval",
- dedent("\
- Message Reliability Protocol retry interval while the device is active \n\
- in milliseconds."),
- MatterTxtRecordParser.parse_pass_through), # None
- "SAT": RecordParser("Session active threshold",
- "Duration of time this device stays active after last activity in milliseconds.",
- MatterTxtRecordParser.parse_pass_through), # None
- "T": RecordParser("Supports TCP",
- "Whether this device supports TCP client and or Server.",
- MatterTxtRecordParser.parse_t), # Decode
- }
- self.unparsed_records = ""
- self.parsed_records = ""
-
- def parse_single_record(self, key: str, value: str):
- parser: RecordParser = self.parsers[key]
- self.parsed_records += add_border(parser.readable_name + "\n")
- self.parsed_records += parser.explanation + "\n\n"
- try:
- self.parsed_records += "PARSED VALUE: " + parser.parse(value) + "\n"
- except Exception:
- logger.error("Exception parsing TXT record, appending raw value")
- logger.error(traceback.format_exc())
- self.parsed_records += f"RAW VALUE: {value}\n"
-
- def get_output(self) -> str:
- unparsed_exp = "\nThe following TXT records were not parsed or explained:\n"
- parsed_exp = "\nThe following was discovered about this device via TXT records:\n"
- ret = ""
- if self.unparsed_records:
- ret += unparsed_exp + self.unparsed_records
- if self.parsed_records:
- ret += parsed_exp + self.parsed_records
- return ret
-
- def parse_records(self, info: ServiceInfo) -> str:
- if info.properties is not None:
- for name, value in info.properties.items():
- try:
- name = name.decode("utf-8")
- except UnicodeDecodeError:
- name = str(name)
- try:
- value = value.decode("utf-8")
- except UnicodeDecodeError:
- value = str(value)
- if name not in self.parsers:
- self.unparsed_records += f"KEY: {name} VALUE: {value}\n"
- else:
- self.parse_single_record(name, value)
- return self.get_output()
-
- @staticmethod
- def parse_pass_through(txt_value: str) -> str:
- return txt_value
-
- @staticmethod
- def parse_d(txt_value: str) -> str:
- return hex(int(txt_value))
-
- @staticmethod
- def parse_vp(txt_value: str) -> str:
- vid, pid = txt_value.split("+")
- vid, pid = hex(int(vid)), hex(int(pid))
- return f"VID: {vid}, PID: {pid}"
-
- @staticmethod
- def parse_cm(txt_value: str) -> str:
- cm = int(txt_value)
- mode_descriptions = [
- "Not in commissioning mode",
- "In passcode commissioning mode (standard mode)",
- "In dynamic passcode commissioning mode",
- ]
- return mode_descriptions[cm]
-
- @staticmethod
- def parse_dt(txt_value: str) -> str:
- application_device_types = {
- # lighting
- "0x100": "On/Off Light",
- "0x101": "Dimmable Light",
- "0x10C": "Color Temperature Light",
- "0x10D": "Extended Color Light",
- # smart plugs/outlets and other actuators
- "0x10A": "On/Off Plug-in Unit",
- "0x10B": "Dimmable Plug-In Unit",
- "0x303": "Pump",
- # switches and controls
- "0x103": "On/Off Light Switch",
- "0x104": "Dimmer Switch",
- "0x105": "Color Dimmer Switch",
- "0x840": "Control Bridge",
- "0x304": "Pump Controller",
- "0xF": "Generic Switch",
- # sensors
- "0x15": "Contact Sensor",
- "0x106": "Light Sensor",
- "0x107": "Occupancy Sensor",
- "0x302": "Temperature Sensor",
- "0x305": "Pressure Sensor",
- "0x306": "Flow Sensor",
- "0x307": "Humidity Sensor",
- "0x850": "On/Off Sensor",
- # closures
- "0xA": "Door Lock",
- "0xB": "Door Lock Controller",
- "0x202": "Window Covering",
- "0x203": "Window Covering Controller",
- # HVAC
- "0x300": "Heating/Cooling Unit",
- "0x301": "Thermostat",
- "0x2B": "Fan",
- # media
- "0x28": "Basic Video Player",
- "0x23": "Casting Video Player",
- "0x22": "Speaker",
- "0x24": "Content App",
- "0x29": "Casting Video Client",
- "0x2A": "Video Remote Control",
- # generic
- "0x27": "Mode Select",
- }
- return application_device_types[hex((int(txt_value))).upper().replace("0X", "0x")]
-
- @staticmethod
- def parse_ph(txt_value: str) -> str:
- pairing_hints = [
- "Power Cycle",
- "Custom commissioning flow",
- "Use existing administrator (already commissioned)",
- "Use settings menu on device",
- "Use the PI TXT record hint",
- "Read the manual",
- "Press the reset button",
- "Press Reset Button with application of power",
- "Press Reset Button for N seconds",
- "Press Reset Button until light blinks",
- "Press Reset Button for N seconds with application of power",
- "Press Reset Button until light blinks with application of power",
- "Press Reset Button N times",
- "Press Setup Button",
- "Press Setup Button with application of power",
- "Press Setup Button for N seconds",
- "Press Setup Button until light blinks",
- "Press Setup Button for N seconds with application of power",
- "Press Setup Button until light blinks with application of power",
- "Press Setup Button N times",
- ]
- ret = "\n"
- b_arr = [int(b) for b in bin(int(txt_value))[2:]][::-1]
- for i in range(0, len(b_arr)):
- b = b_arr[i]
- if b:
- ret += pairing_hints[i] + "\n"
- return ret
-
- @staticmethod
- def parse_t(txt_value: str) -> str:
- return "TCP supported" if int(txt_value) else "TCP not supported"
-
-
-class MatterDnssdListener(ServiceListener):
-
- def __init__(self, artifact_dir: str) -> None:
- super().__init__()
- self.artifact_dir = artifact_dir
- self.logger = logger
- self.discovered_matter_devices: [str, ServiceInfo] = {}
-
- def write_log(self, line: str, log_name: str) -> None:
- with open(self.create_device_log_name(log_name), "a+") as log_file:
- log_file.write(line)
-
- def create_device_log_name(self, device_name) -> str:
- return os.path.join(
- self.artifact_dir,
- create_standard_log_name(f"{device_name}_dnssd", "txt"))
-
- @staticmethod
- def log_addr(info: ServiceInfo) -> str:
- ret = add_border("This device has the following IP addresses\n")
- for addr in info.parsed_scoped_addresses():
- ret += f"{get_addr_type(addr)}: {addr}\n"
- return ret
-
- def handle_service_info(
- self,
- zc: Zeroconf,
- type_: str,
- name: str,
- delta_type: str) -> None:
- info = zc.get_service_info(type_, name)
- self.discovered_matter_devices[name] = info
- to_log = f"{name}\n"
- update_str = f"\nSERVICE {delta_type}\n"
- to_log += ("*" * (len(update_str) - 2)) + update_str
- to_log += _MDNS_TYPES[type_].type + "\n"
- to_log += _MDNS_TYPES[type_].description + "\n"
- to_log += f"A/SRV TTL: {str(info.host_ttl)}\n"
- to_log += f"PTR/TXT TTL: {str(info.other_ttl)}\n"
- txt_parser = MatterTxtRecordParser()
- to_log += txt_parser.parse_records(info)
- to_log += self.log_addr(info)
- self.logger.info(to_log)
- self.write_log(to_log, name)
-
- def add_service(self, zc: Zeroconf, type_: str, name: str) -> None:
- self.handle_service_info(zc, type_, name, "ADDED")
-
- def update_service(self, zc: Zeroconf, type_: str, name: str) -> None:
- self.handle_service_info(zc, type_, name, "UPDATED")
-
- def remove_service(self, zc: Zeroconf, type_: str, name: str) -> None:
- to_log = f"Service {name} removed\n"
- to_log += _MDNS_TYPES[type_].type + "\n"
- to_log += _MDNS_TYPES[type_].description
- if name in self.discovered_matter_devices:
- del self.discovered_matter_devices[name]
- self.logger.warning(to_log)
- self.write_log(to_log, name)
-
- def browse_interactive(self) -> None:
- zc = Zeroconf()
- ServiceBrowser(zc, list(_MDNS_TYPES.keys()), self)
- try:
- self.logger.warning(
- dedent("\
- \n\
- Browsing Matter DNS-SD\n\
- DCL Lookup: https://webui.dcl.csa-iot.org/\n\
- See spec section 4.3 for details of Matter TXT records.\n"))
- border_print("Press enter to stop!", important=True)
- input("")
- finally:
- zc.close()
-
- async def browse_once(self, browse_time_seconds: int) -> Zeroconf:
- zc = Zeroconf()
- ServiceBrowser(zc, list(_MDNS_TYPES.keys()), self)
- await asyncio.sleep(browse_time_seconds)
- zc.close()
- return zc
diff --git a/src/tools/interop/idt/idt.py b/src/tools/interop/idt/idt.py
deleted file mode 100644
index 9ddb1dd..0000000
--- a/src/tools/interop/idt/idt.py
+++ /dev/null
@@ -1,217 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import argparse
-import asyncio
-import os
-import shutil
-import sys
-from pathlib import Path
-
-import probe.runner as probe_runner
-from capture import PacketCaptureRunner, controller
-from discovery import MatterBleScanner, MatterDnssdListener
-from utils.artifact import create_file_timestamp, safe_mkdir
-from utils.host_platform import get_available_interfaces, verify_host_dependencies
-from utils.log import border_print
-
-import config
-
-splash = '''\x1b[0m
-\x1b[32;1m┌────────┐\x1b[33;20m▪\x1b[32;1m \x1b[34;1m┌──────┐ \x1b[33;20m• \x1b[35;1m┌──────────┐ \x1b[33;20m●
-\x1b[32;1m│░░░░░░░░│ \x1b[34;1m│░░░░░░└┐ \x1b[33;20m゚\x1b[35;1m│░░░░░░░░░░│
-\x1b[32;1m└──┐░░┌──┘\x1b[33;20m۰\x1b[32;1m \x1b[34;1m│░░┌┐░░░│ \x1b[35;1m└───┐░░┌───┘
-\x1b[32;1m │░░│ \x1b[34;1m│░░│└┐░░│\x1b[33;20m▫ \x1b[35;1m \x1b[33;20m۰\x1b[35;1m │░░│ \x1b[33;20m。
-\x1b[32;1m \x1b[33;20m•\x1b[32;1m │░░│ \x1b[33;20m● \x1b[34;1m│░░│┌┘░░│ \x1b[35;1m │░░│
-\x1b[32;1m┌──┘░░└──┐ \x1b[34;1m│░░└┘░░░│ \x1b[35;1m │░░│ \x1b[33;20m•
-\x1b[32;1m│░░░░░░░░│ \x1b[34;1m│░░░░░░┌┘\x1b[33;20m۰ \x1b[35;1m \x1b[33;20m▪\x1b[35;1m │░░│
-\x1b[32;1m└────────┘\x1b[33;20m•\x1b[32;1m \x1b[34;1m└──────┘\x1b[33;20m。 \x1b[35;1m └──┘ \x1b[33;20m▫
-\x1b[32;1m✰ Interop\x1b[34;1m ✰ Debugging\x1b[35;1m ✰ Tool
-\x1b[0m'''
-
-
-class InteropDebuggingTool:
-
- def __init__(self) -> None:
- if config.enable_color:
- print(splash)
- self.artifact_dir = None
- create_artifact_dir = True
- if len(sys.argv) == 1:
- create_artifact_dir = False
- elif sys.argv[1] != "capture" and sys.argv[1] != "discover":
- create_artifact_dir = False
- elif len(sys.argv) >= 3 and (sys.argv[2] == "-h" or sys.argv[2] == "--help"):
- create_artifact_dir = False
-
- verify_host_dependencies(["adb", "tcpdump"])
-
- if not os.environ['IDT_OUTPUT_DIR']:
- print('Missing required env vars! Use /scripts!!!')
- sys.exit(1)
-
- self.artifact_dir_parent = os.path.join(
- Path(__file__).resolve().parent,
- os.environ['IDT_OUTPUT_DIR'])
- artifact_timestamp = create_file_timestamp()
- self.artifact_dir = os.path.join(
- self.artifact_dir_parent,
- f'idt_{artifact_timestamp}')
- if create_artifact_dir:
- safe_mkdir(self.artifact_dir)
- border_print(f"Using artifact dir {self.artifact_dir}")
-
- self.available_platforms = controller.list_available_platforms()
- self.available_platforms_default = 'Android' if 'Android' in self.available_platforms else None
- self.platform_required = self.available_platforms_default is None
-
- self.available_ecosystems = controller.list_available_ecosystems()
- self.available_ecosystems_default = 'ALL'
- self.available_ecosystems.append(self.available_ecosystems_default)
-
- self.available_net_interfaces = get_available_interfaces()
- self.available_net_interfaces_default = "any" if "any" in self.available_net_interfaces else None
- self.pcap_artifact_dir = os.path.join(self.artifact_dir, "pcap")
- self.net_interface_required = self.available_net_interfaces_default is None
-
- self.ble_artifact_dir = os.path.join(self.artifact_dir, "ble")
- self.dnssd_artifact_dir = os.path.join(self.artifact_dir, "dnssd")
- self.prober_dir = os.path.join(self.artifact_dir, "probes")
-
- self.process_args()
-
- def process_args(self) -> None:
- parser = argparse.ArgumentParser(
- prog="idt",
- description="Interop Debugging Tool for Matter")
-
- subparsers = parser.add_subparsers(title="subcommands")
-
- discover_parser = subparsers.add_parser(
- "discover", help="Discover all Matter devices")
- discover_parser.set_defaults(func=self.command_discover)
- discover_parser.add_argument(
- "--type",
- "-t",
- help="Specify the type of discovery to execute",
- required=True,
- choices=[
- "ble",
- "b",
- "dnssd",
- "d"])
-
- capture_parser = subparsers.add_parser(
- "capture",
- help="Capture all information of interest while running a manual test")
-
- platform_help = "Run capture for a particular platform"
- if self.available_platforms_default:
- platform_help += f" (default {self.available_platforms_default})"
- capture_parser.add_argument("--platform",
- "-p",
- help=platform_help,
- required=self.platform_required,
- choices=self.available_platforms,
- default=self.available_platforms_default)
-
- capture_parser.add_argument(
- "--ecosystem",
- "-e",
- help="Run capture for a particular ecosystem or ALL ecosystems (default ALL)",
- required=False,
- choices=self.available_ecosystems,
- default=self.available_ecosystems_default)
-
- capture_parser.add_argument("--pcap",
- "-c",
- help="Run packet capture (default t)",
- required=False,
- choices=['t', 'f'],
- default='t')
-
- interface_help = "Specify packet capture interface"
- if self.available_net_interfaces_default:
- interface_help += f" (default {self.available_net_interfaces_default})"
- capture_parser.add_argument(
- "--interface",
- "-i",
- help=interface_help,
- required=self.net_interface_required,
- choices=self.available_net_interfaces,
- default=self.available_net_interfaces_default)
-
- capture_parser.set_defaults(func=self.command_capture)
-
- prober_parser = subparsers.add_parser("probe",
- help="Probe the environment for Matter and general networking info")
- prober_parser.set_defaults(func=self.command_probe)
-
- args, unknown = parser.parse_known_args()
- if not hasattr(args, 'func'):
- parser.print_help()
- else:
- args.func(args)
-
- def command_discover(self, args: argparse.Namespace) -> None:
- if args.type[0] == "b":
- safe_mkdir(self.ble_artifact_dir)
- scanner = MatterBleScanner(self.ble_artifact_dir)
- asyncio.run(scanner.browse_interactive())
- self.zip_artifacts()
- else:
- safe_mkdir(self.dnssd_artifact_dir)
- MatterDnssdListener(self.dnssd_artifact_dir).browse_interactive()
- self.zip_artifacts()
-
- def zip_artifacts(self) -> None:
- zip_basename = os.path.basename(self.artifact_dir)
- archive_file = shutil.make_archive(zip_basename,
- 'zip',
- root_dir=self.artifact_dir)
- output_zip = shutil.move(archive_file, self.artifact_dir_parent)
- border_print(f'Output zip: {output_zip}')
-
- def command_capture(self, args: argparse.Namespace) -> None:
- pcap = args.pcap == 't'
- pcap_runner = None if not pcap else PacketCaptureRunner(
- self.pcap_artifact_dir, args.interface)
- if pcap:
- border_print("Starting pcap")
- safe_mkdir(self.pcap_artifact_dir)
- pcap_runner.start_pcap()
- asyncio.run(controller.init_ecosystems(args.platform,
- args.ecosystem,
- self.artifact_dir))
- asyncio.run(controller.start())
- asyncio.run(controller.run_analyzers())
- if pcap:
- border_print("Stopping pcap")
- pcap_runner.stop_pcap()
- asyncio.run(controller.stop())
- asyncio.run(controller.probe())
- border_print("Checking error report")
- controller.write_error_report(self.artifact_dir)
- border_print("Compressing artifacts...")
- self.zip_artifacts()
-
- def command_probe(self, args: argparse.Namespace) -> None:
- border_print("Starting generic Matter prober for local environment!")
- safe_mkdir(self.dnssd_artifact_dir)
- safe_mkdir(self.prober_dir)
- probe_runner.run_probes(self.prober_dir, self.dnssd_artifact_dir)
- self.zip_artifacts()
diff --git a/src/tools/interop/idt/probe/__init__.py b/src/tools/interop/idt/probe/__init__.py
deleted file mode 100644
index f44dcd9..0000000
--- a/src/tools/interop/idt/probe/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from dataclasses import dataclass
-
-
-@dataclass(repr=True)
-class ProbeTarget:
- name: str
- ip: str
- port: str
diff --git a/src/tools/interop/idt/probe/config.py b/src/tools/interop/idt/probe/config.py
deleted file mode 100644
index 150e407..0000000
--- a/src/tools/interop/idt/probe/config.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-ping_count = 4
-dnssd_browsing_time_seconds = 4
diff --git a/src/tools/interop/idt/probe/ip_utils.py b/src/tools/interop/idt/probe/ip_utils.py
deleted file mode 100644
index ca1e39e..0000000
--- a/src/tools/interop/idt/probe/ip_utils.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import ipaddress
-
-
-def is_ipv4(ip: str) -> bool:
- try:
- ipaddress.IPv4Address(ip)
- return True
- except ipaddress.AddressValueError:
- return False
-
-
-def is_ipv6_ll(ip: str) -> bool:
- try:
- return ipaddress.IPv6Address(ip).is_link_local
- except ipaddress.AddressValueError:
- return False
-
-
-def is_ipv6(ip: str) -> bool:
- try:
- ipaddress.IPv6Address(ip)
- return True
- except ipaddress.AddressValueError:
- return False
-
-
-def get_addr_type(ip: str) -> str:
- if is_ipv4(ip):
- return "V4"
- elif is_ipv6_ll(ip):
- return "V6 Link Local"
- elif is_ipv6(ip):
- return "V6"
diff --git a/src/tools/interop/idt/probe/linux.py b/src/tools/interop/idt/probe/linux.py
deleted file mode 100644
index 05a8adb..0000000
--- a/src/tools/interop/idt/probe/linux.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import probe.probe as p
-from utils.host_platform import get_ll_interface
-from utils.log import get_logger
-
-from . import config
-
-logger = get_logger(__file__)
-
-
-class ProberLinuxHost(p.GenericMatterProber):
-
- def __init__(self, artifact_dir: str, dnssd_artifact_dir: str) -> None:
- # TODO: Parity with macOS
- super().__init__(artifact_dir, dnssd_artifact_dir)
- self.logger = logger
- self.ll_int = get_ll_interface()
-
- def discover_targets_by_neighbor(self) -> None:
- pass
-
- def probe_v4(self, ipv4: str, port: str) -> None:
- self.run_command(f"ping -c {config.ping_count} {ipv4}")
-
- def probe_v6(self, ipv6: str, port: str) -> None:
- self.run_command(f"ping -c {config.ping_count} -6 {ipv6}")
-
- def probe_v6_ll(self, ipv6_ll: str, port: str) -> None:
- self.run_command(f"ping -c {config.ping_count} -6 {ipv6_ll}%{self.ll_int}")
-
- def get_general_details(self) -> None:
- pass
diff --git a/src/tools/interop/idt/probe/mac.py b/src/tools/interop/idt/probe/mac.py
deleted file mode 100644
index b13e5d5..0000000
--- a/src/tools/interop/idt/probe/mac.py
+++ /dev/null
@@ -1,56 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import probe.probe as p
-from utils.host_platform import get_ll_interface
-from utils.log import get_logger
-
-from . import ProbeTarget, config
-
-logger = get_logger(__file__)
-
-
-class ProberMacHost(p.GenericMatterProber):
-
- def __init__(self, artifact_dir: str, dnssd_artifact_dir: str) -> None:
- # TODO: Build out additional probes
- super().__init__(artifact_dir, dnssd_artifact_dir)
- self.logger = logger
- self.ll_int = get_ll_interface()
-
- def discover_targets_by_neighbor(self) -> None:
- pass
-
- def probe_v4(self, target: ProbeTarget) -> None:
- self.logger.info("Ping IPv4")
- self.run_command(f"ping -c {config.ping_count} {target.ip}")
-
- def probe_v6(self, target: ProbeTarget) -> None:
- self.logger.info("Ping IPv6")
- self.run_command(f"ping6 -c {config.ping_count} {target.ip}")
-
- def probe_v6_ll(self, target: ProbeTarget) -> None:
- self.logger.info("Ping IPv6 Link Local")
- self.run_command(f"ping6 -c {config.ping_count} -I {self.ll_int} {target.ip}")
-
- def get_general_details(self) -> None:
- self.logger.info("Host interfaces")
- self.run_command("ifconfig")
- self.logger.info("v4 routes from host")
- self.run_command("netstat -r -f inet -n")
- self.logger.info("v6 routes from host")
- self.run_command("netstat -r -f inet6 -n")
diff --git a/src/tools/interop/idt/probe/probe.py b/src/tools/interop/idt/probe/probe.py
deleted file mode 100644
index 6fcc92a..0000000
--- a/src/tools/interop/idt/probe/probe.py
+++ /dev/null
@@ -1,100 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import asyncio
-import os.path
-from abc import ABC, abstractmethod
-
-from discovery import MatterDnssdListener
-from discovery.dnssd import ServiceInfo
-from utils.artifact import create_standard_log_name
-from utils.log import get_logger
-from utils.shell import Bash
-
-from . import ProbeTarget, config
-from .ip_utils import is_ipv4, is_ipv6, is_ipv6_ll
-
-logger = get_logger(__file__)
-
-
-class GenericMatterProber(ABC):
-
- def __init__(self, artifact_dir: str, dnssd_artifact_dir: str) -> None:
- self.artifact_dir = artifact_dir
- self.dnssd_artifact_dir = dnssd_artifact_dir
- self.logger = logger
- self.targets: [GenericMatterProber.ProbeTarget] = []
- self.output = os.path.join(self.artifact_dir,
- create_standard_log_name("generic_probes", "txt"))
- self.suffix = f"2>&1 | tee -a {self.output}"
-
- def run_command(self, cmd: str, capture_output=False) -> Bash:
- cmd = f"{cmd} {self.suffix}"
- self.logger.debug(cmd)
- bash = Bash(cmd, sync=True, capture_output=capture_output)
- bash.start_command()
- return bash
-
- @abstractmethod
- def probe_v4(self, target: ProbeTarget) -> None:
- raise NotImplementedError
-
- @abstractmethod
- def probe_v6(self, target: ProbeTarget) -> None:
- raise NotImplementedError
-
- @abstractmethod
- def probe_v6_ll(self, target: ProbeTarget) -> None:
- raise NotImplementedError
-
- @abstractmethod
- def discover_targets_by_neighbor(self) -> None:
- raise NotImplementedError
-
- @abstractmethod
- def get_general_details(self) -> None:
- raise NotImplementedError
-
- def discover_targets_by_browsing(self) -> None:
- browser = MatterDnssdListener(self.dnssd_artifact_dir)
- asyncio.run(browser.browse_once(config.dnssd_browsing_time_seconds))
- for name in browser.discovered_matter_devices:
- info: ServiceInfo = browser.discovered_matter_devices[name]
- for addr in info.parsed_scoped_addresses():
- self.targets.append(ProbeTarget(name, addr, info.port))
-
- def probe_single_target(self, target: ProbeTarget) -> None:
- if is_ipv4(target.ip):
- self.logger.debug(f"Probing v4 {target.ip}")
- self.probe_v4(target)
- elif is_ipv6_ll(target.ip):
- self.logger.debug(f"Probing v6 ll {target.ip}")
- self.probe_v6_ll(target)
- elif is_ipv6(target.ip):
- self.logger.debug(f"Probing v6 {target.ip}")
- self.probe_v6(target)
-
- def probe_targets(self) -> None:
- for target in self.targets:
- self.logger.info(f"Probing target {target}")
- self.probe_single_target(target)
-
- def probe(self) -> None:
- self.discover_targets_by_browsing()
- self.discover_targets_by_neighbor()
- self.probe_targets()
- self.get_general_details()
diff --git a/src/tools/interop/idt/probe/runner.py b/src/tools/interop/idt/probe/runner.py
deleted file mode 100644
index ac37317..0000000
--- a/src/tools/interop/idt/probe/runner.py
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from utils.host_platform import is_mac
-
-from .linux import ProberLinuxHost
-from .mac import ProberMacHost
-
-
-def run_probes(artifact_dir: str, dnssd_dir: str) -> None:
- if is_mac():
- ProberMacHost(artifact_dir, dnssd_dir).probe()
- else:
- ProberLinuxHost(artifact_dir, dnssd_dir).probe()
diff --git a/src/tools/interop/idt/requirements.txt b/src/tools/interop/idt/requirements.txt
deleted file mode 100644
index dac2cdf..0000000
--- a/src/tools/interop/idt/requirements.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-zeroconf==0.74.0
-bleak==0.21.1
-psutil==5.9.6
-termcolor==2.3.0
diff --git a/src/tools/interop/idt/res/plugin_demo/ecosystem/demo_ext_ecosystem/__init__.py b/src/tools/interop/idt/res/plugin_demo/ecosystem/demo_ext_ecosystem/__init__.py
deleted file mode 100644
index a91fcfe..0000000
--- a/src/tools/interop/idt/res/plugin_demo/ecosystem/demo_ext_ecosystem/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from .demo_ext_ecosystem import DemoExtEcosystem
-
-__all__ = [
- 'DemoExtEcosystem'
-]
diff --git a/src/tools/interop/idt/res/plugin_demo/ecosystem/demo_ext_ecosystem/demo_ext_ecosystem.py b/src/tools/interop/idt/res/plugin_demo/ecosystem/demo_ext_ecosystem/demo_ext_ecosystem.py
deleted file mode 100644
index 11fe43f..0000000
--- a/src/tools/interop/idt/res/plugin_demo/ecosystem/demo_ext_ecosystem/demo_ext_ecosystem.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from capture.base import EcosystemCapture
-
-
-class DemoExtEcosystem(EcosystemCapture):
-
- def __init__(self, platform, artifact_dir: str) -> None:
- self.artifact_dir = artifact_dir
- self.platform = platform
- self.message = "in the demo external ecosystem"
-
- async def start_capture(self) -> None:
- print("Start capture " + self.message)
-
- async def stop_capture(self) -> None:
- print("Stop capture " + self.message)
-
- async def analyze_capture(self) -> None:
- print("Analyze capture " + self.message)
diff --git a/src/tools/interop/idt/scripts/activate.sh b/src/tools/interop/idt/scripts/activate.sh
deleted file mode 100644
index 8b3469c..0000000
--- a/src/tools/interop/idt/scripts/activate.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-sudo docker run \
- -it \
- --mount source="$PWD"/idt,target=/idt,type=bind \
- --privileged \
- -v /dev/bus/usb:/dev/bus/usb \
- -v /var/run/dbus:/var/run/dbus \
- --net=host \
- idt
diff --git a/src/tools/interop/idt/scripts/alias.sh b/src/tools/interop/idt/scripts/alias.sh
deleted file mode 100644
index e7b598b..0000000
--- a/src/tools/interop/idt/scripts/alias.sh
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-if [[ $SHELL == "/bin/zsh" ]]; then
- echo "idt using zsh config"
- export IDT_SRC_PARENT="$(dirname "$0")/../.."
-else
- echo "idt using bash config"
- export IDT_SRC_PARENT="$(dirname "${BASH_SOURCE[0]:-$0}")/../.."
-fi
-
-export IDT_OUTPUT_DIR="IDT_ARTIFACTS"
-
-alias idt_dir="echo \"idt dir $IDT_SRC_PARENT\""
-idt_dir
-alias idt_go="cd \"$IDT_SRC_PARENT\""
-
-alias idt_activate="idt_go && source idt/scripts/activate.sh"
-alias idt_bootstrap="idt_go && source idt/scripts/bootstrap.sh"
-alias idt_build="idt_go && source idt/scripts/build.sh"
-alias idt_clean="idt_go && source idt/scripts/clean.sh"
-alias idt_connect="idt_go && source idt/scripts/connect.sh"
-alias idt_fetch_artifacts="idt_go && source idt/scripts/fetch_artifacts.sh"
-alias idt_prune_docker="idt_go && source idt/scripts/prune_docker.sh"
-alias idt_push="idt_go && source idt/scripts/push.sh"
-alias idt_vars="idt_go && source idt/scripts/vars.sh"
-alias idt_clean_artifacts="idt_go && source idt/scripts/clean_artifacts.sh"
-alias idt_clean_all="idt_go && source idt/scripts/clean_all.sh"
-alias idt_create_vars="idt_go && source idt/scripts/create_vars.sh"
-alias idt_check_child="idt_go && source idt/scripts/check_child.sh"
-alias idt_clean_child="idt_go && source idt/scripts/clean_child.sh"
-
-alias idt="idt_go && \
-if [ -z $PYTHONPYCACHEPREFIX ]; then export PYTHONPYCACHEPREFIX=$IDT_SRC_PARENT/idt/pycache; fi && \
-if [ -z $VIRTUAL_ENV]; then source idt/scripts/py_venv.sh; fi && \
-python3 idt "
-
-echo "idt commands available! type idt and press tab twice to see available commands."
diff --git a/src/tools/interop/idt/scripts/bootstrap.sh b/src/tools/interop/idt/scripts/bootstrap.sh
deleted file mode 100644
index 2347987..0000000
--- a/src/tools/interop/idt/scripts/bootstrap.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-sudo apt-get update
-sudo apt-get install -y docker.io
diff --git a/src/tools/interop/idt/scripts/build.sh b/src/tools/interop/idt/scripts/build.sh
deleted file mode 100644
index 6b97c9a..0000000
--- a/src/tools/interop/idt/scripts/build.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-sudo docker build idt -t idt
diff --git a/src/tools/interop/idt/scripts/check_child.sh b/src/tools/interop/idt/scripts/check_child.sh
deleted file mode 100644
index 8a54cd2..0000000
--- a/src/tools/interop/idt/scripts/check_child.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-sudo ps -axf | grep -E "(tcpd|adb)"
diff --git a/src/tools/interop/idt/scripts/clean.sh b/src/tools/interop/idt/scripts/clean.sh
deleted file mode 100644
index 056532d..0000000
--- a/src/tools/interop/idt/scripts/clean.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-source idt/scripts/vars.sh
-if [[ "$(hostname)" == "$PIHOST" ]]; then
- echo "Target env detected, cleaning"
- sudo rm -R idt
-else
- echo "Not in the target env, so not cleaning"
-fi
diff --git a/src/tools/interop/idt/scripts/clean_all.sh b/src/tools/interop/idt/scripts/clean_all.sh
deleted file mode 100644
index d7703ab..0000000
--- a/src/tools/interop/idt/scripts/clean_all.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-cd idt
-sudo rm -R venv/
-sudo rm -R pycache/
-sudo rm -R IDT_ARTIFACTS/
-sudo find . -type d -name "BUILD" -delete
-cd ..
diff --git a/src/tools/interop/idt/scripts/clean_artifacts.sh b/src/tools/interop/idt/scripts/clean_artifacts.sh
deleted file mode 100644
index d6a0a3a..0000000
--- a/src/tools/interop/idt/scripts/clean_artifacts.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-cd idt
-sudo rm -R "$IDT_OUTPUT_DIR"
-cd ..
diff --git a/src/tools/interop/idt/scripts/clean_child.sh b/src/tools/interop/idt/scripts/clean_child.sh
deleted file mode 100644
index fc4b2e2..0000000
--- a/src/tools/interop/idt/scripts/clean_child.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-sudo killall tcpdump
-sudo killall adb
diff --git a/src/tools/interop/idt/scripts/compilers.sh b/src/tools/interop/idt/scripts/compilers.sh
deleted file mode 100644
index ee50284..0000000
--- a/src/tools/interop/idt/scripts/compilers.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-sudo apt-get install gcc-arm-linux-gnueabi
-sudo apt-get install gcc-aarch64-linux-gnu
-sudo apt-get install byacc
-sudo apt-get install flex
diff --git a/src/tools/interop/idt/scripts/connect.sh b/src/tools/interop/idt/scripts/connect.sh
deleted file mode 100644
index 05d2326..0000000
--- a/src/tools/interop/idt/scripts/connect.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-source idt/scripts/vars.sh
-ssh "$PIUSER@$PIHOST"
diff --git a/src/tools/interop/idt/scripts/create_vars.sh b/src/tools/interop/idt/scripts/create_vars.sh
deleted file mode 100644
index 44d7a42..0000000
--- a/src/tools/interop/idt/scripts/create_vars.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-read -p "Enter RPi host name " pihost
-read -p "Enter RPi user name " piuser
-
-echo "export PIHOST=\"$pihost\"" >"$IDT_SRC_PARENT"/idt/scripts/vars.sh
-echo "export PIUSER=\"$piuser\"" >>"$IDT_SRC_PARENT"/idt/scripts/vars.sh
diff --git a/src/tools/interop/idt/scripts/fetch_artifacts.sh b/src/tools/interop/idt/scripts/fetch_artifacts.sh
deleted file mode 100644
index 49e9027..0000000
--- a/src/tools/interop/idt/scripts/fetch_artifacts.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-source idt/scripts/vars.sh
-idt_go
-scp -r "$PIUSER@$PIHOST:/home/$PIUSER/idt/$IDT_OUTPUT_DIR" .
-cd "$IDT_OUTPUT_DIR"
-ls
diff --git a/src/tools/interop/idt/scripts/prune_docker.sh b/src/tools/interop/idt/scripts/prune_docker.sh
deleted file mode 100644
index 19a44c2..0000000
--- a/src/tools/interop/idt/scripts/prune_docker.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-sudo docker system prune -a
diff --git a/src/tools/interop/idt/scripts/push.sh b/src/tools/interop/idt/scripts/push.sh
deleted file mode 100644
index 5a3d929..0000000
--- a/src/tools/interop/idt/scripts/push.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-source idt/scripts/vars.sh
-if [[ -d idt/venv ]]; then
- echo "TEMP MOVING venv"
- mv idt/venv TEMPvenv
-fi
-if [[ -d "idt/$IDT_OUTPUT_DIR" ]]; then
- echo "TEMP MOVING IDT_OUTPUT_DIR"
- mv "idt/$IDT_OUTPUT_DIR" "TEMP""$IDT_OUTPUT_DIR"
-fi
-if [[ -d idt/pycache ]]; then
- echo "TEMP moving pycache"
- mv idt/pycache TEMPpycache
-fi
-
-scp -r ./idt/* "$PIUSER@$PIHOST:/home/$PIUSER"/idt
-
-if [[ -d TEMPvenv ]]; then
- mv TEMPvenv idt/venv
- echo "venv restored"
-fi
-if [[ -d "TEMP"$IDT_OUTPUT_DIR ]]; then
- mv "TEMP""$IDT_OUTPUT_DIR" "idt/$IDT_OUTPUT_DIR"
- echo "IDT_OUTPUT_DIR restored"
-fi
-if [[ -d "idt/$IDT_OUTPUT_DIR" ]]; then
- echo "pycache restored"
- mv TEMPpycache idt/pycache
-fi
diff --git a/src/tools/interop/idt/scripts/py_venv.sh b/src/tools/interop/idt/scripts/py_venv.sh
deleted file mode 100644
index 3105cbd..0000000
--- a/src/tools/interop/idt/scripts/py_venv.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-cd idt
-if [ -d venv ]; then
- source venv/bin/activate
-else
- python3 -m venv venv
- source venv/bin/activate
- pip install -r requirements.txt
-fi
-cd ..
diff --git a/src/tools/interop/idt/scripts/setup_shell.sh b/src/tools/interop/idt/scripts/setup_shell.sh
deleted file mode 100644
index 48eb0c9..0000000
--- a/src/tools/interop/idt/scripts/setup_shell.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-echo "source $PWD/idt/scripts/alias.sh" >>~/.bashrc
-echo "source $PWD/idt/scripts/alias.sh" >>~/.zshrc
diff --git a/src/tools/interop/idt/scripts/vars.sh b/src/tools/interop/idt/scripts/vars.sh
deleted file mode 100644
index 5133e8d..0000000
--- a/src/tools/interop/idt/scripts/vars.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-export PIHOST="pi-host"
-export PIUSER="pi-user"
diff --git a/src/tools/interop/idt/utils/__init__.py b/src/tools/interop/idt/utils/__init__.py
deleted file mode 100644
index 43ab9ac..0000000
--- a/src/tools/interop/idt/utils/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from . import artifact, host_platform, log, shell
-
-__all__ = [
- 'artifact',
- 'host_platform',
- 'log',
- 'shell',
-]
diff --git a/src/tools/interop/idt/utils/artifact.py b/src/tools/interop/idt/utils/artifact.py
deleted file mode 100644
index 8749b1a..0000000
--- a/src/tools/interop/idt/utils/artifact.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import os
-import time
-from pathlib import Path
-
-from . import log
-
-logger = log.get_logger(__file__)
-
-
-def create_file_timestamp() -> str:
- """Conventional file timestamp suffix"""
- return time.strftime("%Y%m%d_%H%M%S")
-
-
-def create_standard_log_name(name: str, ext: str, parent: str = "") -> str:
- """Returns the name argument wrapped as a standard log name"""
- ts = create_file_timestamp()
- return os.path.join(parent, f'idt_{ts}_{name}.{ext}')
-
-
-def safe_mkdir(dir_name: str) -> None:
- Path(dir_name).mkdir(parents=True, exist_ok=True)
diff --git a/src/tools/interop/idt/utils/host_platform.py b/src/tools/interop/idt/utils/host_platform.py
deleted file mode 100644
index fd64256..0000000
--- a/src/tools/interop/idt/utils/host_platform.py
+++ /dev/null
@@ -1,90 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import os
-import platform as host_platform
-import sys
-
-from utils import log
-from utils.log import border_print
-from utils.shell import Bash
-
-import config
-
-logger = log.get_logger(__file__)
-
-
-def is_mac():
- p = host_platform.platform().lower()
- return "darwin" in p or "mac" in p
-
-
-def get_ll_interface():
- # TODO: Makes too many assumptions
- if is_mac():
- return "en0"
- net_interface_path = "/sys/class/net/"
- available_net_interfaces = os.listdir(net_interface_path) \
- if os.path.exists(net_interface_path) \
- else []
- for interface in available_net_interfaces:
- if "wl" in interface:
- return interface
-
-
-def get_available_interfaces():
- net_interface_path = "/sys/class/net/"
- available_net_interfaces = os.listdir(net_interface_path) \
- if os.path.exists(net_interface_path) \
- else []
- available_net_interfaces.append("any")
- return available_net_interfaces
-
-
-def command_is_available(cmd_name) -> bool:
- cmd = Bash(f"which {cmd_name}", sync=True, capture_output=True)
- cmd.start_command()
- return cmd.finished_success()
-
-
-def verify_host_dependencies(deps: [str]) -> None:
- if not command_is_available("which"):
- # TODO: Check $PATH explicitly as well
- logger.critical("which is required to verify host dependencies, exiting as its not available!")
- sys.exit(1)
- missing_deps = []
- for dep in deps:
- logger.info(f"Verifying host dependency {dep}")
- if not command_is_available(dep):
- missing_deps.append(dep)
- if missing_deps:
- for missing_dep in missing_deps:
- border_print(f"Missing dependency, please install {missing_dep}!", important=True)
- sys.exit(1)
-
-
-def verify_py_version() -> None:
- py_version_major = sys.version_info[0]
- py_version_minor = sys.version_info[1]
- have = f"{py_version_major}.{py_version_minor}"
- need = f"{config.py_major_version}.{config.py_minor_version}"
- if not (py_version_major == config.py_major_version
- and py_version_minor >= config.py_minor_version):
- logger.critical(
- f"IDT requires python >= {need} but you have {have}")
- logger.critical("Please install the correct version, delete idt/venv, and re-run!")
- sys.exit(1)
diff --git a/src/tools/interop/idt/utils/log.py b/src/tools/interop/idt/utils/log.py
deleted file mode 100644
index 73dc4e0..0000000
--- a/src/tools/interop/idt/utils/log.py
+++ /dev/null
@@ -1,79 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import logging
-from typing import TextIO
-
-from termcolor import colored
-
-import config
-
-_CONFIG_LEVEL = config.log_level
-
-_FORMAT_PRE_FSTRING = "%(asctime)s %(levelname)s {%(module)s} [%(funcName)s] "
-_FORMAT_PRE = colored(_FORMAT_PRE_FSTRING, "blue") if config.enable_color else _FORMAT_PRE_FSTRING
-_FORMAT_POST = "%(message)s"
-_FORMAT_NO_COLOR = _FORMAT_PRE_FSTRING+_FORMAT_POST
-
-FORMATS = {
- logging.DEBUG: _FORMAT_PRE + colored(_FORMAT_POST, "blue"),
- logging.INFO: _FORMAT_PRE + colored(_FORMAT_POST, "green"),
- logging.WARNING: _FORMAT_PRE + colored(_FORMAT_POST, "yellow"),
- logging.ERROR: _FORMAT_PRE + colored(_FORMAT_POST, "red", attrs=["bold"]),
- logging.CRITICAL: _FORMAT_PRE + colored(_FORMAT_POST, "red", "on_yellow", attrs=["bold"]),
-}
-
-
-class LoggingFormatter(logging.Formatter):
-
- def format(self, record):
- log_fmt = FORMATS.get(record.levelno) if config.enable_color else _FORMAT_NO_COLOR
- formatter = logging.Formatter(log_fmt)
- return formatter.format(record)
-
-
-def get_logger(logger_name) -> logging.Logger:
- logger = logging.getLogger(logger_name)
- logger.setLevel(_CONFIG_LEVEL)
- ch = logging.StreamHandler()
- ch.setLevel(_CONFIG_LEVEL)
- ch.setFormatter(LoggingFormatter())
- logger.addHandler(ch)
- logger.propagate = False
- return logger
-
-
-def border_print(to_print: str, important: bool = False) -> None:
- len_borders = len(to_print)
- border = f"\n{'_' * len_borders}\n"
- i_border = f"\n{'!' * len_borders}\n" if important else ""
- to_print = f"{border}{i_border}{to_print}{i_border}{border}"
- if config.enable_color:
- to_print = colored(to_print, "magenta")
- print(to_print)
-
-
-def print_and_write(to_print: str, file: TextIO) -> None:
- if config.enable_color:
- print(colored(to_print, "green"))
- else:
- print(to_print)
- file.write(to_print)
-
-
-def add_border(to_print: str) -> str:
- return '\n' + '*' * len(to_print) + '\n' + to_print
diff --git a/src/tools/interop/idt/utils/shell.py b/src/tools/interop/idt/utils/shell.py
deleted file mode 100644
index e2b0d27..0000000
--- a/src/tools/interop/idt/utils/shell.py
+++ /dev/null
@@ -1,122 +0,0 @@
-#
-# Copyright (c) 2023 Project CHIP Authors
-# All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import multiprocessing
-import shlex
-import subprocess
-
-import psutil
-
-from . import log
-
-logger = log.get_logger(__file__)
-
-
-class Bash:
-
- def __init__(self, command: str, sync: bool = False,
- capture_output: bool = False,
- cwd: str = None) -> None:
- """
- Run a bash command as a sub process
- :param command: Command to run
- :param sync: If True, wait for command to terminate upon start_command()
- :param capture_output: Only applies to sync; if True, store and suppress stdout and stderr
- :param cwd: Set working directory of command
- """
- self.logger = logger
- self.command: str = command
- self.sync = sync
- self.capture_output = capture_output
- self.cwd = cwd
-
- self.args: list[str] = []
- self._init_args()
- self.proc: None | subprocess.CompletedProcess | subprocess.Popen = None
-
- def _init_args(self) -> None:
- command_escaped = self.command.replace('"', '\"')
- self.args = shlex.split(f'/bin/bash -c "{command_escaped}"')
-
- def command_is_running(self) -> bool:
- return self.proc is not None and self.proc.poll() is None
-
- def get_captured_output(self) -> str:
- return "" if not self.capture_output or not self.sync \
- else self.proc.stdout.decode().strip()
-
- def start_command(self) -> None:
- if self.proc is None:
- if self.sync:
- self.proc = subprocess.run(self.args, capture_output=self.capture_output, cwd=self.cwd)
- else:
- self.proc = subprocess.Popen(self.args, cwd=self.cwd, stdin=subprocess.PIPE)
- else:
- self.logger.warning(f'"{self.command}" start requested more than once for same Bash instance!')
-
- def term_with_sudo(self, proc: multiprocessing.Process) -> None:
- self.logger.debug(f"SIGTERM {proc.pid} with sudo")
- Bash(f"sudo kill {proc.pid}", sync=True).start_command()
-
- def kill_with_sudo(self, proc: multiprocessing.Process) -> None:
- self.logger.debug(f"SIGKILL {proc.pid} with sudo")
- Bash(f"sudo kill -9 {proc.pid}", sync=True).start_command()
-
- def term(self, proc: multiprocessing.Process) -> None:
- if "sudo" in self.command:
- self.term_with_sudo(proc)
- else:
- proc.terminate()
-
- def kill(self, proc: multiprocessing.Process) -> None:
- if "sudo" in self.command:
- self.kill_with_sudo(proc)
- else:
- proc.kill()
-
- def stop_single_proc(self, proc: multiprocessing.Process) -> None:
- self.logger.debug(f"Killing process {proc.pid}")
- try:
- self.logger.debug("Sending SIGTERM")
- self.term(proc)
- proc.wait(3)
- except psutil.TimeoutExpired:
- self.logger.error("SIGTERM timeout expired")
- try:
- self.logger.debug("Sending SIGKILL")
- self.kill(proc)
- proc.wait(3)
- except psutil.TimeoutExpired:
- self.logger.critical(f"SIGKILL timeout expired, could not kill pid {proc.pid}")
-
- def stop_command(self) -> None:
- if self.command_is_running():
- psutil_proc = psutil.Process(self.proc.pid)
- suffix = f"{psutil_proc.pid} for command {self.command}"
- self.logger.debug(f"Stopping children of {suffix}")
- for child_proc in psutil_proc.children(recursive=True):
- self.stop_single_proc(child_proc)
- self.logger.debug(f"Killing root proc {suffix}")
- self.stop_single_proc(psutil_proc)
- else:
- self.logger.warning(f'{self.command} stop requested while not running')
-
- def finished_success(self) -> bool:
- if not self.sync:
- return not self.command_is_running() and self.proc.returncode == 0
- else:
- return self.proc is not None and self.proc.returncode == 0