Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions bench/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Bench host setup

Host-side pieces for the HIL bench (`tsi-ha`). Everything else in this repo runs inside
the `firmware-tester` container; these do not, because they drive hardware the container
has no access to.

## BLE flood

`scripts/ble_flood.py` advertises from a fresh random address ~40 times a second, so each
rotation costs a node a new fingerprint slot. It exists to make the slow heap decline in
[ESPresense#2309](https://github.com/ESPresense/ESPresense/issues/2309) show up in a HIL
window instead of over days on someone's shelf.

It talks to the adapter over `HCI_CHANNEL_USER`, so **BlueZ is not required and should not
be installed** — the kernel hands over the controller exclusively and `bluetoothd` would
only fight for it.

Requires a USB Bluetooth adapter passed through to the VM. Verify the kernel sees it:

```bash
ls /sys/class/bluetooth # expect hci0
python3 ble_flood.py --selftest # framing + address rules, no hardware needed
sudo python3 ble_flood.py --index 0 --seconds 30 # 30s live burst
```

Install:

```bash
sudo install -m 755 scripts/ble_flood.py /usr/local/bin/ble_flood.py
sudo install -m 644 bench/ble-flood.service /etc/systemd/system/
sudo systemctl enable --now ble-flood
```

The service idles until a request file appears in `/var/lock/woodpecker/bleflood.d/`. Each
HIL step creates one on entry and removes it on exit, so the flood only runs during tests —
otherwise every ESPresense node within range spends the day logging junk MACs. It is a
directory, not a single flag, because the four device steps run in parallel and the first
one to finish must not cut the flood out from under the rest. Request files older than
`--max-age` (9h) are ignored, so a hard-killed container cannot leave the bench advertising
forever.

To flood by hand (e.g. reproducing a report):

```bash
sudo mkdir -p /var/lock/woodpecker/bleflood.d
sudo touch /var/lock/woodpecker/bleflood.d/manual # journalctl -fu ble-flood to watch
sudo rm /var/lock/woodpecker/bleflood.d/manual
```
24 changes: 24 additions & 0 deletions bench/ble-flood.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[Unit]
Description=BLE advertisement flood for the ESPresense HIL bench
Documentation=https://github.com/ESPresense/firmware-tester
After=network.target

[Service]
# Runs continuously but only advertises while a HIL step asks for it. Steps already
# bind-mount /var/lock/woodpecker, so each one drops a request file there and removes it on
# exit — no host access, no extra plumbing, and the bench is quiet between runs instead of
# filling every ESPresense node in the house with junk fingerprints.
ExecStart=/usr/local/bin/ble_flood.py --index 0 --rate 40 --flag-dir /var/lock/woodpecker/bleflood.d
Restart=always
RestartSec=5
# HCI_CHANNEL_USER needs CAP_NET_ADMIN and an adapter no one else has powered up.
AmbientCapabilities=CAP_NET_ADMIN
CapabilityBoundingSet=CAP_NET_ADMIN
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
ReadWritePaths=/var/lock/woodpecker

[Install]
WantedBy=multi-user.target
Loading
Loading