# Inspect 6LoWPAN IPv6 neighbor state

This Cooja lab uses three Contiki-NG RPL motes on simulated UDGM radio, not
field data. The `hello` UDP payloads produced by the copied firmware are
synthetic sequence labels; they are not measurements. Seed 1, initial
positions (0,0), (110,0), (70,0), 50 m radio range, and all interventions
are in `cooja-6lowpan-neighbor-state.csc`.

## Run

On Linux x86-64 with Docker and X11, extract `lab-files.tar.gz` in a fresh
directory and run:

```bash
tar -xzf 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-6lowpan-neighbor-state/docker-launch.sh
```

The launcher uses a pinned Contiki-NG container image. After closing Cooja,
revoke the temporary X11 access with `xhost -si:localuser:$(id -un)`.
The host evidence run used the shared Apptainer driver with Xvfb `:98`
and the same source pins.

The GUI pauses at simulated 15, 45, 60, 75, 100, and 120 s. Click
**Start/Pause** to advance. Use **Network** for positions, **Mote output**
for `ip-nbr`, `Adding neighbor`, and ping lines, and **Radio messages** for
radio frames. `expected-output.txt` is the unedited headless serial/test log
from this CSC. The headless run ends at 130 s with `TEST OK`.

## What actually changes

At 5.549 s, root 1 reports `Node IPv6 neighbors: none`. At 20.549 s the
script moves mote 2 from x=110 to x=35, into root range. The stack logs the
root adding `fe80::202:2:2:2` at 26.496 s. Root pings that link-local
address at 40.549 s and gets a reply at 40.631 s (82 ms); it pings again
at 50.549 s and gets a reply at 50.616 s (67 ms). At 55.549 s `ip-nbr`
reports that address as `Reachable`.

At 65.549 s the ScriptRunner removes mote 2 and creates a **new mote
instance** of the same type, ID, and position. This is a real simulated
reboot. Cooja's Contiki watchdog `reboot` shell command only prints a
message; the platform implementation is empty and would not reset neighbor
state. The new instance boots at 66.455 s and reports `Node IPv6 neighbors:
none` at 66.549 s. By 80.549 s it has learned mote 3. Root 1 still shows
its existing entry for mote 2 as `Reachable` at 85.549 s. Root pings mote 2
again at 90.549 s and receives the reply at 90.582 s (33 ms). The ScriptRunner
records `before_replies=2 after_replies=1`.

The radio window and RPL/IPv6 neighbor logs show control activity, while
`Received request` lines are synthetic application payloads. The checked
log does **not** isolate a Neighbor Solicitation/Advertisement exchange or
prove a cache miss caused either ping delay. Different pings are not a
controlled latency benchmark. The observation is the cache table transition
at mote 2 and the tested link-local reachability; root's cache did not clear
when only its neighbor rebooted.

This simulated radio result does not establish field neighbor lifetimes,
interference behavior, or Thread network behavior.
