Skip to content

Embedding Ioto

Ioto is provided as a static library that you link into your own application. This lets you add IoT connectivity, an embedded web server, MQTT, database and other services to your product with minimal effort.

There are two ways to integrate Ioto:

  1. Use your own main — Create your own main() and link with the Ioto library. Best when you need full control over startup, or when integrating with an RTOS like FreeRTOS.
  2. Use the Ioto main — Provide ioStart and ioStop functions that Ioto calls during startup and shutdown. Simpler if you are running on a generic Linux or macOS system.

Project Structure

A typical application that embeds Ioto has this directory layout:

myapp/
├── src/                    # Your application source code
├── Makefile                # Your build file
├── ioto/                   # Extracted Ioto source distribution
│   ├── include/            # Ioto headers (ioto.h and dependencies)
│   ├── build/
│   │   └── bin/            # Built library and tools
│   │       └── libioto.a   # Static library (Linux/macOS)
│   └── ...
└── state/
    └── config/             # Runtime configuration files
        ├── ioto.json5      # Main Ioto configuration
        ├── device.json5    # Device identification
        └── web.json5       # Web server config (if web enabled)

The key directories are:

  • ioto/include/ — Contains ioto.h and all dependent headers. Include this path when compiling.
  • ioto/build/bin/ — Contains the built libioto.a static library (or ioto.lib on Windows) and utility tools.
  • state/config/ — Contains the runtime configuration files that Ioto reads at startup. The state/ directory is also used at runtime for certificates, database files and logs.

Building the Ioto Library

Extract the Ioto source distribution and build:

bash
tar xf ioto-VERSION.tar.gz
mv ioto-* ioto
make -C ioto

This builds the Ioto static library and utility tools in ioto/build/bin/. The primary build outputs are:

FileDescription
ioto/build/bin/libioto.aStatic library (Linux/macOS)
ioto/build/bin/ioto.libStatic library (Windows)
ioto/include/ioto.hMain include header

For detailed build options including Windows, ESP32 and cross-compilation, see Building Ioto.

Configuring Services

Before building the Ioto library, you can enable or disable services by editing ioto/include/config.h. Each service is controlled by a SERVICES_* define. Set to 1 to enable or 0 to disable.

The primary services are:

DefineDescription
SERVICES_AIAI / OpenAI integration
SERVICES_DATABASEEmbedded database
SERVICES_MQTTMQTT protocol client
SERVICES_URLHTTP client requests
SERVICES_WEBEmbedded web server

Other services include: SERVICES_CLOUD, SERVICES_KEYS, SERVICES_LOGS, SERVICES_PROVISION, SERVICES_REGISTER, SERVICES_SHADOW, SERVICES_SYNC, and SERVICES_UPDATE.

Some services have dependencies. For example, SERVICES_SYNC requires SERVICES_DATABASE and SERVICES_MQTT. The ioto.h header will automatically enable required dependent services.

After modifying config.h, rebuild the library:

bash
make -C ioto clean
make -C ioto

Configuration Files

Your application must provide a state/config/ directory containing the Ioto runtime configuration files. Ioto reads these files at startup.

Required files:

FileDescription
ioto.json5Main configuration: services, logging, TLS, limits
device.json5Device identification: product token, name, model

Optional files:

FileDescription
web.json5Web server configuration (required if web service is enabled)
local.json5Development overrides (merged over ioto.json5)
schema.json5Database schema (required if database service is enabled)

The ioto.json5 file controls which services are active at runtime via its services property. This is separate from the compile-time config.h settings — a service must be both compiled in and enabled in ioto.json5 to be active.

Compiling and Linking

When compiling your source files, include the Ioto headers:

bash
cc -c -I ioto/include myapp.c

When linking, reference the Ioto static library and the TLS library:

Linux:

bash
cc -o myapp myapp.o ioto/build/bin/libioto.a -lssl -lcrypto

macOS (requires Homebrew OpenSSL):

bash
brew install openssl
cc -o myapp myapp.o ioto/build/bin/libioto.a -L/opt/homebrew/lib -lssl -lcrypto

Windows (Visual Studio):

Set ME_COM_OPENSSL_PATH to the OpenSSL install directory and link with ioto.lib.

If building with MbedTLS instead of OpenSSL, link with the MbedTLS libraries. See Changing the TLS Stack for details.

Embed with Your Own Main

To embed Ioto in your own main program, include ioto.h, call ioStartRuntime and ioRun, and provide ioStart and ioStop functions.

c
#include "ioto.h"

int main()
{
    ioStartRuntime(1);

    //  Service requests until told to stop
    ioRun(NULL);

    ioStopRuntime();
    return 0;
}

int ioStart(void)
{
    rInfo("sample", "Hello World\n");
    //  Your code here
    return 0;
}

void ioStop(void) {}

Ioto calls your ioStart function once initialization is complete. Your ioStart must not block. If you need a long running task, spawn a fiber:

c
int ioStart(void)
{
    rSpawnFiber("myFiber", (RFiberProc) longRunningTask, NULL);
    return 0;
}

Read more about fibers at Fibers.

Embed Using the Ioto Main

The second way to integrate is to use the Ioto command program and provide your own ioStart and ioStop functions. Ioto's main will handle startup and shutdown; it calls your ioStart when ready.

c
#include "ioto.h"

PUBLIC int ioStart(void)
{
    rInfo("sample", "Hello World\n");
    //  Your code here
    return 0;
}

PUBLIC void ioStop(void) {}

Compile this source and link with the Ioto library as described in Compiling and Linking above.

Samples

The link-agent-main sample demonstrates using the Ioto main and providing ioStart/ioStop functions.

The own-main sample demonstrates embedding Ioto with your own main().

For more details about the Ioto API, see the Ioto API Reference.