# Compare WSN routes before and after relay loss

Compare delivery and parent-path length in compact and spread layouts under the same router-removal test.

## Run on Linux x86-64 with Docker and X11

The image, Java, compiler and simulator ran on this host under Apptainer.
Docker is unavailable here: the laptop Docker invocation is syntax-reviewed,
not claimed as laptop-tested. Windows, macOS and ARM display setup is outside
this recipe. No paid service or account is required.

Download `lab-files.tar.gz` from this lab page. In a terminal:

```bash
mkdir cooja-lab
cd cooja-lab
tar -xzf ~/Downloads/lab-files.tar.gz
git clone --depth 1 --branch release/v4.9 https://github.com/contiki-ng/contiki-ng.git contiki-ng
test "$(git -C contiki-ng rev-parse HEAD)" = c20b12cd2db707d6c07918f8b26cfeb52cf298ca
git -C contiki-ng submodule update --init --depth 1 tools/cooja
test "$(git -C contiki-ng/tools/cooja rev-parse HEAD)" = 33d41ae9f8acd6075fb903b0bcd5b4122bad8d8f
mkdir -p jdk17 home/contiki-ng
curl -fL 'https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.20.1%2B1/OpenJDK17U-jdk_x64_linux_hotspot_17.0.20.1_1.tar.gz' -o jdk17.tar.gz
echo '3808d1d15e3ec6bd5b84057fb5d84c33d8a1536a258146bcea2e603fc726e08e  jdk17.tar.gz' | sha256sum -c -
tar -xzf jdk17.tar.gz --strip-components=1 -C jdk17
xhost +si:localuser:$(id -un)
bash cooja-wsn-routing-compare/docker-launch.sh
# After closing Cooja:
xhost -si:localuser:$(id -un)
```

The launcher binds the packet at `/lab`. Cooja loads `/lab/cooja-wsn-routing-compare.csc`
and compiles the included unmodified upstream C files. The project header enables
logging and any explicitly documented parameter changes. The supplied Makefiles
expect the recipe's `/home/user/contiki-ng` mount. The first Gradle build requires
Internet. To use your own native Java 17 installation, set CONTIKI in the supplied
Makefiles to your checkout and open the CSC with that release's Cooja.

The script starts automatically and stops at `TEST OK` or `TEST FAILED`. The GUI
stays open. Use **Mote output → Filter** to show the rows named in the steps;
clear the filter to inspect other messages. **File → Open simulation → Browse...**
loads another CSC. Reopen the original CSC for a fresh seed-1 run.
Times are simulated times, not wall-clock times. `expected-output.txt` is the
unaltered headless serial/test log, including actual measurements and the test result.

For headless Docker execution, replace `--gui --autostart` in the launcher with
`--no-gui --logdir=/lab/run-output` and remove the display requirement/mount.
Cooja writes `COOJA.testlog` under that writable output directory.

## Matched experiment

Unchanged examples/rpl-udp, MRHOF, non-storing RPL, seed 1, 180 s, UDGM
50 m transmit and 100 m interference; TX/RX success 1. Only positions change:

| Source | Compact x,y | Spread x,y |
|---|---|---|
| 1 sink | 0,0 | 0,0 |
| 2 | -15,12 | -30,25 |
| 3 | 15,12 | 30,25 |
| 4 | -30,27 | -60,55 |
| 5 | 0,27 | 0,55 |
| 6 | 30,27 | 60,55 |

Both CSCs remove mote 3 with sim.removeMote at the same 90.065-second event.
It is absent thereafter, not a moved-but-still-transmitting node. Both capture
mote 5 rpl-status at 85 and 150 seconds, and ping the root at 155 seconds.
The test requires initial delivery from all five sources, post-fault deliveries
and mote 5's successful ping. It deliberately does **not** require all-source
recovery: source 6 fails in the spread case and that finding is retained.
Reopen each CSC for a clean repeat. The main CSC equals the spread variant.

| Metric | Compact | Spread |
|---|---|---|
| Whole-run received / sent | 73 / 73 (100%) | 55 / 59 (93.2%) |
| After-fault received / sent | 36 / 36 (100%) | 25 / 29 (86.2%) |
| After-fault source 2 | 9 / 9 | 9 / 9 |
| After-fault source 4 | 9 / 9 | 9 / 9 |
| After-fault source 5 | 9 / 9 | 7 / 9 |
| After-fault source 6 | 9 / 9 | 0 / 2; then no route |
| Source 5 selected path after fault | 5→1, one hop | 5→2→1, two hops |
| Source 5 root ping | TTL 64, 27 ms RTT | TTL 63, 119 ms RTT |

The PATH rows follow current parent annotations at each application send;
they are route-state snapshots, not a frame-by-frame forwarding trace. A saved
last-known hop count can remain after a source loses its path. Check timestamps,
Not reachable yet and actual sink reception before calling a source recovered.
The denominator is attempted samples, not scheduled opportunities while unreachable.
The root is a collection sink, not an Internet gateway in this experiment.

## Original routing runbook and paper exercises

Write the question, topology, roles, traffic, fixed time, route snapshot, decision
rule, event identity, observed forward/drop/repair action and review limit before
running either candidate. Keep failure time, first symptom, replacement path,
missing sources, owner, fallback and retest trigger together. Inspect relay
pressure and freshness as well as the mean. This packet measures delivery and
path length; it does not measure queue age, electrical energy, or all Trickle
suppression counters. Do not claim that low radio chatter proves all nodes fresh.

Collection exercise: the spread run demonstrates why a recovered source 5 does
not justify accepting the disconnected source 6. Recommend another reachable
relay, then repeat both the baseline and failure test before site approval.

Data-centric query worksheet (not executed by RPL): choose region A sources
4,5,6 and a freshness deadline. If replies from 4 and 5 arrive and 6 is absent,
record missing 6 rather than inventing a zero measurement. A late reply is stale,
not proof of timely coverage. This packet does not run AODV, DSR or query matching.

Aggregation worksheet (not executed): measurements 20,21,45 have mean 28.67.
Removing source 6's 45 gives 20.5 and hides the outlier. Preserve membership,
missing status and the raw exception path before using a summary for control.
Dissemination worksheet: name version state, reset cause, suppressed sends,
which nodes heard an update and which remained stale. RPL's route repair alone
is not a measured dissemination-coverage or suppression result.

Decision ledger: accept only this matched topology comparison. Hold field
coverage, power and production readiness. Name the monitoring owner, fallback
for missing source 6, and retest after placement, firmware, interference or
traffic changes. Keep both complete logs, including losses.


## Tested version

Contiki-NG release/v4.9 c20b12cd, Cooja 4.8 (2022071901), Temurin 17.0.20.1, image sha256:b14d5afb0a2a852d9e72bbed607ead03f6ccc5f4d4dee44f0799110be2f4b609
