Lihat sumber di Android Code Search
Jika Anda bukan vendor chip Thread atau perangkat Android, Anda dapat berhenti membaca sekarang.
Dokumen ini memandu Anda melalui langkah-langkah untuk mem-build perangkat Border Router Thread berbasis Android baru dengan kode sumber AOSP terbaru. Dengan mengikuti dokumen ini, Anda akan mempelajari:
- arsitektur dan status dukungan Thread secara keseluruhan di Android
- cara membuat layanan Thread HAL Anda sendiri
- cara membuat perangkat Anda kompatibel dengan Google Home
- cara menguji Router Pembatas Thread
Jika Anda memerlukan dukungan, laporkan masalah di GitHub atau buka Diskusi jika ada pertanyaan.
Ringkasan
Stack Thread Android didasarkan pada OpenThread dan ot-br-posix
yang
bersifat open source oleh Google di GitHub. Dengan cara yang sama, OpenThread dikembangkan di
repositori GitHub publik, sehingga stack Android Thread dikembangkan di
codebase AOSP publik. Semua fitur dan perbaikan bug
dikirimkan terlebih dahulu di AOSP. Hal ini memungkinkan vendor mulai mengadopsi
versi Thread terbaru tanpa menunggu rilis Android reguler.
Arsitektur
Seluruh stack Thread Android terdiri dari dua komponen utama: stack Thread inti dalam partisi sistem generik dan layanan HAL Thread dalam partisi vendor. Vendor perangkat biasanya hanya perlu menangani dan mem-build layanan HAL.
Berikut adalah ringkasan singkat tentang cara kerja stack Thread Android:
- Ada layanan sistem Thread Java di server sistem yang mengelola
seluruh stack - menyediakan API sistem Thread, membuat antarmuka tunnel
thread-wpan
, mendaftarkan jaringan Thread ke
layanan Konektivitas
dan menerapkan fungsi Border Routing dan Advertising Proxy.
- Stack Thread / OpenThread inti dihosting dalam proses native mandiri
tanpa hak istimewa yang bernama ot-daemon
. ot-daemon
dikelola langsung
oleh layanan sistem Java melalui API AIDL pribadi dan mengakses radio
hardware Thread melalui Thread HAL API.
- Layanan Thread HAL yang disediakan vendor HARUS mengimplementasikan Thread HAL API. Protokol ini
biasanya berfungsi sebagai
RCP
dan mengimplementasikan
protokol
spinel.
Di mana kodenya?
- Framework / API dan layanan Android Thread: https://cs.android.com/android/platform/superproject/main/+/main:packages/modules/Connectivity/thread/
- Thread HAL API dan implementasi layanan default: https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/threadnetwork/
- Repositori OpenThread yang diimpor: https://cs.android.com/android/platform/superproject/main/+/main:external/openthread/
- Repositori ot-br-posix yang diimpor: https://cs.android.com/android/platform/superproject/main/+/main:external/ot-br-posix/
Menyiapkan lingkungan pengembangan
Vendor perangkat Android yang telah membuat lingkungan pengembangan Android untuk perangkat dapat melewati bagian ini.
Jika Anda baru menggunakan ekosistem Android atau Anda adalah vendor silicon yang ingin membuat chip Thread Anda kompatibel dengan Android dan memberikan dukungan untuk vendor perangkat, lanjutkan membaca.
Ikuti codelab developer Android
Untuk menyiapkan lingkungan pengembangan Android untuk pertama kalinya, gunakan codelab berikut: https://source.android.com/docs/setup/start. Di akhir codelab ini, Anda akan dapat mem-build dan menjalankan simulasi perangkat Cuttlefish dari kode sumber.
Mem-build layanan HAL Thread
Mencoba Thread di Cuttlefish
Cuttlefish adalah perangkat virtual Android. Sebelum mulai mem-build layanan HAL Anda sendiri, sebaiknya coba Thread di Cuttlefish untuk memahami cara kerja HAL.
Layanan HAL Thread default disediakan di Cuttlefish dan diimplementasikan dengan RCP simulasi yang mentransmisikan dan menerima paket melalui soket UDP ke dan dari radio Thread (802.15.4) simulasi.
Di instance Cuttlefish, "ThreadNetworkDemoApp" sudah diinstal sebelumnya. Buka aplikasi tersebut untuk bergabung dengan perangkat Cuttlefish ke jaringan Thread default.
Ada juga alat command line ot-ctl
dan ot-cli-ftd
yang disediakan untuk
mengonfigurasi jaringan Thread Anda untuk pengujian. Alat tersebut mendukung semua
perintah CLI OpenThread yang mungkin sudah Anda kenal.
Anda dapat mencari log layanan HAL Thread Cuttlefish dengan:
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
Atau grep untuk log ot-daemon dengan:
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]
Layanan HAL Thread Cuttlefish menggunakan layanan HAL Thread default ditambah biner RCP simulasi OpenThread. Lihat bagian berikutnya untuk mengetahui cara kerjanya.
Layanan HAL default
Layanan HAL default disertakan bersama Thread HAL API. Layanan HAL default mendukung perangkat RCP simulasi dan nyata. Perangkat ini menerima URL perangkat RCP opsional dan jika URL tidak diberikan, perangkat akan ditetapkan secara default ke perangkat RCP yang disimulasikan.
Dalam 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
Hal ini setara dengan:
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
Untuk perangkat RCP yang sebenarnya, perangkat ini mendukung antarmuka SPI dan UART, dan Anda dapat
menentukan perangkat dengan skema spinel+spi://
, spinel+hdlc+uart://
, dan
spinel+socket://
.
Memahami APEX vendor
Serupa dengan stack Thread di modul utama Tethering, layanan HAL Thread
default di Cuttlefish juga dikemas dalam modul APEX. Namun, ini adalah
modul APEX vendor yang akan diinstal ke /vendor/apex/
(Artefak dalam
modul akan diekstrak ke /apex/com.android.hardware.threadnetwork/
).
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 ], }
Ada beberapa konfigurasi penting yang perlu Anda perhatikan atau ubah saat mem-build modul HAL APEX Anda sendiri:
file_contexts
: Ini menjelaskan file biner / data yang dikirim dalam modul APEX ini atau file yang perlu diakses oleh layanan HAL (misalnya, perangkat RCP). Hal ini memungkinkan Anda menentukan aturan sepolicy tertentu untuk layanan HAL agar dapat mengakses perangkat RCP hardware.binaries
: File biner yang dikirim dalam modul APEX inithreadnetwork-service.rc
: Cara layanan HAL akan dimulai. Anda harus menentukan jalur perangkat RCP di sini.android.hardware.thread_network.prebuilt.xml
: Menentukan fitur hardwareandroid.hardware.thread_network
. Tindakan ini diperlukan agar sistem Android mengetahui bahwa perangkat Anda memiliki dukungan hardware Thread. Jika tidak, stack Android Thread tidak akan diaktifkan.
Membuat layanan HAL
Baik Anda adalah developer perangkat Android atau vendor silikon, Anda harus mengetahui cara mem-build firmware OT RCP untuk chip Thread. Petunjuk berikut mengasumsikan bahwa chip hardware telah dihubungkan dan divalidasi dengan benar.
Cara termudah untuk mem-build HAL APEX adalah dengan membuat APEX baru dengan
biner dan prebuild dari HAL APEX default. Misalnya, jika perusahaan Anda
adalah Banana dan perangkat RCP di perangkat Anda adalah /dev/ttyACM0
, APEX HAL
Thread Anda akan terlihat seperti ini:
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
Jalur file di kolom pertama terkait dengan /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 }
Dengan asumsi Anda membuat perangkat baru bernama Orange, direktori konfigurasi khusus perangkat Anda akan seperti:
device/banana/orange/threadnetwork/ sepolicy/ Android.bp file_contexts manifest.json threadnetwork-default.xml threadnetwork-service.rc
Lihat bagian berikutnya untuk mengetahui aturan sepolicy yang harus ditambahkan di subdirektori
sepolicy/
.
Aturan sepolicy untuk perangkat RCP
Secara default, layanan HAL Thread Anda tidak memiliki akses ke perangkat RCP (misalnya
/dev/ttyACM0
), aturan sepolicy kustom harus ditambahkan ke
direktori sepolicy/
.
Buat file sepolicy/threadnetwork_hal.te
baru dengan konten di bawah:
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;
Menggabungkan
Sekarang Anda telah menyelesaikan hampir semua kebutuhan kode untuk menambahkan Thread. Langkah terakhir adalah menambahkan aturan sepolicy dan Thread HAL APEX ke image perangkat Anda.
Anda dapat melakukannya dengan menambahkan kode di bawah ke Makefile
perangkat (misalnya,
device.mk
):
PRODUCT_PACKAGES += com.banana.hardware.threadnetwork BOARD_SEPOLICY_DIRS += device/banana/orange/threadnetwork/sepolicy
Jika semuanya berfungsi, sekarang Anda akan dapat melihat log layanan Thread HAL yang mirip dengan:
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
Dan log ot-daemon
akan terlihat seperti:
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
Penyesuaian
Modul utama Thread (sebenarnya merupakan bagian dari modul "Tethering") menyediakan beberapa konfigurasi yang dapat di-overlay yang dapat ditentukan oleh vendor untuk menyesuaikan perilaku stack. Lihat config_thread.xml untuk mengetahui daftar lengkapnya.
Biasanya, Anda harus menetapkan config_thread_border_router_default_enabled
ke true
untuk mengaktifkan perangkat sebagai Router Pembatas Thread, dan mengubah
config_thread_vendor_name
, config_thread_vendor_oui
, dan
config_thread_model_name
ke nilai vendor atau produk Anda. Nilai tersebut akan
disertakan dalam layanan mDNS _meshcop._udp
yang selalu diiklankan oleh
Thread Border Router.
Untuk menambahkan overlay, Anda perlu membuat target ConnectivityOverlayOrange
runtime_resource_overlay baru untuk perangkat Orange. Buat direktori
ConnectivityOverlay/
baru di bagian device/banana/orange/rro_overlays
dan
buat konten di bawah ini di dalamnya:
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
:
<bool name="config_thread_border_router_default_enabled">true</bool> <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>
Serupa dengan HAL APEX, Anda perlu menambahkan aplikasi overlay ke file
device.mk
:
PRODUCT_PACKAGES += \ ConnectivityOverlayOrange</code>
Jika semuanya berfungsi, Anda akan melihat bahwa ot-daemon
mencatat nama vendor dan model
di awal 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
Kompatibel dengan Google Home
Selain itu, jika ingin membuat Border Router digunakan oleh ekosistem
Google Home, Anda dapat menentukan konfigurasi ini di config_thread.xml
:
<string-array name="config_thread_mdns_vendor_specific_txts"> <item>vgh=1</item> </string-array>
Pengujian
Perangkat Anda kini harus kompatibel dengan spesifikasi Border Router Thread 1.3+. Sebelum mengirimkannya ke program sertifikasi Thread, ada beberapa pengujian Android xTS yang harus dilakukan untuk memastikan kompatibilitas.
Pengujian VTS memastikan layanan Thread HAL berfungsi seperti yang diharapkan di perangkat Anda. Anda dapat menjalankan pengujian dengan perintah
atest VtsHalThreadNetworkTargetTest
Pengujian CTS memastikan Thread API berfungsi seperti yang diharapkan di perangkat Anda. Anda dapat menjalankan pengujian dengan perintah
atest CtsThreadNetworkTestCases
Pengujian integrasi memberikan jaminan kualitas yang lebih baik tentang cara kerja kode utama Thread di perangkat Anda. Anda dapat menjalankan pengujian dengan perintah
atest ThreadNetworkIntegrationTests
Anda juga dapat menemukan petunjuk selengkapnya tentang cara menjalankan pengujian VTS/CTS/MTS dengan suite pengujian yang dirilis tersebut:
- https://source.android.com/docs/core/tests/vts
- https://source.android.com/docs/compatibility/cts/run
- https://docs.partner.android.com/mainline/test/mts (Anda harus menjadi partner untuk mengakses link ini)
Menguji dengan aplikasi demo Thread
Serupa dengan perangkat Cuttlefish, Anda dapat menambahkan aplikasi demo Thread ke image sistem:
# ThreadNetworkDemoApp for testing PRODUCT_PACKAGES_DEBUG += ThreadNetworkDemoApp
Perhatikan bahwa Anda hanya boleh menambahkannya ke varian debug / eng (misalnya,
PRODUCT_PACKAGES_DEBUG
) karena tidak boleh disertakan dalam build
pengguna untuk konsumen akhir.