Skip to content

Ioto Architecture

The Ioto device agent is a compact management agent and library. It provides AWS IoT cloud integration, HTTP web server, MQTT client, HTTP client, state persistency, provisioning and OTA upgrading.

Ioto is fast and compact, with a tiny memory footprint of only 130K of code.

Ioto Agent Architecture

Goals

Embedded agents for managing devices have several competing goals:

  • Provide a strong and standard management feature set
  • Minimize memory footprint
  • Minimize CPU consumption
  • Maximize security

To meet all these goals in one agent is difficult, but Ioto utilizes a safe runtime. This maximizes code reuse and security, allowing management services to be coded as simply and efficiently as possible.

Processing Architecture

Ioto is based on an event-driven, single-threaded fibre coroutine core. It uses a non-blocking, event-driven architecture and is capable of running many inbound and outbound requests simultaneously with minimal CPU and memory resources.

Ioto eliminates the ugliness of event callbacks and the complexity of threads by using fiber coroutines. A fiber coroutine is a segment of code that runs with its own stack and cooperatively yields to other fibers when it needs to wait. You can think of a fiber as a thread, but only one fiber runs at a time. For Go programmers, fibers are like Go routines. For JavaScript developers, fibers are similar to async/await.

Ioto fibers are baked into the I/O system so you can easily support parallelism by overlapping requests without any effort. You can read and write sockets, issue HTTP client requests or respond to web server requests using a straight-line procedural programming model.

Core Components

Ioto has a modular architecture where modules can be conditionally compiled as required to minimize your memory and security footprint.

The key components of Ioto are:

Component Description
Embedded Web Server Embedded web server supporting HTTP/1.1, TLS 1.3, C action functions, file upload, transfer-encoding, user management, sessions and cookies, authentication, sandbox limits.
MQTT 3.1.1 Client Supports publish, subscribe, ping and disconnect messages. Includes retained message support and connect over port 443 via ALPN.
AWS Iot Integration AWS Iot cloud ready with data export to IoT shadows, S3, CloudWatch logs, CloudWatch metrics, Kinesis for streaming and DynamoDB for structured device data.
Transport Layer Security (TLS/SSL) Secure Socket Layer protocol stack. This is a virtual interface that can selectively support a variety of TLS providers including: the MbedTLS and OpenSSL stacks.
JSON JSON and JSON 5/6 parser. This module includes JSON persistency to files and a powerful JSON query engine.
Safe Portable Runtime Cross-platform safe portable runtime. Includes services for memory allocation, buffer management, safe string handling, lists, hashing, sockets, events, timers, logging and fiber coroutines.

Integration Models

Ioto can be integrated into your system in two ways:

  • As a stand-alone device agent program
  • Embedded in your applications and devices

Stand-Alone Agent

The simplest integration is by modifying the standard build. The Ioto distribution builds a stand-alone agent program that can be run to provide management services. The agent is built with a stub extend.c file that you can customize to include your code and then rebuild Ioto.

It is best not to modify other Ioto source files as that can make upgrading to future versions more difficult.

Embedded in Applications and Devices

The other way to integrate Ioto is to create your own main program and link with the Ioto library.

The Ioto distribution builds library called libioto.a that you can link with your application. In this manner, your app becomes empowered with MQTT, HTTP and AWS integration services.

The simple embedding API requires only a few lines of code. See the Embed Sample for an example.

This method is desirable if you have more extensive customizations and processing models.

Ioto Configuration

Ioto uses a set of JSON configuration files to control execution. These configuration files are read when Ioto starts.

The configuration files use a relaxed JSON format called JSON/5. This format is similar to the JavaScript object literal notation. Specifically, it supports: comments, keys without quotes, trailing commas and multiline strings.

The configuration files are:

File Description
auth.json5 Authentication configuration for the web server. Includes defined roles, users and passwords.
config.json5 Primary Ioto configuration file. Configures enabled services, logging and log file ingestion

| provision.json5 | Device and cloud provisioning configuration. | | shadow.json5 | Local copy of the AWS IoT shadow state. | | web.json5 | Web server configuration file. |

Ioto HTTP Web Server

The Ioto web server is a fast, compact web server designed for management web applications and serving device data.

Management applications are best created using Single Page Application design techniques where the application is rendered locally in the browser and it requests pure-data from the device to populate dynamic content.

Ioto is ideal for this approach. It includes an integrated JSON parser, query engine and persistency to enable it to respond to HTTP requests with JSON payloads and remit responses in JSON.

Ioto does not provide a web framework — nor do we believe this is the best approach for performing remote device management.

Ioto includes a fully working sample single page application called Kickstart. This is a VueJS application that serves a sample device application from Ioto.

The core web services include:

  • HTTP/1.1 protocol engine
  • Non-blocking socket communications
  • TLS (SSL) 1.3 support
  • Multiple listen endpoints
  • Flexible configuration via the web.json file
  • Session and cookie management
  • Authentication and User management
  • Serve static files
  • Binding URLs to C functions for dynamic content rendering.

The Ioto web server is exceptionally fast and will serve over 3K requests per second on a modest Raspberry PI 4 and yet runs using only 80K of code.

Web Server Security

Ioto provides a suite of measures designed to increase the security of the Ioto web server:

  • TLS — Secure Sockets Layer
  • Sandbox limits directives
  • Authorization directives
  • Safe, secure portable runtime
  • Simple fiber coroutine programming paradigm

TLS

Ioto supports the MbedTLS and OpenSSL stacks. You can configure server and/or client certificate-based authentication.

Sandbox Limits

Sandboxing is the term applied to running Ioto in a confined environment. Ioto has a set of web server configuration file directives that allow you to define a sandbox, which limits the resources that Ioto may use for a given request. By using well defined sandbox directives, you can help ensure that your application and system will not be compromised by malicious requests.

Ioto can be configured to:

  • Reject requests that are too large
  • Reject URLs that are too long
  • Reject Headers that are too big
  • Be run by a designated user account or user group
  • Limit the number of connections and sessions

Safe Portable Runtime (R)

Ioto is built upon a portable runtime layer called the Safe Portable Runtime or "runtime" for short. This layer insulates the rest of the product from the underlying platform and allows it to be highly portable to new operating systems or hardware.

The runtime permits the rest of the Ioto code to be portable and safe by using the safe primitives offered by the runtime. It includes many mechanisms to assist in the creation of secure applications. One such facility is a safe string and buffer handling module to help eliminate the buffer overflows that have plagued many products.

The runtime provides a suite of services that facilitate the creation of high performance management applications, including: buffer management, networking, safe string handling, events, wait management, logging, lists and hashing.

The runtime can be easily integrated into existing applications. It supports a simple integration API and can be included in single or multi-threaded architectures with polled or async event notifications.