Skip to content

bytebeamio/uplink

Repository files navigation

uplink

Rust @bytebeamio

the uplink logo

Uplink is a rust based utility for efficiently sending data and receiving commands from an IoT Backend. The primary backend for uplink is the Bytebeam platform, however uplink can also be used with any broker supporting MQTT 3.1.1.

Features

  • Efficiently send data to cloud with robust handling of flaky network conditions.
  • Persist data to disk in case of network issues.
  • Receive commands from the cloud, execute them and update progress of execution.
  • Can auto download updates from the cloud to perform OTA firmware updates.
  • Provides remote shell access through Tunshell
  • Supports TLS with easy cross-compilation.

Quickstart

Install Uplink

Pre-built binaries for select platform targets have been made available on the releases page, download the binary specific to your system and add it's location to PATH. To compile uplink on your own, please follow the build guide.

Setup

To start uplink on your device, run the following command, where you will need to provide the path to the appropriate device config as an argument with the -a flag:

uplink -a auth.json

The auth.json file must contain information such as the device's ID, the broker's URL, the port to connect to and the TLS certificates to be used while connecting. An example of what such a file's contents would look like is given in dummy.json. When connecting over non-TLS connections, authentication information is unncessary, as given in the example file contents of noauth.json.

NOTE: If you are using the Bytebeam platform, you could use the file downloaded from the Bytebeam UI. If you are using your own broker instead, you could use uplink without TLS, but we recommend that you use TLS and provision your own certificates to do it. You can read more about securing uplink in the uplink Security document.

For more details on how to configure uplink to run on your edge device, read the configuration guide.

Writing Applications

uplink acts as an intermediary between the user's application running on edge devices and the Bytebeam platform or an MQTT 3.1.1 broker of choice. One can accept commands in the form of Actions and update progress of said commands with Action Responses or even push the latest data from applications(such as sensing), with the help of uplink.

Uplink acts as a sidecar, simplifying the programmer's experience of interacting with Bytebeam. By just opening a TCP connection with the uplink daemon and reading/writing JSON as text through the same, the user application is able to take advantage of a secure and reliabale data-pipeline.

uplink architecture

Receiving Actions: Actions are messages that uplink expects to receive from the broker and is executable on the user's device. The JSON format for Actions are as such:

{
    "action_id": "...",
    "name": "...",
    "payload": "..."
}

NOTE: Some Actions are executed by built-in handlers, e.g. Actions. The tunshell action, i.e. Action with name: tunshell is used to initiate a remote connection over tunshell while the OTA action, i.e. Action with name: update_firmware can download OTA updates.

Streaming data: Data from the connected application is handled as payload within a stream. uplink expects the following JSON format for Streamed Payload:

{
    "stream": "...",
    "sequence": ...,
    "timestamp": ...,
    // ...payload: more JSON data
}

NOTE: Connected application should forward all data events as JSON text, following ASCII newline encoding.

An example data packet on the stream "location", with the fields "city" being a string and "altitude" being a number would look like:

{
    "stream": "location",
    "sequence": 10000000,
    "timestamp": 1987654,
    "city": "Bengaluru",
    "altitude": 123456,
}

NOTE: uplink expects values for the stream, sequence and timestamp field to be properly set, the payload maybe as per the requirements of the IoT platform/application.

Responding with Action Responses: Applications can use Action Response messages to update uplink on the progress of an executing Action. They usually contain information such as a progress counter and error backtrace. Action Responses are handled as Streamed data payloads in the "action_status" stream and thus have to be enclosed as such. uplink expects Action Responses to have the following JSON format:

{
    "stream": "action_status",
    "sequence": ...,
    "timestamp": ...,
    "action_id": "...",
    "state": "...",
    "progress": ...,
    "errors": [...]
}

NOTE: Connected application should forward all response events as JSON text, following ASCII newline encoding.

An example success response to an action with the id "123", would look like:

{
    "stream": "action_status",
    "sequence": 234,
    "timestamp": 192323,
    "action_id": "123",
    "state": "Completed",
    "progress": 100,
    "errors": []
}

Downloading OTA updates and other files

uplink has a built-in feature that enables it to download OTA firmware updates, this can be enabled by setting the following field in the config.toml and using the -c option while starting uplink:

[downloader]
actions = ["update_firmware"]
path = "/path/to/directory" # Where you want the update file to be downloaded
uplink -c config.toml -a auth.json

Once enabled, Actions with the following JSON will trigger uplink to download the file and hand-over the action to a connected application to perform the necessary firmware updation:

{
    "action_id": "...",
    "name": "update_firmware",
    "payload": "{
        \"url\": \"https://example.com/file\",
        \"version\":\"1.0\"
    }"
}

Once downloded, the payload JSON is updated with the file's on device path, as such:

{
    "action_id": "...",
    "name": "update_firmware",
    "payload": "{
        \"url\": \"https://example.com/file\",
        \"download_path\": \"/path/to/directory\",
        \"version\":\"1.0\"
    }"
}

Remote Shell Connection

With the help of tunshell, uplink allows you to remotely connect to a device shell. One can provide the necessary details for uplink to initiate such a connection by creating a tunshell action, with the following JSON format:

{
    "action_id": "...",
    "name": "tunshell",
    "payload": "{
        \"session\": \"...\",
        \"encryption\": \"...\"
    }"
}

NOTE: Bytebeam has built-in support for tunshell, if you are using any other MQTT broker, you may have to manage your own tunshell server to use this feature.

Testing with netcat

You can test sending JSON data to Bytebeam over uplink with the following command while uplink is active

nc localhost 5050
{ "stream": "can", "sequence": 1, "timestamp": 12345, "data": 100 }
{ "stream": "can", "sequence": 1, "timestamp": 12345, "data": 100 }
{ "stream": "can", "sequence": 1, "timestamp": 12345, "data": 100 }

The complete API reference for the uplink library is available within the library documentation.

Contributing

Please follow the code of conduct while opening issues to report bugs or before you contribute fixes, also do read our contributor guide to get a better idea of what we'd appreciate and what we won't.