[docs] initial Thread Border Router vendor guide
Provide a guide for vendors to build their own Android-based Thread Border Router products. Bug: 330346403 Change-Id: I93c9f37316992692113552eadd73f3d69a9abc71
This commit is contained in:
parent
d52637ff74
commit
85b0306bc7
4 changed files with 530 additions and 0 deletions
|
|
@ -16,3 +16,7 @@ launch_cvd
|
|||
|
||||
Open `https://localhost:8443/` in your web browser, you can find the Thread
|
||||
demoapp (with the Thread logo) in the cuttlefish instance. Open it and have fun with Thread!
|
||||
|
||||
## More docs
|
||||
|
||||
- [Make your Android Border Router](./docs/make-your-android-border-router.md)
|
||||
|
|
|
|||
BIN
thread/docs/android-thread-arch.png
Normal file
BIN
thread/docs/android-thread-arch.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
526
thread/docs/build-an-android-border-router.md
Normal file
526
thread/docs/build-an-android-border-router.md
Normal file
|
|
@ -0,0 +1,526 @@
|
|||
# Build an Android Border Router
|
||||
|
||||
If you are not an Android device or Thread chip vendor, you can stop reading
|
||||
now.
|
||||
|
||||
This document walks you through the steps to build a new Android-based Thread
|
||||
Border Router device with the latest AOSP source code. By following this
|
||||
document, you will learn:
|
||||
|
||||
1. [the overall architecture and status of Thread support in Android](#architecture)
|
||||
2. [how to create your own Thread HAL service](#build-your-thread-hal-service)
|
||||
3. [how to make your device compatible with Google Home](#be-compatible-with-google-home)
|
||||
4. [how to test your Thread Border Router](#testing)
|
||||
|
||||
If you need support, file an issue in
|
||||
[GitHub](https://github.com/openthread/ot-br-posix/issues) or open a
|
||||
[Dicussion](https://github.com/orgs/openthread/discussions) if you have any
|
||||
questions.
|
||||
|
||||
Note: Before creating an issue or discussion, search to see if it has already
|
||||
been reported or asked.
|
||||
|
||||
## Overview
|
||||
|
||||
The Android Thread stack is based on OpenThread and `ot-br-posix` which are
|
||||
open-sourced by Google in GitHub. The same way OpenThread is developed in a
|
||||
public GitHub repository, so the Android Thread stack is developed in the
|
||||
public [AOSP codebase](https://cs.android.com/). All features and bug fixes
|
||||
are submitted first in AOSP. This allows vendors to start adopting the latest
|
||||
Thread versions without waiting for regular Android releases.
|
||||
|
||||
### Architecture
|
||||
|
||||
The whole Android Thread stack consists of two major components: the core
|
||||
Thread stack in a generic system partition and the Thread HAL service in a
|
||||
vendor partition. Device vendors typically need only to take care and build the
|
||||
HAL service.
|
||||
|
||||

|
||||
|
||||
Here is a brief summary of how the Android Thread stack works:
|
||||
- There is a Java Thread system service in the system server which manages the
|
||||
whole stack - provides the Thread system API, creates the `thread-wpan`
|
||||
tunnel interface, registers the Thread network to the
|
||||
[Connectivity service](https://developer.android.com/reference/android/content/Context#CONNECTIVITY_SERVICE)
|
||||
and implements the Border Routing and Advertising Proxy functionalities.
|
||||
- The core Thread / OpenThread stack is hosted in a non-privileged standalone
|
||||
native process which is named `ot-daemon`. `ot-daemon` is directly managed
|
||||
by the Java system service via private AIDL APIs and it accesses the Thread
|
||||
hardware radio through the Thread HAL API.
|
||||
- A vendor-provided Thread HAL service MUST implement the Thread HAL API. It
|
||||
typically works as an
|
||||
[RCP](https://openthread.io/platforms/co-processor#radio_co-processor_rcp)
|
||||
and implements the
|
||||
[spinel](https://openthread.io/platforms/co-processor#spinel_protocol)
|
||||
protocol.
|
||||
|
||||
Note: Both the Java system service and ot-daemon are delivered in a
|
||||
[Tethering](https://source.android.com/docs/core/ota/modular-system/tethering#overview)
|
||||
mainline module. For mobile devices, the binary is managed by Google and
|
||||
delivered to devices via Google Play monthly. For non-mobile devices such as
|
||||
TV, vendors are free to build from source or use a prebuilt.
|
||||
|
||||
### Where is the code?
|
||||
|
||||
- The Android Thread framework / API and service: https://cs.android.com/android/platform/superproject/main/+/main:packages/modules/Connectivity/thread/
|
||||
- The Thread HAL API and default service implementation: https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/threadnetwork/
|
||||
- Imported OpenThread repo: https://cs.android.com/android/platform/superproject/main/+/main:external/openthread/
|
||||
- Imported ot-br-posix repo: https://cs.android.com/android/platform/superproject/main/+/main:external/ot-br-posix/
|
||||
|
||||
## Set up development environment
|
||||
|
||||
Android device vendors who have already established an Android development
|
||||
environment for the device can skip this section.
|
||||
|
||||
If you are new to Android ecosystem or you are a silicon vendor who wants to
|
||||
make your Thread chip compatible with Android and provide support for device
|
||||
vendors, keep reading.
|
||||
|
||||
### Follow the Android developer codelab
|
||||
|
||||
To set up your Android development environment for the first time, use the
|
||||
following codelab: https://source.android.com/docs/setup/start. At the end of
|
||||
this codelab, you will be able to build and run a simulated Cuttlefish device
|
||||
from source code.
|
||||
|
||||
## Build your Thread HAL service
|
||||
|
||||
### Try Thread in Cuttlefish
|
||||
|
||||
[Cuttlefish](https://source.android.com/docs/devices/Cuttlefish) is the virtual
|
||||
Android device. Before starting building your own HAL service, it's better to
|
||||
try Thread in Cuttlefish to understand how HAL works.
|
||||
|
||||
A default Thread HAL service is provided in Cuttlefish and it's implemented
|
||||
with the [simulated RCP](https://github.com/openthread/openthread/tree/main/examples/platforms/simulation)
|
||||
which transceives packets via UDP socket to and from a simulated
|
||||
Thread (802.15.4) radio.
|
||||
|
||||
In the Cuttlefish instance, a "ThreadNetworkDemoApp" is pre-installed. Open
|
||||
that app to join the Cuttlefish device into a default Thread network.
|
||||
|
||||

|
||||
|
||||
Note: The Border Router functionalities will be started (and OMR address will
|
||||
be created) only when the Cuttlefish device is connected to a virtual Wi-Fi
|
||||
network. You can connect the Wi-Fi network in Settings.
|
||||
|
||||
There are also the `ot-ctl` and `ot-cli-ftd` command line tools provided to
|
||||
configure your Thread network for testing. Those tools support all the
|
||||
OpenThread CLI commands that you may be familiar with already.
|
||||
|
||||
You can grep for logs of the Cuttlefish Thread HAL service by:
|
||||
|
||||
```
|
||||
$ adb logcat | egrep -i threadnetwork-service
|
||||
|
||||
07-21 10:43:05.048 0 0 I init : Parsing file /apex/com.android.hardware.threadnetwork/etc/threadnetwork-service.rc...
|
||||
07-21 10:59:27.233 580 580 W android.hardware.threadnetwork-service: ThreadChip binder is unlinked
|
||||
07-21 10:59:27.233 580 580 I android.hardware.threadnetwork-service: Close IThreadChip successfully
|
||||
07-21 10:59:27.385 580 580 I android.hardware.threadnetwork-service: Open IThreadChip successfully
|
||||
```
|
||||
|
||||
Or grep for ot-daemon logs by:
|
||||
|
||||
```
|
||||
$ adb logcat | egrep -i ot-daemon
|
||||
07-21 10:43:48.741 0 0 I init : starting service 'ot-daemon'...
|
||||
07-21 10:43:48.742 0 0 I init : Created socket '/dev/socket/ot-daemon/thread-wpan.sock', mode 660, user 1084, group 1084
|
||||
07-21 10:43:48.762 0 0 I init : ... started service 'ot-daemon' has pid 2473
|
||||
07-21 10:46:26.320 2473 2473 I ot-daemon: [I] P-Daemon------: Session socket is ready
|
||||
07-21 10:46:30.290 2473 2473 W ot-daemon: [W] P-Daemon------: Daemon read: Connection reset by peer
|
||||
07-21 10:48:07.264 2473 2473 I ot-daemon: [INFO]-BINDER--: Start joining...
|
||||
07-21 10:48:07.267 2473 2473 I ot-daemon: [I] Settings------: Saved ActiveDataset
|
||||
07-21 10:48:07.267 2473 2473 I ot-daemon: [I] DatasetManager: Active dataset set
|
||||
07-21 10:48:07.273 2473 2473 I ot-daemon: [I] DnssdServer---: Started
|
||||
07-21 10:48:07.273 2473 2473 I ot-daemon: [N] Mle-----------: Role disabled -> detached
|
||||
07-21 10:48:07.273 2473 2473 I ot-daemon: [I] Mle-----------: AttachState Idle -> Start
|
||||
07-21 10:48:07.273 2473 2473 I ot-daemon: [I] Notifier------: StateChanged (0x111fd11d) [Ip6+ Role LLAddr MLAddr KeySeqCntr Ip6Mult+ Channel PanId NetName ExtPanId ...
|
||||
07-21 10:48:07.273 2473 2473 I ot-daemon: [I] Notifier------: StateChanged (0x111fd11d) ... NetworkKey PSKc SecPolicy NetifState ActDset]
|
||||
```
|
||||
|
||||
Note: You can also capture Thread system server log with the tag
|
||||
"ThreadNetworkService".
|
||||
|
||||
The Cuttlefish Thread HAL service uses the default Thread HAL service plus the
|
||||
OpenThread simulated RCP binary, see the next section for how it works.
|
||||
|
||||
### The default HAL service
|
||||
|
||||
A [default HAL service](https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/threadnetwork/aidl/default/)
|
||||
is included along with the Thread HAL API. The default HAL service supports
|
||||
both simulated and real RCP devices. It receives an optional RCP device URL and
|
||||
if the URL is not provided, it defaults to the simulated RCP device.
|
||||
|
||||
In file `hardware/interfaces/threadnetwork/aidl/default/threadnetwork-service.rc`:
|
||||
|
||||
```
|
||||
service vendor.threadnetwork_hal /apex/com.android.hardware.threadnetwork/bin/hw/android.hardware.threadnetwork-service
|
||||
class hal
|
||||
user thread_network
|
||||
```
|
||||
|
||||
This is equivalent to:
|
||||
|
||||
```
|
||||
service vendor.threadnetwork_hal /apex/com.android.hardware.threadnetwork/bin/hw/android.hardware.threadnetwork-service spinel+hdlc+forkpty:///apex/com.android.hardware.threadnetwork/bin/ot-rcp?forkpty-arg=1
|
||||
class hal
|
||||
user thread_network
|
||||
```
|
||||
|
||||
For real RCP devices, it supports both SPI and UART interace and you can
|
||||
specify the device with the schema `spinel+spi://`, `spinel+hdlc+uart://` and
|
||||
`spinel+socket://` respectively.
|
||||
|
||||
Note: `spinel+socket://` is a new spinel interface added in the default Thread
|
||||
HAL, it supports transmitting spinel frame via an Unix socket. A full
|
||||
socket-based radio URL may be like
|
||||
`spinel+socket:///data/vendor/threadnetwork/thread_spinel_socket`.
|
||||
|
||||
#### Understand the vendor APEX
|
||||
|
||||
Similar to the Thread stack in the Tethering mainline module, the default Thread
|
||||
HAL service in Cuttlefish is packaged in an APEX module as well. But it's a
|
||||
vendor APEX module which will be installed to `/vendor/apex/` (The artifacts in
|
||||
the module will be unzipped to `/apex/com.android.hardware.threadnetwork/`).
|
||||
|
||||
```aidl
|
||||
apex {
|
||||
name: "com.android.hardware.threadnetwork",
|
||||
manifest: "manifest.json",
|
||||
file_contexts: "file_contexts",
|
||||
key: "com.android.hardware.key",
|
||||
certificate: ":com.android.hardware.certificate",
|
||||
updatable: false,
|
||||
vendor: true,
|
||||
|
||||
binaries: [
|
||||
"android.hardware.threadnetwork-service",
|
||||
"ot-rcp",
|
||||
],
|
||||
|
||||
prebuilts: [
|
||||
"threadnetwork-default.xml", // vintf_fragment
|
||||
"threadnetwork-service.rc", // init_rc
|
||||
"android.hardware.thread_network.prebuilt.xml", // permission
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
There are a few important configurations that you will need to pay attention or
|
||||
make changes to when building your own HAL APEX module:
|
||||
|
||||
- `file_contexts`: This describes the binary / data files delivered in this
|
||||
APEX module or files the HAL service need to access (for example, the RCP
|
||||
device). This allows you to specify specific sepolicy rules for your HAL
|
||||
service to access the hardware RCP device.
|
||||
- `binaries`: The binary file delivered in this APEX module
|
||||
- `threadnetwork-service.rc`: How the HAL service will be started. You need to
|
||||
specify the RCP device path here.
|
||||
- `android.hardware.thread_network.prebuilt.xml`: Defines the
|
||||
`android.hardware.thread_network` hardware feature. This is required for the
|
||||
Android system to know that your device does have Thread hardware support.
|
||||
Otherwise, the Android Thread stack won't be enabled.
|
||||
|
||||
### Create your HAL service
|
||||
|
||||
Whether you are an Android device developer or a silicon vendor, you should be
|
||||
familiar with building OT RCP firmware for your Thread chip. The following
|
||||
instructions assume that the hardware chip is correctly wired and
|
||||
validated.
|
||||
|
||||
The simplest way to build your HAL APEX is to create a new APEX with the
|
||||
binaries and prebuilts of the default HAL APEX. For example, if your company is
|
||||
Banana and the RCP device on your device is `/dev/ttyACM0`, your Thread HAL
|
||||
APEX will look like this:
|
||||
|
||||
- `Android.bp`:
|
||||
```
|
||||
prebuilt_etc {
|
||||
name: "banana-threadnetwork-service.rc",
|
||||
src: "banana-threadnetwork-service.rc",
|
||||
installable: false,
|
||||
}
|
||||
|
||||
apex {
|
||||
name: "com.banana.android.hardware.threadnetwork",
|
||||
manifest: "manifest.json",
|
||||
file_contexts: "file_contexts",
|
||||
key: "com.android.hardware.key",
|
||||
certificate: ":com.android.hardware.certificate",
|
||||
updatable: false,
|
||||
vendor: true,
|
||||
|
||||
binaries: [
|
||||
"android.hardware.threadnetwork-service",
|
||||
],
|
||||
|
||||
prebuilts: [
|
||||
"banana-threadnetwork-service.rc",
|
||||
"threadnetwork-default.xml",
|
||||
"android.hardware.thread_network.prebuilt.xml",
|
||||
],
|
||||
}
|
||||
```
|
||||
- `file_contexts`:
|
||||
```
|
||||
(/.*)? u:object_r:vendor_file:s0
|
||||
/etc(/.*)? u:object_r:vendor_configs_file:s0
|
||||
/bin/hw/android\.hardware\.threadnetwork-service u:object_r:hal_threadnetwork_default_exec:s0
|
||||
/dev/ttyACM0 u:object_r:threadnetwork_rcp_device:s0
|
||||
```
|
||||
The file paths in the first column are related to `/apex/com.android.hardware.threadnetwork/`.
|
||||
- `threadnetwork-service.rc`:
|
||||
```
|
||||
service vendor.threadnetwork_hal /apex/com.android.hardware.threadnetwork/bin/hw/android.hardware.threadnetwork-service spinel+hdlc+uart:///dev/ttyACM0?uart-baudrate=115200
|
||||
class hal
|
||||
user root
|
||||
```
|
||||
- `manifest.json`:
|
||||
```
|
||||
{
|
||||
"name": "com.android.hardware.threadnetwork",
|
||||
"version": 1
|
||||
}
|
||||
```
|
||||
|
||||
Note: The default Thread HAL service is not designed to be a generic system
|
||||
component which works for all Android devices. If the default implementation
|
||||
can't support your device, you are free to make a copy and change it for your
|
||||
needs. In this case, it's just simpler to create a new APEX module without
|
||||
overriding the default one.
|
||||
|
||||
Assuming you are making a new device named Orange, your device specific
|
||||
configuration directory will be like:
|
||||
|
||||
```
|
||||
device/banana/orange/threadnetwork/
|
||||
sepolicy/
|
||||
Android.bp
|
||||
file_contexts
|
||||
manifest.json
|
||||
threadnetwork-default.xml
|
||||
threadnetwork-service.rc
|
||||
```
|
||||
|
||||
See the next section for what sepolicy rules should be added in the `sepolicy/`
|
||||
sub-directory.
|
||||
|
||||
#### Sepolicy rules for RCP device
|
||||
|
||||
By default, your Thread HAL service doesn't have access to the RCP device (for
|
||||
example `/dev/ttyACM0`), custom sepolicy rules need to be added to the
|
||||
`sepolicy/` directory.
|
||||
|
||||
Create a new `sepolicy/threadnetwork_hal.te` file with below content:
|
||||
|
||||
```
|
||||
type threadnetwork_rcp_device, dev_type;
|
||||
|
||||
# Allows the Thread HAL service to read / write the Thread RCP device
|
||||
allow hal_threadnetwork_default threadnetwork_rcp_device:chr_file rw_file_perms;
|
||||
```
|
||||
|
||||
#### Put together
|
||||
|
||||
Now you have finished almost all the code needs for adding Thread, the last
|
||||
step is to add the Thread HAL APEX and sepolicy rules to your device's image.
|
||||
|
||||
You can do this by adding below code to your device's `Makefile` (for example,
|
||||
`device.mk`):
|
||||
|
||||
```
|
||||
PRODUCT_PACKAGES += com.banana.hardware.threadnetwork
|
||||
BOARD_SEPOLICY_DIRS += device/banana/orange/threadnetwork/sepolicy
|
||||
```
|
||||
|
||||
Note: Unfortunately, APEX module doesn't support sepolicy rules, so you need
|
||||
to explicitly specify the sepolicy directory separately.
|
||||
|
||||
If everything works, now you will be able to see the Thread HAL service log similar to:
|
||||
|
||||
```
|
||||
$ adb logcat | egrep -i threadnetwork-service
|
||||
08-13 13:26:41.751 477 477 I android.hardware.threadnetwork-service: ServiceName: android.hardware.threadnetwork.IThreadChip/chip0, Url: spinel+spi
|
||||
08-13 13:26:41.751 477 477 I android.hardware.threadnetwork-service: Thread Network HAL is running
|
||||
08-13 13:26:55.165 477 477 I android.hardware.threadnetwork-service: Open IThreadChip successfully
|
||||
```
|
||||
|
||||
And the `ot-daemon` log will be like:
|
||||
|
||||
```
|
||||
$ adb logcat -s ot-daemon
|
||||
08-13 13:26:55.157 1019 1019 I ot-daemon: [NOTE]-AGENT---: Running OTBR_AGENT/Unknown
|
||||
08-13 13:26:55.157 1019 1019 I ot-daemon: [NOTE]-AGENT---: Thread version: 1.3.0
|
||||
08-13 13:26:55.157 1019 1019 I ot-daemon: [NOTE]-AGENT---: Thread interface: thread-wpan
|
||||
08-13 13:26:55.157 1019 1019 I ot-daemon: [NOTE]-AGENT---: Backbone interface is not specified
|
||||
08-13 13:26:55.157 1019 1019 I ot-daemon: [NOTE]-AGENT---: Radio URL: threadnetwork_hal://binder?none
|
||||
08-13 13:26:55.157 1019 1019 I ot-daemon: [NOTE]-ILS-----: Infra link selected:
|
||||
08-13 13:26:55.160 1019 1019 I ot-daemon: [I] Platform------: [HAL] Wait for getting the service android.hardware.threadnetwork.IThreadChip/chip0 ...
|
||||
08-13 13:26:55.165 1019 1019 I ot-daemon: [I] Platform------: [HAL] Successfully got the service android.hardware.threadnetwork.IThreadChip/chip0
|
||||
08-13 13:26:55.275 1019 1019 I ot-daemon: [I] P-RadioSpinel-: RCP reset: RESET_UNKNOWN
|
||||
08-13 13:26:55.276 1019 1019 I ot-daemon: [I] P-RadioSpinel-: Software reset RCP successfully
|
||||
08-13 13:26:55.277 1019 1019 I ot-daemon: [I] P-RadioSpinel-: RCP reset: RESET_POWER_ON
|
||||
08-13 13:26:55.322 1019 1019 I ot-daemon: [I] ChildSupervsn-: Timeout: 0 -> 190
|
||||
08-13 13:26:55.324 1019 1019 I ot-daemon: [I] RoutingManager: Initializing - InfraIfIndex:0
|
||||
08-13 13:26:55.324 1019 1019 I ot-daemon: [I] InfraIf-------: Init infra netif 0
|
||||
08-13 13:26:55.324 1019 1019 I ot-daemon: [I] Settings------: Read BrUlaPrefix fd7b:cc45:ff06::/48
|
||||
08-13 13:26:55.324 1019 1019 I ot-daemon: [N] RoutingManager: BR ULA prefix: fd7b:cc45:ff06::/48 (loaded)
|
||||
08-13 13:26:55.324 1019 1019 I ot-daemon: [I] RoutingManager: Generated local OMR prefix: fd7b:cc45:ff06:1::/64
|
||||
08-13 13:26:55.324 1019 1019 I ot-daemon: [N] RoutingManager: Local on-link prefix: fdde:ad00:beef:cafe::/64
|
||||
08-13 13:26:55.324 1019 1019 I ot-daemon: [I] RoutingManager: Enabling
|
||||
```
|
||||
|
||||
## Customization
|
||||
|
||||
The Thread mainline module (it's actually a part of the "Tethering" module)
|
||||
provides a few [overlayable configurations](https://source.android.com/docs/core/runtime/rros)
|
||||
which can be specified by vendors to customize the stack behavior. See
|
||||
[config_thread.xml](https://cs.android.com/android/platform/superproject/main/+/main:packages/modules/Connectivity/service/ServiceConnectivityResources/res/values/config_thread.xml)
|
||||
for the full list.
|
||||
|
||||
Typically, you must change the `config_thread_vendor_name`,
|
||||
`config_thread_vendor_oui` and `config_thread_model_name` to your vendor or
|
||||
product values. Those values will be included in the `_meshcop._udp` mDNS
|
||||
service which is always advertised by a Thread Border Router.
|
||||
|
||||
To add the overlay, you need to create a new `ConnectivityOverlayOrange`
|
||||
runtime_resource_overlay target for your Orange device. Create a new
|
||||
`ConnectivityOverlay/` directory under `device/banana/orange/rro_overlays` and
|
||||
create below contents in it:
|
||||
|
||||
```
|
||||
device/banana/orange/rro_overlays/ConnectivityOverlay/
|
||||
res
|
||||
values
|
||||
config_thread.xml
|
||||
Android.bp
|
||||
AndroidManifest.xml
|
||||
```
|
||||
|
||||
- `Android.bp`:
|
||||
```
|
||||
package {
|
||||
default_applicable_licenses: ["Android-Apache-2.0"],
|
||||
}
|
||||
|
||||
runtime_resource_overlay {
|
||||
name: "ConnectivityOverlayOrange",
|
||||
manifest: "AndroidManifest.xml",
|
||||
resource_dirs: ["res"],
|
||||
certificate: "platform",
|
||||
product_specific: true,
|
||||
sdk_version: "current",
|
||||
}
|
||||
```
|
||||
- `AndroidManifest.xml`:
|
||||
```
|
||||
<!-- Orange overlays for the Connectivity module -->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.banana.android.connectivity.resources.orange"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
<application android:hasCode="false" />
|
||||
|
||||
<!-- If your device uses google-signed mainline modules, the targetPackage
|
||||
needs to be "com.google.android.connectivity.resources", otherise, it
|
||||
should be "com.android.connectivity.resources"
|
||||
-->
|
||||
<overlay
|
||||
android:targetPackage="com.google.android.connectivity.resources"
|
||||
android:targetName="ServiceConnectivityResourcesConfig"
|
||||
android:isStatic="true"
|
||||
android:priority="1"/>
|
||||
</manifest>
|
||||
```
|
||||
- `config_thread.xml`:
|
||||
```
|
||||
<string translatable="false" name="config_thread_vendor_name">Banana Inc.</string>
|
||||
<string translatable="false" name="config_thread_vendor_oui">AC:DE:48</string>
|
||||
<string translatable="false" name="config_thread_model_name">Orange</string>
|
||||
```
|
||||
|
||||
Similar to the HAL APEX, you need to add the overlay app to your `device.mk`
|
||||
file:
|
||||
|
||||
```
|
||||
PRODUCT_PACKAGES += \
|
||||
ConnectivityOverlayOrange
|
||||
```
|
||||
|
||||
If everything works, you will see that `ot-daemon` logs the vendor and model name
|
||||
at the very beginning of the log:
|
||||
```
|
||||
$ adb logcat -s ot-daemon
|
||||
07-22 15:31:37.693 1472 1472 I ot-daemon: [I] P-Daemon------: Session socket is ready
|
||||
07-22 15:31:37.693 1472 1472 I ot-daemon: [I] Cli-----------: Input: state
|
||||
07-22 15:31:37.693 1472 1472 I ot-daemon: [I] Cli-----------: Output: disabled
|
||||
07-22 15:31:37.693 1472 1472 I ot-daemon: [I] Cli-----------: Output: Done
|
||||
07-22 15:31:37.693 1472 1472 W ot-daemon: [W] P-Daemon------: Daemon read: Connection reset by peer
|
||||
07-22 15:31:50.091 1472 1472 I ot-daemon: [I] P-Daemon------: Session socket is ready
|
||||
07-22 15:31:50.091 1472 1472 I ot-daemon: [I] Cli-----------: Input: factoryreset
|
||||
07-22 15:31:50.092 1472 1472 I ot-daemon: [I] Settings------: Wiped all info
|
||||
07-22 15:31:50.092 1472 1472 I ot-daemon: [INFO]-ADPROXY-: Stopped
|
||||
07-22 15:31:50.092 1472 1472 I ot-daemon: [INFO]-DPROXY--: Stopped
|
||||
07-22 15:31:50.092 1472 1472 I ot-daemon: [INFO]-BA------: Stop Thread Border Agent
|
||||
07-22 15:31:50.092 1472 1472 I ot-daemon: [INFO]-BA------: Unpublish meshcop service Banana Inc. Orange #4833._meshcop._udp.local
|
||||
07-22 15:31:50.092 1472 1472 I ot-daemon: [INFO]-MDNS----: Removing service Banana Inc. Orange #4833._meshcop._udp
|
||||
07-22 15:31:50.092 1472 1472 I ot-daemon: [INFO]-MDNS----: Unpublishing service Banana Inc. Orange #4833._meshcop._udp listener ID = 0
|
||||
```
|
||||
|
||||
Note: In case the overlay doesn't work, check https://source.android.com/docs/core/runtime/rro-troubleshoot
|
||||
for troubleshooting instructions.
|
||||
|
||||
### Be compatible with Google Home
|
||||
|
||||
Additionally, if you want to make your Border Router be used by the Google Home
|
||||
ecosystem, you can specify this configuration in `config_thread.xml`:
|
||||
|
||||
```
|
||||
<string-array name="config_thread_mdns_vendor_specific_txts">
|
||||
<item>vgh=1</item>
|
||||
</string-array>
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Your device should be compatible with the Thread 1.3+ Border Router
|
||||
specification now. Before sending it to the Thread certification program, there
|
||||
are a few Android xTS tests should be exercised to ensure the compatibility.
|
||||
|
||||
- The VTS test makes sure Thread HAL service work as expected on your device.
|
||||
You can run the tests with command
|
||||
```
|
||||
atest VtsHalThreadNetworkTargetTest
|
||||
```
|
||||
- The CTS test makes sure Thread APIs work as expected on your device. You can
|
||||
run the tests with command
|
||||
```
|
||||
atest CtsThreadNetworkTestCases
|
||||
```
|
||||
- The integration test provides more quality guarantee of how the Thread
|
||||
mainline code works on your device. You can run the tests with command
|
||||
```
|
||||
atest ThreadNetworkIntegrationTests
|
||||
```
|
||||
|
||||
You can also find more instructions of how to run VTS/CTS/MTS tests with those
|
||||
released test suites:
|
||||
|
||||
- https://source.android.com/docs/core/tests/vts
|
||||
- https://source.android.com/docs/compatibility/cts/run
|
||||
- https://docs.partner.android.com/mainline/test/mts (you need to be a partner to access this link)
|
||||
|
||||
### Test with the Thread demo app
|
||||
|
||||
Similar to the Cuttlefish device, you can add the Thread demo app to your system image:
|
||||
|
||||
```
|
||||
# ThreadNetworkDemoApp for testing
|
||||
PRODUCT_PACKAGES_DEBUG += ThreadNetworkDemoApp
|
||||
```
|
||||
|
||||
Note that you should add it to only the debug / eng variant (for example,
|
||||
`PRODUCT_PACKAGES_DEBUG`) given this is not supposed to be included in user
|
||||
build for end consumers.
|
||||
BIN
thread/docs/demoapp-screenshot.png
Normal file
BIN
thread/docs/demoapp-screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 126 KiB |
Loading…
Reference in a new issue