The figure above shows the Stack4Things overall architecture, focusing on communication between end users and sensor- and actuator-hosting nodes.
We assume each of such nodes is a modern smart board, equipped with (low power) micro-processor (MPU) and micro-controller (MCU) units, like the Arduino YUN.
On the board side, the Stack4Things lightning-rod runs on the MPU and interacts with the OS tools and services of the board, and with sensing and actuation resources through I/O pins.
It represents the point of contact with the Cloud infrastructure allowing the end users to manage the board resources even if they are behind a NAT or a strict firewall.
This is ensured by a WAMP and WebSocket-based communication between the Stack4Things lightning-rod and its Cloud counterpart, namely the Stack4Things IoTronic service.
The Stack4Things IoTronic service is implemented as an OpenStack service providing end users with the possibility to manage one or more smart boards, remotely.
This can happen both via a command-line based client, namely Stack4Things command line client, and a Web browser though a set of REST APIs provided by the Stack4Things IoTronic service.
The figure above shows the Stack4Things architecture with more focus on the board side.
We assume that a minimal OS, such as BaTHOS, runs on the MCU while a Linux distribution for embedded systems (like OpenWRT) runs on the MPU.
BaTHOS is equipped with a set of extensions (from now on indicated as MCUIO extensions) that expose the board digital/analog I/O pins to the Linux kernel. The communication is carried out over a serial bus.
The Linux kernel running on the MPU is compiled with built-in host-side MCUIO modules.
In particular, functionalities provided by the MCUIO kernel modules include enumeration of the pins and exporting corresponding handlers for I/O in the form of i-nodes of the Linux sysfs virtual filesystem.
Upwards the sysfs abstraction, which is compliant with common assumptions on UNIX-like filesystems, there is the need to mediate access by means of a set of MCUIO-inspired libraries, namely Stack4Things MCUIO sysfs libraries.
Such libraries represent the interface with respect to the MCUIO sysfs filesystem dealing with read and write requests in terms of concurrency.
This is done at the right level of semantic abstraction, i.e., locking and releasing resources according to bookings and in a way that is dependent upon requirements deriving from the typical behavior of general purpose I/O pins and other requirements that are specific to the sensing and actuating resources.
The Stack4Things lightning-rod engine represents the core of the board-side software architecture.
The engine interacts with the Cloud by connecting to a specific WAMP router (see also figure below) through a WebSocket full-duplex channel, sending and receiving data to/from the Cloud and executing commands provided by the users via the Cloud.
Such commands can be related to the communication with the board digital/analog I/O pins and thus with the connected sensing and actuation resources (through the Stack4Things MCUIO sysfs library) and to the interactions with OS tools and/or resources (e.g., filesystem, services and daemons, package manager).
The communication with the Cloud is assured by a set of libraries implementing the client-side functionalities of the WAMP protocol (Stack4Things WAMP libraries). Moreover, a set of WebSocket libraries (Stack4Things wstunnel libraries) allows the engine to act as a WebSocket reverse tunneling server, connecting to a specific WebSocket server running in the Cloud.
This allows internal services to be directly accessed by external users through the WebSocket tunnel whose incoming traffic is automatically forwarded to the internal daemon (e.g., SSH, HTTP, Telnet) under consideration. Outgoing traffic is redirected to the WebSocket tunnel and eventually reaches the end user that connects to the WebSocket server running in the Cloud in order to interact with the board service.
The Stack4Things lightning-rod engine also implements a plugin loader. Custom plugins can be injected from the Cloud and run on top of the plugin loader in order to implement specific user-defined commands, possibly including system-level interactions, such as, e.g., with a package manager and/or the init/runlevels subsystem.
New REST resources are automatically created exposing the user-defined commands on the Cloud side. As soon as such resources are invoked the corresponding code is executed on top of the smart board.
The Stack4Things Cloud-side architecture consists of an OpenStack service we called IoTronic. The main goals of IoTronic lie in extending the OpenStack architecture towards the management of sensing and actuation resources, i.e., to be an implementation of the SAaaS paradigm. IoTronic is characterized by the standard architecture of an OpenStack service.
The Stack4Things IoTronic conductor represents the core of the service, managing the Stack4Things IoTronic database that stores all the necessary information, e.g., board-unique identifiers, association with users and tenants, board properties and hardware/software characteristics as well as dispatching remote procedure calls among other components.
The Stack4Things IoTronic APIs exposes a REST interface for the end users that may interact with the service both via a custom client (Stack4Things IoTronic command line client) and via a Web browser.
In fact, the OpenStack Horizon dashboard has been enhanced with a Stack4Things dashboard exposing all the functionalities provided by the Stack4Things IoTronic service and other software components. In particular, the dashboard also deals with the access to board-internal services, redirecting the user to the Stack4Things IoTronic WS tunnel agent.
This piece of software is a wrapper and a controller for the WebSocket server to which the boards connect through the use of Stack4Things wstunnel libraries.
Similarly, the Stack4Things IoTronic WAMP agent controls the WAMP router and acts as a bridge between other components and the boards. It translates Advanced Message Queuing Protocol (AMQP) messages into WAMP messages and vice-versa. AMQP is an open standard application layer protocol for message-oriented middleware, a bus featuring message orientation, queueing, routing (including point-to-point and publish-subscribe), reliability and security. Following the standard OpenStack philosophy all the communication among the IoTronic components is performed over the network via an AMQP queue.
This allows the whole architecture to be as scalable as possible given that all the components can be deployed on different machines without affecting the service functionalities, as well as the fact that more than one Stack4Things IoTronic WS tunnel agent and more than one Stack4Things IoTronic WAMP agent can be instantiated, each of them dealing with a sub-set of the IoT devices.
In this way, redundancy and high availability are also guaranteed.
A prominent reason for choosing WAMP as the protocol for node-related interactions, apart from possibly leaner implementations and smoother porting, lies in WAMP being a WebSocket subprotocol and supporting two application messaging patterns, Publish/Subscribe and Remote Procedure Calls, the latter being not available in AMQP.