Skip to content

Commit

Permalink
update 960945b
Browse files Browse the repository at this point in the history
  • Loading branch information
GHA committed Aug 8, 2024
0 parents commit c091459
Show file tree
Hide file tree
Showing 230 changed files with 14,347 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .buildinfo
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: f413431121611f97044a6820d580f3d8
tags: 645f666f9bcd5a90fca523b33c5a78b7
Empty file added .nojekyll
Empty file.
Binary file added _images/summary.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
98 changes: 98 additions & 0 deletions _sources/api.rst.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@

RDFM Server API Reference
-------------------------

API Authentication
~~~~~~~~~~~~~~~~~~

By default, the RDFM server expects all API requests to be authenticated.
Depending on the type of the API, this can be either:

* Device Token
* Management Token

In either case, the server expects the token to be passed as part of the request, in the HTTP Authorization header.
An example authenticated request is shown below:

.. sourcecode:: http

GET /api/v1/groups HTTP/1.1
Host: rdfm-server:5000
User-Agent: python-requests/2.31.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Authorization: Bearer token=eyJhbGciOiJSUzI1NiIsInR5cC<...truncated...>RpPonb7-IAsk89YpGayxg

Any request that was not successfully authenticated (because of a missing or otherwise invalid token) will return the 401 Unauthorized status code.
Additionally, in the case of management tokens, if the given token does not provide sufficient access to the requested resource, the request will be rejected with a 403 Forbidden status code.
This can happen if the token does not claim all scopes required by the target endpoint (for example: trying to upload a package using a read-only token).

Error Handling
~~~~~~~~~~~~~~

Should an error occur during the handling of an API request, either because of incorrect request data or other endpoint-specific scenarios, the server will return an error structure containing a user-friendly description of the error.
An example error response is shown below:

.. sourcecode:: json

{
"error": "delete failed, the package is assigned to at least one group"
}


Packages API
~~~~~~~~~~~~

.. autoflask:: rdfm_mgmt_server:create_docs_app()
:modules: api.v1.packages
:undoc-static:
:order: path

Group API
~~~~~~~~~

.. autoflask:: rdfm_mgmt_server:create_docs_app()
:modules: api.v2.groups
:undoc-static:
:order: path

Group API (legacy)
~~~~~~~~~~~~~~~~~~

.. autoflask:: rdfm_mgmt_server:create_docs_app()
:modules: api.v1.groups
:undoc-static:
:order: path

Update API
~~~~~~~~~~

.. autoflask:: rdfm_mgmt_server:create_docs_app()
:modules: api.v1.update
:undoc-static:
:order: path

Device Management API
~~~~~~~~~~~~~~~~~~~~~

.. autoflask:: rdfm_mgmt_server:create_docs_app()
:modules: api.v2.devices
:undoc-static:
:order: path

Device Management API (legacy)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. autoflask:: rdfm_mgmt_server:create_docs_app()
:modules: api.v1.devices
:undoc-static:
:order: path

Device Authorization API
~~~~~~~~~~~~~~~~~~~~~~~~

.. autoflask:: rdfm_mgmt_server:create_docs_app()
:modules: api.v1.auth
:undoc-static:
:order: path
17 changes: 17 additions & 0 deletions _sources/index.md.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# {{project}}

```{toctree}
:maxdepth: 2

introduction
system_overview
rdfm_linux_device_client
rdfm_android_device_client
rdfm_mcumgr_device_client
rdfm_artifact
rdfm_manager
rdfm_mgmt_server
rdfm_ota_manual
server_operation
api
```
15 changes: 15 additions & 0 deletions _sources/introduction.md.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Introduction

RDFM - Remote Device Fleet Manager - is an open-source ecosystem of tools that enable Over-The-Air (OTA) update delivery and fleet management for systems of embedded devices.

This manual describes the main components of RDFM. It is divided into the following chapters:

- System Architecture - a short overview of the system architecture, and how each component of the system interacts with the other
- RDFM Linux Device Client - build instructions and manual for the Linux RDFM Client, used for installing updates on a device
- RDFM Android Device Client - integration guide and user manual for the RDFM Android Client/app used for providing OTA updates via RDFM on embedded Android devices
- RDFM MCUmgr Device Client - build instructions and manual for the RDFM MCUmgr Client app, used for providing updates via RDFM on embedded devices running ZephyrRTOS
- RDFM Artifact utility - instruction manual for the `rdfm-artifact` utility used for generating update packages for use with the RDFM Linux device client
- RDFM Manager utility - instruction manual for the `rdfm-mgmt` utility, which allows management of devices connected to the RDFM server
- RDFM Management Server - build instructions and deployment manual for the RDFM Management Server
- RDFM Server API Reference - comprehensive reference of the HTTP APIs exposed by the RDFM Management Server
- RDFM OTA Manual - introduces key concepts of the RDFM OTA system and explains it's basic operation principles
172 changes: 172 additions & 0 deletions _sources/rdfm_android_device_client.md.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# RDFM Android Device Client

## Introduction

The RDFM Android Device Client allows for integrating an Android-based device with the RDFM server.
Currently, only OTA update functionality is implemented.

## Integrating the app

This app is **not meant to be built separately** (i.e in Android Studio), but as part of the source tree for an existing device.
The app integrates with the Android UpdateEngine to perform the actual update installation, which requires it to be a system app.
Some configuration is required to the existing system sources.

### Copying the sources

First, copy the sources of the app to the root directory of the AOSP source tree.
After cloning this repository, run the following:
```
mkdir -v -p <path-to-aosp-tree>/vendor/antmicro/rdfm
cd devices/android-client/
cp -r app/src/main/* <path-to-aosp-tree>/vendor/antmicro/rdfm
```

### Configuring the device Makefile

The [product Makefile](https://source.android.com/docs/setup/create/new-device#build-a-product) must be configured to build the RDFM app into the system image.
To do this, add `rdfm` to the `PRODUCT_PACKAGES` variable in the target device Makefile:
```
PRODUCT_PACKAGES += rdfm
```

### Building the app

Afterwards, [the usual Android build procedure](https://source.android.com/docs/setup/build/building) can be used to build just the app.
From an already configured build environment, run:
```
mma rdfm
```
The resulting signed APK is in `out/target/product/<product-name>/system/app/rdfm/rdfm.apk`.

### Using HTTPS for server requests

The default Android system CA certificates are used when validating the certificate presented by the server.
If the RDFM server that is configured in the app uses a certificate that is signed by a custom Certificate Authority, the CA certificate must be added to the system roots.

## System versioning

The app performs update check requests to the configured RDFM server.
The build version and device type are retrieved from the system properties:
- `ro.build.version.incremental` - the current software version (matches `rdfm.software.version`)
- `ro.build.product` - device type (matches `rdfm.hardware.devtype`)

When uploading an OTA package to the RDFM server, currently these values must be **manually** extracted from the update package, and passed as arguments to `rdfm-mgmt`:
```
rdfm-mgmt packages upload --path ota.zip --version <ro.build.version.incremental> --device <ro.build.product>
```

You can extract the values from the [package metadata file](https://source.android.com/docs/core/ota/tools#ota-package-metadata) by unzipping the OTA package.

## Configuring the app

The application will automatically start on system boot.
Available configuration options are shown below.

### Build-time app configuration

The default build-time configuration can be modified by providing a custom `conf.xml` file in the `app/src/main/res/values/` folder, similar to the one shown below:

```xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--
This is an example overlay configuration file for the RDFM app.
To modify the default server address, you can do:

<string name="default_rdfm_server_address">http://rdfm.example.local:6000/</string>

Likewise, overlaying the default update check interval can be done similarly:

<string name="default_update_check_interval_seconds">240</string>

NOTE: These settings are only used during the app's first startup. To change them afterwards,
you must delete the existing configuration file.
-->
</resources>
```

This build-time configuration is applied **only once, at first startup of the app**, as the main use case for this is first-time configuration for newly provisioned devices.
Modifying it afterwards (for example, via an update containing a new version of the RDFM app) will not result in the change of existing configuration.

### Runtime app configuration

It is possible to change the app's configuration at runtime by simply starting the RDFM app from the drawer and selecting `Settings` from the context menu.

### Configuration options

The following configuration options are available:
- RDFM server URL (`http`/`https` scheme)
- Update check interval (in seconds)
- Maximum amount of concurrent shell sessions (set to `0` to disable reverse shell functionality)

## Available intents

### Update check intent

This intent allows an external app to force perform an update check outside of the usual automatic update check interval.
To do this, the app that wants to perform the update check must have the `com.antmicro.update.rdfm.permission.UPDATE_CHECK` permission defined in its `AndroidManifest.xml` file:

```xml
<uses-permission android:name="com.antmicro.update.rdfm.permission.UPDATE_CHECK" />
```

Afterwards, an update check can then be forced like so:
```java
Intent configIntent = new Intent("com.antmicro.update.rdfm.startUpdate");
mContext.sendBroadcast(configIntent);
```

### External configuration via intents

The app settings can also be configured via intents, for example in order to change between different deployment environments.
To do this, the app that performs the configuring step must have the `com.antmicro.update.rdfm.permission.CONFIGURATION` permission defined in its `AndroidManifest.xml` file:
```xml
<uses-permission android:name="com.antmicro.update.rdfm.permission.CONFIGURATION" />
```

To configure the app, use the `com.antmicro.update.rdfm.configurationSet` intent and set extra values on the intent to the settings you wish to change.
For example, to set the server address:
```java
Intent configIntent = new Intent("com.antmicro.update.rdfm.configurationSet");
configIntent.putExtra("ota_server_address", "http://CUSTOM-OTA-ADDRESS/");
mContext.sendBroadcast(configIntent);
```

The supported configuration key names can be found in the `res/values/strings.xml` file with the `preference_` prefix.

Aside from setting the configuration, you can also fetch the current configuration of the app:
```java
Intent configIntent = new Intent("com.antmicro.update.rdfm.configurationGet");
mContext.sendBroadcast(configIntent);

// Now listen for `com.antmicro.update.rdfm.configurationResponse` broadcast intent
// The intent's extras bundle will contain the configuration keys and values
```

## Development

The provided Gradle files can be used for development purposes, simply open the `devices/android-client` directory in Android Studio.
Missing references to the `UpdateEngine` class are expected, but they do not prevent regular use of the IDE.

Do note however that **the app is not buildable from Android Studio**, as it requires integration with the aforementioned system API.
To test the app, an existing system source tree must be used.
Copy the modified sources to the AOSP tree, and re-run the [application build](#building-the-app).
The modified APK can then be uploaded to the device via ADB by running:
```
adb install <path-to-rdfm.apk>
```

### Restarting the app

With the target device connected via ADB, run:
```
adb shell am force-stop com.antmicro.update.rdfm
adb shell am start -n com.antmicro.update.rdfm/.MainActivity
```

### Fetching app logs

To view the application logs, run:
```
adb logcat --pid=`adb shell pidof -s com.antmicro.update.rdfm`
```
Loading

0 comments on commit c091459

Please sign in to comment.