Pakiet SDK Thread Network na Androida

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

Pakiet SDK Thread Network udostępnia funkcję podobną do cyfrowego pęku kluczy, dzięki której aplikacje na Androida mogą udostępniać dane logowania do sieci typu Thread do Usług Google Play. Dzięki temu aplikacje mogą skonfigurować dowolne urządzenie z wątku z dowolnego ekosystemu inteligentnego domu bez bezpośredniego udostępniania danych logowania i danych użytkownika.

Wystarczy kilka wywołań interfejsu API, aby:

  1. Poproś o preferowane dane logowania do sieci typu Thread z usługami Google Play.
  2. Skonfiguruj nowe routery graniczne i dodaj dane logowania do sieci Thread do usług Google Play.
  3. Jeśli masz już routery graniczne, możesz sprawdzić, czy routery graniczne są w preferowanej sieci, i w razie potrzeby je przenieść.

Należy wziąć pod uwagę kilka ścieżek użytkowników i deweloperów. Omówimy w nim większość z nich, a także inne kluczowe funkcje i zalecane zastosowania.

Kluczowa terminologia i pojęcia z interfejsami API

Zanim zaczniesz, warto zapoznać się z tymi warunkami:

  • Dane logowania do sieci typu Thread: binarny obiekt blob z kodami TLV typu Thread, które kodują nazwę sieci, klucz sieciowy i inne właściwości wymagane przez urządzenie do wątku, by dołączyć do danej sieci Thread.

  • Preferowane dane logowania do sieci typu Thread: automatycznie wybrane dane logowania do sieci typu Thread, które mogą być udostępniane aplikacjom różnych dostawców. Służy do tego interfejs API getPreferredCredentials.

  • Identyfikator agenta obramowania: 16-bitowy, unikalny globalnie identyfikator urządzenia Router Thread Border. Identyfikator jest tworzony i obsługiwany przez dostawców routerów granicznych.

  • Aplikacja do konfigurowania routera Thread Granica: to aplikacja na Androida, która konfiguruje nowe urządzenia routera Thread Border i dodaje je do usług Google Play. Twoja aplikacja jest wiarygodnym właścicielem dodanych danych logowania i ma bezpłatny dostęp do tych danych.

Wiele interfejsów Thread Network API zwraca zadanie, które jest asynchronicznie. Aby zarejestrować wywołania zwrotne w celu uzyskania wyniku, możesz użyć funkcji addOnSuccessListener i addOnFailureListener. Więcej informacji znajdziesz w dokumentacji zadań.

Własność i konserwacja danych logowania

Aplikacja, która dodaje dane logowania do sieci typu Thread, staje się właścicielem tych danych i ma pełne uprawnienia dostępu do tych danych. Jeśli spróbujesz uzyskać dostęp do danych logowania dodanych przez inne aplikacje, wystąpi błąd PERMISSION_DENIED.

Jako właściciel aplikacji najlepiej jest aktualizować dane logowania przechowywane w Usługach Google Play w przypadku aktualizacji sieci Thread Border. Oznacza to dodawanie danych logowania, gdy jest to konieczne, aktualizowanie danych logowania w przypadku zmiany routera granicznego routera Thread oraz usuwanie danych logowania w przypadku usunięcia routera Thread Granit, a także przywrócenia ustawień fabrycznych.

Wykrywanie agenta granicznego

Dane logowania muszą być zapisane przy użyciu identyfikatora agenta Border. Musisz sprawdzić, czy aplikacja do konfigurowania routera Thread... jest w stanie określić identyfikatory agentów granicznych routerów granic sieci.

Routery granicy wątków muszą używać mDNS, aby promować informacje o sieci typu Thread, w tym nazwę sieci, identyfikator Rozszerzonego panowania i identyfikator agenta granicznego. odpowiadające im wartości txt w przypadku tych atrybutów to odpowiednio nn, xp i id.

W przypadku sieci z routerami granicznymi Google Usługi Google Play automatycznie otrzymują dane logowania do sieci typu Google Thread.

Zintegruj pakiet SDK z aplikacją na Androida

Aby rozpocząć, wykonaj te czynności:

  1. Postępuj zgodnie z instrukcjami konfigurowania Usług Google Play.

  2. Dodaj zależność Usług Google Play od pliku build.gradle:

    implementation 'com.google.android.gms:play-services-threadnetwork:16.0.0-beta02'
    
  3. Opcjonalnie: określ klasę danych BorderAgent, aby przechowywać informacje o routerach granicznych. W tym przewodniku użyjemy tych danych:

    data class BorderAgentInfo(
      // Network Name max 16 len
      val networkName: String = "",
      val extPanId: ByteArray = ByteArray(16),
      val borderAgentId: ByteArray = ByteArray(16),
      ...
    )
    

Następnie przeprowadzimy zalecane kroki dodawania preferowanych danych logowania i zarządzania nimi.

Nowe konfiguracje routera granicznego

Zanim utworzysz nową sieć dla nowych routerów granicznych, spróbuj najpierw użyć preferowanych danych logowania do sieci. Dzięki temu urządzenia o wątkach są w miarę możliwości połączone z jedną siecią Thread.

Wywołanie funkcji getPreferredCredentials uruchamia aktywność z prośbą o zezwolenie na żądanie sieciowe. Jeśli dane logowania do sieci są przechowywane w cyfrowym pęku kluczy pakietu Thread SDK, dane logowania zostaną zwrócone do aplikacji.

Poproś o dane logowania

Aby poprosić użytkownika o wybranie danych logowania:

  1. Zadeklaruj właściwość ActivityLauncher:

    private lateinit var preferredCredentialsLauncher: ActivityResultLauncher<IntentSenderRequest>
    
  2. Postępuj zgodnie z wynikiem aktywności, która jest zwracana jako ThreadNetworkCredentials:

    preferredCredentialsLauncher =
     registerForActivityResult(
       StartIntentSenderForResult()
     ) { result: ActivityResult ->
       if (result.resultCode == RESULT_OK) {
         val threadNetworkCredentials = ThreadNetworkCredentials.fromIntentSenderResultData(result.data!!)
         Log.d("debug", threadNetworkCredentials.networkName)
       } else {
         Log.d("debug", "User denied request.")
       }
     }
    
  3. Zadzwoń do firmy preferredCredentials i uruchom aktywność:

    private fun getPreferredThreadNetworkCredentials() {
      ThreadNetwork.getClient(this)
        .preferredCredentials
      .addOnSuccessListener { intentSenderResult ->
        intentSenderResult.intentSender?.let {
          preferredCredentialsLauncher.launch(IntentSenderRequest.Builder(it).build())
          } ?: Log.d("debug", "No preferred credentials found.")
        }
      .addOnFailureListener { e: Exception -> Log.d(TAG, "ERROR: [${e}]") }
    }
    

Utwórz nową sieć Thread

Jeśli w sieci użytkownika nie ma preferowanych danych logowania do sieci typu Thread, możesz dodać dane logowania do usług Google Play za pomocą interfejsu addCredentials API. Aby to zrobić, musisz utworzyć ThreadBorderAgent i dostarczyć obiekt ThreadNetworkCredentials.

Aby utworzyć losową sieć, wywołaj funkcję newRandomizeBuilder:

val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder().build()

Aby określić nazwę sieci typu Thread:

val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder()
  .setNetworkName("ThreadNetworkSDK")
  .build()

Dodaj dane logowania

Aby udostępnić dane logowania do sieci typu Thread innym dostawcom Google Thread, musisz dodać je do usług Google Play. Zanim dodamy nowe dane logowania, musimy też wiedzieć, do którego urządzenia routera granicznego należy ta sieć Thread.

W tym przykładzie utworzymy ThreadBorderAgent na podstawie identyfikatora agenta obramowania i przekażemy nowo utworzone dane logowania do sieci typu Thread:

private fun addCredentials(borderAgentInfo: BorderAgentInfo, credentialsToBeAdded: ThreadNetworkCredentials) {

  val threadBorderAgent = ThreadBorderAgent.newBuilder(borderAgentInfo.borderAgentId).build()
  Log.d("debug", "border router id:" + threadBorderAgent.id)

  ThreadNetwork.getClient(this)
    .addCredentials(threadBorderAgent, credentialsToBeAdded)
      .addOnSuccessListener {
        Log.d("debug", "Credentials added.")
      }
      .addOnFailureListener { e: Exception -> Log.d(TAG, "ERROR: [${e}]") }
}

Wykrywanie i migracja routerów granicznych w polu

Jeśli masz już routery graniczne, możesz użyć isPreferredCredentials, by określić, czy routery graniczne należą do preferowanej sieci. Ten interfejs API nie prosi użytkownika o zgodę i sprawdza dane logowania routera granicznego względem danych zapisanych w Usługach Google Play.

isPreferredCredentails zwraca 0 jako niedopasowany, a 1 dla dopasowania jako typ danych Int. Możesz użyć IsPreferredCredentialsResult, aby sprawdzić wyniki.

public @interface IsPreferredCredentialsResult {
    int PREFERRED_CREDENTIALS_NOT_FOUND = -1;
    int PREFERRED_CREDENTIALS_NOT_MATCHED = 0;
    int PREFERRED_CREDENTIALS_MATCHED = 1;
}

Aby używać funkcji isPreferredCredentials, musisz najpierw utworzyć obiekt ThreadNetworkCredentials. Możesz utworzyć instancję ThreadNetworkCredentials na kilka sposobów. W kolejnych krokach omówimy te opcje.

Dane logowania do sieci typu Thread według zbioru danych operacyjnych

W niektórych przypadkach router graniczny jest już skonfigurowany jako sieć z wątkiem i chcesz dodać ją do usług Google Play, aby udostępnić ją innym dostawcom. Instancję ThreadNetworkCredential możesz utworzyć z nieprzetworzonej listy TLV aktywnego zbioru danych wątków:

  1. Przekonwertuj zbiór danych operacyjnych na właściwość ByteArray. Przykład:

    val activeDataset =
          "0e080000000000010000000300000f35060004001fffe0020833333333...".dsToByteArray()
    
    fun String.dsToByteArray(): ByteArray {
      return chunked(2).map { it.toInt(16).toByte() }.toByteArray()
    }
    
  2. Użyj narzędzia fromActiveOperationalDataset, aby utworzyć ThreadNetworkCredentials. Gdy uda Ci się to zrobić, uzyskasz dostęp do nazwy sieci, kanału i innych informacji o sieci. Pełną listę właściwości znajdziesz w temacie ThreadNetworkCredentials.

    val threadNetworkCredentials =
        ThreadNetworkCredentials.fromActiveOperationalDataset(activeDataset)
    Log.d(
        "threadNetworkCredentials",
        threadNetworkCredentials.channel.toString() + " - " + threadNetworkCredentials.networkName)
    
  3. Wywołaj interfejs API isPreferredCredentials i przekaż ThreadNetworkCredentials.

    ThreadNetwork.getClient(this)
    .isPreferredCredentials(threadNetworkCredentials)
    .addOnSuccessListener { result ->
      when (result) {
        IsPreferredCredentialsResult.PREFERRED_CREDENTIALS_NOT_MATCHED ->
            Log.d("isPreferredCredentials", "Credentials not matched.")
        IsPreferredCredentialsResult.PREFERRED_CREDENTIALS_MATCHED ->
            Log.d("isPreferredCredentials", "Credentials matched.")
      }
    }
    .addOnFailureListener { e: Exception -> Log.d("isPreferredCredentials", "ERROR: [${e}]") }
    

Dane logowania do sieci typu Thread według agenta Border

Identyfikator agenta granicznego jednoznacznie identyfikuje urządzenie routera granicznego. Aby korzystać z interfejsu getCredentialsByBorderAgent API, musisz najpierw utworzyć obiekt ThreadBorderAgent i przekazać identyfikator agenta Border.

Po utworzeniu obiektu ThreadBorderAgent wywołaj getCredentialsByBorderAgent. Jeśli dane logowania zostały zapisane, sprawdź, czy są preferowane.

private fun isPreferredThreadNetworkByBorderAgent(borderAgentInfo: BorderAgentInfo) {

  val threadBorderAgent = ThreadBorderAgent.newBuilder(borderAgentInfo.borderAgentId).build()
  Log.d("debug", "border router id:" + threadBorderAgent.id)

  var isPreferred = IsPreferredCredentialsResult.PREFERRED_CREDENTIALS_NOT_FOUND
  var borderAgentCredentials: ThreadNetworkCredentials?
  val taskByBorderAgent = ThreadNetwork.getClient(this)
  taskByBorderAgent
      .getCredentialsByBorderAgent(threadBorderAgent)
      .addOnSuccessListener { result: ThreadNetworkCredentialsResult ->
        borderAgentCredentials = result.credentials
        result.credentials?.let {
          taskByBorderAgent.isPreferredCredentials(it).addOnSuccessListener { result ->
            isPreferred = result
          }
        }
      }
      .addOnFailureListener { e: Exception -> Log.d(TAG, "ERROR: [${e}]") }
}

Dane logowania do sieci typu Thread według identyfikatora rozszerzonego przesuwania

Podobnie jak w przypadku getPreferredCredentials, możesz też poprosić użytkownika o podanie danych logowania z ulepszonego routera granicznego. getCredentialsByExtendedPanId zwraca IntentSender, a wynik aktywności zawiera obiekt ThreadNetworkCredentials po zatwierdzeniu przez użytkownika.

private fun getCredentialsByExtPanId(borderAgentInfo: BorderAgentInfo) {
  ThreadNetwork.getClient(this)
    .getCredentialsByExtendedPanId(borderAgentInfo.extPanId)
    .addOnSuccessListener { intentSenderResult ->
      intentSenderResult.intentSender?.let {
        preferredCredentialsLauncher.launch(IntentSenderRequest.Builder(it).build())
      }
        ?: Log.d("debug", "No credentials found.")
    }
    .addOnFailureListener { e: Exception -> Log.d(TAG, "ERROR: [${e}]") }
}

Usuń dane logowania

Gdy usuniesz urządzenie z granicy z domu lub urządzenia do ustawień fabrycznych, musisz usunąć jego sieć Thread – z Usług Google Play.

private fun removeCredentials(borderAgentInfo: BorderAgentInfo) {

  val threadBorderAgent = ThreadBorderAgent.newBuilder(borderAgentInfo.borderAgentId).build()
  Log.d("debug", "border router id:" + threadBorderAgent.id)

  ThreadNetwork.getClient(this)
      .removeCredentials(threadBorderAgent)
      .addOnSuccessListener { Log.d("debug", "Credentials removed.") }
      .addOnFailureListener { e: Exception -> Log.d(TAG, "ERROR: [${e}]") }
}

Zasoby

Więcej informacji o pakiecie Thread Network SDK znajdziesz w dokumentacji API.