User Guide

Introduction

This document explains how to run the OpenSCHC fragmentation and compression code.

This includes the following steps:

  • installing the “context” that will be used for compressing and fragmenting the traffic flows.

  • establishing the flows of traffic to be compressed/decompressed and fragmented/reassembled, and potentially setup the channel characteristics (in link simulation mode)

Rule Manager

SCHC is based on rules, each of them identified through a Rule ID. A Rule ID designates a rule that is common between a SCHC instance in a device and a SCHC instance in the core network. Conversely, a same Rule ID can be used to designate different rules on different devices.

The Rule ID has a variable length, which allows allocating shorter values to more frequent rules, if desired.

Rule definition

The rule manager is used to manage rules in the SCHC instances in the device and in the core network. On the device side, the rules that are installed are likely to be only the ones used by the applications running on that particular device. Conversely, on the core network side, the rule manager has to maintain a copy of the rules of each associated device.

The rule semantics is defined in the the SCHC context data model. However, in OpenSCHC, rules are written as JSON structures. The common part is the following:

{
"RuleID" : 12,
"RuleIDLength" : 4
}

The RuleID is a positive integer, right-aligned on the number of bits specified by ruleIDLength. In this first exemple, the RuleID is binary 1100. This rule is different from that one:

{
"RuleID" : 12,
"RuleIDLength" : 6
}

which yields the binary value 001100.

Rule IDs compose a binary tree and can also be noted with the / representation (as IP prefixes) 12/4 or 12/6.

A rule is either a fragmentation rule or a compression rule. They are differentiated by the JSON keyword Fragmentation or Compression. A rule can contain only one of these keywords.

For compression, the keyword is followed by an array, containing the field descriptions. A trivial compression rule is one where this array is empty.

{
"RuleID" : 12,
"RuleIDLength" : 4,
"Compression" : []
}

For fragmentation, the keyword is followed by the definition of the fragmentation parameters, which for example describe the fragmentation mode, the direction of the flow the rule applies to and optionnally the size of the different fragment SCHC header fields.

{
"RuleID" : 12,
"RuleIDLength" : 4,
"Fragmentation" : {
  "FRMode" : "noAck",
  "FRDirection" : "UP"
  }
}

SCHC differentiates the traffic generated by the device (upstream traffic) from the traffic sent to the device (downstream traffic). Fragmentation rules are unidirectional. In a fragmentation rule, the direction field is mandatory. It can be “UP” or “DW”. Note that for compression rules, the direction has to be specified for each field, so the rule by itself is bidirectional.

See below for the description of the compression and fragmentation parameters.

The following Python code adds these 2 basic rules into the OpenSCHC rule manager and displays them.

from gen_rulemanager import *

RM = RuleManager()

rule1100 =   {
  "RuleID" : 12,
  "RuleIDLength" : 4,
  "Compression" : []
}

rule001100 =   {
  "RuleID" : 12,
  "RuleIDLength" : 6,
  "Fragmentation" :  {
    "FRMode" : "noAck",
    "FRDirection" : "UP"
  }
}

RM.Add(dev_info=rule1100)
RM.Add(dev_info=rule001100)

RM.Print()

The first line imports the rule manager module.

RM will be the rule manager instance. If necessary, several rule managers can be instantiated.

The two rules are created as Python dictionaries and added to the instance of the rule manager.

Finally, the rules are displayed as cards on the console output.

****************************************
Device: None
/-------------------------\
|Rule 12/4          1100  |
|---------------+---+--+--+------------------------------+-------------+----------------\
\---------------+---+--+--+------------------------------+-------------+----------------/
/-------------------------\
|Rule 12/6        001100  |
!=========================+=============================================================\
!^ Fragmentation mode : noAck    header dtag 2 Window  0 FCN  3                     UP ^!
!^ No Tile size specified                                                              ^!
!^ RCS Algorithm: crc32                                                                ^!
\=======================================================================================/

Compression rules contain the field descriptions (here absent) and Fragmentation rules contain the fragmentation parameters. As we will notice in the rest of this chapter, the rule manager may add some default parameters.

We can notice that, since no device is specified, the rules are associated to the device None.

In the Add() method, we used the dev_info named argument to indicate that the rule is contained in a Python structure. The named argument file could have been used instead, with the name of the file containing the JSON structure.

Set of Rules

A device should contain a set of rules related to compression and fragmentation. In OpenSCHC, the SoR (set of rules) is a JSON array. The following program has the same behavior as the previous one.:

from gen_rulemanager import *

RM = RuleManager()

rule1100 =   {
 "RuleID" : 12,
 "RuleIDLength" : 4,
 "Compression" : []
}

rule001100 =   {
 "RuleID" : 12,
 "RuleIDLength" : 6,
 "Fragmentation" : {
   "FRMode": "noAck",
   "FRDirection" : "UP"
 }
}

RM.Add(dev_info=[rule1100, rule001100])

RM.Print()

Device definition

As seen before, when not specified, the device is identified as None. This can be appropriate when SCHC is instantiated on a device, since there is no ambiguity as to which device the rule set applies to. Conversely, when the SCHC instance is on the core network side, the set of rules must be associated with a device ID.

Rules associated with a Device ID can be directly stored into the rule manager through the Add() method as follows:

RM.Add(device="1234567890", dev_info=[rule1100, rule001100])

Alternately, the JSON structure would be the following:

{
    "DeviceID": 1234567890,
    "SoR" : [ ..... ]
}

where the DeviceID keyword represents the device ID in a specific LPWAN technology, for instance the LoRaWAN DevEUI. Note that this should be viewed as a JSON structure. Therefore, the DeviceID literal must be expressed in decimal, not hexadecimal.

Fragmenter/Reassembler

Using the client-server simulation, it is possible to observe some important details about noAck mode and fragmenter/reassembler. First of all, it is necessary to create a file with any name (e.g. rule1.json) into the examples/configs folder, which will contain our rules as follows:

[{
   "RuleID" : 12,
   "RuleIDLength" : 4,
   "Compression" : []
 },{
  "RuleID" : 12,
  "RuleIDLength" : 6,
  "Fragmentation" :  {
    "FRMode": "noAck",
    "FRDirection" : "UP"
  }
}]

Then, it is possible to define the message that will be sent from client to server. The examples/udp/udp_example.py file contains an example that can be used.

Sending/ receiving over UDP

This is an example of an openSCHC sender transmitting over UDP to an openSCHC receiver, on the same host computer. By default, the example is that of a device sending a single COAP packet processed with one fragmentation rule, but not compressed, to the core (server).

In order to run the example, move to the examples/udp directory, then

  1. In one terminal, run:

    python udp_example.py core-server
    

This will start a node playing the role of the SCHC core (network infrastructure server). It displays the Rules stored in its context,

****************************************
Device: None
/-------------------------\
|Rule 12/4          1100  |
|---------------+---+--+--+------------------------------+-------------+----------------\
\---------------+---+--+--+------------------------------+-------------+----------------/
/-------------------------\
|Rule 12/6        001100  |
!=========================+=============================================================\
!^ Fragmentation mode : noAck    header dtag 2 Window  0 FCN  3                     UP ^!
!^ No Tile size specified                                                              ^!
!^ RCS Algorithm: crc32                                                                ^!
\=======================================================================================/

then awaits a SCHC Message on UDP port 33300 on the loopback interface.

  1. In another terminal, run:

    python udp_example.py device
    

This will start a node playing the device role. It will display the Rules that are stored in its context,

 ****************************************
 Device: None
/-------------------------\
|Rule 12/4          1100  |
|---------------+---+--+--+------------------------------+-------------+----------------\
\---------------+---+--+--+------------------------------+-------------+----------------/
/-------------------------\
|Rule 12/6        001100  |
!=========================+=============================================================\
!^ Fragmentation mode : noAck    header dtag 2 Window  0 FCN  3                     UP ^!
!^ No Tile size specified                                                              ^!
!^ RCS Algorithm: crc32                                                                ^!
\=======================================================================================/

then send one SCHC-processed COAP packet. Since there is no compression Rule (except the mandatory “no-compression” Rule), the packet is simply prepended with the 12/4 RuleID and passed to the fragmentation sublayer. It is then fragmented into 13 SCHC Fragments, which are sent over UDP. Hit Ctrl+C to exit.

In the first terminal, you can observe the SCHC Fragments being received by the SCHC core (server), being reassembled into one SCHC Packet with sucessful RCS (previously known as MIC) check. It is then passed up to the decompression sublayer, which has nothing to do except strip off the 12/4 RuleID.