منبع را در جستجوی کد اندروید مشاهده کنید
اگر یک دستگاه Android یا فروشنده تراشه Thread نیستید، میتوانید اکنون مطالعه را متوقف کنید.
این سند شما را در مراحل ساخت یک دستگاه Thread Border Router جدید مبتنی بر Android با آخرین کد منبع AOSP راهنمایی می کند. با دنبال کردن این سند، یاد خواهید گرفت:
- ساختار کلی و وضعیت پشتیبانی Thread در اندروید
- چگونه سرویس Thread HAL خود را ایجاد کنید
- چگونه دستگاه خود را با Google Home سازگار کنیم
- چگونه Thread Border Router خود را تست کنیم
اگر به پشتیبانی نیاز دارید، مشکلی را در GitHub ثبت کنید یا اگر سؤالی دارید، یک Dicussion را باز کنید.
نمای کلی
پشته Thread Android بر اساس OpenThread و ot-br-posix
است که توسط Google در GitHub منبع باز هستند. همانطور که OpenThread در یک مخزن عمومی GitHub توسعه می یابد، بنابراین پشته Thread Android در پایگاه کد عمومی AOSP توسعه می یابد. همه ویژگی ها و رفع اشکال ابتدا در AOSP ارسال می شوند. این به فروشندگان اجازه میدهد تا بدون انتظار برای نسخههای معمولی اندروید، آخرین نسخههای Thread را اتخاذ کنند.
معماری
کل پشته Thread Android از دو جزء اصلی تشکیل شده است: پشته Thread هسته در یک پارتیشن سیستم عمومی و سرویس Thread HAL در یک پارتیشن فروشنده. فروشندگان دستگاه معمولاً فقط به مراقبت و ساخت سرویس HAL نیاز دارند.
در اینجا خلاصهای از نحوه عملکرد پشته Thread Android آورده شده است: - یک سرویس سیستم Java Thread در سرور سیستم وجود دارد که کل پشته را مدیریت میکند - API سیستم Thread را ارائه میکند، رابط تونل thread-wpan
را ایجاد میکند، شبکه Thread را ثبت میکند. سرویس اتصال و قابلیت های مسیریابی مرزی و پروکسی تبلیغاتی را پیاده سازی می کند. - پشته اصلی Thread / OpenThread در یک فرآیند بومی مستقل غیرمجاز میزبانی می شود که ot-daemon
نام دارد. ot-daemon
مستقیماً توسط سرویس سیستم جاوا از طریق APIهای خصوصی AIDL مدیریت می شود و از طریق Thread HAL API به رادیو سخت افزار Thread دسترسی پیدا می کند. - یک سرویس Thread HAL ارائه شده توسط فروشنده باید Thread HAL API را پیاده سازی کند. معمولاً به عنوان یک RCP کار می کند و پروتکل اسپینل را پیاده سازی می کند.
کد کجاست؟
- چارچوب Android Thread / API و سرویس: https://cs.android.com/android/platform/superproject/main/+/main:packages/modules/Connectivity/thread/
- Thread HAL API و اجرای سرویس پیشفرض: https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/threadnetwork/
- مخزن OpenThread وارداتی: https://cs.android.com/android/platform/superproject/main/+/main:external/openthread/
- مخزن ot-br-posix وارداتی: https://cs.android.com/android/platform/superproject/main/+/main:external/ot-br-posix/
محیط توسعه را تنظیم کنید
فروشندگان دستگاه های اندرویدی که قبلاً یک محیط توسعه اندروید برای دستگاه ایجاد کرده اند، می توانند از این بخش صرف نظر کنند.
اگر تازه وارد اکوسیستم اندروید هستید یا فروشنده سیلیکونی هستید که میخواهید تراشه Thread خود را با اندروید سازگار کنید و برای فروشندگان دستگاهها پشتیبانی کنید، به خواندن ادامه دهید.
کد لبه برنامهنویس اندروید را دنبال کنید
برای راهاندازی محیط توسعه اندروید خود برای اولین بار، از لبه کد زیر استفاده کنید: https://source.android.com/docs/setup/start . در پایان این کد لبه، شما قادر خواهید بود یک دستگاه Cuttlefish شبیه سازی شده را از روی کد منبع بسازید و اجرا کنید.
سرویس Thread HAL خود را بسازید
Thread in Cuttlefish را امتحان کنید
Cuttlefish یک دستگاه اندروید مجازی است. قبل از شروع ساخت سرویس HAL خود، بهتر است Thread را در Cuttlefish امتحان کنید تا بفهمید HAL چگونه کار می کند.
یک سرویس Thread HAL پیشفرض در Cuttlefish ارائه میشود و با RCP شبیهسازی شده پیادهسازی میشود که بستهها را از طریق سوکت UDP به و از یک رادیوی Thread (802.15.4) شبیهسازی شده دریافت میکند.
در نمونه Cuttlefish، یک "ThreadNetworkDemoApp" از قبل نصب شده است. آن برنامه را باز کنید تا دستگاه Cuttlefish را به یک شبکه Thread پیش فرض بپیوندید.
همچنین ابزارهای خط فرمان ot-ctl
و ot-cli-ftd
برای پیکربندی شبکه Thread برای آزمایش ارائه شده است. این ابزارها از تمام دستورات OpenThread CLI که ممکن است قبلاً با آنها آشنا باشید پشتیبانی می کنند.
شما می توانید سیاهههای مربوط به سرویس Cutttlefish Thread HAL را توسط:
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
یا grep برای گزارش های ot-daemon توسط:
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]
سرویس Cuttlefish Thread HAL از سرویس پیشفرض Thread HAL بهعلاوه باینری RCP شبیهسازی شده OpenThread استفاده میکند، بخش بعدی را برای نحوه عملکرد آن ببینید.
سرویس پیش فرض HAL
یک سرویس HAL پیش فرض همراه با Thread HAL API گنجانده شده است. سرویس HAL پیش فرض از دستگاه های RCP شبیه سازی شده و واقعی پشتیبانی می کند. یک URL اختیاری دستگاه RCP دریافت می کند و اگر URL ارائه نشده باشد، به طور پیش فرض به دستگاه RCP شبیه سازی شده تبدیل می شود.
در فایل 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
این معادل است با:
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
برای دستگاه های RCP واقعی، از هر دو رابط SPI و UART پشتیبانی می کند و می توانید دستگاه را به ترتیب با schema spinel+spi://
، spinel+hdlc+uart://
و spinel+socket://
مشخص کنید.
APEX فروشنده را درک کنید
مشابه پشته Thread در ماژول خط اصلی Tethering، سرویس پیشفرض Thread HAL در Cuttlefish در یک ماژول APEX نیز بستهبندی شده است. اما این یک ماژول APEX فروشنده است که در /vendor/apex/
نصب می شود (مصنوعات موجود در ماژول به /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 ], }
چند پیکربندی مهم وجود دارد که هنگام ساخت ماژول HAL APEX خود باید به آنها توجه کنید یا تغییراتی در آنها ایجاد کنید:
file_contexts
: این فایلهای باینری/داده ارائهشده در این ماژول APEX یا فایلهایی را که سرویس HAL باید به آنها دسترسی داشته باشد (مثلاً دستگاه RCP) توصیف میکند. این به شما این امکان را می دهد که قوانین سیاست گذاری خاصی را برای سرویس HAL خود برای دسترسی به دستگاه RCP سخت افزاری مشخص کنید.binaries
: فایل باینری ارائه شده در این ماژول APEXthreadnetwork-service.rc
: نحوه راه اندازی سرویس HAL. در اینجا باید مسیر دستگاه RCP را مشخص کنید.android.hardware.thread_network.prebuilt.xml
: ویژگی سخت افزارandroid.hardware.thread_network
را تعریف می کند. این برای سیستم Android لازم است تا بداند دستگاه شما از سخت افزار Thread پشتیبانی می کند. در غیر این صورت، پشته Thread Android فعال نخواهد شد.
سرویس HAL خود را ایجاد کنید
چه یک توسعه دهنده دستگاه اندرویدی یا یک فروشنده سیلیکون باشید، باید با ساخت سیستم عامل OT RCP برای تراشه Thread خود آشنا باشید. در دستورالعمل های زیر فرض می شود که تراشه سخت افزاری به درستی سیم کشی و تایید شده است.
ساده ترین راه برای ساخت HAL APEX ایجاد یک APEX جدید با باینری ها و پیش ساخته های HAL APEX پیش فرض است. به عنوان مثال، اگر شرکت شما Banana است و دستگاه RCP روی دستگاه شما /dev/ttyACM0
است، Thread HAL APEX شما به شکل زیر خواهد بود:
-
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
مسیرهای فایل در ستون اول مربوط به /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 }
با فرض اینکه در حال ساخت یک دستگاه جدید به نام Orange هستید، دایرکتوری پیکربندی خاص دستگاه شما به صورت زیر خواهد بود:
device/banana/orange/threadnetwork/ sepolicy/ Android.bp file_contexts manifest.json threadnetwork-default.xml threadnetwork-service.rc
بخش بعدی را ببینید که چه قوانین sepolicy باید در فهرست sepolicy/
زیر دایرکتوری اضافه شود.
قوانین سیاست برای دستگاه RCP
بهطور پیشفرض، سرویس Thread HAL شما به دستگاه RCP دسترسی ندارد (به عنوان مثال /dev/ttyACM0
)، قوانین sepolicy سفارشی باید به فهرست sepolicy/
اضافه شوند.
یک فایل sepolicy/threadnetwork_hal.te
جدید با محتوای زیر ایجاد کنید:
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;
کنار هم قرار دهید
اکنون تقریباً تمام کدهای مورد نیاز برای افزودن Thread را تمام کرده اید، آخرین مرحله اضافه کردن Thread HAL APEX و قوانین sepolicy به تصویر دستگاه شما است.
می توانید این کار را با افزودن کد زیر به Makefile
دستگاه خود (به عنوان مثال device.mk
) انجام دهید:
PRODUCT_PACKAGES += com.banana.hardware.threadnetwork BOARD_SEPOLICY_DIRS += device/banana/orange/threadnetwork/sepolicy
اگر همه چیز کار کند، اکنون می توانید گزارش سرویس Thread HAL را مشابه موارد زیر مشاهده کنید:
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
و گزارش ot-daemon
به صورت زیر خواهد بود:
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
سفارشی سازی
ماژول خط اصلی Thread (در واقع بخشی از ماژول "Tethering" است) چند پیکربندی قابل همپوشانی را ارائه می دهد که می تواند توسط فروشندگان برای سفارشی کردن رفتار پشته مشخص شود. برای مشاهده لیست کامل به config_thread.xml مراجعه کنید.
به طور معمول، شما باید config_thread_vendor_name
، config_thread_vendor_oui
و config_thread_model_name
به مقدار فروشنده یا محصول خود تغییر دهید. این مقادیر در سرویس mDNS _meshcop._udp
که همیشه توسط Thread Border Router تبلیغ می شود، گنجانده می شود.
برای افزودن همپوشانی، باید یک هدف جدید ConnectivityOverlayOrange
runtime_resource_overlay برای دستگاه Orange خود ایجاد کنید. یک پوشه ConnectivityOverlay/
در زیر device/banana/orange/rro_overlays
ایجاد کنید و محتوای زیر را در آن ایجاد کنید:
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>
مشابه HAL APEX، باید اپلیکیشن همپوشانی را به فایل device.mk
خود اضافه کنید:
PRODUCT_PACKAGES += \ ConnectivityOverlayOrange</code>
اگر همه چیز کار کند، خواهید دید که ot-daemon
نام فروشنده و مدل را در همان ابتدای گزارش ثبت می کند:
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
با Google Home سازگار باشد
علاوه بر این، اگر میخواهید مسیریاب مرزی خود را توسط اکوسیستم Google Home استفاده کنید، میتوانید این پیکربندی را در config_thread.xml
مشخص کنید:
<string-array name="config_thread_mdns_vendor_specific_txts"> <item>vgh=1</item> </string-array>
تست کردن
اکنون دستگاه شما باید با مشخصات Thread 1.3+ Border Router سازگار باشد. قبل از ارسال آن به برنامه صدور گواهینامه Thread، برای اطمینان از سازگاری، باید چند تست Android xTS انجام دهید.
تست VTS مطمئن می شود که سرویس Thread HAL همانطور که انتظار می رود در دستگاه شما کار می کند. می توانید تست ها را با دستور اجرا کنید
atest VtsHalThreadNetworkTargetTest
آزمایش CTS اطمینان حاصل می کند که API های Thread همانطور که انتظار می رود در دستگاه شما کار می کنند. می توانید تست ها را با دستور اجرا کنید
atest CtsThreadNetworkTestCases
تست یکپارچه سازی تضمین کیفیت بیشتری از نحوه عملکرد کد خط اصلی Thread در دستگاه شما ارائه می دهد. می توانید تست ها را با دستور اجرا کنید
atest ThreadNetworkIntegrationTests
همچنین میتوانید دستورالعملهای بیشتری درباره نحوه اجرای تستهای VTS/CTS/MTS با مجموعههای آزمایشی منتشر شده پیدا کنید:
- https://source.android.com/docs/core/tests/vts
- https://source.android.com/docs/compatibility/cts/run
- https://docs.partner.android.com/mainline/test/mts (برای دسترسی به این لینک باید شریک باشید)
با برنامه آزمایشی Thread تست کنید
مشابه دستگاه Cuttlefish، می توانید برنامه آزمایشی Thread را به تصویر سیستم خود اضافه کنید:
# ThreadNetworkDemoApp for testing PRODUCT_PACKAGES_DEBUG += ThreadNetworkDemoApp
توجه داشته باشید که باید آن را فقط به نوع اشکالزدایی/انگلیسی اضافه کنید (به عنوان مثال PRODUCT_PACKAGES_DEBUG
) زیرا قرار نیست این مورد در ساخت کاربر برای مصرفکنندگان نهایی گنجانده شود.