# Request a temperature resource over a simulated constrained mesh

This lab runs the real Contiki-NG CoAP stack inside Cooja. The radio, positions,
and packet delivery are simulated. It does not measure hardware radio behaviour.
Server 1 is the RPL root at (0,0), relay 2 at (25,0), and client 3 at (50,0).
UDGM range is 40 m, so client 3 needs relay 2 to reach server 1. Seed is 1.
The `temperature` resource starts at `21.5`, accepts a PUT of `22.0`, and
returns text/plain. The run uses GET and PUT, then compares CON and NON GET
across a timed relay outage. The ScriptRunner stops with `TEST OK` only after
GET, PUT, a recovered CON response, and the final NON attempt are observed.

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

The committed `expected-output.txt` and six captures were taken from an actual
Apptainer/Cooja run on Linux x86-64. The Docker recipe below uses the same
pinned image and source revision, but was not separately run on a learner laptop.
No paid account is needed. Start with Docker and an X11 display. Download
`lab-files.tar.gz` from the lab page, then run:

```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-coap-resource-mesh/docker-launch.sh
# After closing Cooja:
xhost -si:localuser:$(id -un)
```

The CSC compiles the three C programs from `firmware/` when opened. The Docker
launcher mounts the packet at `/lab` and source at `/home/user/contiki-ng`.
For a fresh run, use Cooja **File → Open simulation** and reopen the CSC.
The exact host capture commands and log hash are in the lane evidence report.

## What the output proves

The `hex=` lines are actual Contiki-NG `coap_serialize_message()` output
**before** the send API assigns the final message ID. The `0000` message-ID
bytes are placeholders; these lines are not a captured on-wire PCAP. The
first byte `40` is a CON GET with no token; `50` is a NON GET; `52` is a NON
GET with a 2-byte token. The URI-Path `temperature` appears as option `bb`
plus its UTF-8 bytes. PUT includes payload marker `ff` followed by ASCII
`22.0`. The server and client logs are from the executed firmware and show
actual response codes: 69 = 2.05 Content; 68 = 2.04 Changed.

At 43.549 simulated seconds the ScriptRunner moves relay 2 to (300,300),
outside radio range. The client sends a CON GET at 45.882 seconds. The relay
returns at 48.549 seconds, and server 1 receives a GET at 50.380 seconds;
client 3 gets its response at 50.399 seconds. The 4.517-second interval from
client request to reply includes the outage and retransmission period. The
script moves the relay away again immediately before the final NON GET. No
server GET or client response for that final request appears by 60.400 seconds.
A missing response in this bounded simulation is an observation, not a proof
that every NON request must be lost. The earlier baseline NON GET did reach
the server, although this client callback path did not print its response.

Record the request type and URI, the server receipt, the response code and
payload where present, the relay position, and the observation window. Try
changing the fault time or relay range in the CSC, then rerun and compare.
