The birth of tosca
The tosca framework has finally come to light! 🎉🎉
Originally designed as an IoT architecture to make device command risks
transparent to users, tosca has, over the past two years, evolved into a
customizable, self-contained framework.
By customizable, we mean that the framework can easily adapt to any existent
firmware without changing the internal implementation of device commands.
The framework APIs only expose commands to external software, optionally
hiding some parameters or adding metadata.
To achieve this, an HTTP route must be defined for each command.
During firmware startup, tosca aggregates all route information into a
single file representing the device description, which is then made available on
the network through an HTTP server.
To interact with tosca-compliant devices, a software application must
integrate the tosca controller component .
This component first discovers devices on the network, then retrieves their
description files through a REST request and maps the data into its
internal structures.
Eventually, developers can use the controller APIs to configure device command
parameters and then send these commands as REST requests.
A controller also provides APIs to allow or block requests to devices based on
privacy rules defined from the risks associated with each command.
By self-contained, we mean that the framework operates as an independent system, minimizing reliance on external resources. One of its key features is the ability to establish communication between the firmware and its controller using only built-in functionalities.
Main Features
- Designed for IoT applications: from home automation to industrial processes, including devices for social purposes, such as those assisting people with disabilities and older adults.
- Firmware APIs: for building firmware components, including device descriptors, discovery protocols, and server configurations.
- Controller APIs: for discovering devices on a network, executing their commands, and managing their hazards information.
- Command Hazards: labels attached to device commands to alert users of potential safety, privacy, and financial hazards during execution.
- Safe programming with Rust: memory and thread safety guarantees, preventing many classes of bugs at compile time.
Still Missing Features
- Secure communication: ensure confidentiality, integrity, and authentication between firmware devices and controllers.
- Bluetooth stack integration: enable wireless connectivity and communication with devices.
- Accurate energy and performance metrics: provide primitives for precise on-device monitoring and performance analysis.
- Support for additional microcontroller architectures: expand hardware compatibility and improve portability.
- Command scheduling system: allow controllers to execute device commands at specific times or according to predefined schedules.
- Over-the-Air (OTA) updates: enable reliable remote firmware upgrades.
Technical aspects
- Code Refactoring: remove duplicated code, clarify the intent of some APIs, and eliminate ambiguous logic between devices and controllers.
- Reduced heap allocations on firmware devices: improve memory efficiency for resource-constrained environments
- Performance Optimizations: reduce the number of instructions in critical methods, leverage more efficient hardware instructions, and minimize reliance on external crates whenever possible.
Framework Structure
The framework is centered around the tosca interface, which serves as a bridge
between the two different sides of the framework.
The first side is the Firmware Side, which provides APIs for developing
firmware and drivers for sensors.
The second side is the Controller Side, which provides APIs for interacting
with devices built using the tosca framework.
The tosca
interface is the core component of the framework. It is used by both the
firmware and controller side APIs to provide a uniform set of definitions.
It can:
-
Create and manage REST routes that issue commands from a controller to a device. Each route can specify parameters to configure the corresponding device command and returns a single response type.
Ok: indicates that the command was successfully executed on the device.Serial: returns additional data related to device operation.Info: provides metadata and other details about the device.Stream(optional feature): delivers chunks of multimedia data as byte streams. The sending of responses is implemented differently in each supported firmware-side crate, while their reception in the controller remains consistent.
-
Provide a description of a device, including its internal data, available methods, and information about its economic and energy consumption.
-
Associate hazards with a route. As mentioned earlier, hazards are categorized into three types:
- Safety hazards refer to potential risks to human life.
- Financial hazards concern the economic impact of the device and its commands.
- Privacy hazards relate to issues involving the handling and management of sensitive data.
Firmware Side
The firmware side provides the APIs required to develop a tosca-compliant
firmware device. These APIs are split into two library crates according to the
target hardware architecture:
The APIs are largely equivalent across the two crates, and both integrate the
tosca crate to maintain a common interface between firmware and controller
components.
The tosca-os library crate is designed for firmware running
on operating systems.
It offers APIs to:
- Define routes for commands, including support for
Streamresponses, which can be enabled via a feature. - Encapsulate commands in functions invoked by the server when a route is called.
- Configure the mDNS-SD discovery service.
- Initialize and run an HTTP server.
Using these APIs, we have implemented firmware for a smart light and an IP camera.
Instead, the tosca-esp32c3 library crate is designed for building firmware
that runs on ESP32-C3 microcontrollers.
It provides APIs to:
- Connect a device to a Wi-Fi access point.
- Build and configure the network stack.
- Define routes for commands.
Streamresponses are not supported. - Encapsulate commands in functions invoked by the server when a route is called.
- Configure the mDNS-SD discovery service.
- Declare events for specific route tasks.
- Initialize and run an HTTP server.
To showcase the capabilities of these APIs, we developed several light firmware examples that progressively increase in complexity.
Finally, we developed a library crate that provides architecture-agnostic
implementations for sensors without dedicated drivers:
tosca-drivers.
While more complex sensor drivers can be imported directly into
firmware, the goal of this library is to provide simple, reusable modules that
can be shared across all tosca architectures.
Controller Side
The controller side provides the APIs needed to build software capable of
interacting with all tosca-compliant firmware devices on the same network.
To use these APIs, a controller application must simply include the
tosca-controller
library crate as a dependency.
The core functionalities of this crate include:
- Discovering devices: automatically discovering all
tosca-compliant firmware devices available on the network. - Issuing device commands: from a device’s description, constructing the corresponding REST requests and sending them over the network to invoke the device's commands.
- Enforcing security and privacy policies: define policies to allow or block requests for commands that have determined hazards.
- Subscribing to device events broker: intercepting events published by a device to its broker. These events represent the internal state of the device. The controller subscribes to the broker using the IP address or URL specified in the relevant field of the device description.
Conclusions & Future Plans
tosca represents a new approach to connecting firmware devices with a
controller. It leverages cutting-edge technologies to build components that
are reliable and less error-prone.
One of the framework’s main features is the provision of clear and easily
understandable APIs that guide developers in building the crates of their
IoT systems. These APIs are designed to resemble natural language as closely as
possible, making them intuitive and easy to use.
As future work, we plan to release the 0.2 version of the framework with the
following improvements:
- Contract-based
toscacrate: extend thetoscalibrary crate so that it serves as a shared contract between a firmware binary crate and a controller binary crate. In this way, developers do not need to modify the framework to change hard-coded values or introduce additional interfaces. Instead, they can rely on a minimal shared interface. - Support for dynamic device behavior: devices may join or
leave the network at any time. The
tosca-controllershould be able to reliably detect these changes and provide mechanisms to register and manage the behaviors of connected devices. - Secure communication: implement secure communication between firmware devices and controllers. Currently, no security mechanisms exist, and all exchanged messages are transmitted in plaintext, making the infrastructure vulnerable.
- API unification across device crates: uniform the APIs of the
tosca-osandtosca-esp32c3crates. Currently, some features are implemented only for specific targets. For example, the event manager exists intosca-esp32c3but not intosca-os.
Acknowledgments
Along the journey to the first release of tosca, I have not been alone.
I would like to sincerely thank:
- @alexle0nte: for contributing to the development of numerous features over the past year and for his invaluable advice.
- @giusbianco: for his continuous support and for helping me in shaping the framework’s design during the early stages of development.
Thank you, guys!