README.md 15.3 KB

IoTivity Examples

These examples implement some simple clients and a server to test the IoTivity package for RIOT-OS. The pkg is based on the IoTivity-Constrained library. All examples use the realm-local multicast address ff03:158 instead of the link-local multicast address ff02::158. Every payload is CBOR encoded. All examples have been tested on Native and SAMR21-XPRO. ##Index

#Examples

##Server Example This example implements an IoTivity Server that contains 4 resources.

  1. /oic/res: returns the representation of resources available on the server. Defined here.
  2. /oic/p: returns information about the platform on which the server runs. Defined here.
  3. /oic/d: returns information about the device on which the server runs. Defined here.
  4. /light/1 : it is a light (LED) management resource (implemented in resources/res-light.c). Resource Type: oic.r.light.
    • GET: returns the status of the LED. The payload is: {state: true/false}
    • PUT: changes the status of the LED. The payload is: {state: true/false}
    • OBSERVE: the registered client is notified when the status changes. The payload is the same of the GET response.

Client Example

This example implements a simple client. It is able to discover resources with ResourceType oic.r.light. Once it finds a resource, it registers for OBSERVE notifications. It changes the status every second by sending a periodic PUT request.

##Client_Switch Example This example implements a simple client. It is able to discover resources with ResourceType oic.r.light. Once it finds a resource, it registers for OBSERVE notifications. It changes the status when the User Button is pressed. If the button is not present it is just an observer.

##BR_FW Example It is an "enhanced" version of the GNRC Border Router. It implements a simple forwarder (UDP server/client) for multicast requests with destination ff03::158 port 5683.

#Scenarios It is possible to deploy 2 different scenarios with these examples.

##Node-to-Node Communications In this scenario, we will deploy an IoTivity Client and IoTivity Server on different nodes. We can choose two different clients for this scenario: client (periodic PUT) or client_switch (PUT sent on User Button pressed). The first one runs well both on native either on SAMR21-XPRO boards, the second one runs just on SAMR21-XPRO boards. Native target hasn't the button.

Server and Client (Periodic PUT) - native target

Create taps interfaces (to which RIOT will connect). Go to /dist/tools/tapsetup and type

$ sudo ./tapsetup -c

After this step we have created three tap interfaces: tap0, tap1 and tapbr0. Now, we compile the server. Go to /examples/iotivity-examples/server and type

$ make all BOARD=native

Run the server by invoking

$ sudo bin/native/ocf_server.elf tap0

The server output will be similar to this

RIOT native interrupts/signals initialized.
LED_RED_OFF
LED_GREEN_ON
RIOT native board initialized.
RIOT native hardware initialization complete.

main(): This is RIOT! (Version: 2017.01-devel-13-g2b77e-mattia-Latitude-E6410-pkg/iotivity)
server_oic: Waiting for address autoconfiguration...ipadapter: waiting for server requests...
ipadapter: waiting for multicast requests...
server_oic: LED0 is OFF
LED_RED_OFF
oc_main: Stack successfully initialized
server_oic: Configured network interfaces:
Iface  5   HWaddr: e6:e8:ff:6b:0c:f2

           MTU:1500  HL:64  RTR  RTR_ADV
           Source address length: 6
           Link type: wired
           inet6 addr: ff02::1/128  scope: local [multicast]
           inet6 addr: fe80::e4e8:ffff:fe6b:cf2/64  scope: local
           inet6 addr: ff02::1:ff6b:cf2/128  scope: local [multicast]
           inet6 addr: ff02::2/128  scope: local [multicast]
           inet6 addr: ff02::1a/128  scope: local [multicast]
           inet6 addr: ff03::158/128  scope: global [multicast]

It is waiting for requests. Open a new terminal window, go to /examples/iotivity-examples/client and type

$ make all BOARD=native

Run the client by invoking

$ sudo bin/native/ocf_client.elf tap1

The client runs and it starts with the discovery phase

RIOT native interrupts/signals initialized.
LED_RED_OFF
LED_GREEN_ON
RIOT native board initialized.
RIOT native hardware initialization complete.

main(): This is RIOT! (Version: 2017.01-devel-13-g2b77e-mattia-Latitude-E6410-pkg/iotivity)
LED_RED_OFF
client_oic: Waiting for address autoconfiguration...ipadapter: waiting for server requests...
ipadapter: waiting for multicast requests...
oc_main: Stack successfully initialized
client_oic: Configured network interfaces:Iface  5   HWaddr: a6:ab:89:bd:1f:80

           MTU:1500  HL:64  RTR  RTR_ADV
           Source address length: 6
           Link type: wired
           inet6 addr: ff02::1/128  scope: local [multicast]
           inet6 addr: fe80::a4ab:89ff:febd:1f80/64  scope: local
           inet6 addr: ff02::1:ffbd:1f80/128  scope: local [multicast]
           inet6 addr: ff02::2/128  scope: local [multicast]
           inet6 addr: ff02::1a/128  scope: local [multicast]
           inet6 addr: ff03::158/128  scope: global [multicast]

client_oic: continue discovery
Outgoing message to [ff03:0000:0000:0000:0000:0000:0000:0158]:5683
client_oic: continue discovery
...
ipadapter: got server request
Incoming message from [fe80:0000:0000:0000:241c:c8ff:fe14:3d79]:56789
ipadapter: waiting for server requests...
client_oic: Discovery done
client_oic: Ready...
LED_RED_ON

Once the resource is discovered, the client registers as an Observer of the resource and it switches on its LED as notification of Discovery Completed. From this point it will send a PUT request every second. Client Output:

client_oic: Sent PUT request
Outgoing message to [fe80:0000:0000:0000:241c:c8ff:fe14:3d79]:56789
ipadapter: got server request
Incoming message from [fe80:0000:0000:0000:241c:c8ff:fe14:3d79]:56789
ipadapter: waiting for server requests...
client_oic: PUT_light:
client_oic: PUT response OK
ipadapter: got server request
Incoming message from [fe80:0000:0000:0000:241c:c8ff:fe14:3d79]:56789
ipadapter: waiting for server requests...
client_oic: OBSERVE_light: key state, value 0

Server output:

Incoming message from [fe80:0000:0000:0000:a4ab:89ff:febd:1f80]:56789
ipadapter: waiting for server requests...
server_oic: PUT request
server_oic: key: state value: 0
server_oic: LED0 is OFF
LED_RED_OFF
Outgoing message to [fe80:0000:0000:0000:a4ab:89ff:febd:1f80]:56789
server_oic: GET request
server_oic: Light state 0
Outgoing message to [fe80:0000:0000:0000:a4ab:89ff:febd:1f80]:56789

TAPs interfaces can be easily deleted. Go to /dist/tools/tapsetup and type

$ sudo ./tapsetup -d

### Server and Client (Periodic PUT) - SAMR21-XPRO target Now, we reproduce the previous scenario using two SAMR21-XPRO nodes. Connect your nodes, go to /examples/iotivity-examples/server and check the list of USB-connected nodes by typing:

$ make list-ttys

The output will be similar to

/sys/bus/usb/devices/2-1.3: Atmel Corp. EDBG CMSIS-DAP serial: 'ATML2127031800001234', tty(s): ttyACM0
/sys/bus/usb/devices/2-1.4: Atmel Corp. EDBG CMSIS-DAP serial: 'ATML2127031800004321', tty(s): ttyACM1

We will use Serial Numbers in order to identify the designed node during the compilation phase. Now, we compile the server

$ make flash BOARD=samr21-xpro SERIAL=server_node_serial

then we open the serial connection

$ make term BOARD=samr21-xpro SERIAL=server_node_serial

The server starts and it is waiting for incoming requests. Now, open a new terminal window, go to /examples/iotivity-examples/client and type

$ make flash BOARD=samr21-xpro SERIAL=client_node_serial
$ make term BOARD=samr21-xpro SERIAL=client_node_serial

Client starts the discovery phase. Once it finds a resource (with ResourceType oic.r.light), it registers as an observer on the resource, then it switches on its LED and it finally starts with periodic PUT requests. The server LED will blink periodically. Client and Server terminal outputs are similar to the outputs in case of native target.

### Server and Client_Switch - SAMR21-XPRO target This deployment emulates a smart home scenario in which we have a SmartBulb (server) and a SmartSwitch (client_switch). It requires two SAMR21-XPRO nodes or similar. Connect your nodes, go to /examples/iotivity-examples/server and check the list of USB-connected nodes by typing:

$ make list-ttys

The output will be similar to

/sys/bus/usb/devices/2-1.3: Atmel Corp. EDBG CMSIS-DAP serial: 'ATML2127031800001234', tty(s): ttyACM0
/sys/bus/usb/devices/2-1.4: Atmel Corp. EDBG CMSIS-DAP serial: 'ATML2127031800004321', tty(s): ttyACM1

We will use Serial Numbers in order to identify the designed node during the compilation phase.

Now, we compile the server

$ make flash BOARD=samr21-xpro SERIAL=server_node_serial

then we open the serial connection

$ make term BOARD=samr21-xpro SERIAL=server_node_serial

The server starts and it is waiting for incoming requests.

Now, we open a new terminal window, go to /examples/iotivity-examples/client_switch and type

$ make flash BOARD=samr21-xpro SERIAL=client_node_serial
$ make term BOARD=samr21-xpro SERIAL=client_node_serial

Client performs the discovery phase. Once it is completed, client registers as an Observer of the resource, then it switches on its LED. Client is now ready to send a PUT request when the User Button is pressed. The server LED will change the status when the button is pressed. Terminal outputs are similar to outputs in previous examples.

##Linux-to-Nodes communications In this scenario, we will deploy an IoTivity server on a RIOT node and the IoTivity client will run on a Linux machine. This architecture requires the "enhanced" version of the Border Router BR_FW. It requires two SAMR21-XPRO nodes or similar.

###Preliminary step Connect your nodes, go to /examples/iotivity-examples/server and check the list of USB-connected nodes by typing:

$ make list-ttys

The output will be similar to

/sys/bus/usb/devices/2-1.3: Atmel Corp. EDBG CMSIS-DAP serial: 'ATML2127031800001234', tty(s): ttyACM0
/sys/bus/usb/devices/2-1.4: Atmel Corp. EDBG CMSIS-DAP serial: 'ATML2127031800004321', tty(s): ttyACM1

We will use Serial Numbers in order to identify the designed node during the compilation phase.

###Start the Server Open a terminal window, go to /examples/iotivity-examples/server and type

$ make flash BOARD=samr21-xpro SERIAL=server_node_serial

then we open the serial connection

$ make term BOARD=samr21-xpro SERIAL=server_node_serial

The server starts the initialization phase, then it is ready for incoming requests.

###Start the Border Router Step 1) Open a terminal window in /example/iotivity-examples/br_fw/ and type

$ make flash BOARD=samr21-xpro SERIAL=br_node_serial

Step 2) Once the flashing is finished, we have to open a network interface. Type

$  PORT=/dev/ttyACM0 make term

Step 3) We have to complete the routing strategy on the BR, so in the RIOT shell type

> ifconfig 7 add 2001:db8::2
> fibroute add :: via 2001:db8::1 dev 7

Now the BR is ready. The network is configured as follow:

  • Serial Port: /dev/ttyACM0
  • Interface: tap0
  • Address Prefix: 2001:db8::\64
  • Routing on tap0 of multicast packets with destination ff03::158

It is possible to configure the network with different parameters by invoking directly the initialization script instead of executing the Step 2:

$ make host-tools
$ sudo ./start_network_mcast.sh <serial-port> <tap-device> <IPv6-prefix> <IPv6-mcast>

then run the Step 3 with the proper changes.

We can check the reachability of the server by typing in another terminal window

$ ping6 <IPv6 server>

The IPv6 address of the server can be found by typing in the Border Router console:

> routers

The output will be similar to

if  Router                          state      type
---------------------------------------------------
 6  2001:db8::5859:1c2a:64c7:c48a   REACHABLE   REG

###Server Output Managing a GET request the output is like

2016-11-04 14:39:32,115 - INFO # ipadapter: got server request
2016-11-04 14:39:32,121 - INFO # Incoming message from [2001:0db8:0000:0000:0000:0000:0000:0001]:56214
2016-11-04 14:39:32,125 - INFO # ipadapter: waiting for server requests...
2016-11-04 14:39:32,128 - INFO # server_oic: GET request
2016-11-04 14:39:32,130 - INFO # server_oic: Light state 0
2016-11-04 14:39:32,145 - INFO # Outgoing message to [2001:0db8:0000:0000:0000:0000:0000:0001]:56214

Managing a PUT request the output is like

2016-11-04 14:39:35,119 - INFO # ipadapter: got server request
2016-11-04 14:39:35,125 - INFO # Incoming message from [2001:0db8:0000:0000:0000:0000:0000:0001]:56214
2016-11-04 14:39:35,128 - INFO # ipadapter: waiting for server requests...
2016-11-04 14:39:35,134 - INFO # server_oic: PUT request
2016-11-04 14:39:35,136 - INFO # server_oic: key: state value: 1
2016-11-04 14:39:35,138 - INFO # server_oic: LED0 is ON
2016-11-04 14:39:35,141 - INFO # Outgoing message to [2001:0db8:0000:0000:0000:0000:0000:0001]:56214

###Testing There are many different ways to test this scenario.

  • Tools: you can use coap-cbor-cli to perform get request. Put -c as argument.
  • Iotivity Client: you can write an iotivity client that runs on Linux. Here and Here there are some sample clients that can be used to test this scenario.

#Good Practice Discoveries and Requests are usually fast, but a timeout delay of some seconds on responses can be useful. In these examples, delays are set to 1 second for discoveries and they can be increased. For requests coming from a linux-based client, timeout delays should be higher (e.g. 5-10 seconds for discoveries and 3 seconds for requests). They can be tuned depending on the application. The minimum value is around 1 second.