---
tags: BlogPost
---
# An overview from an outcomer
## Me and IoT
I finally started my long journey into the world of Web of Things. I have
been interested to the topic in the past, but unfortunately this technology
still needs some time to get traction from the industry, and from a user
standpoint this is the main reason to stay away from the _smart
electronics_ world. Ok ok, this could seem a bit _harsh_, just let me
explain.
Internet of Things (IoT) is a very fascinating field, until you realize
that everyone is building its own infrastructure, with its own protocols,
proprietary firmware blobs and servers. It is pretty easy to find examples,
in the last few decades, of [discovered in closed or unmaintained pieces
software](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-26567),
[services
shutdown](https://www.theregister.com/2022/04/22/insteon_shutdown_explained/)
and [privacy data
leaks](https://www.wired.co.uk/article/google-home-chromecast-location-security-data-privacy-leak).
Personally, I do not like the idea that I subscribed to some kind of online
service and, at some point, one of the things I just mentioned happens to
that service:
- If it stops working, I just _lost_ my _useful_ service. If I paid for
that, this is much worse.
- If it uses proprietary closed source code, I can just _hope_ that no one
found a zero-day vulnerability in order to gain access to their data and,
as a consequence, to _my_ data.
- If the service is unmaintained, take the two previous points and make
them even more plausible, because if no one is actively watching, who
knows what could happen.
This point of view unfortunately can be applied to most of the services out
there, and we can accept the risk for the benefits of the various services
available. _I_ can accept it without too much trouble.
However, if you take everything I said and you consider these sort of risks
for your lamps, your fridge, your oven and, badly enough, for the gate of
your house, I do not know what other people think but I _surely_ cannot
accept it. I already have got _working_ lamps, I cannot trade the
convenience of remotely control them with my smartphone with the
uncertainty that some bad actors could be able to do the same. And, even
worse, to collect some personal information about me, my house and my
family.
But now I am able to work on Web of Things, and I want to help improving
the technology around smart devices.
## Enter Web of Things
Web of Things (WoT) is a [set of
standards](https://www.w3.org/WoT/documentation/#further-reading) aimed to
give a common way to implement smart devices to the industry. This is
extremely beneficial for both users and companies, because there is no need
to reinvent the wheel (how should expose the devices API? Which protocols
are better for the purpose?) and, at the same time, you automatically gain a
compatibility layer with all the WoT technology already available. Let me
show you why.
The central concept for WoT is, as you could have expected, the _Thing_.
This is
> an abstraction of a physical or virtual entity that provides interactions
> to and participates in the Web of Things.[^1]
This is a one-to-one relationship to the electrical devices I mentioned
previously (i.e.: a lamp, an oven, a fridge) and, interestingly enough,
to eventual _virtual_ devices.
The very interesting concept behind a _Thing_ is that it is self-describing
in a standard way, both human and machine readable. Here an example taken
from the _WoT Thing Description_ standard:
``` json
{
"@context": [
"https://www.w3.org/2019/wot/td/v1",
{
"cov": "http://www.example.org/coap-binding#"
}
],
"id": "urn:dev:ops:32473-WoTLamp-1234",
"title": "MyLampThing",
"description" : "MyLampThing uses JSON serialization",
"securityDefinitions": {"psk_sc":{"scheme": "psk"}},
"security": ["psk_sc"],
"properties": {
"status": {
"description" : "Shows the current status of the lamp",
"type": "string",
"forms": [{
"op": "readproperty",
"href": "coaps://mylamp.example.com/status",
"cov:methodName" : "GET"
}]
}
},
"actions": {
"toggle": {
"description" : "Turn on or off the lamp",
"forms": [{
"href": "coaps://mylamp.example.com/toggle",
"cov:methodName" : "POST"
}]
}
},
"events": {
"overheating": {
"description" : "Lamp reaches a critical temperature (overheating)",
"data": {"type": "string"},
"forms": [{
"href": "coaps://mylamp.example.com/oh",
"cov:methodName" : "GET",
"subprotocol" : "cov:observe"
}]
}
}
}
```
This is a plausible response from a smart lamp with a limited set of
functionalities, expressed using a
[JSON-LD](https://www.w3.org/TR/json-ld11/) format. From the code it is
easy to recognise the following:
- The _Thing_ has a unique identifier and it replies with a human-readable
description;
- there is an explicit way of establishing a secure connection to the
device (`security*` fields);
- the properties are explicitly enumerated with the information to query or
to set the actual value;
- the ways to actively interact with the devices are enumerated in the
`actions` field;
- it is possible to subscribe to events generated by the _Thing_, and these
are enumerated as well;
- everything is described following the specs given by the `@context`
field, which always includes the _Thing Description_ and, in this
example, an auxiliary _vocabulary_ context to expose the APIs through the
COAP protocol.
This approach highlights two major characteristics:
1. The _Thing_ has an incredible expressiveness power in terms of both
capabilities and expandability. The basic vocabulary is probably enough for
most of the common use cases, and at the same time it is possible to expand
the possibilities using arbitrary [_context
extensions_](https://www.w3.org/TR/wot-thing-description/#sec-context-extensions)
based on a standard schema[^2].
2. The complexity of this expressiveness is not reflected on the device,
but on hypothetical third-party software that aims to support a big amount
of device types and protocols.
Comparing this situation with the issues of the IoT, we already see that
this approach is a huge improvement, because all the problems related to
_closed protocols_ suddenly disappear. In fact, thanks to the _Thing
Description_ standard, you could easily choose different implementations to
handle all your smart devices, without being tied to the software created
by a specific producer for a specific set of smart devices. Moreover, this
means that it is easier for WoT devices to interact one each other using
[links](https://www.w3.org/TR/wot-thing-description/#link).
As already said, the _Thing_ is not burdened from the complexity[^3] of the
protocol, which means that risks related to software issues can be heavily
mitigated. However, this is not enough in order to have a sane WoT
ecosystem, and this is why at Sifis we are developing the fundamental
pieces to empower everyone to build safe and secure WoT software.
## Enter Rust
Rust is a system programming language with a strong typing system, a
minimal runtime and zero cost abstractions. This is the perfect fit in
order to create an abstraction layer to safely build software for the WoT.
Indeed, we are developing a crate (a sort of _Rust library_) that can be
used to describe the characteristics of a _Thing_, taking advantage of the
type system in order to catch lots of common issues at compile-time and
to _make impossible states impossible_[^4]. I want to imagine that it will
be possible to write something like the following:
```rust
/// MyLampThing
///
/// MyLampThing uses JSON serialization
#[derive(WebThing)]
#[webthing(
contexts = {
cov = "http://www.example.org/coap-binding#"
},
id = "urn:dev:ops:32473-WoTLamp-1234",
security = Security::Psk(security::Psk::default()),
actions = [
ToggleAction,
],
events = [
OverHeatingEvent,
]
)]
struct MyLampThing {
/// Shows the current status of the lamp
#[webthing(
forms = [{
op = readproperty,
href = "coaps://mylamp.example.com/status",
cov:methodName = "GET"
}]
)]
status: String
}
/// Turn on or off the lamp
#[derive(WebThingAction)]
#[webthing(
forms: [{
href: "coaps://mylamp.example.com/toggle",
cov:methodName : "POST"
}]
)]
struct ToggleAction;
/// Lamp reaches a critical temperature (overheating)
#[derive(WebThingEvent)]
#[webthing(
forms: [{
href = "coaps://mylamp.example.com/oh",
cov:methodName = "GET",
subprotocol = "cov:observe"
}]
)]
struct OverHeatingEvent(String)
```
For people not familiar with Rust, this code declares three data structures
with some _metadata_ information that can be evaluated at compile-time in
order to automatically generate code to extend the behavior of the _structs_.
This is just my idea of how things should look like, therefore it should be
taken with a grain of salt. In any case, the main concept I want to express
with this code is that writing _Things_ needs to be easy in order to have
compile time guarantees and, at the same time, to push toward the growth of
the ecosystem. Another important point is that we would like to give the
basic building blocks to the developers, without tying to a specific Web
framework in order to expose the APIs.
Needless to say, reaching this goal is totally not trivial, there is _a
lot_ to consider and to take into account in order to make things work as
intended. For instance, performing compile-time checks for the `cov`
namespace involves downloading, parsing of RDF files and performing codegen
in a way that independent _structs_ can _see_ properties like `methodName`.
### ...and more
It is important to create a solid working ground for Rust
developers, but there are a lot of companies that would rather use other
languages, like C or Python. Rust is extremely convenient for the
interoperability with other languages, because of its support to Foreign
Function Interfaces (FFI), code generation through procedural macros and
third-party tools from the ecosystem. With all of this, it is possible to
create different set of APIs for different languages, using, for instance,
[`cbindgen`](https://github.com/eqrion/cbindgen) to expose C functions and
[`PyO3`](https://github.com/PyO3/pyo3) to create a Python extension module, with [`cargo-c`](https://github.com/lu-zero/cargo-c) and [`maturin`](https://github.com/PyO3/maturin) to fully streamline the experience.
Obviously, we cannot leverage compile-time checks in these cases, simply
because when the Rust library is used from a different language the
compilation step is already done. This only implies that all the many
coherence checks are performed at runtime, which means that even in this
case all the concerns about security and privacy are still addressed. The
biggest change is perceived by the developers, which need to carefully
check that their usage of the high-level library does not return an error
at runtime. This is an acceptable compromise in order to make the _Web of
Things_ ecosystem grow in many directions and in many programming
languages.
Thanks for taking the time to read my vision. I will help Sifis to make it
real, because we deserve a more secure, reliable and resilient technology
for smart electronics. In the next few years, I would like to buy some
smart lamps for my family without any worries, let's make it real.
[^1]: https://www.w3.org/TR/wot-thing-description
[^2]: https://www.w3.org/TR/rdf-schema/
[^3]: The _complex_ term is used with its precise meaning. Saying that
something is _complex_ does mean that there are multiple level of
concepts that need to be understood in order to have a complete
overview.
[^4]: This concept is expressed in [a
talk](https://www.youtube.com/watch?v=VU1NKX6Qkxc) by David Khourshid
and it is often used [in
Elm](https://sporto.github.io/elm-patterns/basic/impossible-states.html).
The concept can (and probably should) be applied in all static typed
language that are able to express this kind of constraints. Obviously,
the idea can be used in Rust.