Android Sınır Yönlendirici oluşturma

Android Kod Arama Aracı'nda kaynağı görüntüleme

Android cihaz veya Thread çipi tedarikçisi değilseniz bu e-postanın devamını okumaya son verebilirsiniz.

Bu dokümanda, en son AOSP kaynak koduyla yeni bir Android tabanlı Thread Border Router cihazı oluşturma adımları açıklanmaktadır. Bu dokümanı uygulayarak şunları öğreneceksiniz:

  1. Android'de Thread desteğinin genel mimarisi ve durumu
  2. how to create your own Thread HAL service
  3. Cihazınızı Google Home ile uyumlu hale getirme
  4. Thread sınır yönlendiricinizi test etme

Desteğe ihtiyacınız varsa GitHub'da sorun kaydı oluşturun veya sorunuzu Tartışma bölümünde paylaşın.

Genel Bakış

Android Thread yığını, Google tarafından GitHub'da açık kaynak olarak yayınlanan OpenThread ve ot-br-posix'e dayanır. OpenThread'in herkese açık bir GitHub deposunda geliştirildiği gibi Android Thread yığını da herkese açık AOSP kod tabanında geliştirilir. Tüm özellikler ve hata düzeltmeleri önce AOSP'ye gönderilir. Bu sayede tedarikçiler, normal Android sürümlerini beklemeden en son Thread sürümlerini kullanmaya başlayabilir.

Mimari

Android Thread yığınının tamamı iki ana bileşenden oluşur: genel sistem bölümündeki çekirdek Thread yığını ve tedarikçi bölümündeki Thread HAL hizmeti. Cihaz tedarikçilerinin genellikle yalnızca HAL hizmetini oluşturması ve yönetmesi gerekir.

android-thread-arch

Android Thread yığınının işleyiş şeklinin kısa bir özetini aşağıda bulabilirsiniz: - Sistem sunucusunda, yığının tamamını yöneten bir Java Thread sistem hizmeti bulunur. Bu hizmet, Thread sistem API'sini sağlar, thread-wpan tüneli arayüzünü oluşturur, Thread ağını Bağlantı hizmetine kaydeder ve Sınır Yönlendirme ve Reklam Aracısı işlevlerini uygular. - Temel Thread / OpenThread yığını, ot-daemon adlı ayrıcalıklı olmayan bağımsız bir yerel süreçte barındırılır. ot-daemon, özel AIDL API'leri aracılığıyla doğrudan Java sistem hizmeti tarafından yönetilir ve Thread HAL API üzerinden Thread donanım radyosuna erişir. - Tedarikçi firma tarafından sağlanan bir Thread HAL hizmeti, Thread HAL API'yi UYGULAMALIDIR. Genellikle RCP olarak çalışır ve spinel protokolünü uygular.

Kod nerede?

Geliştirme ortamını ayarlama

Cihaz için Android geliştirme ortamı oluşturmuş Android cihaz tedarikçileri bu bölümü atlayabilir.

Android ekosistemine yeni katıldıysanız veya Thread çipinizi Android ile uyumlu hale getirmek ve cihaz tedarikçileri için destek sağlamak isteyen bir silikon tedarikçisiyseniz okumaya devam edin.

Android geliştirici kod laboratuvarını takip edin

Android geliştirme ortamınızı ilk kez kurmak için aşağıdaki codelab'i kullanın: https://source.android.com/docs/setup/start. Bu codelab'in sonunda, kaynak koddan simüle edilmiş bir Mürekkep Balığı cihazı oluşturup çalıştırabileceksiniz.

Thread HAL hizmetinizi oluşturma

Cuttlefish'te ileti dizisini deneyin

Mürekkepbalığı, sanal Android cihazdır. Kendi HAL hizmetinizi oluşturmaya başlamadan önce, HAL'in nasıl çalıştığını anlamak için Cuttlefish'te Thread'i denemeniz önerilir.

Cuttlefish'te varsayılan bir Thread HAL hizmeti sağlanır ve bu hizmet, UDP soketi üzerinden simüle edilmiş bir Thread (802.15.4) radyosuyla paketleri alıcı ve verici olarak kullanan simulasyonlu RCP ile uygulanır.

Cuttlefish örneğine "ThreadNetworkDemoApp" önceden yüklenmiştir. Cuttlefish cihazını varsayılan bir Thread ağına katılmak için bu uygulamayı açın.

demoapp-screenshot

Ayrıca, Thread ağınızı test için yapılandırmak üzere ot-ctl ve ot-cli-ftd komut satırı araçları da sağlanır. Bu araçlar, aşina olabileceğiniz tüm OpenThread CLI komutlarını destekler.

Aşağıdakileri yaparak Cuttlefish Thread HAL hizmetinin günlüklerini arayabilirsiniz:

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

Dilerseniz aşağıdaki yöntemlerle ot-daemon günlüklerini arayabilirsiniz:

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 hizmeti, varsayılan Thread HAL hizmetinin yanı sıra OpenThread simüle edilmiş RCP ikilisini kullanır. Bu hizmetin nasıl çalıştığıyla ilgili bilgi için sonraki bölüme bakın.

Varsayılan HAL hizmeti

Thread HAL API ile birlikte varsayılan bir HAL hizmeti de dahildir. Varsayılan HAL hizmeti hem simüle edilmiş hem de gerçek RCP cihazlarını destekler. İsteğe bağlı bir RCP cihaz URL'si alır ve URL sağlanmazsa varsayılan olarak simüle edilmiş RCP cihazını kullanır.

hardware/interfaces/threadnetwork/aidl/default/threadnetwork-service.rc dosyasında:

service vendor.threadnetwork_hal /apex/com.android.hardware.threadnetwork/bin/hw/android.hardware.threadnetwork-service
    class hal
    user thread_network

Bu, aşağıdakilere eşdeğerdir:

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

Gerçek RCP cihazları için hem SPI hem de UART arayüzlerini destekler. Cihazları sırasıyla spinel+spi://, spinel+hdlc+uart:// ve spinel+socket:// şemalarıyla belirtebilirsiniz.

Tedarikçi APEX'i anlama

Tethering ana hat modülündeki Thread yığınına benzer şekilde, Cuttlefish'teki varsayılan Thread HAL hizmeti de bir APEX modülüne paketlenmiştir. Ancak bu, /vendor/apex/'e yüklenecek bir tedarikçi APEX modülüdür (Modüldeki yapıların sıkıştırması /apex/com.android.hardware.threadnetwork/'te açılır).

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
    ],
}

Kendi HAL APEX modülünüzü oluştururken dikkat etmeniz veya değişiklikler yapmanız gereken birkaç önemli yapılandırma vardır:

  • file_contexts: Bu, bu APEX modülünde yayınlanan ikili program / veri dosyalarını veya HAL hizmetinin erişmesi gereken dosyaları (ör. RCP cihazı) tanımlar. Bu sayede, HAL hizmetinizin donanım RCP cihazına erişmesi için belirli sepolicy kuralları belirtebilirsiniz.

  • binaries: Bu APEX modülünde yayınlanan ikili dosya

  • threadnetwork-service.rc: HAL hizmetinin nasıl başlatılacağı. Burada RCP cihaz yolunu belirtmeniz gerekir.

  • android.hardware.thread_network.prebuilt.xml: Donanım özelliğini tanımlar.android.hardware.thread_network Bu, Android sisteminin cihazınızın Thread donanım desteğine sahip olduğunu bilmesi için gereklidir. Aksi takdirde Android Thread yığını etkinleştirilmez.

HAL hizmetinizi oluşturma

Android cihaz geliştiricisi veya silikon tedarikçisi olmanız fark etmeksizin, Thread çipiniz için OT RCP donanım yazılımı oluşturma hakkında bilgi sahibi olmanız gerekir. Aşağıdaki talimatlarda, donanım çipinin doğru şekilde bağlandığı ve doğrulandığı varsayılır.

HAL APEX'inizi oluşturmanın en basit yolu, varsayılan HAL APEX'in ikili dosyalarını ve önceden derlenmiş öğelerini içeren yeni bir APEX oluşturmaktır. Örneğin, şirketiniz Banana ise ve cihazınızdaki RCP cihazı /dev/ttyACM0 ise Thread HAL APEX'iniz şu şekilde görünür:

  • 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

İlk sütundaki dosya yolları /apex/com.android.hardware.threadnetwork/ ile ilgilidir.

  • 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 adlı yeni bir cihaz oluşturduğunuzu varsayalım. Cihazınıza özel yapılandırma dizini şu şekilde olur:

device/banana/orange/threadnetwork/
    sepolicy/
    Android.bp
    file_contexts
    manifest.json
    threadnetwork-default.xml
    threadnetwork-service.rc

sepolicy/ alt dizinine hangi sepolicy kurallarının eklenmesi gerektiği için sonraki bölüme bakın.

RCP cihazı için Sepolicy kuralları

Thread HAL hizmetiniz varsayılan olarak RCP cihazına (ör. /dev/ttyACM0) erişemez. sepolicy/ dizinine özel sepolicy kurallarının eklenmesi gerekir.

Aşağıdaki içeriği içeren yeni bir sepolicy/threadnetwork_hal.te dosyası oluşturun:

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;

Bir araya getirme

Thread eklemek için gereken neredeyse tüm kodları tamamladınız. Son adımda, Thread HAL APEX ve sepolicy kurallarını cihazınızın resmine eklemeniz gerekir.

Bunu, cihazınızın Makefile bölümüne (örneğin, device.mk) aşağıdaki kodu ekleyerek yapabilirsiniz:

PRODUCT_PACKAGES += com.banana.hardware.threadnetwork
BOARD_SEPOLICY_DIRS += device/banana/orange/threadnetwork/sepolicy

Her şey yolunda giderse Thread HAL hizmet günlüğünü şuna benzer şekilde görebilirsiniz:

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 günlüğü ise şöyle görünür:

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

Özelleştirme

Thread ana modülü (aslında "Tethering" modülünün bir parçasıdır), tedarikçi firmaların yığın davranışını özelleştirmek için belirtebileceği birkaç üst üste bindirilebilir yapılandırma sağlar. Tam liste için config_thread.xml dosyasını inceleyin.

Genellikle, cihazınızı Thread sınır yönlendirici olarak etkinleştirmek için config_thread_border_router_default_enabled değerini true olarak ayarlamanız ve config_thread_vendor_name, config_thread_vendor_oui ve config_thread_model_name değerlerini tedarikçi veya ürün değerlerinize göre değiştirmeniz gerekir. Bu değerler, her zaman bir Thread Sınır Yönlendiricisi tarafından reklamı yapılan _meshcop._udp mDNS hizmetine dahil edilir.

Yer paylaşımını eklemek için Orange cihazınız için yeni bir ConnectivityOverlayOrange runtime_resource_overlay hedefi oluşturmanız gerekir. device/banana/orange/rro_overlays altında yeni bir ConnectivityOverlay/ dizini oluşturun ve aşağıdaki içerikleri bu dizinde oluşturun:

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>
  

HAL APEX'e benzer şekilde, yer paylaşımı uygulamasını device.mk dosyanıza eklemeniz gerekir:

PRODUCT_PACKAGES += \
    ConnectivityOverlayOrange</code>

Her şey yolunda giderse ot-daemon, tedarikçi firma ve model adını günlüğün en başında kaydettiğini görürsünüz:

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 ile uyumlu olmalıdır.

Ayrıca, Sınır Yönlendiricinizin Google Home ekosistemi tarafından kullanılmasını istiyorsanız bu yapılandırmayı config_thread.xml'te belirtebilirsiniz:

<string-array name="config_thread_mdns_vendor_specific_txts">
  <item>vgh=1</item>
</string-array>

Test

Cihazınız artık Thread 1.3 ve sonraki sürümlerin sınır yönlendirici özellikleriyle uyumlu olmalıdır. Thread sertifika programına gönderilmeden önce, uyumluluğu sağlamak için birkaç Android xTS testi uygulanmalıdır.

  • VTS testi, Thread HAL hizmetinin cihazınızda beklendiği gibi çalıştığından emin olur. Testleri şu komutla çalıştırabilirsiniz:

    atest VtsHalThreadNetworkTargetTest

  • CTS testi, Thread API'lerinin cihazınızda beklendiği gibi çalıştığından emin olur. Testleri şu komutla çalıştırabilirsiniz:

    atest CtsThreadNetworkTestCases

  • Entegrasyon testi, Thread ana hattı kodunun cihazınızda nasıl çalıştığıyla ilgili daha fazla kalite garantisi sunar. Testleri komutla çalıştırabilirsiniz

    atest ThreadNetworkIntegrationTests

Ayrıca, yayınlanan bu test paketleriyle VTS/CTS/MTS testlerinin nasıl çalıştırılacağına dair daha fazla talimat da bulabilirsiniz:

Mesaj dizisi demo uygulamasıyla test etme

Mürekkepbalığı cihazına benzer şekilde, sistem resminize Thread demo uygulamasını ekleyebilirsiniz:

# ThreadNetworkDemoApp for testing
PRODUCT_PACKAGES_DEBUG += ThreadNetworkDemoApp

Son tüketiciler için kullanıcı derlemesine dahil edilmemesi gerektiğinden, yalnızca hata ayıklama / mühendislik varyantına (örneğin, PRODUCT_PACKAGES_DEBUG) eklemeniz gerektiğini unutmayın.