# Compare a star and an RPL mesh during node failure

Objective from the Core Networking guide's Packet Switching and Performance chapter:
trace independent packet forwarding and diagnose loss when a path changes.
This is a **simulated radio** exercise, not field reliability data.

## Inputs and what changes

Both CSC files use six motes, seed 1, Contiki-NG release/v4.9 RPL/UDP firmware,
the same coordinates, the same application traffic, and the same node-3
intervention at simulated 90.065 s. Root 1 is at (0,0); relays/leaves 2 and 3
at (-30,25) and (30,25); leaves 4, 5, and 6 at (-60,55), (0,55), and (60,55).
The **mesh** uses UDGM 50 m transmit and interference ranges, so target 5
starts through node 3 and can switch to node 2. The **star** uses 120 m ranges,
so target 5 reaches root 1 directly. At 90.065 s the script moves node 3 to
(300,300); at 210.065 s it restores node 3. GUI runs pause at about 89 and
150 s. Click Start/Pause to advance after each pause. Headless runs continue.

The radio range is deliberately different to create the two topologies. It also
changes contention and routing opportunities, so compare the **same target 5
fault-window requests**, not the two whole-network totals as a causal estimate.

## Run with the pinned free simulator

On Linux x86-64 with Docker and an X11 desktop, extract `lab-files.tar.gz` in a
new `cooja-lab` directory. The host run for this packet used Apptainer and Xvfb;
this Docker learner command follows the verified parent-switch lab recipe.

```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
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)
```

Run either `mesh` or `star` as `MODE`:

```bash
MODE=mesh
docker run --rm -it --entrypoint /bin/bash \
  --user "$(id -u):$(id -g)" -e DISPLAY="$DISPLAY" -e HOME=/home/user \
  -e JAVA_HOME=/opt/jdk17 -e JAVA_OPTS=-Djava.awt.headless=false \
  -e GRADLE_USER_HOME=/home/user/.gradle \
  --mount "type=bind,source=$PWD/home,target=/home/user" \
  --mount "type=bind,source=$PWD/contiki-ng,target=/home/user/contiki-ng" \
  --mount "type=bind,source=$PWD/jdk17,target=/opt/jdk17,readonly" \
  --mount "type=bind,source=$PWD/cooja-star-mesh-node-failure,target=/lab" \
  --mount type=bind,source=/tmp/.X11-unix,target=/tmp/.X11-unix \
  --workdir /home/user/contiki-ng \
  contiker/contiki-ng:latest@sha256:b14d5afb0a2a852d9e72bbed607ead03f6ccc5f4b609 \
  -lc "cd tools/cooja; ./gradlew --no-daemon --max-workers=4 installDist && exec build/install/cooja/bin/cooja --gui --autostart --javac=/opt/jdk17/bin/javac --contiki=/home/user/contiki-ng /lab/$MODE.csc"
# After closing Cooja:
xhost -si:localuser:$(id -un)
```

To collect a fresh headless log, use the same container command but replace
`--gui --autostart` with `--no-gui --logdir=/lab/run-output-$MODE`, remove the
X11 display requirement, and read `COOJA.testlog` in that output directory.
The included `mesh-headless.log` and `star-headless.log` are the unaltered
headless ScriptRunner logs from the pinned host run; search for `FAULT`,
`SUMMARY`, and `TEST OK` to check the outcome.

## Observed result from the included logs

| Scenario | Target 5 route before/after node 3 moves | Target 5 requests delivered during fault | Route/application timing |
|---|---|---:|---|
| Mesh, 50 m | 5→3→1, then 5→2→1 | 10/12 | Parent change 100.760728 s; first recovered root request 110.644856 s |
| Star, 120 m | 5→1 before and after | 12/12 | No target route change; first scheduled root request after fault 92.147568 s |

The mesh parent change occurs 10.695728 s after removal. Its first observed
successful application uplink occurs 20.579856 s after removal. A successful
packet only bounds recovery; it does not reveal every failed instant between
these observations. The star's 92.147568 s packet is a scheduled message on an
unbroken direct route, **not** a measured recovery time.
