Pakiet Thread Network SDK udostępnia funkcje podobne do cyfrowego pęku kluczy, dzięki czemu aplikacje na Androida mogą udostępniać dane logowania do sieci Thread usługom Google Play. Dzięki temu aplikacje mogą konfigurować dowolne urządzenia Thread z dowolnego ekosystemu inteligentnego domu bez bezpośredniego ujawniania danych logowania i danych użytkownika.
Za pomocą kilku wywołań interfejsu API możesz:
- Poproś Usługi Google Play o preferowane dane logowania do sieci Thread.
- Skonfiguruj nowe urządzenia Thread Border Router (TBR) i dodaj dane uwierzytelniające sieci Thread do Usług Google Play.
- Jeśli masz już urządzenia TBR, możesz sprawdzić, czy są TBRone w preferowanej sieci, i w razie potrzeby je przenieść.
Należy wziąć pod uwagę kilka ścieżek użytkowników i programistów. W tym przewodniku omówimy większość z nich, a także inne kluczowe funkcje i zalecane zastosowania.
Kluczowa terminologia i pojęcia związane z interfejsem API
Zanim zaczniesz, zapoznaj się z tymi terminami:
Dane logowania do sieci Thread: binarny obiekt blob TLV Thread, który koduje nazwę sieci Thread, klucz sieciowy i inne właściwości wymagane przez urządzenie Thread do dołączenia do danej sieci Thread.
Preferowane dane logowania do sieci Thread: automatycznie wybrane dane logowania do sieci Thread, które można udostępniać aplikacjom różnych dostawców za pomocą interfejsu API
getPreferredCredentials.Identyfikator agenta granicznego: 16-bajtowy globalnie unikalny identyfikator urządzenia TBR. Ten identyfikator jest tworzony przez dostawców border router, którzy nim zarządzają.
Aplikacja do konfiguracji TBR: to aplikacja na Androida, która konfiguruje nowe urządzenia TBR i dodaje dane logowania do sieci Thread do Usług Google Play. Twoja aplikacja jest autorytatywnym właścicielem dodanych danych logowania i ma do nich dostęp.
Wiele interfejsów Thread Network API zwraca zadanie, które jest wykonywane asynchronicznie. Możesz użyć addOnSuccessListener i addOnFailureListener, aby zarejestrować wywołania zwrotne do otrzymywania wyniku. Więcej informacji znajdziesz w dokumentacji Task.
Własność i utrzymanie danych logowania
Aplikacja, która dodaje dane uwierzytelniające sieci Thread, staje się ich właścicielem i ma pełne uprawnienia dostępu do nich. Jeśli spróbujesz uzyskać dostęp do danych logowania dodanych przez inne aplikacje, pojawi się błąd PERMISSION_DENIED.
Zalecamy, aby właściciel aplikacji aktualizował dane logowania przechowywane w usługach Google Play, gdy sieć TBR zostanie zaktualizowana. Oznacza to dodawanie danych logowania, gdy jest to wymagane, aktualizowanie danych logowania, gdy zmieniają się dane logowania sieci Thread urządzenia border router, oraz usuwanie danych logowania, gdy urządzenie TBR zostanie usunięte lub przywrócone do ustawień fabrycznych.
Wykrywanie agenta granicznego
Dane logowania muszą być zapisane z identyfikatorem agenta granicznego. Musisz się upewnić, że aplikacja do konfiguracji TBR może określić identyfikatory agentów granicznych Twoich urządzeń TBR.
TBR musi używać mDNS do rozgłaszania informacji o sieci Thread, w tym nazwy sieci, rozszerzonego identyfikatora PAN i identyfikatora agenta granicznego. Odpowiednie wartości txt dla tych atrybutów to odpowiednio nn, xp i id.
W przypadku sieci z Google Thread Border Router (gTBR) Usługi Google Play automatycznie pobierają dane logowania do sieci Thread od Google.
Integrowanie pakietu SDK z aplikacją na Androida
Aby rozpocząć, wykonaj te czynności:
Postępuj zgodnie z instrukcjami podanymi w artykule Konfigurowanie Usług Google Play.
Dodaj zależność Usług Google Play do pliku
build.gradle:implementation 'com.google.android.gms:play-services-threadnetwork:16.2.1'Opcjonalnie: zdefiniuj klasę danych
BorderAgent, aby przechowywać informacje o TBR. W tym przewodniku będziemy używać 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 omówimy zalecane kroki dodawania preferowanych danych logowania i zarządzania nimi.
Konfiguracja nowych routerów granicznych Thread
Zanim utworzysz nową sieć dla nowych routerów granicznych, najpierw spróbuj użyć danych logowania do preferowanej sieci. Dzięki temu urządzenia Thread są połączone z jedną siecią Thread, gdy jest to możliwe.
Wywołanie metody getPreferredCredentials uruchamia aktywność, która prosi użytkowników o zezwolenie na żądanie sieciowe. Jeśli dane uwierzytelniające sieci zostały zapisane w cyfrowym pęku kluczy pakietu Thread SDK, zostaną one zwrócone do aplikacji.
Poproś o dane logowania
Aby poprosić użytkownika o preferowane dane logowania:
Zadeklaruj
ActivityLauncher:private lateinit var preferredCredentialsLauncher: ActivityResultLauncher<IntentSenderRequest>Obsłuż wynik aktywności zwrócony 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.") } }Jeśli konfigurujesz nową aktywność TBR, zalecamy wywołanie
preferredCredentialsi uruchomienie aktywności. To wywołanie sprawi, że nowa karta TBR będzie używać tych samych danych logowania, które są już zapisane jako preferowane na telefonie, co ułatwi konwergencję różnych kart TBR w tej samej sieci.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}]") } }Jeśli Twój przypadek użycia dotyczy konfigurowania urządzeń, które nie są routerami Thread, np. nowego urządzenia końcowego Matter-over-Thread, zalecamy użycie interfejsu API
allActiveCredentialsdo pobierania danych logowania. To wywołanie skanuje w poszukiwaniu TBR-ów znalezionych w sieci lokalnej, więc nie zwraca danych logowania, które nie są dostępne lokalnie przez istniejący TBR.// Creates the IntentSender result launcher for the getAllActiveCredentials API private val getAllActiveCredentialsLauncher = registerForActivityResult( StartIntentSenderForResult() ) { result: ActivityResult -> if (result.resultCode == RESULT_OK) { val activeCredentials: List<ThreadNetworkCredentials> = ThreadNetworkCredentials.parseListFromIntentSenderResultData( result.data!! ) // Use the activeCredentials list } else { // The user denied to share! } } // Invokes the getAllActiveCredentials API and starts the dialog activity with the returned // IntentSender threadNetworkClient .getAllActiveCredentials() .addOnSuccessListener { intentSenderResult: IntentSenderResult -> val intentSender = intentSenderResult.intentSender if (intentSender != null) { getAllActiveCredentialsLauncher.launch( IntentSenderRequest.Builder(intentSender).build() ) } else { // No active network credentials found! } } // Handles the failure .addOnFailureListener { e: Exception -> // Handle the exception }
Tworzenie nowej sieci Thread
Jeśli w sieci Thread użytkownika nie ma preferowanych ani aktywnych danych logowania, możesz użyć interfejsu API addCredentials, aby dodać dane logowania do Usług Google Play. Aby to zrobić, musisz utworzyć ThreadBorderAgent i podać obiekt ThreadNetworkCredentials.
Aby utworzyć losową sieć, wywołaj newRandomizeBuilder:
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder().build()
Aby określić nazwę sieci Thread:
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder()
.setNetworkName("ThreadNetworkSDK")
.build()
Dodawanie danych logowania
Aby dane logowania do sieci Thread były dostępne dla innych dostawców Thread, musimy dodać je do Usług Google Play. Zanim dodamy nowe dane logowania, musimy też wiedzieć, do którego urządzenia TBR należy ta sieć Thread.
W tym przykładzie utworzymy ThreadBorderAgent na podstawie identyfikatora agenta granicznego i przekażemy nowo utworzone dane logowania do sieci 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 border routerów w terenie
Jeśli masz border router w terenie, możesz użyć isPreferredCredentials, aby sprawdzić, czy border router należą do preferowanej sieci. Ten interfejs API nie prosi użytkownika o uprawnienia i sprawdza dane logowania border router pod kątem danych przechowywanych w usługach Google Play.
Funkcja isPreferredCredentials zwraca wartość 0 w przypadku braku dopasowania i 1 w przypadku dopasowania jako typ danych Int. Aby sprawdzić wyniki, możesz użyć IsPreferredCredentialsResult.
public @interface IsPreferredCredentialsResult {
int PREFERRED_CREDENTIALS_NOT_FOUND = -1;
int PREFERRED_CREDENTIALS_NOT_MATCHED = 0;
int PREFERRED_CREDENTIALS_MATCHED = 1;
}
Aby używać isPreferredCredentials, musisz najpierw utworzyć obiekt ThreadNetworkCredentials. Istnieje kilka sposobów na utworzenie instancji ThreadNetworkCredentials. W kolejnych krokach omówimy te opcje.
Dane logowania do sieci Thread według operacyjnego zbioru danych
W niektórych przypadkach urządzenie TBR jest już skonfigurowane z siecią Thread i chcesz dodać tę sieć do Usług Google Play, aby udostępnić ją innym dostawcom. Możesz utworzyć instancję ThreadNetworkCredential z nieprzetworzonej listy TLV aktywnego operacyjnego zbioru danych Thread:
Przekonwertuj operacyjny zbiór danych na
ByteArray. Na przykład:val activeDataset = "0e080000000000010000000300000f35060004001fffe0020833333333...".dsToByteArray()fun String.dsToByteArray(): ByteArray { return chunked(2).map { it.toInt(16).toByte() }.toByteArray() }Użyj
fromActiveOperationalDataset, aby utworzyćThreadNetworkCredentials. Jeśli się uda, zobaczysz nazwę sieci Thread, kanał i inne informacje o sieci. Pełną listę właściwości znajdziesz w artykule ThreadNetworkCredentials.val threadNetworkCredentials = ThreadNetworkCredentials.fromActiveOperationalDataset(activeDataset) Log.d( "threadNetworkCredentials", threadNetworkCredentials.channel.toString() + " - " + threadNetworkCredentials.networkName)Wywołaj interfejs API
isPreferredCredentialsi 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 Thread według agenta granicznego
Identyfikator agenta granicznego jednoznacznie identyfikuje urządzenie TBR. Aby używać interfejsu API getCredentialsByBorderAgent, musisz najpierw utworzyć obiekt ThreadBorderAgent i podać identyfikator agenta granicznego.
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 Thread według rozszerzonego identyfikatora PAN
Podobnie jak w przypadku getPreferredCredentials, możesz też poprosić użytkownika o dane logowania z rozszerzonego identyfikatora PAN urządzenia TBR. getCredentialsByExtendedPanId zwraca IntentSender, a wynik aktywności zawiera obiekt ThreadNetworkCredentials, gdy użytkownik zatwierdzi działanie.
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}]") }
}
Usuwanie danych logowania
Gdy urządzenie border router zostanie usunięte z domu lub przywrócone 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.