= ATS Garage SOTA Client: Manual installation and integration guide
:icons: font
:toc: left
:toclevels: 3

== Starting the SOTA client

The SOTA client should be run at startup, as a service. We provide a systemd service file below as an example, but systemd is not a requirement. You can also, of course, run it from the command line to test. Setting the `RUST_LOG` environment variable will let you configure how much debug info you receive.

===== Example systemd service file
----
[Unit]
Description=SOTA Client
Wants=network-online.target
After=network.target network-online.target
Requires=network-online.target

[Service]
RestartSec=5
Restart=on-failure
Environment="RUST_LOG=info"
DefaultTimeoutStopSec=5
ExecStart=/usr/bin/sota_client --config /etc/sota.toml

[Install]
WantedBy=multi-user.target
----

== SOTA Client config file guide

The config file for the SOTA client is in TOML format, and can be invoked at startup with `sota_client  --config /path/to/config_file.toml`. A config file unique to each device can be downloaded from its device page on ATS Garage.

=== [auth]

This section is required for connection to an SOTA server that implements authentication. It needs to be the first section of the config file.

----
[auth]
server = "https://auth-plus.gw.prod01.advancedtelematic.com" <1>
client_id = "bf66425f-d4d6-422b-b510-7c7f178af9fe" <2>
client_secret = "hr8nEWzQc9" <2>
credentials_file = "/opt/sota/credentials.toml" <3>
----
<1> The URL of the auth server. Should not change.
<2> A unique client ID and secret for this device. With ATS Garage, this is assigned upon device creation and should not change.
<3> If this value is defined, SOTA client will check this file for auth credentials first, and use the credentials it finds there. If the file does not exist, it will be created with the `client_id` and `client_secret` above.

=== [core]

This is simply the URL of the core SOTA update server. It should not be changed.

----
[core]
server = "https://sota-core.gw.prod01.advancedtelematic.com"
----

=== [device]

This section contains device-specific configuration.

----
[device]
uuid = "123e4567-e89b-12d3-a456-426655440000" <1>
vin = "" <2>
system_info = "system_info.sh" <3>
polling_interval = 10 <4>
packages_dir = "/tmp/" <5>
package_manager = "deb" <6>
certificates_path = "/tmp/sota_certificates" <7>
----
<1> The UUID of the device. This is assigned by ATS Garage upon device creation, and should not be changed.
<2> The device's VIN, if it has one. Deprecated feature; this value is not used by the current version of ATS Garage.
<3> The script to use to gather system information.
<4> The frequency, in seconds, with which the SOTA client should poll the server for updates.
<5> The location SOTA Client should use for temporary package storage until they are processed by the software loading manager.
<6> The software loading manager backend to use. Possible values are `deb`, `rpm`, and `off`. If an external software loading manager is in use, this should be set to `off`.
<7> The certificate authorities SOTA Client trusts. Defaults taken from Mozilla Servo.

=== [network]

This section contains network configuration information for various gateways. Note that if the corresponding gateway is not enabled, these settings will have no effect.

----
[network]
http_server = "127.0.0.1:8080" <1>
socket_commands_path = "/tmp/sota-commands.socket" <2>
socket_events_path = "/tmp/sota-events.socket" <3>
websocket_server = "https://sota-core.gw.prod01.advancedtelematic.com" <4>
rvi_edge_server = "http://127.0.0.1:9080" <5>
----
<1> The path to the http-only core server, if the http gateway is enabled in the [gateway] section.
<2> The name of the unix domain socket to be used for sending commands, if the socket gateway is enabled in the [gateway] section.
<3> The name of the unix domain socket to be used for sending events, if the socket gateway is enabled in the [gateway] section.
<4> The location of the websocket server, for communication with the ATS Garage Core server.
<5> The location of the RVI edge node, if the rvi gateway is enabled in the [gateway] section.

=== [gateway]

OTA Client communicates externally with the SOTA Core server, and internally with the device's software loading manager. This section defines which gateways/protocols it should use to do so.

----
[gateway]
console = false <1>
dbus = false
http = false
rvi = false
socket = false <2>
websocket = true
----
<1> REPL mode, for debug use only.
<2> Unix domain sockets for local communication.

==== Optional gateway: [rvi]

Remote Vehicle Interaction (RVI) is an open source infrastructure developed by GENIVI and Jaguar Land Rover to power the next generation of connected vehicle services. This section contains values for configuration of RVI nodes. Note that having this section defined does not imply that RVI will be used; if the RVI gateway is turned off in the `[gateway]` section, this is ignored.

----
[rvi]
client = "http://127.0.0.1:8901"
storage_dir = "/var/sota"
timeout = 20
----

==== Optional gateway: [dbus]

This section contains values for dbus configuration, using the GENIVI software loading manager's names as the default. Note that having this section defined does not imply that dbus will be used; if the dbus gateway is turned off in the `[gateway]` section, this is ignored.

----
[dbus]
name = "org.genivi.SotaClient"
path = "/org/genivi/SotaClient"
interface = "org.genivi.SotaClient"
software_manager = "org.genivi.SoftwareLoadingManager"
software_manager_path = "/org/genivi/SoftwareLoadingManager"
timeout = 60
----

== API Documentation

The SOTA client is capable of integrating with various types of software loading manager (SWLM). This enables, with a relatively small amount of integration work, the installation of unlimited varieties of software or firmware packages. A complete API is available via D-Bus, but there are other options in development, including a simple unix domain socket API.

=== D-Bus API

For more information on the D-Bus API, please check out the https://github.com/advancedtelematic/rvi_sota_client[rvi_sota_client] repo from GitHub, and use `make doc` to build the Rustdoc library for this or better yet link:mailto:support@atsgarage.com[contact us] and let us know what you'd like to do and how we can help.

=== Unix domain socket API

Currently, only the core functionality of making software updates available and accepting reports on their installation is present in the unix domain socket API. A software loading manager must support the following:

- It must listen for `DownloadComplete` events on the events socket. At the moment, the only events published on the events socket are DownloadComplete events, but in future other types of events may be published. The SWLM should be capable of filtering for only the type of events it is interested in.
- It must send a `SendUpdateReport` command on the command socket, with a status code, when the update finishes.

==== Configuration

To communicate with the SOTA Client over unix domain sockets, `socket = true` must be defined in the `[gateway]` section of the config file. Additionally, the names of the two sockets are configurable in the link:#__network[[network]] section.

==== DownloadComplete

Once the SOTA client has successfully downloaded an update ordered by an ATS Garage user, it will send a DownloadComplete event on the events socket with the following body:

[source,json]
----
{
	"update_id": "string", <1>
	"update_image": "string", <2>
	"signature": "string" <3>
}
----
<1> A unique ID for the update. The SWLM will need to reference this ID when reporting on the status of the install.
<2> The location of the delivered update file.
<3> A cryptographic signature; may be blank if the package uploader chose not to supply one. The SWLM *may* implement signature verification, but is not required to do so.

==== SendUpdateReport

The Software Loading Manager should send this command on the command socket upon termination of the install, whether it was successful or failed. The form of the command over unix domain sockets is `SendUpdateReport update_id result_code`.

* The update ID is the one received from the `DownloadComplete` message.
* The result of the update attempt, either in numberical or verbal form. The possible update codes are enumerated below.

TIP: Over D-Bus, it is also possible to sent a longer textual description of the install status/error. This feature is not yet available via unix domain sockets, but will be in the future. It is recommended that SWLM integration developers maintain the capability to send more verbose status messages.

===== Possible update result codes

[cols="1,2,5",options="header"]
|===
| Numerical | Verbal | Description
|0  | OK | Operation executed successfully
|1  | ALREADY_PROCESSED | Operation has already been processed
|2  | DEPENDENCY_FAILURE | Dependency failure during package install, upgrade, or removal
|3  | VALIDATION_FAILED | Update image integrity has been compromised
|4  | INSTALL_FAILED | Package installation failed
|5  | UPGRADE_FAILED | Package upgrade failed
|6  | REMOVAL_FAILED | Package removal failed
|7  | FLASH_FAILED | The module loader could not flash its managed module
|8  | CREATE_PARTITION_FAILED | Partition creation failed
|9  | DELETE_PARTITION_FAILED | Partition deletion failed
|10 | RESIZE_PARTITION_FAILED | Partition resize failed
|11 | WRITE_PARTITION_FAILED | Partition write failed
|12 | PATCH_PARTITION_FAILED | Partition patching failed
|13 | USER_DECLINED | User declined the update
|14 | SOFTWARE_BLACKLISTED | Software was blacklisted
|15 | DISK_FULL | Ran out of disk space
|16 | NOT_FOUND | Software package not found
|17 | OLD_VERSION | Tried to downgrade to older version
|18 | INTERNAL_ERROR | SWM Internal integrity error
|19 | GENERAL_ERROR | Other error
|===

