probe
One CLI and library for the physical layer (radio and wired buses). The same commands drive a virtual lab target and real hardware.
probe is a generalist command line tool and Python library for the physical layer: the media that do not ride on IP. Where most tooling assumes a TCP/UDP stack, probe speaks directly to radio links and wired buses. It is Espilon's own tool, built so that the same verbs cover very different media and run the same way in a lab and on the bench.
It covers two families of media:
- Radio: BLE and Zigbee (802.15.4).
- Wired buses: CAN and UART.
The headline property is that the same verbs run everywhere. The command you type against a virtual lab target is the command you type against real hardware. Only the backend changes (see Real hardware). You learn the verbs once and reuse them on physical gear.
Why it matters
Physical-layer work is normally a pile of one-off tools, each with its own flags: one utility for BLE GATT, another for 802.15.4, can-utils for CAN, a serial terminal for UART. probe collapses that into a single verb set with a single mental model, so the effort you spend learning to scan, sniff, inject, and replay transfers straight from a radio target to a wired one. Because the virtual backend behaves exactly like the real one, a course can teach the workflow on a lab target and you carry the identical commands to real hardware with no relearning. probe deliberately stays a live-I/O tool and hands analysis off to the tools you already trust.
Install
pip install https://learn.espilon.net/learn/probe/espilon_probe-0.1.0-py3-none-any.whl
This installs the probe console command.
Setup
A lab gives you a backend endpoint. Point probe at it with an environment variable:
export ESP_PROBE=tcp://<host>:<port>
The default backend is virtual and reads this endpoint from ESP_PROBE. Check your connection:
probe info
You can also pass the endpoint per command with --target tcp://<host>:<port> instead of the environment variable.
Verbs
All verbs share one invocation surface: probe <verb> .... The core verbs work on every medium; the medium verbs (gatt, can, uart) appear when the backend offers them.
Core verbs
info shows the backend, the medium, the channels, and what the backend can do.
probe info
scan enumerates what is present on the medium (devices, ids, addresses).
probe scan
sniff captures frames to a standard pcap. Bound it with a frame count, a duration, or a channel.
probe sniff -w capture.pcap -t 60
inject transmits one raw frame, given inline as hex or read from a file.
probe inject --hex DEADBEEF
replay re-transmits frames from a pcap. Pre-filter the pcap first with tshark -w if you only want a subset.
probe replay -r capture.pcap
Medium verbs
gatt drives BLE GATT operations: enum lists services and characteristics, read reads one, write writes one. A handle looks like 0x0011, or you can use a UUID.
probe gatt enum
probe gatt read 0x0011
probe gatt write 0x0014 01
can drives the CAN bus: send transmits one frame (arbitration id plus hex payload), dump captures frames to a pcap.
probe can send 0x7DF 0201
probe can dump -w can.pcap -c 20
uart drives a UART console: write sends text to the line, read reads available output. The line rate defaults to 115200 and is set with --baud.
probe uart write "version"
probe uart read
Captures and analysis
probe writes plain pcap. It does not dissect, decrypt, or crack anything itself. Analyse the capture with stock tools:
probe sniff -w zb.pcap -t 60
tshark -r zb.pcap # dissect
zbdsniff zb.pcap # recover a Zigbee key
This keeps the boundary clean: probe does the live physical I/O, your existing tooling does the offline analysis.
Real hardware
The same verbs run against real backends by selecting one with --backend and pointing --target at the device. No relearning.
probe --backend socketcan --target vcan0 scan
probe --backend socketcan --target vcan0 can send 0x7DF 1003
probe --backend serial --target /dev/ttyUSB0 --baud 115200 uart read
Backend status:
- Live today:
socketcan(real CAN over Linux SocketCAN) andserial(real UART). - Planned:
hci(BLE over BlueZ),killerbee(802.15.4 / Zigbee),sdr(sub-GHz over SoapySDR), andopenocd/ftdi(JTAG / SPI).
Pitfalls
probeis a live-I/O tool, not an analyser. It will not dissect, decrypt, or crack; if you expected it to recover a key, that is a job fortshark,zbdsniff, or similar on the pcap it writes.- The medium verbs only appear when the backend supports them.
probe gattagainst a CAN backend is meaningless; runprobe infofirst to see what the current medium offers. - The virtual backend faithfully mimics the real one, but real hardware adds real-world failure modes (termination, baud mismatch, RF noise) that a lab target never shows.
- Selecting the wrong
--backend/--targetpair fails fast rather than guessing; confirm the endpoint withprobe infobefore a capture session.
What it pairs with
probe deliberately stops at the pcap boundary and hands off to the analysis stack you already use: tshark and Wireshark to dissect, zbdsniff for Zigbee keys, and the same offline crackers you would reach for anyway. On the hardware side it complements the medium-specific tools, can-utils for CAN and picocom/emon for UART, giving you one portable verb set that maps onto the same buses those tools drive.