Doctoral research · 2017–2022
Directional and Steerable Antennas in TSCH / 6TiSCH Networks
These notes reconstruct, in a form that a newcomer can follow and reproduce, a doctoral study carried out between 2017 and 2022. The study extended a 6TiSCH protocol stack (4eMAC on Contiki) and the Cooja network simulator so that a sensor node can carry two or three sector antennas or a single electronically steerable antenna, and it exploited antenna direction both in distributed medium access and in a centralised scheduler. The notes first introduce Time-Slotted Channel Hopping, the 6TiSCH stack and the antenna models, then prepare the toolchain. Seven laboratory units rebuild the system layer by layer: the multi-radio driver and hardware platforms, the MSP430 emulator, the antenna and propagation model of the simulator, the antenna-aware MAC layer, the native simulation target, the direction-aware TASA scheduler and the end-to-end experiment. The final chapters explain how scenarios were designed and measured, summarise the results and list known defects. An appendix indexes all 199 source files that were changed.
Learning outcomes
- TSCH and 6TiSCH
- Explain slotframes, cells and channel hopping, and the roles of 6P, SF0, RPL and Orchestra.
- Antenna models
- Distinguish omnidirectional, sectored multi-radio and steerable antennas and compute their effective ranges from a link budget.
- Simulator extension
- Extend Contiki, MSPSim and Cooja consistently so that antenna direction flows from the MAC layer to the radio medium and back.
- Antenna-aware MAC
- Implement per-neighbour antenna selection, orientation learning, fake-beacon discovery and autonomous control cells.
- Centralised scheduling
- Modify TASA so that conflicting links with separated beams share a channel, and run it in a closed loop with the simulated network.
- Experimentation
- Design repeatable Cooja scenarios and compute PRR, delay, energy, collision rate and join time from simulation logs.
1Preface and how to use these notes
These notes reconstruct, in a form that a newcomer can follow and reproduce, a body of work that extended a 6TiSCH protocol stack and the Cooja network simulator with support for nodes carrying several sector antennas or a single electronically steerable antenna, and that exploited antenna direction both in distributed MAC operation and in a centralised scheduler.
The material is organised as a course. Sections 2–4 introduce the concepts and prepare the toolchain. Sections 5–11 consist of seven laboratory units (L1–L7), each of which re-implements one layer of the system: the radio driver and hardware platform, the instruction-level emulator, the propagation model of the simulator, the medium access control (MAC) layer, the fast native simulation target, the centralised scheduler and, finally, the end-to-end experiment that connects them. Sections 12–15 explain how scenarios were designed, which metrics were collected and what results were obtained, and Section 16 offers self-check questions. Appendix A lists every one of the 199 source files that differ from the baseline, grouped by purpose.
1.1Prerequisites
- Working knowledge of C (pointers, bit masks, preprocessor conditionals) and Java (classes, interfaces, the Observer pattern).
- Basic Linux command-line usage,
makeand Apacheant. - Introductory wireless networking: path loss, received signal strength (RSSI), interference, duty cycling.
- No prior exposure to Contiki, TSCH or Cooja is assumed; Section 2 supplies the necessary background.
1.2Conventions
| Notation | Meaning |
|---|---|
RADIO_PRIMARY = 1, RADIO_SECONDARY = 2, RADIO_TERTIARY = 4, RADIO_ALL = 7 | Bit mask selecting one or more physical radios (antennas) of a node. A function receiving radio_index = 3 acts on the first two radios. |
| Orientation index k ∈ {0,…,23} | Direction of a steerable antenna in 15° steps; the physical angle is 15·k degrees. The MAC layer and the scheduler exchange k, the emulator and Cooja work in degrees. |
| Omni / 2-dir / 3-dir / steerable | One omnidirectional radio; two radios with 180° sectors at 0° and 180°; three radios with 120° sectors at 0°, 120° and 240°; one radio whose main lobe can be rotated. |
| Δ +a / −r | Lines added and removed with respect to the baseline version of the file (Appendix A). |
Each laboratory unit opens with learning objectives, proceeds through numbered implementation steps with verbatim excerpts from the final source code, and closes with a checkpoint that tells you how to verify the step before moving on. Pitfall boxes record defects and traps that were found in the original code.
The protocol stack is a fork of 4eMAC, a 6TiSCH implementation for Contiki developed by a research group (S. Görmüş, A. F. Yavuz, K. Yanık and colleagues). The directional-antenna skeleton in Cooja (Direction, ARM, two visualiser skins) originates from a 2015 contribution by V. Rege. The centralised scheduler starts from a public TSCH scheduling library that implements TASA, MCC and MODESA. Everything else described here was added in the doctoral work. Baselines used for comparison are listed in Appendix A.
2Background: TSCH, 6TiSCH and antennas
- Explain how Time-Slotted Channel Hopping organises time, frequency and cells.
- Name the components of the 6TiSCH stack used in this work (minimal configuration, 6P, SF0, RPL) and the two schedulers used for comparison (6TiSCH minimal/SF0 and Orchestra).
- Distinguish omnidirectional, sectored multi-radio and electronically steerable antennas, and state why each could improve a TSCH network.
2.1Time-Slotted Channel Hopping
IEEE 802.15.4e-2012 introduced Time-Slotted Channel Hopping (TSCH) as a MAC mode for low-power industrial networks. Time is divided into timeslots of fixed length (10 ms by default; 15 ms throughout this work), counted network-wide by the Absolute Slot Number (ASN). Timeslots are grouped into a repeating slotframe of L slots. A cell is a pair (slot offset, channel offset) inside the slotframe and is either dedicated to one transmitter–receiver pair or shared by contention. The physical channel used by a cell in a given slot is
so that successive uses of the same cell hop across frequencies and escape narrow-band interference. Nodes join the network by listening for Enhanced Beacons (EB), which carry the ASN and the timeslot template, and stay synchronised by timing corrections exchanged in acknowledgements and keep-alive frames.
2.2The 6TiSCH stack and 4eMAC
6TiSCH places IPv6 (6LoWPAN) and the RPL routing protocol on top of TSCH. Three IETF components matter here:
- Minimal configuration (RFC 8180): a small number of shared cells sufficient for bootstrapping, EB and routing traffic.
- 6top Protocol, 6P (RFC 8480): a two-way transaction with which neighbours add, delete, list or relocate dedicated cells between them.
- Scheduling Function Zero, SF0 (IETF draft): a distributed policy that decides how many cells to request from 6P, based on measured traffic and a hysteresis threshold.
4eMAC is the Contiki implementation of this stack on which the study builds. Its main files are core/net/mac/4emac/4emac.c (MAC driver), 4erdc.c (slot operation, the equivalent of a radio duty-cycling layer), 4emac-buf.c (per-neighbour queues and cell tables), 4emac-timesynch.c (joining, EB, synchronisation) and the 6top-pce/ directory (6P and scheduling functions). A node's MAC keeps one destination_t record per neighbour; dedicated cells hang from that record as a list of slot_t.
Orchestra (Duquennoy et al., 2015) is an alternative, fully autonomous scheduler for Contiki's own TSCH implementation: every node derives its cells from a hash of node addresses, so no negotiation is required. Orchestra and 6TiSCH-minimal/SF0 serve as the comparison baselines of the 2018 experiments.
2.3Why antennas matter for TSCH
Low-power motes normally carry a single omnidirectional antenna, so every transmission illuminates all neighbours. In a dense TSCH network this has three consequences: the same cell cannot be reused by nearby links (low spatial reuse), shared cells suffer collisions, and receivers spend energy on frames that are not addressed to them. Directional radiation can reduce all three, at the cost of making neighbour discovery harder, because two nodes only hear each other when their beams point at each other. The study examined three antenna models.
| Model | Hardware abstraction | Beam | How a direction is selected |
|---|---|---|---|
| Omnidirectional | One CC2420 radio | 360° | Not applicable |
| Sectored, 2 radios (“2-dir”) | Two CC2420 chips on one MSP430 | 2 × 180° (0°, 180°) | By choosing which radio transmits (radio_index) |
| Sectored, 3 radios (“3-dir”) | Three CC2420 chips | 3 × 120° (0°, 120°, 240°) | As above |
| Steerable | One CC2420 with a virtual orientation register | Cardioid main lobe, rotated in 15° steps | By writing the orientation register (RADIO_PARAM_ORIENTATION) |
2.4Research questions addressed
- Can sectored antennas reduce collisions and energy in 6TiSCH-minimal/SF0 and in Orchestra, and by how much (2018 conference study)?
- How should a node with a single steerable antenna discover neighbours, learn the best direction to each of them and still join the network in reasonable time (2019)?
- How do network formation time and control overhead scale with node count (25, 49, 81) and density (20, 30, 40 m spacing) for omnidirectional versus steerable nodes (2020)?
- Can a centralised scheduler exploit antenna direction to let interfering links share a channel and thereby shorten the schedule (2020–2022)?
3System architecture
The system spans four software components, each of which had to be modified consistently: the node firmware (Contiki and 4eMAC), the MSP430 emulator (MSPSim), the network simulator (Cooja) and an external scheduler process on the host.
Two simulation paths exist. In the emulated path (2017–2019) each node runs the real MSP430 binary inside MSPSim, so pin-level details of the second and third CC2420 must be emulated; this is precise but slow and limits experiments to about 35 nodes. In the native path (2020 onward) Contiki is compiled for the host CPU as a shared library and loaded by Cooja through JNI; radio state is exchanged through C variables, which permits 81-node networks and batch runs.
The information flow for directional operation is the same on both paths. The MAC chooses a radio or an orientation for every slot and passes it down through the radio API. The driver (or the native radio stub) records the choice in a register or variable. The simulator reads it, updates the node's Direction object, and the radio medium recomputes which receivers can hear the transmission using the antenna gains of both ends. On reception the driver tags the frame with the receiving radio index or orientation, which the MAC uses to learn the best direction per neighbour.
4Development environment
- Prepare a Linux machine (or the supplied Instant Contiki virtual machine) that can build MSP430 and native Contiki targets and run Cooja.
- Know which source tree to use for which experiment.
4.1Host system
All work was carried out in Instant Contiki 3.0, an Ubuntu 12.04 32-bit VMware image, later also on 64-bit Ubuntu with 32-bit compatibility libraries. Cooja's native mote type requires that the Contiki library and the Java virtual machine have the same word size; because 4eMAC and the native radio stub were written for a 32-bit layout, a 32-bit JVM and -m32 compilation are required.
- Install the MSP430 toolchain. The study used a pre-built mspgcc 4.7.2 (supplied as
mspgcc-4.7.2-compiled.tar.bz2):tar -xf mspgcc-4.7.2-compiled.tar.bz2 sudo mv msp430 /usr/local/ echo 'export PATH=$PATH:/usr/local/msp430/bin' >> ~/.bashrc - Install 32-bit runtime libraries and Java 8 (i386) on a 64-bit host:
sudo dpkg --add-architecture i386 sudo apt-get update sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 zlib1g:i386 sudo apt-get install openjdk-8-jdk:i386 ant gcc-multilib export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-i386 - Install the libraries of the centralised scheduler:
sudo apt-get install libglpk-dev(the linker line expectslibglpk.so.40). - Build
tunslip6once per source tree:cd tools && make tunslip6.
4.2Source trees
The work was not kept under version control; dated archives stand in for commits. Use the tree that matches the experiment you want to reproduce.
| Experiment | Source tree | Mote type in Cooja |
|---|---|---|
| 2018 sectored-antenna study (SF0 / Orchestra × omni / 2-dir / 3-dir) | sharedvm/6tisch_3.0_trl_bildiri_* (one folder per configuration) | Exp5438 (MSPSim) |
| 2019 steerable antenna, realistic radiation pattern | sharedvm/sedatgormus-6tisch_3.1.6.7 | Exp5438 2-antenna / 3-antenna / steerable |
| 2019–2020 discovery and network formation (fake beacons) | antenna_sim_2020_02_18.tar.gz | Exp5438 steerable |
| 2020 scaling study (25–81 nodes) and 2021 centralised scheduling | 6tisch_3.1_ky_merge_native_central.20210221.zip | Cooja native (ContikiMoteType) |
| Centralised scheduler (host) | tsch_scheduling_algorithms-master.20210221.zip (matches the 2021 firmware); 2022 version in …20220114.zip | — |
4.3Building and launching
Firmware for an MSPSim node is selected by the Contiki TARGET; the file extension of the resulting binary tells Cooja how many radios to emulate (Lab 2):
cd examples/ipv6/tsch/rpl-udp/udp-client
make TARGET=exp5438 udp-client # → udp-client.exp5438 (omni)
make TARGET=exp5438_2dir udp-client # → udp-client.exp5438_2dir (two sectors)
make TARGET=exp5438_3dir udp-client # → udp-client.exp5438_3dir (three sectors)
make TARGET=exp5438_steerable udp-client # → udp-client.exp5438_steerable (steerable)Native motes are compiled by Cooja itself from the command stored in the scenario (make udp-client.cooja TARGET=cooja). Cooja is started from the tree whose code you want to simulate, because scenarios refer to sources as [CONTIKI_DIR]/…:
cd tools/cooja
ant run # interactive
ant run_nogui -Dargs=/abs/path/scenario.csc # batch, writes build/COOJA.testlogThe build file was changed to give the JVM 2048 MB instead of 512 MB, which large native simulations need.
Open any scenario of the chosen tree, press Start, and confirm that motes compile without errors and print 4eMAC:joining lines in the Mote output window. On a native tree, a JVM/library word-size mismatch shows up as an UnsatisfiedLinkError when the first mote is created.
5Lab 1: Multi-radio hardware abstraction
- Extend Contiki's radio driver interface so that every operation addresses a subset of radios.
- Attach a second and third CC2420 transceiver to the EXP430F5438 platform at the pin level.
- Add a virtual orientation register for a single steerable antenna.
- Measure listen and transmit time per radio with Energest.
5.1Extend the radio driver interface
Contiki's struct radio_driver assumes one transceiver. The first step is to add a radio_index argument to every function that touches the hardware, and to define the bit masks that name the radios. The receive path of the RDC layer gets the same argument so that a frame can be answered through the radio that received it.
// core/dev/radio.h — excerpt · Δ +16 / −8
#define RADIO_NONE 0
#define RADIO_PRIMARY 1
#define RADIO_SECONDARY 2
#define RADIO_TERTIARY 4
#define RADIO_ALL 7
/* ... in enum radio_param_e ... */
RADIO_PARAM_ORIENTATION
/* ... in struct radio_driver ... */
int (* prepare)(const void *payload, unsigned short payload_len, unsigned short radio_index);
int (* transmit)(unsigned short transmit_len, unsigned short radio_index);
int (* send)(const void *payload, unsigned short payload_len, unsigned short radio_index);
int (* channel_clear)(unsigned short radio_index);
int (* on)(unsigned short radio_index);
radio_result_t (* get_value)(radio_param_t param, radio_value_t *value, unsigned short radio_index);
radio_result_t (* set_value)(radio_param_t param, radio_value_t value, unsigned short radio_index);Every caller must then be adapted. In core/net/mac/rdc.h the input hook becomes input(unsigned short radio_index); nullradio.c, nullrdc.c, nullrdc-noframer.c, contikimac.c and the Linux radio driver cpu/native/net/linuxradio-drv.c receive mechanical signature changes. Where no antenna choice exists, use RADIO_PRIMARY for transmission and RADIO_ALL for on(). Two packet-buffer attributes carry antenna information between the layers:
// core/net/packetbuf.h — Δ +2 / −0
PACKETBUF_ATTR_ANTENNA, /* radio (mask bit) that received or must send the frame */
PACKETBUF_ATTR_ANTENNA_ORIENTATION, /* orientation index 0..23 of a steerable antenna */Finally, extend Energest with one listen and one transmit counter for each additional radio (ENERGEST_TYPE_LISTEN2, LISTEN3, TRANSMIT2, TRANSMIT3 in core/sys/energest.h) so that energy can be reported per antenna.
5.2Wire additional CC2420 chips to the platform
The TI EXP430F5438 board drives one CC2420 over SPI with chip select on port 3. Additional chips share the SPI bus but need their own chip select, voltage regulator, reset and interrupt-capable FIFOP/FIFO/CCA/SFD lines. Create the platforms platform/exp5438_2dir, exp5438_3dir and exp5438_steerable by copying platform/exp5438, then add the pin map. The secondary radio uses port 2 with chip select on P6.0; the tertiary radio uses port 4 with chip select on P5.0.
// platform/exp5438_3dir/platform-conf.h — excerpt · secondary radio
#define CC2420S_FIFOP_PORT(type) P2##type
#define CC2420S_FIFOP_PIN 6
#define CC2420S_FIFO_PORT(type) P2##type
#define CC2420S_FIFO_PIN 5
#define CC2420S_CCA_PORT(type) P2##type
#define CC2420S_CCA_PIN 7
#define CC2420S_SFD_PORT(type) P2##type
#define CC2420S_SFD_PIN 3
#define CC2420S_CSN_PORT(type) P6##type
#define CC2420S_CSN_PIN 0
#define CC2420S_VREG_PORT(type) P2##type
#define CC2420S_VREG_PIN 4
#define CC2420S_RESET_PORT(type) P2##type
#define CC2420S_RESET_PIN 2
#define CC2420S_IRQ_VECTOR PORT2_VECTOR
#define CC2420S_SPI_ENABLE() (CC2420S_CSN_PORT(OUT) &= ~BV(CC2420S_CSN_PIN))
#define CC2420S_SPI_DISABLE() (CC2420S_CSN_PORT(OUT) |= BV(CC2420S_CSN_PIN))
/* CC2420T_* : identical block on port 4, chip select P5.0, PORT4_VECTOR */The platform headers also define EXP5438_HAS_2_ANTENNA, EXP5438_HAS_3_ANTENNA or EXP5438_HAS_STEERABLE_ANTENNA, which the driver uses to compile only the code paths that exist on the board. The remaining platform files need small, consistent edits:
spix.c: configure SCK/MOSI/MISO on ports 5 and 6 as SPI peripheral pins.msp430.c: clearP2DIRand disable port 3/4 interrupts at boot (P3IE = P4IE = 0).ld/msp430.x: export the port 3/4 interrupt vector symbols (P3IV,P4IV,PBIE, …). The emulated configuration (Lab 2) must use the same RAM start (0x1a00) and flash start (0x7f00).cc2420-arch.c: one FIFOP interrupt service routine per radio.
// platform/exp5438_2dir/cc2420-arch.c — Δ +18 / −1
ISR(CC2420S_IRQ, cc2420s_fifop_interrupt)
{
ENERGEST_ON(ENERGEST_TYPE_IRQ);
/* check P2IV: FIFOP of the secondary radio */
if(P2IV == (2 * (1 + CC2420S_FIFOP_PIN))) {
if(cc2420_interrupt(RADIO_SECONDARY)) {
LPM4_EXIT;
}
}
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
}5.3Make the CC2420 driver address several chips
The driver change is the largest single edit of the study (dev/cc2420/cc2420.c, Δ +953 / −223). The pattern is uniform: every low-level SPI primitive takes the mask and repeats the bus transaction for each selected chip.
// dev/cc2420/cc2420.c — strobe(), the pattern used by getreg, setreg, write_fifo_buf, …
static void
strobe(enum cc2420_register regname, int index)
{
if(index & RADIO_PRIMARY) {
CC2420_SPI_ENABLE();
SPI_WRITE(regname);
CC2420_SPI_DISABLE();
}
#ifdef EXP5438_HAS_2_ANTENNA
if(index & RADIO_SECONDARY) {
CC2420S_SPI_ENABLE();
SPI_WRITE(regname);
CC2420S_SPI_DISABLE();
}
#endif
#ifdef EXP5438_HAS_3_ANTENNA
if(index & RADIO_TERTIARY) {
CC2420T_SPI_ENABLE();
SPI_WRITE(regname);
CC2420T_SPI_DISABLE();
}
#endif
}On top of these primitives:
on,prepare,transmit,send,cca,get_valueandset_valueforward the mask; channel, PAN identifier and address are configured withRADIO_ALL.cc2420_interrupt(int index)records which radio raised FIFOP;cc2420_readreads the corresponding FIFO (alternating between radios when several are pending) and stores the index inPACKETBUF_ATTR_ANTENNA.- Energest uses
LISTEN2/3andTRANSMIT2/3for the extra radios.
5.4A virtual orientation register for the steerable antenna
Real steerable antennas are controlled by switching lines or a phase network that the CC2420 does not have. The study therefore defines two unused CC2420 register addresses as virtual registers, which the emulator interprets (Lab 2): CC2420_ORIENTATION = 0x31 and CC2420_BEAMWIDTH = 0x32 in dev/cc2420/cc2420_const.h. At initialisation the driver writes orientation 0 and beam width 180°.
// dev/cc2420/cc2420.c — steerable antenna
#ifdef EXP5438_HAS_STEERABLE_ANTENNA
void
cc2420_set_orientation(int ori) /* ori = 0..23 */
{
if(ori >= 0 && ori < 24)
{
setreg(CC2420_ORIENTATION, ori * 15, RADIO_PRIMARY); /* degrees */
cc2420_last_orientation = ori;
}
}
#endif
/* set_value(): case RADIO_PARAM_ORIENTATION: cc2420_set_orientation(value); */When a frame is received the driver attaches cc2420_last_orientation as PACKETBUF_ATTR_ANTENNA_ORIENTATION, which lets the MAC learn which direction worked (Lab 4).
All four targets (exp5438, exp5438_2dir, exp5438_3dir, exp5438_steerable) build without warnings about implicit declarations. Grep the build for any remaining call of NETSTACK_RADIO.on() or .transmit(len) with the old arity; every such call is a latent bug that the compiler may only warn about.
In cpu/msp430/cc2420-arch-sfd.c the port-select lines for the secondary and tertiary SFD use CC2420_SFD_PIN instead of CC2420S_SFD_PIN/CC2420T_SFD_PIN; the pin numbers happen to coincide on this board, so the error is latent. In contikimac.c one #if branch still calls transmit(transmit_len) with the old signature.
6Lab 2: Emulating radios in MSPSim
- Teach the MSP430 emulator to host up to three CC2420 chips on the pins chosen in Lab 1.
- Implement the virtual orientation registers and notify Cooja when they change.
- Register 2-antenna, 3-antenna and steerable mote types in Cooja.
6.1Virtual registers in the CC2420 model
MSPSim's CC2420.java already keeps an array of registers. Writes to the two virtual addresses are stored and, when the value changes, forwarded to an OrientationListener (a new interface in chip/OrientationListener.java with a single method orientationChanged(int)). Radio802154.java gains the abstract accessors getOrientation(), getBeamwidth(), addOrientationListener() and setRSSIForLastReceivedPacket(); the last one lets the simulator write a per-packet RSSI into the receive FIFO so that the firmware can compare directions.
// tools/mspsim/se/sics/mspsim/chip/CC2420.java — Δ +46 / −1
public static final int REG_ORIENTATION = 0x31;
public static final int REG_BEAMWIDTH = 0x32;
/* ... in the register write handler ... */
case REG_ORIENTATION:
registers[address] = data;
if(orientation != data){
orientation = data;
this.orientationListener.orientationChanged(data);
}
break;
case REG_BEAMWIDTH:
registers[address] = data;
if(beamwidth != data){
beamwidth = data;
this.orientationListener.orientationChanged(data);
}
break;6.2Several chips on one emulated node
Exp5438Node is given a constructor Exp5438Node(int count) and three fields radio1, radio2, radio3. Port listeners map chip-select bits on ports 3, 6 and 5, and voltage-regulator bits on ports 1, 2 and 4, to the right chip; incoming SPI bytes are routed to whichever chip is currently selected. MSP430f5437Config.java adds the port 3/4 interrupt registers and vectors and sets RAM at 0x1a00 and flash at 0x7f00 to match the linker script of Lab 1.
// tools/mspsim/se/sics/mspsim/platform/ti/Exp5438Node.java — SPI routing
if(antennaCount > 0 && radio1.getChipSelect()) {
radio1.dataReceived(source, data);
}
else if(antennaCount > 1 && radio2.getChipSelect()) {
radio2.dataReceived(source, data);
}
else if(antennaCount > 2 && radio3.getChipSelect()) {
radio3.dataReceived(source, data);
}MSP430Core.getChips() is modified to return the next matching chip on each call (a counter called_getChips). As a result, when Cooja instantiates the Msp802154Radio interface two or three times for one mote, each instance binds to a different CC2420.
6.3Mote types in Cooja
- Copy
Exp5438MoteType.javathree times asExp5438Mote2AntennaType,Exp5438Mote3AntennaTypeandExp5438MoteSteerableType. Change the target name and file extension (exp5438_2dir,exp5438_3dir,exp5438_steerable) and listMsp802154Radiotwo, three or one time(s) among the mote interfaces, followed byDirection. - In
Exp5438Mote.java, create the node according to the firmware extension:// tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438Mote.java — Δ +10 / −1 } else if (filename.endsWith(".exp5438_2dir")) { exp5438Node = new Exp5438Node(2); } else if (filename.endsWith(".exp5438_3dir")) { exp5438Node = new Exp5438Node(3); } else if (filename.endsWith(".exp5438_steerable")) { exp5438Node = new Exp5438Node(1); - Register the new types in
tools/cooja/apps/mspsim/cooja.config(MOTETYPES). - In
Msp802154Radio.java, create aDirectionfor each radio interface and subscribe to the chip's orientation changes so that Cooja rotates the antenna when the firmware writes register 0x31; also write the simulated RSSI of each received packet back into the chip. - Give the other radio interfaces (
CC1101Radio,CC1120Radio,CC2520Radio,TR1001Radio, Avrora'sMicaZRadio) trivial implementations of the new abstract methods so that Cooja still compiles.
An earlier approach duplicated the radio interface as Msp802154SecondaryRadio and Msp802154TertiaryRadio (fixed to chip 1 and chip 2). These classes are still in the tree but no mote type uses them; the counter in getChips() superseded them.
In Cooja, Motes → Add motes must offer “EXP430F5438 2antenna mote”, “3antenna mote” and “Steerable mote”. Add one of each, open Mote interface viewer, and verify that the 3-antenna mote shows three radio interfaces and that writing an orientation from the steerable firmware changes the value displayed by its Direction interface.
The removal method added to Radio802154.java is misnamed removeChannelListener, so orientation listeners cannot be removed; this is harmless in batch runs but leaks listeners when motes are deleted interactively.
7Lab 3: Antenna and propagation model in Cooja
- Attach a
Directionobject with orientation, beam width and gain pattern to every simulated radio. - Replace the distance-only Unit Disk Graph Medium (UDGM) decision with a link-budget test that includes both antenna gains.
- Derive the effective communication and interference ranges of each antenna model.
- Visualise sectors and rotating lobes.
7.1Several radios per mote
Cooja assumes one Radio per mote. Three changes lift that restriction:
MoteInterfaceHandler.javakeeps an array of up to three radios and offersgetRadio(i),getRadios()andgetRadioCount(). When the radios are created it callssetAntennaOffset(count, i)on each.interfaces/Radio.javagains a publicDirection directionfield,radioCountandradioOffset.setAntennaOffsetconverts the order 0/1/2 into the mask bit 1/2/4 and callsdirection.setProperties(count, order).AbstractRadioMedium.javaregisters and unregisters all radios of a mote, not only the first.
Because the new class is called Direction, the pre-existing method getDirection() of DirectionalAntennaRadio and ApplicationRadio is renamed getDirectionAngle(), and its two callers in the MRM plug-in (AreaViewer.java, ChannelModel.java) are updated.
7.2The Direction interface
tools/cooja/java/org/contikios/cooja/interfaces/Direction.java (323 lines, new) is a Cooja mote interface, so its state is saved in the scenario file and visible in the interface viewer. Its geometry is fixed by the number of radios on the mote:
// interfaces/Direction.java — sector layout
public void setProperties(int radioCount, int order)
{
this.radioCount = radioCount;
if(radioCount == 1) { /* omni or steerable */
omni = true;
beamwidthDegrees = 360.0;
orientationDegrees = 0.0;
}
else if(radioCount == 2) { /* two 180-degree sectors */
omni = false;
beamwidthDegrees = 180.0;
orientationDegrees = (order == 0) ? 0.0 : 180.0;
}
else if(radioCount == 3) { /* three 120-degree sectors */
omni = false;
beamwidthDegrees = 120.0;
orientationDegrees = (order == 0) ? 0.0 : (order == 1) ? 120.0 : 240.0;
}
}A single-radio mote is omnidirectional unless its antenna type is set to directional (setAntennaType(1), or <omni>0</omni> in a native scenario), in which case it is steerable.
Gain pattern
Let θ be the bearing from the antenna to the other node, measured in degrees with atan2, and θ0 the antenna orientation. The gain in dBi returned by getGain(θ) is
The steerable pattern is a cardioid that yields +5 dBi on boresight, −5 dBi at ±90° and −15 dBi behind the antenna. Note that a sector spans from its orientation, not symmetrically around it: the 0° sector of a 2-radio node covers bearings 0°–180°.
Link budget
The received power combines log-distance path loss with exponent 2.5, both antenna gains and Gaussian fading with variance 0.5 dB²:
// interfaces/Direction.java — link budget
public double getSignalStrength(double distance, double gain1, double gain2)
{
Random rand = new Random();
return -52 - 25 * Math.log10(distance) + gain1 + gain2
+ rand.nextGaussian() * Math.sqrt(0.5);
}
public double getMaxRange(double gain1, double gain2)
{
return Math.pow(10.0, (42.5 + (gain1 + gain2)/2) / 25.0);
}7.3Angle-dependent connectivity in UDGM
UDGM normally connects a receiver if it lies within a fixed transmission radius. The modified medium instead compares Prx with two thresholds: a frame is receivable above −95 dBm and causes interference above −102 dBm. Both gains are evaluated, the receiver's at the reverse bearing.
// radiomediums/UDGM.java — createConnections(), Δ +87 / −19
public double TRANSMITTING_RANGE_SIGNAL_STRENGTH = -95;
public double INTERFERENCE_RANGE_SIGNAL_STRENGTH = -102;
/* ... for every candidate receiver recv of sender ... */
double distance = senderPos.getDistanceTo(recvPos);
double bearing = sender.direction.getAngle(recv.getPosition());
if(sender.direction.getSignalStrength(distance, sender.direction.getGain(bearing),
recv.direction.getGain(180 + bearing)) > TRANSMITTING_RANGE_SIGNAL_STRENGTH)
{
/* destination or interfered, as in the original UDGM */
}The same expression is used in the edge analysis that drives the visualiser, in updateSignalStrengths and, through getMaxRange, in the success-probability computation. A Observer attached to every Direction re-runs the edge analysis whenever an orientation changes, so a steerable node that rotates between slots immediately gains and loses neighbours.
Worked example: effective ranges
Setting (L3.4) equal to a threshold T and ignoring fading gives the range
| Antenna pair (tx → rx) | Gtx + Grx [dB] | Range, T = −95 dBm | Interference, T = −102 dBm |
|---|---|---|---|
| Omni → omni | 0 | 52 m | 100 m |
| Steerable boresight → omni | +5 | 83 m | 158 m |
| Steerable boresight → steerable boresight | +10 | 132 m | 251 m |
| Steerable at ±90° → omni | −5 | 33 m | 63 m |
| Steerable rear → omni | −15 | 13 m | 25 m |
| Sector (inside) → sector (inside) | +10 | 132 m | 251 m |
These figures explain the parameters of the 2020 scenarios: omnidirectional runs use a 50 m transmission and 100 m interference radius, steerable runs 79 m and 100 m. The omni and boresight-to-omni values of the model are 52 m and 83 m.
getMaxRange uses 42.5 and the mean of the two gains, while (L3.5) with T = −95 uses 43 and their sum. The two agree for omni links and diverge for directional ones; any analysis that relies on the success probability should be checked against the edge analysis. An earlier version (3.1.6.4) used a fourth-order polynomial of the bearing for the range and a line rssi = 1; that discarded the computed RSSI; neither survives in the final code.
7.4Visualisation
UDGMVisualizerSkin.java draws every radio of a mote separately: a circle for an omni radio, a pie slice (Arc2D.PIE) for a sector, and a quadratic-curve lobe rotated with an AffineTransform for a steerable antenna. ARM.java, ARMVisualizerSkin.java and DirectionVisualizerSkin.java come from the 2015 contribution; ARM (“Antenna Radio Medium”) is registered in cooja_applet.config but its antenna effects are only placeholders, so all experiments use the modified UDGM. Register Direction as a default mote interface and add the two native radio properties in cooja_default.config:
org.contikios.cooja.contikimote.interfaces.ContikiRadio.RADIO_COUNT = 1
org.contikios.cooja.contikimote.interfaces.ContikiRadio.RADIO_OMNI = 1
# and append org.contikios.cooja.interfaces.Direction to MOTE_INTERFACESPlace two 3-antenna motes 60 m apart on the x-axis. The visualiser must show three 120° slices per mote, and only the slice of each mote that faces the other should produce a link. Move one mote to 140 m: the link disappears (beyond 132 m), but the interference relation remains.
8Lab 4: Antenna-aware MAC in 4eMAC
- Associate an antenna (multi-radio) or an orientation (steerable) with every neighbour and use it in every dedicated slot.
- Learn the best orientation from the RSSI of received frames.
- Let unsynchronised steerable nodes find neighbours with fake beacons.
- Deliver broadcast control traffic (EB, DIO, DIS) reliably through autonomous unicast cells.
- Reproduce the antenna extensions of Contiki TSCH used with Orchestra.
8.1Per-neighbour antenna and orientation
Extend the neighbour record in 4emac-buf.h with three fields and a second slot list (used in Section 8.5):
// core/net/mac/4emac/4emac-buf.h — struct destination, added fields
uint8_t antenna; /* RADIO_PRIMARY / SECONDARY / TERTIARY that hears this neighbour */
int8_t max_rssi; /* best RSSI observed from this neighbour so far */
uint16_t orientation; /* orientation index 0..23 that produced max_rssi */
LIST_STRUCT(slot_list2); /* autonomous cells in the second slotframe */For multi-radio nodes, 4erdc.c calls packet_input(radio_index) and the MAC stores the receiving radio in dn->antenna. Unicast frames to that neighbour are then prepared, transmitted and acknowledged on that radio only, while broadcasts and EBs use RADIO_ALL. 4esec.c copies dn->antenna and dn->orientation into the packet attributes before the radio is invoked, and the channel of a slot is set on the neighbour's radio.
8.2Learning the best orientation
For a steerable node every received frame carries the orientation that was active. The MAC keeps, per neighbour, the orientation that yielded the highest RSSI; ties are broken in favour of the newer observation.
// core/net/mac/4emac/4emac-buf.c — foure_mac_buf_slot_inc_rx_from_linkaddr()
if(simRadioOmni == 0 && simRadioCount == 1){ /* steerable node */
if(dn->max_rssi <= packetbuf_attr(PACKETBUF_ATTR_RSSI) &&
dn->orientation != packetbuf_attr(PACKETBUF_ATTR_ANTENNA_ORIENTATION))
{
dn->max_rssi = packetbuf_attr(PACKETBUF_ATTR_RSSI);
dn->orientation = packetbuf_attr(PACKETBUF_ATTR_ANTENNA_ORIENTATION);
vrt_nbr_cell_table_add_nbr(linkaddr); /* see Section 8.4 */
}
}8.3Orientation policy per slot type
Before each slot the scheduler of 4eMAC selects the orientation according to the slot's role:
| Slot type | Orientation | Rationale |
|---|---|---|
| Shared or timekeeping | get_best_orientation() (currently uniform random in 0…23) | The intended receiver is unknown; random scanning eventually covers all directions. |
| Dedicated receive | Learned orientation with probability ≈ 0.5, otherwise ±1 step | Keeps tracking the sender if the best direction drifts. |
| Dedicated transmit | Learned orientation | Point the main lobe at the receiver. |
// core/net/mac/4emac/4emac-6top-scheduler-minimal.c — Δ +60 / −6
if(simRadioOmni == 0 && simRadioCount == 1){
if((sl->type & SLOT_TYPE_SHARED) || (sl->type & SLOT_TYPE_TIMEKEEP)){
NETSTACK_RADIO.set_value(RADIO_PARAM_ORIENTATION, get_best_orientation(), dn->antenna);
} else if(sl->type & SLOT_TYPE_RECEIVE){
if(random_rand() % 10 > 4)
NETSTACK_RADIO.set_value(RADIO_PARAM_ORIENTATION, dn->orientation, dn->antenna);
else if(random_rand() % 10 > 4)
NETSTACK_RADIO.set_value(RADIO_PARAM_ORIENTATION, (dn->orientation - 1) % 24, dn->antenna);
else
NETSTACK_RADIO.set_value(RADIO_PARAM_ORIENTATION, (dn->orientation + 1) % 24, dn->antenna);
} else {
NETSTACK_RADIO.set_value(RADIO_PARAM_ORIENTATION, dn->orientation, dn->antenna);
}
}An earlier, MSPSim-only variant (4emac-6top-scheduler.c, guarded by EXP5438_HAS_STEERABLE_ANTENNA) instead rotated the antenna by +181° (mod 360) in every shared slot, a deterministic sweep that visits every degree.
(orientation − 1) % 24 is negative when the orientation is 0, because C's remainder keeps the sign of the dividend. The driver silently rejects values outside 0…23, so the radio keeps its previous direction. Use (orientation + 23) % 24.
8.4Neighbour discovery with fake beacons
A steerable node that has not yet joined must point at a synchronised neighbour exactly when that neighbour sends an EB in a shared slot, which is unlikely. The remedy is to let unsynchronised nodes transmit themselves: every 5 s they send a short fake beacon (FB) on a random channel in a random direction. A synchronised node that receives an FB records the sender and the direction in a virtual neighbour table, and can then aim EBs at it.
- Define the frame type
FRAME802154_FAKEBEACONFRAME = 0x04incore/net/mac/frame802154.handieee802154e.h. - Add
4emac-ie-fb.c/.hwithfoure_packet_create_fb()andfoure_packet_parse_fb()(constant payload 0x2345) and an IE parserieee802154e_parse_fb_information_elements()inieee802154e.c. - Give FBs their own security level and key index (
FOURE_SECURITY_KEY_SEC_LEVEL_FB,FOURE_SECURITY_KEY_INDEX_FB) in4emac-6tisch-minimal-security.c/.hand4esec.c. - Route received FBs from
4erdc.ctotsch_fb_input()and send them from the EB timer when not synchronised:
// core/net/mac/4emac/4emac-timesynch.c — tsch_send_fb() and the EB timer
void tsch_send_fb()
{
uint8_t fb_buf[FOURE_MAC_MAX_PACKET_LEN];
uint8_t fb_len, hdr_len = 0, tsch_sync_ie_offset;
fb_len = foure_packet_create_fb(fb_buf, FOURE_MAC_MAX_PACKET_LEN, &hdr_len, &tsch_sync_ie_offset);
if(fb_len > 0) {
radio_value_t new_channel = FOURE_RF_CHANNEL_MIN + (random_rand() % NUMBER_OF_MAX_CHANNELS);
NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, new_channel, RADIO_PRIMARY);
NETSTACK_RADIO.set_value(RADIO_PARAM_ORIENTATION, get_best_orientation(), RADIO_PRIMARY);
NETSTACK_RADIO.send(&fb_buf, fb_len, RADIO_PRIMARY);
}
}
/* in the EB timer process */
if(foure_control.synched && default_instance != NULL){
tsch_send_eb(); /* normal EB, jittered interval */
}
#ifdef FOURE_CONF_FB_ENABLED
else if(!foure_control.synched){
tsch_send_fb(); /* not synchronised: fake beacon */
etimer_set(&eb_timer, 5 * CLOCK_SECOND);
}
#endif8.5Autonomous cells for control traffic
Even after joining, broadcast control frames sent in a shared slot reach only the neighbours that happen to face the sender. The solution adopted from 2020 onward gives every neighbour pair a pair of autonomous unicast cells in a second, long slotframe (251 slots), computed by both ends from their identifiers without negotiation, in the spirit of Orchestra and ALICE:
so that node a's transmit cell towards b equals b's receive cell from a. The cells are installed when the neighbour first enters the virtual neighbour table:
// core/net/mac/4emac/4emac-timesynch.c — vrt_nbr_cell_table_add_nbr()
n->id = linkaddr->u8[7];
n->orientation = packetbuf_attr(PACKETBUF_ATTR_ANTENNA_ORIENTATION);
n->rssi = packetbuf_attr(PACKETBUF_ATTR_RSSI);
n->transmit_slot = ((linkaddr_node_addr.u8[7] + 1) * 7 + (n->id + 1) * 13) % SLOT_FRAME_MAX_SIZE_2;
n->receive_slot = ((linkaddr_node_addr.u8[7] + 1) * 13 + (n->id + 1) * 7) % SLOT_FRAME_MAX_SIZE_2;
n->channel = (linkaddr_node_addr.u8[7] + n->id) % NUMBER_OF_MAX_CHANNELS;
list_add(vrt_nbr_cell_table_list, n);
#ifdef FOURE_CONF_AUTONOMOUS_SLOTS_ENABLED
foure_mac_buf_destination_add(&n->linkaddr, NBR_TABLE_REASON_RPL_DIS, NULL);
foure_mac_buf_slot_schedule2(&n->linkaddr, SLOT_TYPE_TRANSMIT, SLOT_UNLOCK,
n->transmit_slot, n->channel, FOURE_SLOT_INFINITE_LIFETIME);
foure_mac_buf_slot_schedule2(&n->linkaddr, SLOT_TYPE_RECEIVE, SLOT_UNLOCK,
n->receive_slot, n->channel, FOURE_SLOT_INFINITE_LIFETIME);
#endifWhen the MAC enqueues an EB, DIS or DIO addressed to the broadcast address, 4emac-buf.c places a unicast copy on the autonomous cell of each parent and child in the neighbour table (FOURE_CONF_AUTONOMOUS_SLOTS_ENABLED). Supporting changes:
4emac-buf.c: second slot pool and API (slot_mem2,foure_mac_buf_slot_schedule2/unschedule2/get2,get_next_scheduled_2,content_get_scheduled_2), plusfoure_mac_buf_slot_unschedule_all()andcontent_delete_all_buffers()used by the centralised scheduler (Lab 6).4emac-private.h:SLOT_FRAME_MAX_SIZE = 31,SLOT_FRAME_MAX_SIZE_2 = 251; on Cooja,RTIMER_GUARD 0and aBUSYWAIT_UNTIL_ABSthat yields withcooja_mt_yield().4emac-6top-scheduler-minimal.c: search the second slotframe (current_slot_2) when the first has no cell in the current slot.4emac.c: count transmission statistics and blacklisted channels only for slots of the primary slotframe (sl->primary), so that autonomous cells do not distort SF0.4emac-ie-eb.c:foure_packet_update_src_addr()rewrites the source address in a copied EB.
8.6Adjustments to 6P and SF0
Smaller changes keep the distributed scheduler stable alongside the new cells: SF0 ignores events from non-primary slots, its add/relocate thresholds are lowered to 10 and a division by zero is guarded (6p-sf-0.c); 6P retries a LIST once more and doubles its process timeouts to 8 s (6top-pce.c); the 6P queue grows from 3 to 8 entries (6p-queue.c). In the 2018 trees, SF time-outs are expressed in seconds instead of slotframes (6p-sf-backup.c, 6p-sf-pid.c, 6top-pce.h, and the group applications in Appendix A, group 10). A field antenna_offset for 6P cells was sketched in 4emac-ie-sixtop.h and 6p-protocol.c but left commented out. In 3.1.4, an antenna-aware 6P LIST (NEIGHBOUR_LIST_WRT_ANTENNA) reported only the cells of neighbours on the same antenna, so that cells on other antennas could be reused.
8.7Antenna support in Contiki TSCH for the Orchestra baseline
For the 2018 comparison, the same idea was applied to Contiki's own TSCH, on which Orchestra runs:
tsch-private.h: masksRADIO_PRIMARY(1) / SECONDARY(2) / TERTIARY(4) / BOTH(7).tsch-queue.h: anantennafield instruct tsch_neighbor;tsch-slot-operation.h: anantennafield in received packets. The slot operation sends unicast on the neighbour's antenna and broadcasts on all.tsch-conf.h: single-channel hopping sequence (TSCH_HOPPING_SEQUENCE_1_1) and 15 ms timeslots with a matching timing template.tsch-queue.c/.h: minimum backoff exponent 2 and a linear backoff window (% BE + 1).apps/orchestra/orchestra-conf.h: shorter slotframes, EB 397 → 31, common shared 31 → 13, unicast 17 → 5.
Run a 3-node line of steerable native motes with FOURE_CONF_FB_ENABLED and FOURE_CONF_AUTONOMOUS_SLOTS_ENABLED. Every node must print 4eMAC:joining and later 6P:Parent; the mote output must show maxrssi … lines as orientations are learned. Disable FBs and confirm that joining takes noticeably longer.
9Lab 5: Scaling with native Cooja motes
- Run 4eMAC on Cooja's native mote type to simulate 49–81 nodes.
- Provide up to three virtual radios and a steerable orientation in the native radio stub.
- Connect the C-side radio state to the Java
Directionobject.
Instruction-level emulation in MSPSim made networks of more than about 35 nodes impractically slow. Cooja's native mote type compiles Contiki for the host CPU, loads one shared library per mote type, and exchanges state with Java by reading and writing C variables in the library's memory. The radio of such a mote is the stub platform/cooja/dev/cooja-radio.c paired with the Java interface ContikiRadio.
9.1Three virtual radios in the native stub
Duplicate every per-radio variable three times and add the antenna state. Cooja finds these symbols by name, so the names must match the Java side exactly.
// platform/cooja/dev/cooja-radio.c — Δ +203 / −83
char simInDataBuffer1[COOJA_RADIO_BUFSIZE]; /* ...2, ...3 likewise */
char simOutDataBuffer1[COOJA_RADIO_BUFSIZE];
int simInSize1 = 0, simOutSize1 = 0;
char simRadioHWOn1 = 0;
int simSignalStrength1 = -100;
/* antenna state shared with ContikiRadio.java */
int simRadioOrientation = 0; /* degrees, written by the MAC */
int simRadioReceivedIndex = 0; /* radio that received the last frame */
int simRadioCount = 1; /* written by Cooja from the scenario */
int simRadioOmni = 1; /* 1 = omni, 0 = directional/steerable */
void
radio_set_orientation(int orientation) /* orientation index 0..23 */
{
if(orientation >= 0 && orientation < 24)
simRadioOrientation = orientation * 15;
}All driver functions take radio_index and act on radio 2 or 3 only if simRadioCount is large enough. A received frame is tagged with PACKETBUF_ATTR_ANTENNA, PACKETBUF_ATTR_ANTENNA_ORIENTATION and a timestamp. The original stub's busy-wait during transmission, its turnaround delay and its CCA emulation were removed because they interfered with 4eMAC's slot timing. Because simRadioOmni and simRadioCount are global, the MAC code of Lab 4 can test simRadioOmni == 0 && simRadioCount == 1 to detect a steerable node.
9.2Java side: ContikiRadio
The interface reads two new configuration properties, RADIO_COUNT and RADIO_OMNI, from cooja_default.config or from the scenario (<count>, <omni>), and writes them into the mote's memory. Each ContikiRadio instance owns a Direction and uses its radioOffset to read and write the matching …1/2/3 variables. After every tick it polls the orientation variable:
// tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRadio.java — Δ +162 / −22
RADIO_COUNT = mote.getType().getConfig().getIntegerValue(ContikiRadio.class, "RADIO_COUNT");
RADIO_OMNI = mote.getType().getConfig().getIntegerValue(ContikiRadio.class, "RADIO_OMNI");
/* ... */
private int getOrientation() {
return myMoteMemory.getIntValueOf("simRadioOrientation");
}
/* ... in doActionsAfterTick() ... */
if (RADIO_COUNT == 1 && RADIO_OMNI == 0 && getOrientation() != oldRadioOrientation) {
oldRadioOrientation = getOrientation();
direction.setOrientation(oldRadioOrientation); /* triggers UDGM edge re-analysis */
lastEvent = RadioEvent.UNKNOWN;
this.setChanged();
this.notifyObservers();
}Two dialog classes must be adapted so that a mote type can list ContikiRadio more than once: AbstractCompileDialog.java no longer rejects duplicate interfaces, and ContikiMoteCompileDialog.java loads the default interface list from the configuration in getDefaultMoteInterfaces().
9.3Platform configuration for 4eMAC
platform/cooja/contiki-conf.h: define the radio masks; setNETSTACK_CONF_MAC foure_mac_driver,NETSTACK_CONF_RDC foure_driver,NETSTACK_CONF_LLSEC foure_sec_driver,FOURE_CONF_DEFAULT_TIMESLOT_LENGTH 15000,RPL_CONF_OF_OCP RPL_OCP_TSCH,ENERGEST_CONF_ON 1; delete the IPv4 and Rime branches.platform/cooja/contiki-cooja-main.c: hard-wire IPv6 and remove the IPv4/SLIP start-up code;platform/native/contiki-conf.h: IPv6 and 4eMAC by default.platform/cooja/rtimer-arch.handcpu/native/rtimer-arch.h: provideUS_TO_RTIMERTICKS,RTIMERTICKS_TO_USand their_64variants, which 4eMAC uses; on Cooja one tick equals one microsecond.cpu/x86/Makefile.x86_common: compile withgcc -m32andCFLAGS += -m32.
Ten files tools/cooja/{1,2,3,4,}/org/contikios/cooja/corecomm/Lib1.java and Lib2.java are emitted by Cooja from its CoreComm template each time a native mote type is compiled. They are not source code and need not be reproduced.
Open sim25steer.csc (Section 12), start it, and add the Radio messages plug-in. With <omni>0</omni> the visualiser must show rotating lobes that change between slots; with <omni>1</omni> circles. Twenty-five native motes should run at least an order of magnitude faster than the same scenario on MSPSim.
10Lab 6: Direction-aware centralised scheduler
- Turn an offline TSCH scheduling library into a live scheduler that receives topology reports over UDP and returns schedules.
- Modify the TASA channel-allocation (colouring) step so that conflicting transmitters that point in sufficiently different directions may share a channel.
- Avoid the autonomous cells of Lab 4 and give precedence to freshly received packets.
10.1Starting point: TASA
The Traffic-Aware Scheduling Algorithm (TASA; Palattella et al.) builds a convergecast schedule on a routing tree. Each slot is filled in two phases. A matching phase selects a set of tree links that can transmit simultaneously without half-duplex conflicts, favouring nodes with the largest queue Q. A colouring phase assigns channel offsets so that links which interfere receive different channels; links that exceed the number of channels are deferred to the next slot. The original library (tsch_scheduling_algorithms-master.zip, 2017) also contains MCC, MODESA and FHSS and reads link-quality files from the Tutornet testbed. All of these except TASA were removed; matrices were reduced to a single channel dimension.
10.2Report and schedule protocol
Nodes report to fd00::1, UDP port 5678, every PERIOD = 2 s. The message is ASCII, fields separated by spaces, numbers in hexadecimal except the sequence number:
| Message | Format | Meaning |
|---|---|---|
| Topology report | Tello <seq> <parent> <nbr> <ori> <nbr> <ori> … | The first letter is set to T when the neighbour set changed or every 100 periods. ori is the learned orientation index (0–23) towards that neighbour. |
| Data | Hello <seq> … | Sent after more than three schedules were received; the scheduler only counts it. |
| Schedule | ts <cell> <cell> … | One 32-bit hexadecimal word per cell (below). |
A cell is encoded as
| Bits | Field | Range |
|---|---|---|
| 18–12 | slot offset | 0–127 |
| 11–8 | channel offset | 0–15 |
| 7 | type: 0 transmit, 1 receive | 0–1 |
| 6–0 | neighbour identifier − 1 | 0–127 |
// examples/ipv6/tsch/rpl-udp/udp-client/udp-client.c — schedule installation, Δ +181 / −24
char *ptr = strtok(str, " "); /* "ts" or "ok" */
if(strncmp(ptr, "ts", 2) == 0) {
ts_msg_received++;
foure_mac_buf_slot_unschedule_all(); /* replace the whole schedule */
}
ptr = strtok(NULL, " ");
while(ptr != NULL) {
int part = strtol(ptr, NULL, 16);
int dest = part % 128 + 1;
int type = (part >> 7) % 2; /* 0 tx, 1 rx */
int channel = (part >> 8) % 16;
int slot = (part >> 12) % 128;
/* find neighbour dest in the virtual neighbour table, then: */
foure_mac_buf_slot_schedule(&n->linkaddr, type + 1, SLOT_UNLOCK,
slot + 3, channel, FOURE_SLOT_INFINITE_LIFETIME);
ptr = strtok(NULL, " ");
}The offset +3 skips the hard cells 0 (timekeeping) and 1–3 (shared) of the 31-slot primary slotframe.
10.3Building the network model
main.c listens on an IPv6 UDP socket. For each T report it calls parseMessage(srcid, msg), which records the parent in parentMatrix, creates links with a fixed ETX, stores each orientation in degreeMatrix[src][nbr], and marks the autonomous cells of (L4.1) of the reporting node, its parent and its children as occupied in schedule[][]. When every node (exactly MAX_NODES) is attached to the tree, the scheduler builds the connectivity matrix, an interference matrix (nodes within two hops), a conflict matrix and the degree matrix, runs TASA and sends ts … to every node whose schedule changed, 30 ms apart.
10.4Direction-aware colouring
The decisive change is a single condition in tasa/coloring.c. In the original algorithm a link must take a new colour (channel) whenever a conflicting link already uses the current one. In the modified algorithm the colour is advanced only if the two transmitters point within ±8 orientation steps (±120°) of each other; otherwise their main lobes are assumed to be separated enough for both to use the same channel in the same slot.
// tasa/coloring.c — Δ +20 / −5
if (confMatrix[nodeToColor->id][n->id]) /* the two links conflict */
{
if (ListFind(&n->channels, (void *)color)) /* and n already uses this colour */
{
/* 24 * 15 = 360 degree */
if(nodeToColor->antenna_direction - n->antenna_direction <= 8 &&
nodeToColor->antenna_direction - n->antenna_direction >= -8)
{
color++; /* beams overlap: next channel */
break;
}
}
}The transmitter's direction is taken from the report of the transmitting node: tx->antenna_direction = degreeMatrix[n1][n2] in tasa.c. With a single channel (NUM_CHANNELS 1), every link whose colour exceeds 0 is deferred, so the rule directly converts angular separation into shorter schedules.
The difference is not wrapped around 360°: orientations 23 and 1 differ by 22 steps in the code, yet only by 2 steps (30°) in reality, so two nearly parallel beams are treated as separated. A correct test is d = abs(a − b) % 24; if (min(d, 24 − d) <= 8) color++;. Only the transmitter's direction is used; the receiver's is commented out.
10.5Autonomous-cell avoidance and pipelining
tasa/matching.creceivesschedule[][]and admits a link in slot k only ifschedule[k][tx]andschedule[k][rx]are free, so dedicated cells never collide with the autonomous cells of Lab 4.- After a link is scheduled, its receiver gets
recently_added = 100; matching and colouring order nodes by Q +recently_added, so a packet that has just arrived is forwarded in the next slots (pipelining towards the sink). graphs.h:MAX_NODES(=NODE_COUNT),NUM_CHANNELS 1,AUTONOMOUS_SLOTFRAME_LENGTH 251;Node_tgainsantenna_direction,received_message,recently_added;Link_tgainsdegree.util/files.caccepts a new line typed<i>=…carrying link directions when topologies are read from files;util/print.cprints the degree matrix in degrees (×15).
10.6Building, running and replaying
The Makefile of the scheduler is a list of commands without targets; execute the lines yourself:
gcc -c util/gen_beta.c util/list.c util/print.c util/files.c
gcc -c tasa/coloring.c tasa/matching.c tasa/tasa.c
gcc -c graphs/graphs.c
gcc -g main.c coloring.o files.o graphs.o list.o matching.o print.o tasa.o \
/usr/lib/x86_64-linux-gnu/libglpk.so.40 -o Scheduling
./Scheduling > run.log # no arguments; listens on UDP 5678Set MAX_NODES in graphs/graphs.h to the exact number of nodes before compiling; otherwise the “all nodes attached” condition never becomes true and TASA never runs. Two auxiliary programs support offline work: maincoojatofile.c appends every received report as <id> <message> to a topology file (e.g. topolojisercanomni30m), and mainfiletocooja.c replays such a file line by line through parseMessage without Cooja. mainnodebased.c is a byte-identical copy of main.c.
Replay a recorded 81-node topology with mainfiletocooja.c twice, once with the direction test of Section 10.4 and once with an unconditional color++. The direction-aware run should need fewer slots; in the recorded data a single-channel 20-node run needed between 25 and 32 slots against a lower bound of 19.
11Lab 7: End-to-end experiment
- Bridge a simulated border router to the host's IPv6 stack.
- Run Cooja,
tunslip6and the scheduler together and observe schedules being installed.
- Prepare the border router.
examples/ipv6/tsch/rpl-border-router/border-router.ccarries the blocks marked//sercan: it opens a UDP connection on port 5678, reports its own neighbours and orientations asTello …every 100 s, and parsestsexactly like the client (Δ +135 / −0). Itsproject-conf.hmust match the clients (slotframes 31/251, hard cells 0–3, keep-alive and autonomous cells on, one channel, 26). - Open the scenario. In Cooja open
zzotoscript/borderroute.csc(six native motes, mote 1 = border router). Right-click mote 1 → Mote tools → Serial Socket (SERVER), port 60001, and start the simulation. - Start the tunnel in a second terminal:
The host now ownscd tools sudo ./tunslip6 -a 127.0.0.1 fd00::1/64 # equivalently: make connect-router-coojafd00::1, the address to which all nodes report. - Start the scheduler (built with
MAX_NODES 6) in a third terminal:./Scheduling. It printsDATA recv from …for each report, thenLinks scheduled at time slot nand the encodedpartwords it sends. - Observe. Node outputs show
ts …being received; after the fourth schedule they switch toHellodata messages. In the reference run of 7 December 2020 the six-node network was scheduled in five slots, and in slot 1 two links shared channel 0 because their transmitters pointed in different directions.
The 2022 scheduler expects an extra traffic field after the parent (parent q nbr ori …); the February 2021 firmware does not send it. Use the February 2021 scheduler with the February 2021 firmware, or add the queue length to send_packet() in the client.
12Scenario design
Scenarios vary three factors one at a time: network size (7 to 81 nodes), antenna model (omni, two or three sectors, steerable) and density (20, 30 or 40 m grid spacing). The sink is always placed in the centre so that nodes can be grouped into hop rings around it.
12.1Anatomy of a scenario file
A Cooja scenario (.csc) is an XML file with a radio medium, one or more mote types, the motes with their interface configurations, and a test script. The fragments below are taken from sim25steer3anten.csc (2020, native motes).
<!-- zzotoscript/sim25steer3anten.csc — radio medium and mote type -->
<radiomedium>
org.contikios.cooja.radiomediums.UDGM
<transmitting_range>79.0</transmitting_range>
<interference_range>100.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<motetype>
org.contikios.cooja.contikimote.ContikiMoteType
<source>[CONTIKI_DIR]/examples/ipv6/tsch/rpl-udp/udp-client/udp-client.c</source>
<commands>make udp-client.cooja TARGET=cooja</commands>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Direction</moteinterface>
...
</motetype><!-- zzotoscript/sim25steer3anten.csc — the sink mote with three directional radios -->
<mote>
<interface_config>
org.contikios.cooja.interfaces.Position
<x>80.0</x> <y>80.0</y> <z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.interfaces.Direction
<orientationDegrees>0.0</orientationDegrees>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
<count>3</count> <!-- number of radios on this mote -->
<omni>0</omni> <!-- 0 = directional / steerable -->
</interface_config>
<!-- the ContikiRadio block is repeated once per radio -->
</mote>All scenarios fix the random seed (123456) so that runs are repeatable, and bound the run with TIMEOUT(…) in the script (30 min to 5 h of simulated time).
12.2Scenario families
| Period | Scenario | Nodes | Layout | Antennas | Purpose |
|---|---|---|---|---|---|
| 2017–18 | sim7lineer, sim9lineer | 7, 9 | Line | Omni, 2-dir | First functional tests of sector selection |
| 2017–18 | sim10random, sim15random, sim16dir, sim17lineer | 10–17 | Random; centre + rings; two rows | Omni, 2-dir, 3-dir | PRR and collision comparison for the 2018 study |
| 2018–19 | sim25midaraomnioval, sim25makale | 25 | Sink centred, 40 m grid | Omni, 2-dir, 3-dir | Main configuration of the published figures; reception ratio 0.70–1.00 swept |
| 2019 | sim50, sim75, sim100 | 49, 73, 101 | Grid | Sectored | Scaling on MSPSim |
| 2019 | steerable, rssitest, hepsibir, hepsibir6 | 3–11 | Small, mixed | Mixed in one network | Unit tests of orientation learning and of coexistence of antenna types |
| 2019–20 | steerablescenarios/sim15/25/35 omni|steer | 15, 25, 35 | Grid | Omni vs. steerable | Discovery and formation time with fake beacons |
| 2020 | sim25/49/81 omni3anten, …steer3anten | 25, 49, 81 | 5×5, 7×7, 9×9, 40 m | Sink with 3 radios; others omni or steerable | Effect of a directional sink on joining per hop ring |
| 2020 | sim81allomni, sim81allsteer | 81 | 9×9, 40 m | All omni / all steerable | Join and synchronisation time, PRR |
| 2020 | sim81all{omni,steer}{20,30,40}m | 25 | 5×5, 20/30/40 m | All omni / all steerable | Density: time to find a parent, number of EB/RPL/6P transmissions |
| 2020–21 | borderroute, …border* | 6–81 | Random; grids | Sink omni, others steerable | Centralised scheduling with a border router (Lab 7) |
Two design principles recur. First, every steerable scenario has an omni twin with identical positions, so that differences can be attributed to the antenna alone. Second, with the sink in the centre of a square grid, nodes fall into Manhattan rings of 8, 16, 24 and 32 nodes (81-node case); joining time is averaged per ring to show how delay accumulates with hop distance. With a 50 m omni range a node reaches only its four grid neighbours at 40 m spacing, whereas the 79 m boresight range of a steerable antenna also covers the diagonals.
The files sim81all…20m/30m/40m.csc contain 25 motes, not 81. Topology recordings of 81-node 20/30/40 m networks exist (topolojisercan*) but the scenarios that produced them were not archived.
13Metrics and data collection
All metrics are computed inside Cooja by the scenario's JavaScript test script, which receives every line printed by every mote (msg, id, time in microseconds) and writes results with log.log() to COOJA.testlog. No external post-processing scripts were used; values were transcribed into gnuplot .dat files.
| Metric | Definition | Where it is computed |
|---|---|---|
| Packet reception ratio (PRR) | Received / sent application packets, from DATA send and DATA recv lines; the first 100 sends are a warm-up | Script of the 2017–19 scenarios: Total PRR x recv N sent M noack K |
| Unacknowledged transmissions | Count of MAC noack lines | Same script |
| End-to-end delay | Mean delay of messages 51–150 per node | sim25makale, sim49omni3anten: ortalamadelay |
| Energy | Energest listen/transmit/CPU/LPM ticks printed by the client every 60 messages, converted to mWh | Same scripts: power rx … tx … cpu … lpm … → ortpower |
| Collision rate | Share of receptions that were followed by interference in the same slot, per radio | Cooja TimeLine.java (event codes 1 TX, 2 RX, 3 interfered, 4 RX then interfered); an earlier counter Depo.java is unused |
| Join / formation time | Simulated time of the first 4eMAC:joining and 6P:Parent line per node, averaged per hop ring | 2020 scenarios |
| Control overhead | Counts of sercan:transmit eb|rpl|6top lines | sim81allomni20m |
| Schedule length | Last Links scheduled at time slot n of a TASA run | Scheduler output |
// Test script pattern — join time per hop ring (from sim25steer3anten.csc, abridged)
TIMEOUT(18000000000, log.log("success\n")); // 5 h simulated
nodeCount = 25;
while(1) {
YIELD(); // wait for the next printed line
msgArray = msg.split(' ');
if(msgArray[0].equals("4eMAC:joining")) recvfromallnodes[id-1] = time/1000000;
if(msgArray[0].equals("6P:Parent")) recvfromallnodesdio[id-1] = time/1000000;
/* when every node has joined and found a parent:
sum the times of the nodes in ring 1, 2, 3, 4 and print the ring means */
}In TimeLine.java the absolute slot number is reconstructed as simulated time / 15 ms, and only slots whose position in a 51-slot frame is 0 or 50 are evaluated (presumably the shared cells of the slotframe used when the counter was written). Up to 81 motes are tracked.
14Representative results
Sectored antennas reduced collisions by 58–62 % and energy by 53–58 % relative to a single omnidirectional radio, and raised PRR at low traffic from 46 % to 99 % in 6TiSCH minimal.
14.1Sectored antennas (2018–2019, 25 nodes, MSPSim)
| Metric | Condition | 1 antenna | 2 antennas | 3 antennas |
|---|---|---|---|---|
| Collision rate [%] | reception ratio 100 % / 70 % | 39.95 / 72.08 | 31.67 / 52.96 | 16.64 / 27.72 |
| Energy [mWh] | reception ratio 100 % / 70 % | 2.83 / 3.83 | 1.59 / 1.99 | 1.34 / 1.59 |
| PRR, 6TiSCH minimal [%] | 0.25 / 0.5 / 1 / 2 packets s⁻¹ | 46.3 / 17.1 / 2.1 / 1.0 | 95.4 / 47.7 / 19.4 / 8.0 | 99.4 / 76.6 / 35.5 / 11.6 |
| PRR, Orchestra [%] | 0.25 / 0.5 / 1 / 2 packets s⁻¹ | 73.2 / 32.3 / 5.8 / 3.4 | 74.8 / 49.9 / 22.1 / 13.6 | 88.5 / 54.0 / 25.9 / 15.6 |
| PRR, SF0, 1 frequency [%] | 2 packets s⁻¹, reception 100 % | 12.2 | 68.1 | 78.0 |
| PRR, SF0, 4 frequencies [%] | 2 packets s⁻¹, reception 100 % | 87.2 | 94.3 | 95.5 |
| Delay, SF0 [s] | 1 packet s⁻¹, 1 frequency vs. 3 antennas + 4 frequencies | 1.72 | — | 0.52 |
14.2Steerable antenna: discovery and formation (2019, MSPSim)
| Metric | Method | 15 nodes | 25 nodes | 35 nodes |
|---|---|---|---|---|
| Discovery time [min] | Omni | 4.22 | 7.52 | 13.69 |
| Steerable, proposed | 11.21 | 18.40 | 29.21 | |
| Steerable, random direction | 14.62 | 26.12 | 35.68 | |
| Formation time [min] | Omni | 10.23 | 21.76 | 28.93 |
| Steerable, proposed | 16.30 | 26.12 | 32.61 | |
| Steerable, random direction | 25.53 | 30.37 | 37.57 | |
| Synchronisation time-outs [count] | Omni | 2 | 2 | 4 |
| Steerable, proposed | 0 | 0 | 3 | |
| Steerable, random direction | 15 | 42 | 79 |
Omnidirectional nodes always discover fastest, but the proposed steerable scheme is 18–30 % faster than random steering and almost eliminates loss of synchronisation. Over three hours, the RSSI of learned links rose from about −80 to −55 dBm (nodes 1–2) as orientations converged. With one frequency at 1 packet s⁻¹, the steerable antenna raised PRR from 46.2 % to 91.6 %.
14.3Centralised scheduling (2020–2021)
| Run | Setting | Schedule length [slots] |
|---|---|---|
| 81 nodes, 2 channels, steerable | Offline replay | 119 |
| 81 nodes, 2 channels, omni | Offline replay | 119 |
| 81 nodes, 3 channels | Offline replay (label ambiguous) | 80 (lower bound 80) |
| 20 nodes, 1 channel | Live Cooja, four runs, December 2020 | 25–32 (lower bound 19) |
| 20 / 58 / 61 nodes | Live Cooja, February 2021 | 31 / 114 / 112 |
The collision, energy and two-frequency PRR series of the 2019 steerable figures are numerically identical to the 2018 sector-antenna series (relabelled “omni / random / proposed”) and pre-date the steerable implementation. Only the December 2019 Turkish-language data (PRR, delay, energy per traffic rate) were produced with the steerable code. With two channels, direction awareness did not shorten the 81-node schedule in the recorded replay; its effect is expected in the single-channel case.
15Known issues and pitfalls
The following defects were identified while preparing these notes. They do not invalidate the approach but should be fixed before new experiments.
| Location | Problem | Remedy |
|---|---|---|
tasa/coloring.c | Orientation difference not taken modulo 24 | Use the circular difference (Section 10.4) |
4emac-6top-scheduler-minimal.c | (orientation − 1) % 24 negative at 0 | (orientation + 23) % 24 |
4emac-timesynch.c | get_best_orientation() returns a random value; the learned table is not used | Return the orientation of a known neighbour with probability p |
Direction.getMaxRange | Inconsistent with the link budget used for edges | Derive from (L3.5) |
Scheduler main.c | recvfrom length argument not initialised; results file opened but never written | Initialise len = sizeof(addr); remove or fill the file |
Scheduler Makefile | No targets; links a non-existent graph_coloring.o | Write a proper Makefile; drop the object |
mainfiletocooja.c, maincoojatofile.c | Use old signatures of createInterferenceMatrix and main_tasa | Update to the current headers |
| Topology recordings | Some files store orientation in degrees, others as an index 0–23 | Normalise to the index before replay |
tsch-slot-operation.c (2018 trees) | A closing ); was commented out with a debug remark | Restore the statement |
| Versioning | No version control; firmware and scheduler versions drift apart | Import the dated archives into one Git repository |
16Self-check questions
Try to answer each question before opening the solution. All answers follow from the chapters above.
Why must the radio API carry a
radio_indexmask rather than a single radio number?Answer
Some operations must address several radios at once (switching all receivers on, broadcasting an EB on every sector, configuring the channel), while unicast must use exactly one. A bit mask expresses both cases with one argument (
RADIO_ALL = 7versusRADIO_SECONDARY = 2).How does the firmware tell the simulator where a steerable antenna points, given that the CC2420 has no such feature?
Answer
Through a virtual register: the driver writes 15·k to address 0x31; MSPSim stores it and notifies an
OrientationListener, which rotates theDirectionobject in Cooja. On native motes the same value travels through the C variablesimRadioOrientation.Using (L3.5), what is the communication range between a steerable antenna pointing at an omnidirectional receiver, and what does the scenario file use?
Answer
With Gtx + Grx = 5 dB and T = −95 dBm, d = 1048/25 ≈ 83 m. The 2020 steerable scenarios set a 79 m transmission range.
Why can a steerable node fail to join a network even though a neighbour sends Enhanced Beacons regularly?
Answer
EBs are sent in shared cells while the joining node points in some random direction; both beams must face each other in the same slot. Fake beacons reverse the roles: the unsynchronised node transmits, and any synchronised neighbour that hears it records the node and its direction.
Show that the autonomous cells of (L4.1) are consistent at both ends of a link.
Answer
Node a transmits to b in ((a+1)·7 + (b+1)·13) mod 251. Node b receives from a in ((b+1)·13 + (a+1)·7) mod 251, which is the same number because addition is commutative.
In the direction-aware colouring rule, when may two conflicting links share a channel, and what is wrong with the implemented test?
Answer
When the transmitters' orientation indices differ by more than 8 steps (120°). The code compares the plain difference, so indices 23 and 1 appear 22 steps apart although they are only 2 steps (30°) apart; the circular difference min(d, 24 − d) must be used.
Why did the study move from MSPSim to native Cooja motes in 2020?
Answer
Instruction-level emulation of MSP430 nodes with several CC2420 chips was too slow for networks beyond roughly 35 nodes. Native motes run Contiki on the host CPU and allowed 49- and 81-node scenarios and batch runs.
Why does the scheduler never run if
MAX_NODESis larger than the number of simulated nodes?Answer
TASA is started only after every node, counted up to
MAX_NODES, has reported and attached to the tree. Missing nodes keep the condition false indefinitely.
AIndex of all 199 changed files
Every file that differs from its baseline is listed exactly once, under the purpose it serves. Baselines: the group's Git history at 6tisch_3.0 (2017-06-15) for the 2018 trees, at 6tisch_3.1 master (2017-11-02) for the 3.1.x and antenna_sim trees, at oldest-6p (2019-10-30) for the merge/native/central archives, the original MSPSim copy for emulator files, and the 2017 scheduling library for the scheduler. New platform directories are compared with platform/exp5438. new marks files without a baseline.
A.1Multi-radio hardware and CC2420 driver (Lab 1) · 29 files
| File | Δ lines | Change |
|---|---|---|
dev/cc2420/cc2420.c | +953 / −223 | All SPI primitives and driver calls take a radio mask; per-radio FIFOP handling; antenna and orientation packet attributes; cc2420_set_orientation(); Energest per radio |
dev/cc2420/cc2420.h | +5 / −5 | Prototypes take radio_index; cc2420_interrupt(int index) |
dev/cc2420/cc2420_const.h | +3 / −0 | Virtual registers CC2420_ORIENTATION 0x31 and CC2420_BEAMWIDTH 0x32 |
cpu/msp430/cc2420-arch-sfd.c | +5 / −1 | SFD interrupt considers all radios; port select for extra SFD pins |
platform/exp5438/platform-conf.h | +12 / −6 | EXP5438_HAS_1_ANTENNA, radio masks, CC2420_ prefix for reset/VREG macros; file and log systems disabled |
platform/exp5438/cc2420-arch.c | +1 / −1 | cc2420_interrupt(RADIO_PRIMARY) |
platform/exp5438/ld/msp430.x | +13 / −2 | Port 3/4 interrupt symbols; RAM 0x1a00, ROM 0x7f00 |
platform/exp5438/msp430.c | +6 / −2 | P2DIR cleared, ACLK output disabled, P3IE = P4IE = 0 |
platform/exp5438/spix.c | +11 / −0 | SPI pins on ports 5 and 6 |
platform/exp5438/contiki-exp5438-main.c | +2 / −5 | packetbuf_init removed, duty-cycle scroller enabled (not antenna-related) |
platform/exp5438/contiki-conf.h | +3 / −0 | Comments only |
platform/exp5438_2dir/platform-conf.h new | +74 / −5 | Secondary radio pin map CC2420S_* (port 2, CS P6.0), EXP5438_HAS_2_ANTENNA |
platform/exp5438_2dir/cc2420-arch.c new | +18 / −1 | FIFOP ISR for the secondary radio |
platform/exp5438_2dir/spix.c new | +10 / −0 | SPI pins on ports 5 and 6 |
platform/exp5438_2dir/ld/msp430.x new | +11 / −0 | Port 3/4 interrupt symbols |
platform/exp5438_2dir/msp430.c new | +6 / −2 | Port initialisation as exp5438 |
platform/exp5438_2dir/contiki-conf.h new | +3 / −0 | Comments only |
platform/exp5438_3dir/platform-conf.h new | +132 / −4 | Secondary and tertiary (CC2420T_*, port 4, CS P5.0) pin maps, EXP5438_HAS_3_ANTENNA |
platform/exp5438_3dir/cc2420-arch.c new | +35 / −1 | FIFOP ISRs for secondary and tertiary radios |
platform/exp5438_3dir/spix.c new | +10 / −0 | SPI pins on ports 5 and 6 |
platform/exp5438_3dir/ld/msp430.x new | +11 / −0 | Port 3/4 interrupt symbols |
platform/exp5438_3dir/msp430.c new | +2 / −0 | P3IE = P4IE = 0 |
platform/exp5438_3dir/contiki-conf.h new | +3 / −0 | Comments only |
platform/exp5438_steerable/platform-conf.h new | +134 / −7 | EXP5438_HAS_STEERABLE_ANTENNA; extra-radio pin blocks present but inactive |
platform/exp5438_steerable/cc2420-arch.c new | +1 / −1 | Primary radio only |
platform/exp5438_steerable/spix.c new | +10 / −0 | SPI pins on ports 5 and 6 |
platform/exp5438_steerable/ld/msp430.x new | +13 / −2 | As exp5438 (enlarged RAM/ROM) |
platform/exp5438_steerable/msp430.c new | +6 / −2 | As exp5438 |
platform/exp5438_steerable/contiki-conf.h new | +3 / −0 | Comments only |
A.2Radio API and network stack (Lab 1) · 15 files
| File | Δ lines | Change |
|---|---|---|
core/dev/radio.h | +16 / −8 | Radio masks, RADIO_PARAM_ORIENTATION, radio_index in all driver functions |
core/net/mac/rdc.h | +1 / −1 | input(unsigned short radio_index) |
core/dev/nullradio.c | +9 / −9 | Signatures adapted |
core/net/mac/nullrdc.c | +8 / −8 | Send on the packet's antenna; ACK on the receiving radio; on(RADIO_ALL) |
core/net/mac/nullrdc-noframer.c | +3 / −3 | RADIO_PRIMARY for send, RADIO_ALL for on() |
core/net/mac/contikimac/contikimac.c | +8 / −8 | RADIO_PRIMARY for CCA and transmission; one branch not updated |
core/net/packetbuf.h | +2 / −0 | PACKETBUF_ATTR_ANTENNA, PACKETBUF_ATTR_ANTENNA_ORIENTATION |
core/net/mac/frame802154.h | +1 / −0 | FRAME802154_FAKEBEACONFRAME (0x04) |
core/net/packetbuf-enhanced.c | +2 / −2 | Interrupt masking in packetbuf_alloc commented out |
core/net/packetbuf.c | +0 / −2 | Attribute arrays always compiled |
core/sys/energest.h | +4 / −1 | LISTEN2/3 and TRANSMIT2/3 counters |
core/net/ipv6/sicslowpan.c | +0 / −60 | 2018 copy without the 4eMAC hooks of 6tisch_3.0 (removals only) |
core/net/ipv6/uip6.c | +0 / −31 | 2018 copy without the RSSI/ASN forwarding hook |
core/net/rpl/rpl-icmp6.c | +6 / −29 | 2018 copy without route callbacks; log prefixes |
core/net/ip/tcpip.c | +1 / −0 | Comment only |
A.3MAC layer: 4eMAC, Contiki TSCH, Orchestra (Lab 4) · 41 files
| File | Δ lines | Change |
|---|---|---|
core/net/mac/4emac/4emac-buf.h | +16 / −0 | Neighbour fields antenna, max_rssi, orientation, slot_list2; primary flag; new prototypes |
core/net/mac/4emac/4esec.c | +11 / −2 | Antenna and orientation attributes from the neighbour record; FB security level |
core/net/mac/4emac/4erdc.c | +92 / −129 | Radio index in all radio calls; packet_input(radio_index); FB dispatch; CCA branches removed |
core/net/mac/4emac/4emac-6top-scheduler.c | +15 / −0 | Steerable: +181 degree sweep in shared slots, learned orientation otherwise |
core/net/mac/4emac/4emac-6top-scheduler-minimal.c | +60 / −6 | Orientation per slot type; search of the autonomous slotframe |
core/net/mac/4emac/4emac-ie-fb.c new | +197 / −0 | Fake-beacon frame creation and parsing |
core/net/mac/4emac/4emac-ie-fb.h new | +65 / −0 | Fake-beacon structure and prototypes |
core/net/mac/4emac/4emac-timesynch.c | +186 / −17 | Virtual neighbour table, autonomous cells (L4.1), tsch_fb_input, tsch_send_fb, get_best_orientation |
core/net/mac/4emac/4emac-timesynch.h | +85 / −0 | vrt_nbr_cell_table_t, VIRTUAL_NEIGHBOUR_NUM, prototypes |
core/net/mac/4emac/ieee802154e.c | +101 / −0 | Information-element parser for fake beacons |
core/net/mac/4emac/ieee802154e.h | +2 / −0 | Fake-beacon frame type and header include |
core/net/mac/4emac/4emac-6tisch-minimal-security.c | +16 / −0 | Security level and key index for fake beacons |
core/net/mac/4emac/4emac-6tisch-minimal-security.h | +14 / −0 | FB security macros |
core/net/mac/4emac/4emac-buf.c | +297 / −4 | Second slot pool and API; EB/DIO/DIS replicated to neighbours; orientation learning; unschedule_all, delete_all_buffers |
core/net/mac/4emac/4emac-private.h | +30 / −4 | Slotframe sizes 31 and 251; Cooja busy-wait yields |
core/net/mac/4emac/4emac-ie-eb.c | +10 / −0 | Rewrite source address of copied EBs |
core/net/mac/4emac/6top-pce/nbr-cell-table.c | +6 / −0 | nbr_cell_table_get_next_nbr |
core/net/mac/4emac/6top-pce/nbr-cell-table.h | +4 / −0 | New prototypes |
core/net/mac/4emac/tsch-minimal-conf.h | +0 / −4 | Hopping macros removed |
core/net/mac/4emac/4emac.c | +3 / −2 | Statistics only for primary-slotframe cells |
core/net/mac/4emac/6top-pce/6p-sf-0.c | +24 / −10 | Thresholds 10; zero-division guard; ignore non-primary slots |
core/net/mac/4emac/6top-pce/6top-pce.c | +5 / −5 | SF0 removed from list; LIST retry 2; time-outs 8 s |
core/net/mac/4emac/6top-pce/6p-queue.c | +1 / −1 | Queue 3 -> 8 |
core/net/mac/4emac/6top-pce/6p-sf-backup.c | +1 / −1 | Time-out 8 s (2018 tree) |
core/net/mac/4emac/6top-pce/6p-sf-pid.c | +1 / −1 | Time-out 8 s (2018 tree) |
core/net/mac/4emac/6top-pce/6top-pce.h | +0 / −3 | Slotframe-duration macros removed |
core/net/mac/4emac/4emac-ie-sixtop.c | +2 / −2 | Payload termination IE made conditional |
core/net/mac/4emac/4emac-ie-sixtop.h | +1 / −0 | Commented-out antenna_offset field |
core/net/mac/4emac/6top-pce/6p-protocol.c | +7 / −0 | Commented-out antenna_offset handling |
core/net/mac/4emac/6top-pce/6p-protocol.h | +1 / −0 | extern declaration |
core/net/mac/4emac/6top-pce/6p-sf.c | +2 / −2 | Log macro |
core/net/mac/4emac/6top-pce/6p-sf.h | +1 / −0 | extern declaration |
apps/orchestra/orchestra-conf.h | +3 / −3 | Orchestra periods 397/31/17 -> 31/13/5 |
core/net/mac/tsch/tsch-conf.h | +19 / −2 | Single-channel hopping; 15 ms timeslot template |
core/net/mac/tsch/tsch-private.h | +6 / −0 | Radio masks |
core/net/mac/tsch/tsch-queue.h | +2 / −1 | Neighbour antenna field; minimum BE 2 |
core/net/mac/tsch/tsch-queue.c | +1 / −1 | Linear backoff window |
core/net/mac/tsch/tsch-slot-operation.h | +1 / −0 | Antenna field in received packets |
core/net/mac/tsch/tsch-slot-operation.c | +4 / −1 | Debug comments (see Section 15) |
core/net/mac/tsch/tsch-log.h | +1 / −1 | Log level 1 |
core/net/mac/tsch/tsch.c | +0 / −1 | Blank line removed |
A.4MSPSim and Cooja MSPSim motes (Lab 2) · 20 files
| File | Δ lines | Change |
|---|---|---|
tools/mspsim/se/sics/mspsim/chip/CC2420.java | +46 / −1 | Orientation and beam-width registers, listener, per-packet RSSI |
tools/mspsim/se/sics/mspsim/chip/OrientationListener.java new | +53 / −0 | New listener interface |
tools/mspsim/se/sics/mspsim/chip/Radio802154.java | +15 / −0 | Abstract orientation and RSSI methods |
tools/mspsim/se/sics/mspsim/platform/ti/Exp5438Node.java | +93 / −25 | Up to three CC2420 chips, pin and SPI routing |
tools/mspsim/se/sics/mspsim/config/MSP430f5437Config.java | +7 / −5 | Port 3/4 interrupts; memory map |
tools/mspsim/se/sics/mspsim/core/MSP430Core.java | +8 / −1 | getChips returns the next chip on each call |
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438Mote2AntennaType.java new | +238 / −0 | Two-antenna mote type |
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438Mote3AntennaType.java new | +238 / −0 | Three-antenna mote type |
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438MoteSteerableType.java new | +236 / −0 | Steerable mote type |
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438Mote.java | +10 / −1 | Node created by firmware extension |
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438MoteType.java | +10 / −5 | Direction import; renamed Exp5438_Omni |
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/JCreateMoteType.java | +6 / −0 | Extra interfaces |
tools/cooja/apps/mspsim/cooja.config | +1 / −1 | New mote types registered |
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java | +23 / −1 | Direction per radio; orientation listener; RSSI write-back |
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154SecondaryRadio.java new | +445 / −0 | Superseded copy bound to chip 1 (unused) |
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154TertiaryRadio.java new | +447 / −0 | Superseded copy bound to chip 2 (unused) |
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC1101Radio.java | +17 / −0 | Stubs for new Radio methods |
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC1120Radio.java | +18 / −1 | Stubs for new Radio methods |
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2520Radio.java | +17 / −0 | Stubs for new Radio methods |
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/TR1001Radio.java | +17 / −0 | Stubs for new Radio methods |
A.5Cooja antenna and radio-medium model (Lab 3) · 21 files
| File | Δ lines | Change |
|---|---|---|
tools/cooja/java/org/contikios/cooja/interfaces/Direction.java new | +323 / −0 | Orientation, beam width, gain pattern, link budget, range |
tools/cooja/java/org/contikios/cooja/interfaces/SecondaryDirection.java new | +83 / −0 | Subclass, unused |
tools/cooja/java/org/contikios/cooja/interfaces/TertiaryDirection.java new | +78 / −0 | Subclass, unused |
tools/cooja/java/org/contikios/cooja/interfaces/Radio.java | +23 / −0 | direction field, radio count and offset |
tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/interfaces/MicaZRadio.java | +17 / −0 | Stubs for new Radio methods |
tools/cooja/java/org/contikios/cooja/interfaces/DirectionalAntennaRadio.java | +1 / −1 | getDirection -> getDirectionAngle |
tools/cooja/java/org/contikios/cooja/interfaces/ApplicationRadio.java | +1 / −1 | getDirection -> getDirectionAngle |
tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java | +2 / −2 | Follows the rename |
tools/cooja/apps/mrm/java/org/contikios/mrm/ChannelModel.java | +2 / −2 | Follows the rename |
tools/cooja/java/org/contikios/cooja/MoteInterfaceHandler.java | +71 / −5 | Up to three radios per mote |
tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java | +23 / −3 | Register all radios |
tools/cooja/config/cooja_default.config | +3 / −1 | RADIO_COUNT, RADIO_OMNI, Direction as default interface |
tools/cooja/java/org/contikios/cooja/MoteInterface.java | +4 / −0 | toString only |
tools/cooja/java/org/contikios/cooja/interfaces/Position.java | +4 / −0 | toString only |
tools/cooja/java/org/contikios/cooja/radiomediums/UDGM.java | +87 / −19 | Link-budget thresholds -95/-102 dBm with antenna gains; orientation observer |
tools/cooja/java/org/contikios/cooja/radiomediums/ARM.java new | +373 / −0 | Antenna Radio Medium skeleton (2015), unused |
tools/cooja/config/cooja_applet.config | +1 / −1 | ARM registered |
tools/cooja/java/org/contikios/cooja/plugins/skins/UDGMVisualizerSkin.java | +115 / −21 | Per-radio sectors and rotating lobes |
tools/cooja/java/org/contikios/cooja/plugins/skins/ARMVisualizerSkin.java new | +479 / −0 | ARM visualiser (2015) |
tools/cooja/java/org/contikios/cooja/plugins/skins/DirectionVisualizerSkin.java new | +138 / −0 | Orientation labels (drawing commented out) |
tools/cooja/java/org/contikios/cooja/plugins/Visualizer.java | +45 / −3 | Polar gain helper |
A.6Cooja measurement tools (Section 13) · 6 files
| File | Δ lines | Change |
|---|---|---|
tools/cooja/java/org/contikios/cooja/plugins/TimeLine.java | +151 / −11 | Per-radio timelines and collision counting |
tools/cooja/java/org/contikios/cooja/plugins/Depo.java new | +326 / −0 | Earlier per-antenna collision counter, unused |
tools/cooja/java/org/contikios/cooja/plugins/LogScriptEngine.java | +2 / −2 | Progress reported in 1 % steps |
tools/cooja/build.xml | +2 / −2 | JVM heap 2048 MB |
tools/cooja/java/org/contikios/cooja/plugins/EventListener.java | +2 / −0 | Listens to Direction |
tools/cooja/java/org/contikios/cooja/plugins/analyzers/IEEE802154EAnalyzer.java | +2 / −2 | 6P version and SFID masks |
A.7Native Cooja mote (Lab 5) · 22 files
| File | Δ lines | Change |
|---|---|---|
platform/cooja/dev/cooja-radio.c | +203 / −83 | Three virtual radios; orientation, count and omni variables |
platform/cooja/dev/cooja-radio.h | +0 / −6 | Prototype removed |
tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRadio.java | +162 / −22 | RADIO_COUNT/RADIO_OMNI; per-radio variables; orientation polling |
tools/cooja/java/org/contikios/cooja/dialogs/ContikiMoteCompileDialog.java | +33 / −18 | Default interfaces from configuration |
tools/cooja/java/org/contikios/cooja/dialogs/AbstractCompileDialog.java | +1 / −1 | Duplicate interfaces allowed |
cpu/native/net/linuxradio-drv.c | +6 / −6 | Signatures adapted |
platform/cooja/contiki-conf.h | +63 / −54 | 4eMAC stack, radio masks, Energest; IPv4/Rime removed |
platform/cooja/contiki-cooja-main.c | +3 / −50 | IPv6 only |
platform/native/contiki-conf.h | +2 / −4 | IPv6 and 4eMAC by default |
cpu/x86/Makefile.x86_common | +2 / −2 | -m32 |
cpu/native/rtimer-arch.h | +18 / −0 | Microsecond/tick conversion macros |
platform/cooja/rtimer-arch.h | +18 / −0 | 64-bit conversion macro |
tools/cooja/1/org/contikios/cooja/corecomm/Lib1.java new | +58 / −0 | Generated by Cooja |
tools/cooja/1/org/contikios/cooja/corecomm/Lib2.java new | +58 / −0 | Generated by Cooja |
tools/cooja/2/org/contikios/cooja/corecomm/Lib1.java new | +58 / −0 | Generated by Cooja |
tools/cooja/2/org/contikios/cooja/corecomm/Lib2.java new | +58 / −0 | Generated by Cooja |
tools/cooja/3/org/contikios/cooja/corecomm/Lib1.java new | +58 / −0 | Generated by Cooja |
tools/cooja/3/org/contikios/cooja/corecomm/Lib2.java new | +58 / −0 | Generated by Cooja |
tools/cooja/4/org/contikios/cooja/corecomm/Lib1.java new | +58 / −0 | Generated by Cooja |
tools/cooja/4/org/contikios/cooja/corecomm/Lib2.java new | +58 / −0 | Generated by Cooja |
tools/cooja/org/contikios/cooja/corecomm/Lib1.java new | +58 / −0 | Generated by Cooja |
tools/cooja/org/contikios/cooja/corecomm/Lib2.java new | +58 / −0 | Generated by Cooja |
A.8Applications and scheduler integration (Labs 6–7) · 19 files
| File | Δ lines | Change |
|---|---|---|
examples/ipv6/tsch/rpl-udp/udp-client/udp-client.c | +181 / −24 | Topology reports with orientations; ts parsing and installation |
examples/ipv6/tsch/rpl-border-router/border-router.c | +135 / −0 | Same for the border router |
examples/ipv6/tsch/rpl-udp/udp-client/project-conf.h | +48 / −6 | Slotframes 31/251, hard cells 0-3, FB, autonomous cells, channel 26 |
examples/ipv6/tsch/rpl-border-router/project-conf.h | +25 / −5 | As the client |
examples/ipv6/tsch/rpl-udp/udp-server/project-conf.h | +45 / −6 | Older setting 51/251, four channels |
examples/ipv6/tsch/rpl-cjoin/rpl-border-router/project-conf.h | +15 / −0 | 51/251, four channels, capacities |
examples/ipv6/tsch/rpl-udp/udp-server/udp-server.c | +2 / −2 | No server reply; root ::1 |
examples/ipv6/rpl-udp/Makefile | +5 / −0 | Contiki TSCH and Orchestra enabled |
examples/ipv6/rpl-udp/project-conf.h | +94 / −3 | TSCH MAC, Orchestra callbacks |
examples/ipv6/rpl-udp/udp-client.c | +39 / −7 | Orchestra start-up; period 5 s |
examples/ipv6/rpl-udp/udp-server.c | +37 / −5 | RPL root and TSCH coordinator |
examples/ipv6/rpl-tsch/node.c | +1 / −1 | Coordinator rule for all targets |
examples/ipv6/rpl-tsch/project-conf.h | +4 / −4 | Orchestra on, log level 1 |
examples/ipv6/rpl-udp-tsch/Makefile new | +30 / −0 | Builds 4eMAC UDP example |
examples/ipv6/rpl-udp-tsch/udp-client.c new | +310 / −0 | Early 4eMAC client with slotframe report |
examples/ipv6/rpl-udp-tsch/udp-server.c new | +199 / −0 | Early 4eMAC server |
examples/ipv6/tsch/rpl-udp/project-conf.h | +110 / −0 | 2019 setting with NEIGHBOUR_LIST_WRT_ANTENNA |
examples/ipv6/tsch/rpl-udp/udp-client.c | +4 / −51 | Early client, period 2 s |
examples/ipv6/tsch/rpl-udp/udp-server.c | +1 / −1 | Root ::1 |
A.9Centralised scheduler (Lab 6) · 16 files
| File | Δ lines | Change |
|---|---|---|
main.c | +388 / −327 | Live UDP scheduler, report parsing, autonomous-cell marking, schedule encoding |
mainnodebased.c new | +448 / −0 | Copy of main.c |
Makefile new | +8 / −0 | Command list without targets |
maincoojatofile.c new | +382 / −0 | Records reports to a topology file |
mainfiletocooja.c new | +382 / −0 | Replays a topology file |
tasa/coloring.c | +20 / −5 | Direction-aware colouring (+/-8 steps) |
tasa/tasa.c | +36 / −13 | Degree matrix and schedule input; transmitter direction; pipelining priority |
tasa/matching.c | +10 / −7 | Autonomous-cell avoidance; priority |
tasa/coloring.h | +1 / −1 | Signature without channel dimension |
tasa/matching.h | +1 / −1 | Signature with schedule |
tasa/tasa.h | +3 / −2 | New main_tasa prototype |
graphs/graphs.c | +154 / −196 | Degree matrix, two-hop interference, single channel |
graphs/graphs.h | +20 / −19 | MAX_NODES, NUM_CHANNELS 1, slotframe 251; new node and link fields |
util/files.c | +56 / −359 | Direction lines; OpenWSN export removed |
util/print.c | +30 / −75 | Degree matrix output |
util/print.h | +4 / −4 | Prototypes |
A.10Group modules, tools and documentation (not part of the antenna work) · 10 files
| File | Δ lines | Change |
|---|---|---|
apps/6top-tracking/6p-sf-tracking.c | +1 / −1 | Time-out in seconds |
apps/6top-tracking/6p-tracking-process1.c | +2 / −2 | Retry delay in seconds |
apps/central-sch/4emac-central-scheduler.c | +5 / −5 | Check intervals in seconds |
apps/central-sch/4emac-cs-sf0.c | +4 / −1 | Time-out in seconds |
tools/tunslip6 | binary | SLIP tunnel binary (Lab 7) |
tools/ota/ota-process.c | +33 / −78 | Group OTA tool (version difference) |
tools/ota/ota-process.h new | +59 / −0 | Group OTA constants |
tools/ota/ota_process | binary | OTA binary |
platform/mahmote/dev/board.h | +8 / −8 | Pin constants rewritten, same values |
platform/srf06-cc26xx/6TiSCH_README.md new | +75 / −0 | CC1310 notes of the group |
BGlossary
| ASN | Absolute Slot Number; the network-wide count of timeslots since the start of the network. |
|---|---|
| Autonomous cell | A cell that both neighbours compute from their identifiers without negotiation (here: equation (L4.1) in a 251-slot slotframe). |
| Beam width | Angular extent of a sector (180° or 120°) or nominal width of a steerable lobe. |
| Cell | A (slot offset, channel offset) pair in a slotframe. |
| Colouring | The TASA step that assigns channel offsets so that conflicting links use different channels. |
| Cooja | The Java network simulator of Contiki; simulates radio media and hosts emulated or native motes. |
| EB | Enhanced Beacon; the IEEE 802.15.4e frame that advertises a TSCH network. |
| Energest | Contiki's energy accounting module, which accumulates time spent in CPU, LPM, listen and transmit states. |
| FB | Fake beacon; a short frame sent by unsynchronised steerable nodes so that synchronised neighbours can discover them. |
| 4eMAC | The 6TiSCH/TSCH MAC implementation for Contiki on which this work is based. |
| MSPSim | Instruction-level emulator for the TI MSP430, used by Cooja for “emulated” motes. |
| Native mote | A Cooja mote whose Contiki code is compiled for the host and loaded through JNI. |
| Orientation index | Integer 0–23 encoding a steerable antenna direction in 15° steps. |
| Orchestra | Autonomous TSCH scheduler for Contiki in which cells are derived from node addresses. |
| PRR | Packet reception ratio; delivered over sent application packets. |
| RDC | Radio duty-cycling layer of Contiki; in 4eMAC, the slot operation in 4erdc.c. |
| RPL | IPv6 Routing Protocol for Low-Power and Lossy Networks; builds the routing tree (DODAG) using DIO, DIS and DAO messages. |
| Sector antenna | Fixed directional antenna covering an angular sector; here realised as one CC2420 per sector. |
| SF0 | Scheduling Function Zero; the default distributed 6TiSCH scheduling function. |
| 6P | 6top Protocol; transactions for adding, deleting, listing and relocating cells between neighbours. |
| Slotframe | A repeating sequence of timeslots; this work uses a 31-slot primary and a 251-slot secondary slotframe. |
| Steerable antenna | A single antenna whose main lobe can be rotated electronically. |
| TASA | Traffic-Aware Scheduling Algorithm; centralised convergecast scheduler based on matching and colouring. |
| TSCH | Time-Slotted Channel Hopping, the MAC mode of IEEE 802.15.4e. |
| tunslip6 | Contiki tool that bridges a SLIP serial link to a Linux tun interface. |
| UDGM | Unit Disk Graph Medium; Cooja radio medium, modified here to use antenna gains. |
CReferences
- IEEE Std 802.15.4e-2012, Amendment 1: MAC sublayer. IEEE, 2012.
- X. Vilajosana, K. Pister, T. Watteyne, Minimal IPv6 over the TSCH Mode of IEEE 802.15.4e (6TiSCH) Configuration. RFC 8180, IETF, 2017.
- Q. Wang, X. Vilajosana, T. Watteyne, 6TiSCH Operation Sublayer (6top) Protocol (6P). RFC 8480, IETF, 2018.
- D. Dujovne, L. A. Grieco, M. R. Palattella, N. Accettura, 6TiSCH 6top Scheduling Function Zero (SF0). Internet-Draft draft-ietf-6tisch-6top-sf0, IETF.
- T. Winter et al., RPL: IPv6 Routing Protocol for Low-Power and Lossy Networks. RFC 6550, IETF, 2012.
- S. Duquennoy, B. Al Nahas, O. Landsiedel, T. Watteyne, “Orchestra: Robust Mesh Networks Through Autonomously Scheduled TSCH,” in Proc. ACM SenSys, 2015.
- M. R. Palattella, N. Accettura, M. Dohler, L. A. Grieco, G. Boggia, “Traffic Aware Scheduling Algorithm for Reliable Low-Power Multi-Hop IEEE 802.15.4e Networks,” in Proc. IEEE PIMRC, 2012.
- M. R. Palattella et al., “On Optimal Scheduling in Duty-Cycled Industrial IoT Applications Using IEEE 802.15.4e TSCH,” IEEE Sensors Journal, 13(10), 2013.
- S. Kim, H.-S. Kim, C. Kim, “ALICE: Autonomous Link-based Cell Scheduling for TSCH,” in Proc. ACM/IEEE IPSN, 2019.
- A. Dunkels, B. Grönvall, T. Voigt, “Contiki — a Lightweight and Flexible Operating System for Tiny Networked Sensors,” in Proc. IEEE LCN Workshops, 2004.
- F. Österlind, A. Dunkels, J. Eriksson, N. Finne, T. Voigt, “Cross-Level Sensor Network Simulation with COOJA,” in Proc. IEEE LCN, 2006.
- J. Eriksson et al., “COOJA/MSPSim: Interoperability Testing for Wireless Sensor Networks,” in Proc. SIMUTools, 2009.
These notes were compiled from the source archives in the study folder. Statements marked as presumable in the text are inferences from code and file dates rather than documented facts.
Related: Index of changed files · Glossary · References · © Sercan Külcü. All rights reserved.