13 6LoWPAN Review: Hands-On Labs
Lab execution time can be estimated before starting runs:
\[ T_{\text{total}} = N_{\text{runs}} \times (t_{\text{setup}} + t_{\text{run}} + t_{\text{review}}) \]
Worked example: With 5 runs and per-run times of 4 min setup, 6 min execution, and 3 min review, total lab time is \(5\times(4+6+3)=65\) minutes. This prevents under-scoping and helps schedule complete experimental cycles.
13.1 Learning Objectives
By the end of this chapter, you will be able to:
- Configure 6LoWPAN Border Routers: Compile, flash, and validate Contiki-NG border router firmware with tunslip6 TUN interface creation
- Construct CoAP Sensor Nodes: Implement REST resource handlers in Contiki-NG that expose sensor data as discoverable CoAP endpoints
- Diagnose Connectivity Failures: Isolate root causes of routing, addressing, and compression problems using ping6, coap-client, and Wireshark
- Evaluate Fragmentation Trade-offs: Analyse simulation results to assess how payload size affects fragment count, reliability, and overhead
- Validate Designs Through Simulation: Execute Python-based 6LoWPAN simulations and interpret compression, fragmentation, and packet-loss statistics
These hands-on labs let you explore 6LoWPAN networking through guided exercises. You will set up networks, analyze packet captures, and troubleshoot common issues. Practical experience with 6LoWPAN gives you confidence to work with this important IoT networking technology in real projects.
“Time to get our hands dirty!” announced Max the Microcontroller. “We are going to set up a real 6LoWPAN network with three parts: a border router that connects our mesh to the internet, sensor nodes that collect data, and a client app that reads the sensor values.”
Sammy the Sensor asked, “What software do we use?” Max explained, “Contiki-NG is the operating system designed for tiny IoT devices. It includes a full 6LoWPAN stack with header compression, fragmentation, and RPL routing. The border router runs a special program called tunslip6 that creates a virtual network interface bridging your mesh to the computer’s IPv6 stack.”
“And our sensors talk using CoAP,” added Lila the LED. “It is like a lightweight version of HTTP designed for constrained devices. Each sensor exposes its readings as a REST resource – like a tiny web page that only serves one number. A CoAP client can request temperature from one sensor and humidity from another, just like browsing web pages.”
Bella the Battery offered her usual practical wisdom. “Start in a simulator before touching real hardware! Cooja, the Contiki-NG simulator, lets you create virtual sensor networks and watch every packet flow through the mesh. Once your simulation works perfectly, moving to real hardware is mostly just flashing the same code onto physical boards.”
13.2 Prerequisites
Before working through these labs, you should be familiar with:
- 6LoWPAN Review: Architecture: Understanding of protocol stack and border router design
- 6LoWPAN Fundamentals: Core concepts of header compression and fragmentation
- RPL Fundamentals: Understanding of mesh routing for 6LoWPAN
13.4 Lab 1: Contiki-NG 6LoWPAN Border Router
Set up a complete 6LoWPAN network with border router and sensor nodes.
Hardware Required:
- 2x Zolertia RE-Mote (or similar 802.15.4 boards)
- USB cables
- Linux PC (Ubuntu 20.04+ recommended)
13.4.1 Part 1: Install Contiki-NG
# Install dependencies
sudo apt-get update
sudo apt-get install -y git gcc-arm-none-eabi gdb-multiarch \
python3-serial python3-pip
# Clone Contiki-NG
cd ~
git clone https://github.com/contiki-ng/contiki-ng.git
cd contiki-ng
# Verify toolchain
arm-none-eabi-gcc --version13.4.2 Part 2: Flash Border Router
# Navigate to border router example
cd examples/rpl-border-router
# Compile for Zolertia RE-Mote
make TARGET=zoul BOARD=remote-revb
# Flash to device (connect via USB)
make TARGET=zoul BOARD=remote-revb border-router.upload
# Start border router (creates TUN interface)
sudo make TARGET=zoul BOARD=remote-revb connect-router
# In another terminal, check TUN interface
ifconfig tun0
# Should show fd00::1/64 address13.4.3 Part 3: Create CoAP Sensor Node
Create coap-sensor.c:
/**
* 6LoWPAN CoAP Temperature Sensor
*
* Exposes temperature reading via CoAP GET request
*/
#include "contiki.h"
#include "coap-engine.h"
#include "dev/button-sensor.h"
#include "dev/leds.h"
#include "sys/log.h"
#define LOG_MODULE "CoAP-Sensor"
#define LOG_LEVEL LOG_LEVEL_INFO
// Simulated temperature (in real device, read from sensor)
static int temperature = 22;
// CoAP resource handler
static void temperature_get_handler(coap_message_t *request,
coap_message_t *response,
uint8_t *buffer, uint16_t preferred_size,
int32_t *offset);
// Define CoAP resource
RESOURCE(temperature_resource,
"title=\"Temperature\";rt=\"temperature-c\"",
temperature_get_handler,
NULL,
NULL,
NULL);
static void
temperature_get_handler(coap_message_t *request, coap_message_t *response,
uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{
LOG_INFO("CoAP GET /temperature\n");
// Simulate temperature fluctuation
temperature = 20 + (random_rand() % 10);
// Create JSON response
int length = snprintf((char *)buffer, preferred_size,
"{\"temperature\":%d,\"unit\":\"celsius\"}",
temperature);
// Set response
coap_set_header_content_format(response, APPLICATION_JSON);
coap_set_payload(response, buffer, length);
// Blink LED to indicate activity
leds_toggle(LEDS_GREEN);
}
PROCESS(coap_sensor_process, "CoAP Sensor");
AUTOSTART_PROCESSES(&coap_sensor_process);
PROCESS_THREAD(coap_sensor_process, ev, data)
{
PROCESS_BEGIN();
LOG_INFO("CoAP Temperature Sensor Starting\n");
// Activate CoAP engine
coap_activate_resource(&temperature_resource, "sensors/temperature");
// Wait for network configuration
PROCESS_PAUSE();
LOG_INFO("IPv6 addresses:\n");
uip_ds6_addr_t *lladdr = uip_ds6_get_link_local(-1);
if(lladdr != NULL) {
LOG_INFO(" Link-local: ");
LOG_INFO_6ADDR(&lladdr->ipaddr);
LOG_INFO_("\n");
}
uip_ds6_addr_t *globaladdr = uip_ds6_get_global(-1);
if(globaladdr != NULL) {
LOG_INFO(" Global: ");
LOG_INFO_6ADDR(&globaladdr->ipaddr);
LOG_INFO_("\n");
}
LOG_INFO("CoAP server ready\n");
LOG_INFO("Access: coap://[IPv6]/sensors/temperature\n");
PROCESS_END();
}Compile and Flash:
# Compile
make TARGET=zoul BOARD=remote-revb coap-sensor
# Flash to second device
make TARGET=zoul BOARD=remote-revb coap-sensor.upload13.4.4 Part 4: Test with Python CoAP Client
#!/usr/bin/env python3
"""
6LoWPAN CoAP Client
Fetches temperature from sensor node
"""
import asyncio
from aiocoap import *
async def fetch_temperature(sensor_ipv6):
"""Fetch temperature from CoAP sensor"""
print(f"Connecting to sensor: {sensor_ipv6}")
context = await Context.create_client_context()
uri = f"coap://[{sensor_ipv6}]/sensors/temperature"
request = Message(code=GET, uri=uri)
try:
response = await context.request(request).response
print(f"Response Code: {response.code}")
print(f"Payload: {response.payload.decode('utf-8')}")
return response.payload.decode('utf-8')
except Exception as e:
print(f"Error: {e}")
return None
async def continuous_monitoring(sensor_ipv6, interval=5):
"""Continuously monitor sensor"""
print(f"\n=== 6LoWPAN Sensor Monitoring ===")
print(f"Sensor: {sensor_ipv6}")
print(f"Interval: {interval} seconds\n")
while True:
print(f"[{asyncio.get_event_loop().time():.2f}] Fetching...")
await fetch_temperature(sensor_ipv6)
print()
await asyncio.sleep(interval)
if __name__ == "__main__":
import sys
if len(sys.argv) < 2:
print("Usage: python3 coap_client.py <sensor_ipv6_address>")
print("Example: python3 coap_client.py fd00::212:4b00:1234:5678")
sys.exit(1)
sensor_ipv6 = sys.argv[1]
# Install dependencies first: pip3 install aiocoap
asyncio.run(continuous_monitoring(sensor_ipv6))Run Client:
# Install aiocoap
pip3 install aiocoap
# Get sensor IPv6 address (check border router output)
# Example: fd00::212:4b00:615:a4cb
# Run client
python3 coap_client.py fd00::212:4b00:615:a4cbExpected Output:
=== 6LoWPAN Sensor Monitoring ===
Sensor: fd00::212:4b00:615:a4cb
Interval: 5 seconds
[0.00] Fetching...
Connecting to sensor: fd00::212:4b00:615:a4cb
Response Code: 2.05 Content
Payload: {"temperature":24,"unit":"celsius"}
[5.12] Fetching...
Connecting to sensor: fd00::212:4b00:615:a4cb
Response Code: 2.05 Content
Payload: {"temperature":22,"unit":"celsius"}
[10.24] Fetching...
Connecting to sensor: fd00::212:4b00:615:a4cb
Response Code: 2.05 Content
Payload: {"temperature":26,"unit":"celsius"}
13.4.5 Part 5: Verification and Debugging
# Ping sensor from PC
ping6 fd00::212:4b00:615:a4cb
# Use coap-client tool (libcoap2-bin on Ubuntu 20.04, libcoap3-bin on 22.04+)
sudo apt-get install libcoap2-bin || sudo apt-get install libcoap3-bin
coap-client -m get coap://[fd00::212:4b00:615:a4cb]/sensors/temperature
# Analyze traffic with Wireshark
sudo wireshark -i tun0 -f "ip6"
# See 6LoWPAN compression in action!Common Issues and Solutions:
- TUN interface not created: Check USB connection and permissions (
sudorequired) - No ping response: Verify RPL routing has converged (wait 30-60 seconds)
- CoAP timeout: Check firewall rules allowing UDP port 5683
- Wrong IPv6 address: The sensor address combines the prefix (fd00::/64) with MAC-derived IID
13.5 Lab 2: Python 6LoWPAN Network Simulator
Create a simulation framework for testing 6LoWPAN scenarios without hardware.
Simulation Goals:
- Model header compression efficiency
- Calculate fragmentation overhead
- Simulate packet loss and reliability
- Analyze network statistics
Run Simulation:
python3 6lowpan_simulator.pyExpected Output:
======================================================================
6LoWPAN NETWORK SIMULATION
======================================================================
Configuration:
Nodes: 10
MTU: 102 bytes
Packet loss rate: 10.0%
Simulation time: 60s
Running simulation...
Simulation complete
======================================================================
SIMULATION STATISTICS
======================================================================
Packet Transmission:
Total attempts: 60
Successful: 47 (78.3%)
- Single frame: 35
- Fragmented: 12
Failed:
- Lost: 6 (10.0%)
- Reassembly failed: 7 (11.7%)
Node Statistics:
Node Sent Received Fragments Bytes Sent
----------------------------------------------------------------------
BR 0 47 0 15324
N1 7 0 21 2268
N2 8 0 24 2592
N3 6 0 18 1944
N4 5 0 15 1620
N5 7 0 21 2268
N6 7 0 21 2268
N7 6 0 18 1944
N8 7 0 21 2268
N9 7 0 21 2268
Header Compression Efficiency:
Average payload: 426 bytes
Uncompressed overhead: 48 bytes (10.1%)
Compressed overhead: 6 bytes (1.4%)
Overhead reduction: 87.5%
Fragmentation Analysis:
64 byte payload -> 1 frame (no fragmentation)
128 byte payload -> 2 fragments
256 byte payload -> 3 fragments
512 byte payload -> 6 fragments
1280 byte payload -> 13 fragments
======================================================================
13.5.1 Understanding the Simulation Results
Key Metrics Explained:
| Metric | Description | Target |
|---|---|---|
| Compression Efficiency | Header size reduction (48 -> 6 bytes) | >85% |
| Single-Frame Success | Packets not requiring fragmentation | Maximize |
| Fragmented Success | Multi-frame packet delivery | Monitor closely |
| Reassembly Failures | Lost due to missing fragments | Minimize |
Design Implications:
- High reassembly failures (>10%) indicate excessive fragmentation or lossy channel
- Low compression efficiency (<80%) suggests non-link-local or context-less traffic
- Many fragments per packet (>4) will cause reliability issues in lossy environments
The simulator models ideal 6LoWPAN behavior. Real-world deployments face additional challenges:
- Hidden node problem: Nodes can’t hear each other, causing collisions
- Multipath fading: Signal reflections cause intermittent connectivity
- Interference: Wi-Fi, microwave ovens, and other 2.4 GHz devices
- Battery drain: Retransmissions consume significant power
Use simulation for initial design, then validate with real hardware and Wireshark analysis.
13.5.2 Knowledge Check: Simulation Interpretation
13.6 Lab Exercises
13.6.1 Exercise 1: Optimize for Battery Life
Modify the CoAP sensor to minimize transmissions:
- Add local averaging (send mean of 10 readings instead of each)
- Implement threshold-based reporting (only send if change > 2 degrees)
- Measure power consumption difference
13.6.2 Exercise 2: Multi-Hop Routing
Extend the network to test multi-hop scenarios:
- Add a third sensor node positioned beyond direct range of border router
- Configure as RPL router (not leaf)
- Verify traffic routes through intermediate node
- Measure additional latency from multi-hop path
13.6.3 Exercise 3: Fragmentation Testing
Test fragmentation behavior with large payloads:
- Modify sensor to send 500-byte diagnostic logs
- Capture traffic with Wireshark
- Count fragments and verify reassembly
- Calculate actual vs theoretical reliability
13.6.4 Knowledge Check: Border Router Setup
13.6.5 Knowledge Check: CoAP Sensor Design
13.7 Summary
This chapter provided hands-on experience with 6LoWPAN networks:
- Border Router Setup: Contiki-NG configuration with tunslip6 for IPv6 connectivity
- CoAP Sensor Implementation: REST-based sensor interface with JSON payloads
- Python Client: Asynchronous CoAP client for sensor monitoring
- Network Simulation: Python framework for testing compression and fragmentation scenarios
- Debugging Tools: ping6, coap-client, and Wireshark for troubleshooting
Key Takeaways:
- Border router setup requires TUN interface and proper routing configuration
- CoAP provides lightweight REST interface ideal for constrained devices
- Simulation helps validate designs before hardware deployment
- Real-world testing with Wireshark reveals actual compression behavior
13.8 Knowledge Check
::
::
The Symptom: After successfully setting up the border router with tunslip6 -s /dev/ttyUSB0 fd00::1/64, sensors join the RPL DODAG and receive global addresses. You can ping sensors from the border router PC (ping6 fd00::212:4b00:1234:5678 works), but remote hosts on the building network cannot reach sensors.
Why It Happens: The TUN interface (tun0) creates a virtual network on the border router PC, but Linux disables IPv6 forwarding by default. Without forwarding enabled, the PC treats packets arriving on eth0 (building network) destined for fd00::/64 as “not for me” and drops them instead of routing to tun0.
The Fix (two steps required):
# Step 1: Enable IPv6 forwarding on border router PC
sudo sysctl -w net.ipv6.conf.all.forwarding=1
# Make permanent (survives reboot):
echo "net.ipv6.conf.all.forwarding=1" | sudo tee -a /etc/sysctl.conf
# Step 2: Add route on building network router
# On building core router:
ip -6 route add fd00::/64 via 2001:db8::100 # BR's eth0 addressVerification:
# From remote host on building network:
ping6 fd00::212:4b00:1234:5678
# Should now receive repliesWhy This Catches Everyone:
- Local pings work because they originate on the same host as tunslip6
- Remote pings fail because they arrive on eth0 and need forwarding to tun0
- Error message is silent - packets just disappear
- Affects 90% of first-time 6LoWPAN deployments
13.9 What’s Next
| Chapter | Focus | Why It Matters |
|---|---|---|
| 6LoWPAN Review: Performance Analysis | Compression efficiency calculations, fragmentation reliability modelling | Quantify the trade-offs you observed in the labs with formal analysis |
| 6LoWPAN Review: Quiz and Assessment | Scenario-based assessment covering addressing, routing, and compression | Test your understanding from the hands-on work before moving on |
| 6LoWPAN Lab Simulation | Complete ESP32 Wokwi simulation with IPHC, fragmentation, and RPL | Run a browser-based 6LoWPAN simulation without physical hardware |
| 6LoWPAN Common Pitfalls | Seven frequent mistakes and troubleshooting scenarios | Avoid deployment errors encountered in real-world 6LoWPAN networks |
| Zigbee Fundamentals and Architecture | Higher-level protocol built on IEEE 802.15.4 with application profiles | Compare 6LoWPAN’s IP-based approach with Zigbee’s cluster-library model |