Ring-of-Things

Purpose

The purpose of the Ring-Of-Things is to use the openwsn firmware stack and the CoAP library to implement a simple demo where a 'ringmaster' (in this case a local python client), instructs motes via CoAP packet communication to do simple actions like blink or buzz.

Powerpoint of initial design: https://docs.google.com/presentation/d/1atlBdYjgV6HwVyvTbz42K-ek7jkmLHYt7oatlnUHvk0

Design

A CoAP app must be added to the firmware, called 'rrt', to allow for the ringmaster to send and receive CoAP packets to the resource.  A tutorial for adding a CoAP app is described here: Adding a CoAP app

This app needs to have several functionalities:

  • notify the ringmaster of a mote's availability (when it goes 'online')
  • ability for a mote to wait for an incoming packet from the ringmaster
  • checking for a message type upon reception, and knowing whether to 'blink', 'buzz', perform another simple action, or forward an action to another mote (identified via ipv6)
  • ability to send a CoAP packet from itself to another mote (with some data)

The ringmaster needs to:

  • send packets to motes via the coap library
  • wait on incoming packets
  • keep track of all motes that are in its ring (in this case with a simple queue) and send instructions in a rotation
  • handle error handling - motes dropping off unexpectedly, packet loss, receiving unexpected packets

Code - firmware

The firmware code is the main addition (openwsn-fw), which runs on the motes.

Here is the firmware pull request: https://github.com/openwsn-berkeley/openwsn-fw/pull/128/

File ChangedDescription
bsp/boards/python/openwsnmodule_obj.hadd rrt_vars_t struct to python OpenMote struct
inc/opendefs.hadd ringmaster port constant on which to listen to and send ring master packets
openapps/SConscriptadd rrt as part of the default apps to be built with SCons
openapps/openapps.c add rrt_init(), the initialization function for rrt resource
openapps/rrt/rrt.cadd rrt resource to openapps, with the code for handling all mote actions.  A GET action sends confirmation to the ringmaster, a POST action accepts payloads and determines what to do next (forward, perform action, or nothing), and a DELETE (which unregisters a mote).  rrt.c also defines a function sendCoAPMsg, which sends a char to either an address or a hardcoded ringmaster address
openapps/rrt/rrt.hdefine function signatures to be used outside of rrt.c, as well as the rrt_vars_t struct
openapps/rrt/rrt.pysimple python program for testing python coap library functionality - no purpose other than coap library experimentation
openstack/04-TRAN/opencoap.hhardcoded ringmaster address added here 
openstack/04-TRAN/openudp.cadd switch blocks for the ringmaster port in openudp_receive and openudp_sendDone
openstack/SConscriptadd proper path for rrt folder
projects/python/SConscript.envadd proper constants to get the proper objectification


Code - ringmaster.py

Here is the repo: https://github.com/openwsn-berkeley/ringmaster

To run the client, simply execute 

python ringmaster.py

This will open up communication with OpenWSN motes on default port 15000.

This script maintains a stack (array) of registered motes that have sent a discovery packet to it.  It maintains a pointer which rotates through the stack.

Analysis

Here is a screenshot of wireshark whilst the ringmaster and simulator is running at some point in time

 

Notice some interesting packets:

packet #13 - A CoAP packet is captured from the localhost to mote bbbb::1415:92cc:0:2 (mote 2 in simulation).  This is the packet that is sent when sending a GET request to the 'rt' resource of mote 2 through Firefox Copper (CoAP Interaction#CoAPdiscovery).  In the context of ringmaster, this triggers the mote to be online

packet #17 - a UDP packet headed for localhost from mote 2.  This packet has the simple message 'D' in its payload, representing Discovery. Notice the Source port is 5683, the default port for COAP communication, while the destination is 15000, the hardcoded port I chose for the ringmaster to listen on.

packet #22 - A CoAP PUT packet telling the mote that it has been confirmed as registered by the ringmaster

packet #28 - ringmaster tells packet 2 to perform action 'B' - in this case, blink

 

Here is a simple ringmaster output, as of this writing:

The output here is fairly arbitrarily, used just for demonstration purposes.  First, the ringmaster is started, where it waits for incoming messages.  At some point, it received a discovery message from mote 2, after which it sends a confirmation message via CoAP PUT. Then, it sends an action B to the same mote, as it now has a mote queue to work with.  When the mote blinks, it notifies the ringmaster.  Seeing as there is only one mote in the queue at the time, the ringmaster tells mote 2 to forward an action to another ipv6, which in this case is the same one.  Only after mote 3 gets registered can we start seeing oscillation between the two motes performing actions.