SDK Thread Network per Android

Thread Network SDK offre funzionalità simili a quelle portachiavi, che consente alle app Android di condividere le credenziali di rete Thread Google Play Services. In questo modo le tue app possono configurare qualsiasi dispositivo Thread da in qualsiasi ecosistema per la smart home, senza esporre direttamente le credenziali e i dati utente.

Con poche chiamate API puoi:

  1. Richiedi le credenziali di rete Thread preferite da Google Play Services.
  2. Configura nuovi router di confine e aggiungi le tue credenziali di rete Thread a Google Play Services.
  3. Se disponi già di router di confine sul campo, puoi controllare se i router si trovano nella rete preferita ed eseguine la migrazione, se necessario.

Ci sono diversi percorsi utente e sviluppatore da prendere in considerazione. Tratteremo la maggior parte delle in questa guida, insieme ad altre funzionalità chiave e all'utilizzo consigliato.

Terminologia chiave e concetti delle API

Prima di iniziare, è utile comprendere i seguenti termini:

  • Credenziali di rete Thread: BLOB binario di TLV Thread che codificano Nome rete Thread, chiave di rete e altre proprietà richieste dal un dispositivo Thread per accedere a una determinata rete Thread.

  • Credenziali di rete Thread preferite:la rete Thread selezionata automaticamente. e credenziali che possono essere condivise con app di diversi fornitori utilizzando API getPreferredCredentials.

  • ID agente di confine:un ID univoco globale da 16 byte per un router di confine Thread dispositivo. Questo ID viene creato e gestito dai fornitori di router di confine.

  • App di configurazione router di confine Thread: è l'app per Android che consente di configurare nuovi dispositivi router di confine Thread e aggiunge le credenziali di rete Thread Google Play Services. La tua app sia il proprietario autorevole dei contenuti aggiunti credenziali e che vi abbia accesso.

Molte delle API di rete Thread restituiscono un Attività che viene completata in modo asincrono. Puoi utilizzare addOnSuccessListener e addOnFailureListener per registrare i callback per ricevere il risultato. Per saperne di più, consulta Attività documentazione.

Proprietà e manutenzione delle credenziali

L'app che aggiunge le credenziali di rete Thread diventa la proprietaria della credenziali e dispone di autorizzazioni complete per accedervi. Se provi per accedere alle credenziali aggiunte da altre app, riceverai un PERMISSION_DENIED .

In qualità di proprietario dell'app, ti consigliamo di conservare le credenziali archiviate su Google Play Services aggiornato quando la rete del router di confine Thread viene aggiornata. Questo significa aggiungere credenziali quando sono necessarie, aggiornare le credenziali quando il confine le credenziali di rete Thread del router cambiano e rimuovono le credenziali quando Il router di confine Thread è stato rimosso o è stato ripristinato i dati di fabbrica.

Scoperta agente di frontiera

Le credenziali devono essere salvate con un ID agente di frontiera. Dovrai assicurarti l'app di configurazione del router di confine Thread è in grado di determinare gli ID agente di confine dei tuoi router di confine Thread.

i router di confine Thread devono utilizzare mDNS per pubblicizzare le informazioni di rete Thread, tra cui nome di rete, ID pan esteso e ID agente di confine. La i valori di txt corrispondenti per questi attributi sono nn, xp e id, rispettivamente.

Per le reti con router di confine Google, Google Play Services automaticamente ottiene le credenziali di rete Thread di Google da utilizzare.

Integra l'SDK nella tua app per Android

Per iniziare, completa i seguenti passaggi:

  1. Segui le istruzioni fornite all'indirizzo Configura Google Play Services.

  2. Aggiungi la dipendenza di Google Play Services al file build.gradle:

    implementation 'com.google.android.gms:play-services-threadnetwork:16.0.0'
    
  3. (Facoltativo) Definisci una classe di dati BorderAgent per archiviare il router di confine informazioni. Utilizzeremo questi dati nel corso della guida:

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

Ora esamineremo i passaggi consigliati per aggiungere e gestire le e credenziali.

Nuove configurazioni del router di confine

Prima di creare una nuova rete per i nuovi router di confine, è importante di provare prima a utilizzare le credenziali di rete preferite. Ciò garantisce che I dispositivi Thread sono connessi a una singola rete Thread quando possibile.

Viene avviata una chiamata al numero getPreferredCredentials un'attività, che chiede agli utenti di consentire la richiesta di rete. Se la rete sono state archiviate nel portachiavi digitale dell'SDK Thread, le credenziali vengono restituiti alla tua app.

Richiedi credenziali

Per richiedere all'utente le credenziali preferite:

  1. Dichiara ActivityLauncher:

    private lateinit var preferredCredentialsLauncher: ActivityResultLauncher<IntentSenderRequest>
    
  2. Gestisci il risultato dell'attività, restituito come 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. Chiama preferredCredentials e avvia l'attività:

    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}]") }
    }
    

Crea una nuova rete Thread

Se non sono disponibili credenziali di rete Thread preferite nel Thread, quindi puoi usare l'API addCredentials per aggiungere le credenziali Google Play Services. Per farlo, dovrai creare un ThreadBorderAgent, e fornisce anche un oggetto ThreadNetworkCredentials.

Per creare una rete casuale, richiama newRandomizeBuilder:

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

Per specificare il nome della rete Thread:

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

Aggiungi credenziali

Per rendere disponibili le tue credenziali di rete Thread ad altri fornitori di Thread, dobbiamo aggiungerle a Google Play Services. Prima di poter aggiungere il nostro nuovo credenziali, dobbiamo anche sapere a quale router di confine è presente questo Thread a cui appartiene ogni singola rete.

In questo esempio, creeremo un ThreadBorderAgent da un ID agente di frontiera e passa le nuove credenziali di rete Thread che hai appena creato:

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}]") }
}

Rilevare ed eseguire la migrazione dei router di confine sul campo

Se al momento disponi di router di confine sul campo, puoi usare isPreferredCredentials per determinare se i tuoi router di confine appartengono alla rete preferita. Questa API non richiede all'utente per richiedere l'autorizzazione e controlla le credenziali del router di confine in base a quanto archiviato in Google Play Services.

isPreferredCredentails restituisce 0 per non corrispondente e 1 per corrispondente, come tipo di dati Int. Puoi usare IsPreferredCredentialsResult per controllare i risultati.

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

Per usare isPreferredCredentials, dovrai creare un ThreadNetworkCredentials prima dell'oggetto. Esistono diversi modi per creare un'istanza per ThreadNetworkCredentials. Nei prossimi passaggi, esamineremo queste opzioni.

Credenziali di rete in Thread per set di dati operativo

In alcuni casi il router di confine Thread è già configurato con un Rete Thread e vuoi aggiungerla a Google Play Services per condividerlo con altri fornitori. Puoi creare un ThreadNetworkCredential da un elenco TLV di un set di dati operativo Thread attivo non elaborato:

  1. Converti il set di dati operativo in un ByteArray. Ad esempio:

    val activeDataset =
          "0e080000000000010000000300000f35060004001fffe0020833333333...".dsToByteArray()
    
    fun String.dsToByteArray(): ByteArray {
      return chunked(2).map { it.toInt(16).toByte() }.toByteArray()
    }
    
  2. Usa fromActiveOperationalDataset per creare ThreadNetworkCredentials. Se l'operazione ha esito positivo, potrai ottenere il nome, il canale e altre informazioni di rete. Per un elenco completo delle proprietà, consulta ThreadNetworkCredentials.

    val threadNetworkCredentials =
        ThreadNetworkCredentials.fromActiveOperationalDataset(activeDataset)
    Log.d(
        "threadNetworkCredentials",
        threadNetworkCredentials.channel.toString() + " - " + threadNetworkCredentials.networkName)
    
  3. Chiama l'API isPreferredCredentials e passa il metodo 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}]") }
    

Credenziali di rete Thread di Border Agent

Un ID agente di confine identifica in modo univoco un dispositivo router di confine. Per utilizzare l'API getCredentialsByBorderAgent, per prima cosa dovrai creare ThreadBorderAgent e passa l'ID agente di confine.

Dopo aver creato l'oggetto ThreadBorderAgent, richiama getCredentialsByBorderAgent. Se le credenziali sono state salvate, controlla se lo desiderano.

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}]") }
}

Credenziali di rete Thread per ID pan esteso

Come per getPreferredCredentials, puoi anche chiedere all'utente di le credenziali dell'ID pan esteso di un router di confine. La getCredentialsByExtendedPanId restituisce IntentSender e l'attività Il risultato contiene un oggetto ThreadNetworkCredentials quando l'utente approva.

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}]") }
}

Rimuovi credenziali

Quando il router di confine viene rimosso da casa o hai ripristinato i dati di fabbrica, deve rimuovere la relativa rete Thread da Google Play Services.

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}]") }
}

Risorse

Per scoprire di più sull'SDK di rete Thread, consulta le Riferimento API.