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