Skip to content

O500 tools and setup ​

This guide explains how to use the tools for investigating local control of the ECOVACS GOAT O500. It includes setup instructions, diagnostic examples, and guidelines for running experiments on your own mower.

The main focus is device-side analysis: network behavior, TLS trust, and hardware and boot interfaces. Android app inspection supports specific questions that the device-side evidence hasn't answered.

The available notes and tools include:

  • Protocol and hardware research notes in docs/O500_Research.md
  • Passive PCAP metadata tooling in tools/o500_pcap_inventory.py
  • A minimal TLS test listener for isolated certificate-trust experiments
  • A redacting MQTT metadata probe for isolated JMQ protocol experiments
  • The reviewed UART maintenance-shell bootstrap used during device analysis
  • Authorized, narrowly scoped Frida observers for Android app traffic metadata

Scope and safety ​

Work on your own mower, or one you have explicit permission to investigate. Make one change at a time and keep a clear rollback path.

  • Do not run tests on networks or devices you do not control.
  • Do not collect account credentials, tokens, full payload contents, or private user data.
  • Do not redirect the mower's DNS or block cloud access until replacement components are proven in an isolated test environment.
  • Keep captures (PCAPs, logs) out of version control.

The observers in tools/ collect metadata and omit sensitive fields, so you can inspect protocol behavior without logging credentials or private data.

Research scopes ​

Primary scope: device analysis ​

Start with device-side evidence. Expand app inspection when a specific question remains unanswered.

  • Router/gateway passive capture for DNS/TLS/STUN/flow behavior
  • TLS trust-path testing on isolated infrastructure
  • Device boot, UART, storage, and verified-boot observations
  • Reproducible, one-change-at-a-time experiments with rollback discipline

Dedicated secondary scope: Android checks ​

Android checks are supporting instrumentation, not the main direction. Use them only to answer specific protocol unknowns that cannot be resolved from device-side evidence.

  • Keep collection metadata-only and time-bounded
  • Prefer schema/selectors/header-name extraction over values
  • Run only on an authorized test device and account

Repository layout ​

text
docs/
  O500_Research.md                     # Current findings and milestone plan
tools/
  o500_pcap_inventory.py               # Passive DNS/TLS/STUN/flow inventory
  tls_probe.py                         # Minimal TLS handshake probe listener
  jmq_metadata_probe.py                # Redacted TLS/MQTT framing probe
  goat_serial_bootstrap.sh             # Owner-installed UART maintenance shell
  goat_serial_bootstrap_diag.sh        # Staged no-echo UART shell diagnostic
  uart_raw_diag.py                     # Interactive raw UART RX/TX diagnostic
  o500_app_mqtt_observer.py            # List app MQTT method signatures
  o500_app_mqtt_metadata_observer.py   # Redacted MQTT topic metadata
  o500_app_http_metadata_observer.py   # HTTP method/host/path metadata
  o500_app_control_schema_observer.py  # JSON key-path + type schema only
  o500_app_control_selector_observer.py# Narrow action selector values only
  o500_app_control_metadata_observer.py# Header names + enum-like protocol keys

Prerequisites ​

Python tooling ​

  • Python 3.10+
  • pip

Install dependencies used by the full toolset:

sh
python -m pip install frida frida-tools

Notes:

  • o500_pcap_inventory.py and tls_probe.py use only the Python standard library.
  • Frida-based app observers are secondary-scope tools and additionally require a working Frida setup with an authorized Android test device.

Packet capture tooling ​

  • tcpdump on your gateway/router (or equivalent capture mechanism)

Quick start ​

Decision policy:

  • Treat steps 1 through 4 as required baseline device analysis.
  • Run step 5 only if a concrete protocol question remains unanswered.
  • Record the exact unanswered question before starting any Android check.

1) Read the current findings ​

Start with:

  • docs/O500_Research.md

It documents known endpoints, trust observations, UART findings, and next milestones.

2) Capture passive network data safely ​

Example gateway capture (from the research doc):

sh
tcpdump -npi <GATEWAY_IFACE> -s 0 -U -w <CAPTURE_PATH>/o500.pcap 'host <MOWER_IP>'

Then inventory non-decrypted metadata:

sh
python tools/o500_pcap_inventory.py <CAPTURE_PATH>/o500.pcap --device-ip <MOWER_IP> --json

What you get:

  • DNS question names
  • TLS ClientHello SNI/ALPN
  • STUN flow detection
  • Basic TCP/UDP flow counters and timing

3) Run isolated TLS trust probe (device-side) ​

Use only in an isolated lab network with narrowly scoped redirect rules:

sh
python tools/tls_probe.py --cert ./server.crt --key ./server.key --port 11443 --seconds 300

This confirms TCP/TLS handshake outcomes only; it is not an app protocol emulator. jmq_metadata_probe.py additionally accepts MQTT CONNECT/SUBSCRIBE framing and records redacted topic and packet metadata without storing payloads or credentials. Keep it on an isolated network behind a source-restricted redirect.

goat_serial_bootstrap.sh is the reviewed payload used by the owner-installed /data/autostart/10-serial-root.sh maintenance hook. It opens an interactive root shell on the physical UART and no network listener. It remains persistent root access while installed; see the research note for the UART/ADB state and removal path.

goat_serial_bootstrap_diag.sh is a separate diagnostic candidate that turns off Linux TTY echo and Bash line editing to distinguish echoed input from shell output. It is not installed on the mower. Do not deploy it until /data has a verified backup and tested rollback path.

4) Review device-focused milestones ​

Continue with the device-analysis milestones and hand-off notes in docs/O500_Research.md.

Before moving on, confirm whether device-side evidence already answers your current question. Typical examples:

  • Endpoint and transport mapping (DNS, SNI, ALPN, flow patterns)
  • TLS trust acceptance or rejection behavior
  • Boot/interface behavior and persistence boundaries

If these cover your question, stop here and continue device-side work.

Horizon X5 UART diagnostics ​

On Linux, identify the USB-UART adapter with:

sh
python -m serial.tools.list_ports -v
ls -l /dev/serial/by-id/

The stable /dev/serial/by-id/... name is preferable to /dev/ttyUSB*. Install PySerial if needed (python -m pip install pyserial) and run the raw diagnostic tool:

sh
python o500/tools/uart_raw_diag.py /dev/serial/by-id/<ADAPTER-ID> --log /tmp/o500-uart.log

The tool opens 115200 8N1 with RTS/CTS, XON/XOFF, and DSR/DTR flow control off. It does not echo keyboard input locally, and it sends nothing automatically. Every RX line is bytes actually read from the adapter, shown as hex and printable ASCII; every explicit TX is separately recorded. At the uart> prompt, use preset interrupt only to stop autoboot, then wait for Hobot>. Use send 68, send 65, send 6c, and send 70 to try bytes individually; then test preset help, preset cr, preset lf, and preset crlf as separate actions. A command is not confirmed by terminal display: look for corresponding RX bytes and a U-Boot response. The optional log captures timestamps and both directions. Keep the mower UART at 3.3 V, share ground, and do not connect the mower's 3.3 V rail to the adapter's supply output.

For a paced, read-only U-Boot check, use send-paced to transmit one byte at a time with a bounded 10–500 ms gap. For example, send-paced 100 76 65 72 73 69 6f 6e 0d sends version followed by CR. The tool logs each TX byte and drains RX between bytes. This can distinguish a timing-sensitive input path from the earlier burst test; matching RX bytes alone still do not prove that U-Boot executed the command.

5) (Secondary scope, optional) Run authorized Android metadata observers ​

Run this step only for a named gap that is still unresolved after step 4, for example:

  • Missing control-request schema paths/types
  • Missing control selector fields (act, type, content.type)
  • Missing protocol constants (header.m, header.channel, header.ver)

These scripts attach to the ECOVACS app process and print strictly scoped metadata for a short test window.

Examples:

sh
python tools/o500_app_http_metadata_observer.py --process "ECOVACS HOME" --seconds 180
python tools/o500_app_control_schema_observer.py --process "ECOVACS HOME" --control-host "api-ngiot.dc-eu.ww.ecouser.net" --seconds 180
python tools/o500_app_mqtt_metadata_observer.py --process "ECOVACS HOME" --seconds 300

Tool reference ​

Passive network inventory ​

  • tools/o500_pcap_inventory.py
  • Input: classic little-endian Ethernet PCAP
  • Output: text or JSON metadata summary
  • Does not initiate any outbound connection

TLS trust probe ​

  • tools/tls_probe.py
  • Accepts multiple inbound TCP connections and logs TLS establish/reject events
  • Intended for authorized certificate-trust experiments

Android checks (dedicated secondary scope) ​

Use only for targeted gaps after device-side analysis.

  • tools/o500_app_mqtt_observer.py
    • Lists relevant com.ecovacs.mqtt.MqttClient method signatures
  • tools/o500_app_mqtt_metadata_observer.py
    • Logs redacted topic metadata for publish/subscribe/unsubscribe
  • tools/o500_app_http_metadata_observer.py
    • Logs HTTP method + host + path only
  • tools/o500_app_control_schema_observer.py
    • Logs JSON field paths and value types only
  • tools/o500_app_control_selector_observer.py
    • Logs narrow selector fields (act, type, content.type)
  • tools/o500_app_control_metadata_observer.py
    • Logs HTTP header names and enum-like control request keys (m, channel, ver)

Current status ​

Based on current findings, O500 control depends on both:

  • App-facing NG-IoT HTTPS control endpoint semantics
  • Mower-facing JMQ-over-TLS channel semantics and trust

Practical local replacement remains an active research effort. See docs/O500_Research.md for the current hand-off state and next milestones.

Current direction priority for this repository is device-side analysis first, with Android checks used only as a dedicated supporting scope.

Contributing ​

Contributions are welcome if they preserve the repository's safety model:

  • Keep collection narrowly scoped and metadata-only by default.
  • Prefer isolated-lab validation before any operational-network changes.
  • Document assumptions, rollback plans, and reproducible test steps.