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, make and Apache ant.
  • 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

Table 1.1: Conventions.
NotationMeaning
RADIO_PRIMARY = 1, RADIO_SECONDARY = 2, RADIO_TERTIARY = 4, RADIO_ALL = 7Bit 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 / steerableOne 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 / −rLines 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.

Provenance of the 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

Objectives
  • 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

channel = HoppingSequence[(ASN + channelOffset) mod |HoppingSequence|] (1.1)

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.

Table 2.1: Why antennas matter for TSCH.
ModelHardware abstractionBeamHow a direction is selected
OmnidirectionalOne CC2420 radio360°Not applicable
Sectored, 2 radios (“2-dir”)Two CC2420 chips on one MSP4302 × 180° (0°, 180°)By choosing which radio transmits (radio_index)
Sectored, 3 radios (“3-dir”)Three CC2420 chips3 × 120° (0°, 120°, 240°)As above
SteerableOne CC2420 with a virtual orientation registerCardioid main lobe, rotated in 15° stepsBy writing the orientation register (RADIO_PARAM_ORIENTATION)

2.4Research questions addressed

  1. Can sectored antennas reduce collisions and energy in 6TiSCH-minimal/SF0 and in Orchestra, and by how much (2018 conference study)?
  2. 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)?
  3. 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)?
  4. 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.

NODE FIRMWARE (C, Contiki) Application · udp-client / udp-server / border-router topology report “T…”, schedule “ts …” (Lab 6–7) 4eMAC MAC · 6P · SF0 · time synchronisation per-neighbour antenna / orientation, fake beacons, autonomous cells (Lab 4) Radio API · radio.h · packetbuf attributes radio_index mask, RADIO_PARAM_ORIENTATION (Lab 1) CC2420 driver · exp5438* 1–3 chips, orientation reg. (Lab 1) cooja-radio.c (native) 3 virtual radios, orientation (Lab 5) SIMULATION HOST (Java) MSPSim CC2420 ×3, 0x31/0x32 registers (Lab 2) ContikiRadio (JNI) reads simRadioOrientation (Lab 5) Cooja · Direction · UDGM · TimeLine · Visualizer antenna gain, angle-dependent links, collision counting (Lab 3) scripts → PRR, join time, energy (Sec. 13) EXTERNAL HOST PROCESSES tunslip6 SLIP ↔ tun, fd00::1/64 Centralised scheduler UDP :5678, TASA with direction-aware colouring (Lab 6) Serial Socket (server) Cooja plug-in, port 60001 UDP
Figure 3.1: Components and the laboratory unit in which each is built. Shaded boxes were modified or created in this work.

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

Objectives
  • 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.

  1. 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
  2. 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
  3. Install the libraries of the centralised scheduler: sudo apt-get install libglpk-dev (the linker line expects libglpk.so.40).
  4. Build tunslip6 once 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.

Table 4.1: Source trees.
ExperimentSource treeMote 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 patternsharedvm/sedatgormus-6tisch_3.1.6.7Exp5438 2-antenna / 3-antenna / steerable
2019–2020 discovery and network formation (fake beacons)antenna_sim_2020_02_18.tar.gzExp5438 steerable
2020 scaling study (25–81 nodes) and 2021 centralised scheduling6tisch_3.1_ky_merge_native_central.20210221.zipCooja 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.testlog

The build file was changed to give the JVM 2048 MB instead of 512 MB, which large native simulations need.

Checkpoint 4.1

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

Objectives
  • 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: clear P2DIR and 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_value and set_value forward the mask; channel, PAN identifier and address are configured with RADIO_ALL.
  • cc2420_interrupt(int index) records which radio raised FIFOP; cc2420_read reads the corresponding FIFO (alternating between radios when several are pending) and stores the index in PACKETBUF_ATTR_ANTENNA.
  • Energest uses LISTEN2/3 and TRANSMIT2/3 for 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).

Checkpoint 5.1

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.

Common pitfall

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

Objectives
  • 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

  1. Copy Exp5438MoteType.java three times as Exp5438Mote2AntennaType, Exp5438Mote3AntennaType and Exp5438MoteSteerableType. Change the target name and file extension (exp5438_2dir, exp5438_3dir, exp5438_steerable) and list Msp802154Radio two, three or one time(s) among the mote interfaces, followed by Direction.
  2. 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);
  3. Register the new types in tools/cooja/apps/mspsim/cooja.config (MOTETYPES).
  4. In Msp802154Radio.java, create a Direction for 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.
  5. Give the other radio interfaces (CC1101Radio, CC1120Radio, CC2520Radio, TR1001Radio, Avrora's MicaZRadio) trivial implementations of the new abstract methods so that Cooja still compiles.
Historical note

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.

Checkpoint 6.1

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.

Common pitfall

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

Objectives
  • Attach a Direction object 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.java keeps an array of up to three radios and offers getRadio(i), getRadios() and getRadioCount(). When the radios are created it calls setAntennaOffset(count, i) on each.
  • interfaces/Radio.java gains a public Direction direction field, radioCount and radioOffset. setAntennaOffset converts the order 0/1/2 into the mask bit 1/2/4 and calls direction.setProperties(count, order).
  • AbstractRadioMedium.java registers 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

Gsteer(θ) = 10 · (1 + cos(θ − θ0)) − 15 (L3.1)
Gsector(θ) = +5 if θ0 ≤ θ < θ0 + beam width, otherwise −15 (L3.2)
Gomni(θ) = 0 (L3.3)

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²:

Prx(d) = −52 − 25 · log10 d + Gtx(θ) + Grx(θ + 180°) + 𝒩(0, 0.5)  [dBm] (L3.4)
// 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

dmax = 10(−52 − T + Gtx + Grx) / 25 (L3.5)
Table 7.1: Angle-dependent connectivity in UDGM.
Antenna pair (tx → rx)Gtx + Grx [dB]Range, T = −95 dBmInterference, T = −102 dBm
Omni → omni052 m100 m
Steerable boresight → omni+583 m158 m
Steerable boresight → steerable boresight+10132 m251 m
Steerable at ±90° → omni−533 m63 m
Steerable rear → omni−1513 m25 m
Sector (inside) → sector (inside)+10132 m251 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.

Common pitfall

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_INTERFACES
Checkpoint 7.1

Place 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

Objectives
  • 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:

Table 8.1: Orientation policy per slot type.
Slot typeOrientationRationale
Shared or timekeepingget_best_orientation() (currently uniform random in 0…23)The intended receiver is unknown; random scanning eventually covers all directions.
Dedicated receiveLearned orientation with probability ≈ 0.5, otherwise ±1 stepKeeps tracking the sender if the best direction drifts.
Dedicated transmitLearned orientationPoint 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.

Common pitfall

(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.

  1. Define the frame type FRAME802154_FAKEBEACONFRAME = 0x04 in core/net/mac/frame802154.h and ieee802154e.h.
  2. Add 4emac-ie-fb.c/.h with foure_packet_create_fb() and foure_packet_parse_fb() (constant payload 0x2345) and an IE parser ieee802154e_parse_fb_information_elements() in ieee802154e.c.
  3. Give FBs their own security level and key index (FOURE_SECURITY_KEY_SEC_LEVEL_FB, FOURE_SECURITY_KEY_INDEX_FB) in 4emac-6tisch-minimal-security.c/.h and 4esec.c.
  4. Route received FBs from 4erdc.c to tsch_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);
}
#endif

8.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:

stx(a→b) = ((a + 1)·7 + (b + 1)·13) mod 251,   srx(a←b) = ((a + 1)·13 + (b + 1)·7) mod 251 (L4.1)

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);
#endif

When 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), plus foure_mac_buf_slot_unschedule_all() and content_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 0 and a BUSYWAIT_UNTIL_ABS that yields with cooja_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: masks RADIO_PRIMARY(1) / SECONDARY(2) / TERTIARY(4) / BOTH(7).
  • tsch-queue.h: an antenna field in struct tsch_neighbor; tsch-slot-operation.h: an antenna field 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.
Checkpoint 8.1

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

Objectives
  • 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 Direction object.

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; set NETSTACK_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.h and cpu/native/rtimer-arch.h: provide US_TO_RTIMERTICKS, RTIMERTICKS_TO_US and their _64 variants, which 4eMAC uses; on Cooja one tick equals one microsecond.
  • cpu/x86/Makefile.x86_common: compile with gcc -m32 and CFLAGS += -m32.
Generated files

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.

Checkpoint 9.1

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

Objectives
  • 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:

Table 10.1: Report and schedule protocol.
MessageFormatMeaning
Topology reportTello <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.
DataHello <seq> …Sent after more than three schedules were received; the scheduler only counts it.
Schedulets <cell> <cell> …One 32-bit hexadecimal word per cell (below).

A cell is encoded as

cell = slot · 212 + channel · 28 + type · 27 + (neighbourId − 1) (L6.1)
Table 10.2: Report and schedule protocol.
BitsFieldRange
18–12slot offset0–127
11–8channel offset0–15
7type: 0 transmit, 1 receive0–1
6–0neighbour identifier − 10–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.

Common pitfall

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.c receives schedule[][] and admits a link in slot k only if schedule[k][tx] and schedule[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_t gains antenna_direction, received_message, recently_added; Link_t gains degree.
  • util/files.c accepts a new line type d<i>=… carrying link directions when topologies are read from files; util/print.c prints 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 5678

Set 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.

Checkpoint 10.1

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

Objectives
  • Bridge a simulated border router to the host's IPv6 stack.
  • Run Cooja, tunslip6 and the scheduler together and observe schedules being installed.
Node (udp-client) Border router tunslip6 Scheduler joins via EB / FB, learns orientations (Lab 4)Tello seq parent nbr ori … (RPL/TSCH)SLIP over Serial Socket :60001UDP to fd00::1 :5678 all MAX_NODES attached → build matrices, run TASAts cell cell …SLIPts … (downward RPL route) unschedule_all(); schedule(slot+3, channel)Hello seq (data in dedicated cells) reports again on topology change or every 100 periods
Figure 11.1: Control loop between the simulated network and the host scheduler.
  1. Prepare the border router. examples/ipv6/tsch/rpl-border-router/border-router.c carries the blocks marked //sercan: it opens a UDP connection on port 5678, reports its own neighbours and orientations as Tello … every 100 s, and parses ts exactly like the client (Δ +135 / −0). Its project-conf.h must match the clients (slotframes 31/251, hard cells 0–3, keep-alive and autonomous cells on, one channel, 26).
  2. 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.
  3. Start the tunnel in a second terminal:
    cd tools
    sudo ./tunslip6 -a 127.0.0.1 fd00::1/64     # equivalently: make connect-router-cooja
    The host now owns fd00::1, the address to which all nodes report.
  4. Start the scheduler (built with MAX_NODES 6) in a third terminal: ./Scheduling. It prints DATA recv from … for each report, then Links scheduled at time slot n and the encoded part words it sends.
  5. Observe. Node outputs show ts … being received; after the fourth schedule they switch to Hello data 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.
Version pairing

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

Table 12.1: Scenario families.
PeriodScenarioNodesLayoutAntennasPurpose
2017–18sim7lineer, sim9lineer7, 9LineOmni, 2-dirFirst functional tests of sector selection
2017–18sim10random, sim15random, sim16dir, sim17lineer10–17Random; centre + rings; two rowsOmni, 2-dir, 3-dirPRR and collision comparison for the 2018 study
2018–19sim25midaraomnioval, sim25makale25Sink centred, 40 m gridOmni, 2-dir, 3-dirMain configuration of the published figures; reception ratio 0.70–1.00 swept
2019sim50, sim75, sim10049, 73, 101GridSectoredScaling on MSPSim
2019steerable, rssitest, hepsibir, hepsibir63–11Small, mixedMixed in one networkUnit tests of orientation learning and of coexistence of antenna types
2019–20steerablescenarios/sim15/25/35 omni|steer15, 25, 35GridOmni vs. steerableDiscovery and formation time with fake beacons
2020sim25/49/81 omni3anten, …steer3anten25, 49, 815×5, 7×7, 9×9, 40 mSink with 3 radios; others omni or steerableEffect of a directional sink on joining per hop ring
2020sim81allomni, sim81allsteer819×9, 40 mAll omni / all steerableJoin and synchronisation time, PRR
2020sim81all{omni,steer}{20,30,40}m255×5, 20/30/40 mAll omni / all steerableDensity: time to find a parent, number of EB/RPL/6P transmissions
2020–21borderroute, …border*6–81Random; gridsSink omni, others steerableCentralised 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.

Naming trap

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.

Table 13.1: Metrics and data collection.
MetricDefinitionWhere 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-upScript of the 2017–19 scenarios: Total PRR x recv N sent M noack K
Unacknowledged transmissionsCount of MAC noack linesSame script
End-to-end delayMean delay of messages 51–150 per nodesim25makale, sim49omni3anten: ortalamadelay
EnergyEnergest listen/transmit/CPU/LPM ticks printed by the client every 60 messages, converted to mWhSame scripts: power rx … tx … cpu … lpm … → ortpower
Collision rateShare of receptions that were followed by interference in the same slot, per radioCooja TimeLine.java (event codes 1 TX, 2 RX, 3 interfered, 4 RX then interfered); an earlier counter Depo.java is unused
Join / formation timeSimulated time of the first 4eMAC:joining and 6P:Parent line per node, averaged per hop ring2020 scenarios
Control overheadCounts of sercan:transmit eb|rpl|6top linessim81allomni20m
Schedule lengthLast Links scheduled at time slot n of a TASA runScheduler 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)

Table 14.1: Sectored antennas (2018–2019, 25 nodes, MSPSim).
MetricCondition1 antenna2 antennas3 antennas
Collision rate [%]reception ratio 100 % / 70 %39.95 / 72.0831.67 / 52.9616.64 / 27.72
Energy [mWh]reception ratio 100 % / 70 %2.83 / 3.831.59 / 1.991.34 / 1.59
PRR, 6TiSCH minimal [%]0.25 / 0.5 / 1 / 2 packets s⁻¹46.3 / 17.1 / 2.1 / 1.095.4 / 47.7 / 19.4 / 8.099.4 / 76.6 / 35.5 / 11.6
PRR, Orchestra [%]0.25 / 0.5 / 1 / 2 packets s⁻¹73.2 / 32.3 / 5.8 / 3.474.8 / 49.9 / 22.1 / 13.688.5 / 54.0 / 25.9 / 15.6
PRR, SF0, 1 frequency [%]2 packets s⁻¹, reception 100 %12.268.178.0
PRR, SF0, 4 frequencies [%]2 packets s⁻¹, reception 100 %87.294.395.5
Delay, SF0 [s]1 packet s⁻¹, 1 frequency vs. 3 antennas + 4 frequencies1.72—0.52

14.2Steerable antenna: discovery and formation (2019, MSPSim)

Table 14.2: Steerable antenna: discovery and formation (2019, MSPSim).
MetricMethod15 nodes25 nodes35 nodes
Discovery time [min]Omni4.227.5213.69
Steerable, proposed11.2118.4029.21
Steerable, random direction14.6226.1235.68
Formation time [min]Omni10.2321.7628.93
Steerable, proposed16.3026.1232.61
Steerable, random direction25.5330.3737.57
Synchronisation time-outs [count]Omni224
Steerable, proposed003
Steerable, random direction154279

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)

Table 14.3: Centralised scheduling (2020–2021).
RunSettingSchedule length [slots]
81 nodes, 2 channels, steerableOffline replay119
81 nodes, 2 channels, omniOffline replay119
81 nodes, 3 channelsOffline replay (label ambiguous)80 (lower bound 80)
20 nodes, 1 channelLive Cooja, four runs, December 202025–32 (lower bound 19)
20 / 58 / 61 nodesLive Cooja, February 202131 / 114 / 112
Interpreting the results

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.

Table 15.1: Known issues and pitfalls.
LocationProblemRemedy
tasa/coloring.cOrientation difference not taken modulo 24Use the circular difference (Section 10.4)
4emac-6top-scheduler-minimal.c(orientation − 1) % 24 negative at 0(orientation + 23) % 24
4emac-timesynch.cget_best_orientation() returns a random value; the learned table is not usedReturn the orientation of a known neighbour with probability p
Direction.getMaxRangeInconsistent with the link budget used for edgesDerive from (L3.5)
Scheduler main.crecvfrom length argument not initialised; results file opened but never writtenInitialise len = sizeof(addr); remove or fill the file
Scheduler MakefileNo targets; links a non-existent graph_coloring.oWrite a proper Makefile; drop the object
mainfiletocooja.c, maincoojatofile.cUse old signatures of createInterferenceMatrix and main_tasaUpdate to the current headers
Topology recordingsSome files store orientation in degrees, others as an index 0–23Normalise to the index before replay
tsch-slot-operation.c (2018 trees)A closing ); was commented out with a debug remarkRestore the statement
VersioningNo version control; firmware and scheduler versions drift apartImport 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.

  1. Why must the radio API carry a radio_index mask 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 = 7 versus RADIO_SECONDARY = 2).

  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 the Direction object in Cooja. On native motes the same value travels through the C variable simRadioOrientation.

  3. 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.

  4. 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.

  5. 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.

  6. 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.

  7. 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.

  8. Why does the scheduler never run if MAX_NODES is 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

Table A.1: Multi-radio hardware and CC2420 driver (Lab 1).
FileΔ linesChange
dev/cc2420/cc2420.c+953 / −223All 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 / −5Prototypes take radio_index; cc2420_interrupt(int index)
dev/cc2420/cc2420_const.h+3 / −0Virtual registers CC2420_ORIENTATION 0x31 and CC2420_BEAMWIDTH 0x32
cpu/msp430/cc2420-arch-sfd.c+5 / −1SFD interrupt considers all radios; port select for extra SFD pins
platform/exp5438/platform-conf.h+12 / −6EXP5438_HAS_1_ANTENNA, radio masks, CC2420_ prefix for reset/VREG macros; file and log systems disabled
platform/exp5438/cc2420-arch.c+1 / −1cc2420_interrupt(RADIO_PRIMARY)
platform/exp5438/ld/msp430.x+13 / −2Port 3/4 interrupt symbols; RAM 0x1a00, ROM 0x7f00
platform/exp5438/msp430.c+6 / −2P2DIR cleared, ACLK output disabled, P3IE = P4IE = 0
platform/exp5438/spix.c+11 / −0SPI pins on ports 5 and 6
platform/exp5438/contiki-exp5438-main.c+2 / −5packetbuf_init removed, duty-cycle scroller enabled (not antenna-related)
platform/exp5438/contiki-conf.h+3 / −0Comments only
platform/exp5438_2dir/platform-conf.h new+74 / −5Secondary radio pin map CC2420S_* (port 2, CS P6.0), EXP5438_HAS_2_ANTENNA
platform/exp5438_2dir/cc2420-arch.c new+18 / −1FIFOP ISR for the secondary radio
platform/exp5438_2dir/spix.c new+10 / −0SPI pins on ports 5 and 6
platform/exp5438_2dir/ld/msp430.x new+11 / −0Port 3/4 interrupt symbols
platform/exp5438_2dir/msp430.c new+6 / −2Port initialisation as exp5438
platform/exp5438_2dir/contiki-conf.h new+3 / −0Comments only
platform/exp5438_3dir/platform-conf.h new+132 / −4Secondary and tertiary (CC2420T_*, port 4, CS P5.0) pin maps, EXP5438_HAS_3_ANTENNA
platform/exp5438_3dir/cc2420-arch.c new+35 / −1FIFOP ISRs for secondary and tertiary radios
platform/exp5438_3dir/spix.c new+10 / −0SPI pins on ports 5 and 6
platform/exp5438_3dir/ld/msp430.x new+11 / −0Port 3/4 interrupt symbols
platform/exp5438_3dir/msp430.c new+2 / −0P3IE = P4IE = 0
platform/exp5438_3dir/contiki-conf.h new+3 / −0Comments only
platform/exp5438_steerable/platform-conf.h new+134 / −7EXP5438_HAS_STEERABLE_ANTENNA; extra-radio pin blocks present but inactive
platform/exp5438_steerable/cc2420-arch.c new+1 / −1Primary radio only
platform/exp5438_steerable/spix.c new+10 / −0SPI pins on ports 5 and 6
platform/exp5438_steerable/ld/msp430.x new+13 / −2As exp5438 (enlarged RAM/ROM)
platform/exp5438_steerable/msp430.c new+6 / −2As exp5438
platform/exp5438_steerable/contiki-conf.h new+3 / −0Comments only

A.2Radio API and network stack (Lab 1) · 15 files

Table A.2: Radio API and network stack (Lab 1).
FileΔ linesChange
core/dev/radio.h+16 / −8Radio masks, RADIO_PARAM_ORIENTATION, radio_index in all driver functions
core/net/mac/rdc.h+1 / −1input(unsigned short radio_index)
core/dev/nullradio.c+9 / −9Signatures adapted
core/net/mac/nullrdc.c+8 / −8Send on the packet's antenna; ACK on the receiving radio; on(RADIO_ALL)
core/net/mac/nullrdc-noframer.c+3 / −3RADIO_PRIMARY for send, RADIO_ALL for on()
core/net/mac/contikimac/contikimac.c+8 / −8RADIO_PRIMARY for CCA and transmission; one branch not updated
core/net/packetbuf.h+2 / −0PACKETBUF_ATTR_ANTENNA, PACKETBUF_ATTR_ANTENNA_ORIENTATION
core/net/mac/frame802154.h+1 / −0FRAME802154_FAKEBEACONFRAME (0x04)
core/net/packetbuf-enhanced.c+2 / −2Interrupt masking in packetbuf_alloc commented out
core/net/packetbuf.c+0 / −2Attribute arrays always compiled
core/sys/energest.h+4 / −1LISTEN2/3 and TRANSMIT2/3 counters
core/net/ipv6/sicslowpan.c+0 / −602018 copy without the 4eMAC hooks of 6tisch_3.0 (removals only)
core/net/ipv6/uip6.c+0 / −312018 copy without the RSSI/ASN forwarding hook
core/net/rpl/rpl-icmp6.c+6 / −292018 copy without route callbacks; log prefixes
core/net/ip/tcpip.c+1 / −0Comment only

A.3MAC layer: 4eMAC, Contiki TSCH, Orchestra (Lab 4) · 41 files

Table A.3: MAC layer: 4eMAC, Contiki TSCH, Orchestra (Lab 4).
FileΔ linesChange
core/net/mac/4emac/4emac-buf.h+16 / −0Neighbour fields antenna, max_rssi, orientation, slot_list2; primary flag; new prototypes
core/net/mac/4emac/4esec.c+11 / −2Antenna and orientation attributes from the neighbour record; FB security level
core/net/mac/4emac/4erdc.c+92 / −129Radio index in all radio calls; packet_input(radio_index); FB dispatch; CCA branches removed
core/net/mac/4emac/4emac-6top-scheduler.c+15 / −0Steerable: +181 degree sweep in shared slots, learned orientation otherwise
core/net/mac/4emac/4emac-6top-scheduler-minimal.c+60 / −6Orientation per slot type; search of the autonomous slotframe
core/net/mac/4emac/4emac-ie-fb.c new+197 / −0Fake-beacon frame creation and parsing
core/net/mac/4emac/4emac-ie-fb.h new+65 / −0Fake-beacon structure and prototypes
core/net/mac/4emac/4emac-timesynch.c+186 / −17Virtual neighbour table, autonomous cells (L4.1), tsch_fb_input, tsch_send_fb, get_best_orientation
core/net/mac/4emac/4emac-timesynch.h+85 / −0vrt_nbr_cell_table_t, VIRTUAL_NEIGHBOUR_NUM, prototypes
core/net/mac/4emac/ieee802154e.c+101 / −0Information-element parser for fake beacons
core/net/mac/4emac/ieee802154e.h+2 / −0Fake-beacon frame type and header include
core/net/mac/4emac/4emac-6tisch-minimal-security.c+16 / −0Security level and key index for fake beacons
core/net/mac/4emac/4emac-6tisch-minimal-security.h+14 / −0FB security macros
core/net/mac/4emac/4emac-buf.c+297 / −4Second 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 / −4Slotframe sizes 31 and 251; Cooja busy-wait yields
core/net/mac/4emac/4emac-ie-eb.c+10 / −0Rewrite source address of copied EBs
core/net/mac/4emac/6top-pce/nbr-cell-table.c+6 / −0nbr_cell_table_get_next_nbr
core/net/mac/4emac/6top-pce/nbr-cell-table.h+4 / −0New prototypes
core/net/mac/4emac/tsch-minimal-conf.h+0 / −4Hopping macros removed
core/net/mac/4emac/4emac.c+3 / −2Statistics only for primary-slotframe cells
core/net/mac/4emac/6top-pce/6p-sf-0.c+24 / −10Thresholds 10; zero-division guard; ignore non-primary slots
core/net/mac/4emac/6top-pce/6top-pce.c+5 / −5SF0 removed from list; LIST retry 2; time-outs 8 s
core/net/mac/4emac/6top-pce/6p-queue.c+1 / −1Queue 3 -> 8
core/net/mac/4emac/6top-pce/6p-sf-backup.c+1 / −1Time-out 8 s (2018 tree)
core/net/mac/4emac/6top-pce/6p-sf-pid.c+1 / −1Time-out 8 s (2018 tree)
core/net/mac/4emac/6top-pce/6top-pce.h+0 / −3Slotframe-duration macros removed
core/net/mac/4emac/4emac-ie-sixtop.c+2 / −2Payload termination IE made conditional
core/net/mac/4emac/4emac-ie-sixtop.h+1 / −0Commented-out antenna_offset field
core/net/mac/4emac/6top-pce/6p-protocol.c+7 / −0Commented-out antenna_offset handling
core/net/mac/4emac/6top-pce/6p-protocol.h+1 / −0extern declaration
core/net/mac/4emac/6top-pce/6p-sf.c+2 / −2Log macro
core/net/mac/4emac/6top-pce/6p-sf.h+1 / −0extern declaration
apps/orchestra/orchestra-conf.h+3 / −3Orchestra periods 397/31/17 -> 31/13/5
core/net/mac/tsch/tsch-conf.h+19 / −2Single-channel hopping; 15 ms timeslot template
core/net/mac/tsch/tsch-private.h+6 / −0Radio masks
core/net/mac/tsch/tsch-queue.h+2 / −1Neighbour antenna field; minimum BE 2
core/net/mac/tsch/tsch-queue.c+1 / −1Linear backoff window
core/net/mac/tsch/tsch-slot-operation.h+1 / −0Antenna field in received packets
core/net/mac/tsch/tsch-slot-operation.c+4 / −1Debug comments (see Section 15)
core/net/mac/tsch/tsch-log.h+1 / −1Log level 1
core/net/mac/tsch/tsch.c+0 / −1Blank line removed

A.4MSPSim and Cooja MSPSim motes (Lab 2) · 20 files

Table A.4: MSPSim and Cooja MSPSim motes (Lab 2).
FileΔ linesChange
tools/mspsim/se/sics/mspsim/chip/CC2420.java+46 / −1Orientation and beam-width registers, listener, per-packet RSSI
tools/mspsim/se/sics/mspsim/chip/OrientationListener.java new+53 / −0New listener interface
tools/mspsim/se/sics/mspsim/chip/Radio802154.java+15 / −0Abstract orientation and RSSI methods
tools/mspsim/se/sics/mspsim/platform/ti/Exp5438Node.java+93 / −25Up to three CC2420 chips, pin and SPI routing
tools/mspsim/se/sics/mspsim/config/MSP430f5437Config.java+7 / −5Port 3/4 interrupts; memory map
tools/mspsim/se/sics/mspsim/core/MSP430Core.java+8 / −1getChips returns the next chip on each call
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438Mote2AntennaType.java new+238 / −0Two-antenna mote type
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438Mote3AntennaType.java new+238 / −0Three-antenna mote type
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438MoteSteerableType.java new+236 / −0Steerable mote type
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438Mote.java+10 / −1Node created by firmware extension
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/Exp5438MoteType.java+10 / −5Direction import; renamed Exp5438_Omni
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/JCreateMoteType.java+6 / −0Extra interfaces
tools/cooja/apps/mspsim/cooja.config+1 / −1New mote types registered
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154Radio.java+23 / −1Direction per radio; orientation listener; RSSI write-back
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154SecondaryRadio.java new+445 / −0Superseded copy bound to chip 1 (unused)
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/Msp802154TertiaryRadio.java new+447 / −0Superseded copy bound to chip 2 (unused)
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC1101Radio.java+17 / −0Stubs for new Radio methods
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC1120Radio.java+18 / −1Stubs for new Radio methods
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/CC2520Radio.java+17 / −0Stubs for new Radio methods
tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/interfaces/TR1001Radio.java+17 / −0Stubs for new Radio methods

A.5Cooja antenna and radio-medium model (Lab 3) · 21 files

Table A.5: Cooja antenna and radio-medium model (Lab 3).
FileΔ linesChange
tools/cooja/java/org/contikios/cooja/interfaces/Direction.java new+323 / −0Orientation, beam width, gain pattern, link budget, range
tools/cooja/java/org/contikios/cooja/interfaces/SecondaryDirection.java new+83 / −0Subclass, unused
tools/cooja/java/org/contikios/cooja/interfaces/TertiaryDirection.java new+78 / −0Subclass, unused
tools/cooja/java/org/contikios/cooja/interfaces/Radio.java+23 / −0direction field, radio count and offset
tools/cooja/apps/avrora/src/org/contikios/cooja/avrmote/interfaces/MicaZRadio.java+17 / −0Stubs for new Radio methods
tools/cooja/java/org/contikios/cooja/interfaces/DirectionalAntennaRadio.java+1 / −1getDirection -> getDirectionAngle
tools/cooja/java/org/contikios/cooja/interfaces/ApplicationRadio.java+1 / −1getDirection -> getDirectionAngle
tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java+2 / −2Follows the rename
tools/cooja/apps/mrm/java/org/contikios/mrm/ChannelModel.java+2 / −2Follows the rename
tools/cooja/java/org/contikios/cooja/MoteInterfaceHandler.java+71 / −5Up to three radios per mote
tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java+23 / −3Register all radios
tools/cooja/config/cooja_default.config+3 / −1RADIO_COUNT, RADIO_OMNI, Direction as default interface
tools/cooja/java/org/contikios/cooja/MoteInterface.java+4 / −0toString only
tools/cooja/java/org/contikios/cooja/interfaces/Position.java+4 / −0toString only
tools/cooja/java/org/contikios/cooja/radiomediums/UDGM.java+87 / −19Link-budget thresholds -95/-102 dBm with antenna gains; orientation observer
tools/cooja/java/org/contikios/cooja/radiomediums/ARM.java new+373 / −0Antenna Radio Medium skeleton (2015), unused
tools/cooja/config/cooja_applet.config+1 / −1ARM registered
tools/cooja/java/org/contikios/cooja/plugins/skins/UDGMVisualizerSkin.java+115 / −21Per-radio sectors and rotating lobes
tools/cooja/java/org/contikios/cooja/plugins/skins/ARMVisualizerSkin.java new+479 / −0ARM visualiser (2015)
tools/cooja/java/org/contikios/cooja/plugins/skins/DirectionVisualizerSkin.java new+138 / −0Orientation labels (drawing commented out)
tools/cooja/java/org/contikios/cooja/plugins/Visualizer.java+45 / −3Polar gain helper

A.6Cooja measurement tools (Section 13) · 6 files

Table A.6: Cooja measurement tools (Section 13).
FileΔ linesChange
tools/cooja/java/org/contikios/cooja/plugins/TimeLine.java+151 / −11Per-radio timelines and collision counting
tools/cooja/java/org/contikios/cooja/plugins/Depo.java new+326 / −0Earlier per-antenna collision counter, unused
tools/cooja/java/org/contikios/cooja/plugins/LogScriptEngine.java+2 / −2Progress reported in 1 % steps
tools/cooja/build.xml+2 / −2JVM heap 2048 MB
tools/cooja/java/org/contikios/cooja/plugins/EventListener.java+2 / −0Listens to Direction
tools/cooja/java/org/contikios/cooja/plugins/analyzers/IEEE802154EAnalyzer.java+2 / −26P version and SFID masks

A.7Native Cooja mote (Lab 5) · 22 files

Table A.7: Native Cooja mote (Lab 5).
FileΔ linesChange
platform/cooja/dev/cooja-radio.c+203 / −83Three virtual radios; orientation, count and omni variables
platform/cooja/dev/cooja-radio.h+0 / −6Prototype removed
tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRadio.java+162 / −22RADIO_COUNT/RADIO_OMNI; per-radio variables; orientation polling
tools/cooja/java/org/contikios/cooja/dialogs/ContikiMoteCompileDialog.java+33 / −18Default interfaces from configuration
tools/cooja/java/org/contikios/cooja/dialogs/AbstractCompileDialog.java+1 / −1Duplicate interfaces allowed
cpu/native/net/linuxradio-drv.c+6 / −6Signatures adapted
platform/cooja/contiki-conf.h+63 / −544eMAC stack, radio masks, Energest; IPv4/Rime removed
platform/cooja/contiki-cooja-main.c+3 / −50IPv6 only
platform/native/contiki-conf.h+2 / −4IPv6 and 4eMAC by default
cpu/x86/Makefile.x86_common+2 / −2-m32
cpu/native/rtimer-arch.h+18 / −0Microsecond/tick conversion macros
platform/cooja/rtimer-arch.h+18 / −064-bit conversion macro
tools/cooja/1/org/contikios/cooja/corecomm/Lib1.java new+58 / −0Generated by Cooja
tools/cooja/1/org/contikios/cooja/corecomm/Lib2.java new+58 / −0Generated by Cooja
tools/cooja/2/org/contikios/cooja/corecomm/Lib1.java new+58 / −0Generated by Cooja
tools/cooja/2/org/contikios/cooja/corecomm/Lib2.java new+58 / −0Generated by Cooja
tools/cooja/3/org/contikios/cooja/corecomm/Lib1.java new+58 / −0Generated by Cooja
tools/cooja/3/org/contikios/cooja/corecomm/Lib2.java new+58 / −0Generated by Cooja
tools/cooja/4/org/contikios/cooja/corecomm/Lib1.java new+58 / −0Generated by Cooja
tools/cooja/4/org/contikios/cooja/corecomm/Lib2.java new+58 / −0Generated by Cooja
tools/cooja/org/contikios/cooja/corecomm/Lib1.java new+58 / −0Generated by Cooja
tools/cooja/org/contikios/cooja/corecomm/Lib2.java new+58 / −0Generated by Cooja

A.8Applications and scheduler integration (Labs 6–7) · 19 files

Table A.8: Applications and scheduler integration (Labs 6–7).
FileΔ linesChange
examples/ipv6/tsch/rpl-udp/udp-client/udp-client.c+181 / −24Topology reports with orientations; ts parsing and installation
examples/ipv6/tsch/rpl-border-router/border-router.c+135 / −0Same for the border router
examples/ipv6/tsch/rpl-udp/udp-client/project-conf.h+48 / −6Slotframes 31/251, hard cells 0-3, FB, autonomous cells, channel 26
examples/ipv6/tsch/rpl-border-router/project-conf.h+25 / −5As the client
examples/ipv6/tsch/rpl-udp/udp-server/project-conf.h+45 / −6Older setting 51/251, four channels
examples/ipv6/tsch/rpl-cjoin/rpl-border-router/project-conf.h+15 / −051/251, four channels, capacities
examples/ipv6/tsch/rpl-udp/udp-server/udp-server.c+2 / −2No server reply; root ::1
examples/ipv6/rpl-udp/Makefile+5 / −0Contiki TSCH and Orchestra enabled
examples/ipv6/rpl-udp/project-conf.h+94 / −3TSCH MAC, Orchestra callbacks
examples/ipv6/rpl-udp/udp-client.c+39 / −7Orchestra start-up; period 5 s
examples/ipv6/rpl-udp/udp-server.c+37 / −5RPL root and TSCH coordinator
examples/ipv6/rpl-tsch/node.c+1 / −1Coordinator rule for all targets
examples/ipv6/rpl-tsch/project-conf.h+4 / −4Orchestra on, log level 1
examples/ipv6/rpl-udp-tsch/Makefile new+30 / −0Builds 4eMAC UDP example
examples/ipv6/rpl-udp-tsch/udp-client.c new+310 / −0Early 4eMAC client with slotframe report
examples/ipv6/rpl-udp-tsch/udp-server.c new+199 / −0Early 4eMAC server
examples/ipv6/tsch/rpl-udp/project-conf.h+110 / −02019 setting with NEIGHBOUR_LIST_WRT_ANTENNA
examples/ipv6/tsch/rpl-udp/udp-client.c+4 / −51Early client, period 2 s
examples/ipv6/tsch/rpl-udp/udp-server.c+1 / −1Root ::1

A.9Centralised scheduler (Lab 6) · 16 files

Table A.9: Centralised scheduler (Lab 6).
FileΔ linesChange
main.c+388 / −327Live UDP scheduler, report parsing, autonomous-cell marking, schedule encoding
mainnodebased.c new+448 / −0Copy of main.c
Makefile new+8 / −0Command list without targets
maincoojatofile.c new+382 / −0Records reports to a topology file
mainfiletocooja.c new+382 / −0Replays a topology file
tasa/coloring.c+20 / −5Direction-aware colouring (+/-8 steps)
tasa/tasa.c+36 / −13Degree matrix and schedule input; transmitter direction; pipelining priority
tasa/matching.c+10 / −7Autonomous-cell avoidance; priority
tasa/coloring.h+1 / −1Signature without channel dimension
tasa/matching.h+1 / −1Signature with schedule
tasa/tasa.h+3 / −2New main_tasa prototype
graphs/graphs.c+154 / −196Degree matrix, two-hop interference, single channel
graphs/graphs.h+20 / −19MAX_NODES, NUM_CHANNELS 1, slotframe 251; new node and link fields
util/files.c+56 / −359Direction lines; OpenWSN export removed
util/print.c+30 / −75Degree matrix output
util/print.h+4 / −4Prototypes

A.10Group modules, tools and documentation (not part of the antenna work) · 10 files

Table A.10: Group modules, tools and documentation (not part of the antenna work).
FileΔ linesChange
apps/6top-tracking/6p-sf-tracking.c+1 / −1Time-out in seconds
apps/6top-tracking/6p-tracking-process1.c+2 / −2Retry delay in seconds
apps/central-sch/4emac-central-scheduler.c+5 / −5Check intervals in seconds
apps/central-sch/4emac-cs-sf0.c+4 / −1Time-out in seconds
tools/tunslip6binarySLIP tunnel binary (Lab 7)
tools/ota/ota-process.c+33 / −78Group OTA tool (version difference)
tools/ota/ota-process.h new+59 / −0Group OTA constants
tools/ota/ota_processbinaryOTA binary
platform/mahmote/dev/board.h+8 / −8Pin constants rewritten, same values
platform/srf06-cc26xx/6TiSCH_README.md new+75 / −0CC1310 notes of the group

BGlossary

Table B.1: Terms used in these notes.
ASNAbsolute Slot Number; the network-wide count of timeslots since the start of the network.
Autonomous cellA cell that both neighbours compute from their identifiers without negotiation (here: equation (L4.1) in a 251-slot slotframe).
Beam widthAngular extent of a sector (180° or 120°) or nominal width of a steerable lobe.
CellA (slot offset, channel offset) pair in a slotframe.
ColouringThe TASA step that assigns channel offsets so that conflicting links use different channels.
CoojaThe Java network simulator of Contiki; simulates radio media and hosts emulated or native motes.
EBEnhanced Beacon; the IEEE 802.15.4e frame that advertises a TSCH network.
EnergestContiki's energy accounting module, which accumulates time spent in CPU, LPM, listen and transmit states.
FBFake beacon; a short frame sent by unsynchronised steerable nodes so that synchronised neighbours can discover them.
4eMACThe 6TiSCH/TSCH MAC implementation for Contiki on which this work is based.
MSPSimInstruction-level emulator for the TI MSP430, used by Cooja for “emulated” motes.
Native moteA Cooja mote whose Contiki code is compiled for the host and loaded through JNI.
Orientation indexInteger 0–23 encoding a steerable antenna direction in 15° steps.
OrchestraAutonomous TSCH scheduler for Contiki in which cells are derived from node addresses.
PRRPacket reception ratio; delivered over sent application packets.
RDCRadio duty-cycling layer of Contiki; in 4eMAC, the slot operation in 4erdc.c.
RPLIPv6 Routing Protocol for Low-Power and Lossy Networks; builds the routing tree (DODAG) using DIO, DIS and DAO messages.
Sector antennaFixed directional antenna covering an angular sector; here realised as one CC2420 per sector.
SF0Scheduling Function Zero; the default distributed 6TiSCH scheduling function.
6P6top Protocol; transactions for adding, deleting, listing and relocating cells between neighbours.
SlotframeA repeating sequence of timeslots; this work uses a 31-slot primary and a 251-slot secondary slotframe.
Steerable antennaA single antenna whose main lobe can be rotated electronically.
TASATraffic-Aware Scheduling Algorithm; centralised convergecast scheduler based on matching and colouring.
TSCHTime-Slotted Channel Hopping, the MAC mode of IEEE 802.15.4e.
tunslip6Contiki tool that bridges a SLIP serial link to a Linux tun interface.
UDGMUnit Disk Graph Medium; Cooja radio medium, modified here to use antenna gains.

CReferences

  1. IEEE Std 802.15.4e-2012, Amendment 1: MAC sublayer. IEEE, 2012.
  2. X. Vilajosana, K. Pister, T. Watteyne, Minimal IPv6 over the TSCH Mode of IEEE 802.15.4e (6TiSCH) Configuration. RFC 8180, IETF, 2017.
  3. Q. Wang, X. Vilajosana, T. Watteyne, 6TiSCH Operation Sublayer (6top) Protocol (6P). RFC 8480, IETF, 2018.
  4. D. Dujovne, L. A. Grieco, M. R. Palattella, N. Accettura, 6TiSCH 6top Scheduling Function Zero (SF0). Internet-Draft draft-ietf-6tisch-6top-sf0, IETF.
  5. T. Winter et al., RPL: IPv6 Routing Protocol for Low-Power and Lossy Networks. RFC 6550, IETF, 2012.
  6. S. Duquennoy, B. Al Nahas, O. Landsiedel, T. Watteyne, “Orchestra: Robust Mesh Networks Through Autonomously Scheduled TSCH,” in Proc. ACM SenSys, 2015.
  7. 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.
  8. 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.
  9. S. Kim, H.-S. Kim, C. Kim, “ALICE: Autonomous Link-based Cell Scheduling for TSCH,” in Proc. ACM/IEEE IPSN, 2019.
  10. A. Dunkels, B. Grönvall, T. Voigt, “Contiki — a Lightweight and Flexible Operating System for Tiny Networked Sensors,” in Proc. IEEE LCN Workshops, 2004.
  11. F. Österlind, A. Dunkels, J. Eriksson, N. Finne, T. Voigt, “Cross-Level Sensor Network Simulation with COOJA,” in Proc. IEEE LCN, 2006.
  12. 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.