SDK Thread Network for Android

Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

L'SDK di rete Thread fornisce funzionalità simili a un portachiavi digitale, permettendo alle tue app Android di condividere le credenziali di rete di Thread con Google Play Services. In questo modo le app possono configurare qualsiasi dispositivo Thread da qualsiasi ecosistema per la smart home, senza esporre direttamente credenziali e dati utente.

Con poche chiamate API puoi:

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

Esistono diversi percorsi degli utenti e degli sviluppatori da prendere in considerazione. In questa guida ne analizzeremo la maggior parte, insieme ad altre funzionalità chiave e all'utilizzo consigliato.

Terminologia e concetti chiave chiave

Prima di iniziare, è utile comprendere i seguenti termini:

  • Credenziali di rete di thread: blob binario dei TLV di Thread che codificano il nome di rete di Thread, le chiavi di rete e altre proprietà necessarie a un dispositivo Thread per collegarsi a una determinata rete Thread.

  • Credenziali di rete Thread preferite: le credenziali di rete Thread selezionate automaticamente che possono essere condivise con app di fornitori diversi utilizzando l'API getPreferredCredentials.

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

  • App Thread Route Router Config: si tratta della tua app Android che configura nuovi dispositivi Thread Border Router e aggiunge le credenziali di rete Thread a Google Play Services. L'app è il proprietario autorevole delle credenziali aggiunte e ha accesso senza costi alle credenziali.

Molte delle API Thread Network restituiscono una attività che viene completata in modo asincrono. Puoi utilizzare addOnSuccessListener e addOnFailureListener per registrare i callback per ricevere il risultato. Per scoprire di più, consulta la documentazione di Task.

Proprietà e manutenzione delle credenziali

L'app che aggiunge le credenziali di rete Thread diventa il proprietario delle credenziali e dispone di tutte le relative autorizzazioni di accesso. Se tenti di accedere alle credenziali aggiunte da altre app, riceverai un errore PERMISSION_DENIED.

In qualità di proprietario dell'app, ti consigliamo di mantenere aggiornate le credenziali memorizzate in Google Play Services quando viene aggiornata la rete del router di confine Thread. Questo significa aggiungere le credenziali quando necessario, aggiornare le credenziali quando il thread di confine del router Thread le credenziali di rete cambiano e rimuovere le credenziali quando il router di confine Thread viene rimosso o ripristinato i dati di fabbrica.

Rilevamento agenti di frontiera

Le credenziali devono essere salvate con un ID agente di frontiera. Dovrai assicurarti che l'app di configurazione del router di confine Thread sia 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 dei thread, inclusi nome di rete, ID panoramica esteso e ID agente di frontiera. I valori txt corrispondenti per questi attributi sono nn, xp e id, rispettivamente.

Per le reti con router Google di confine, Google Play Services riceve automaticamente le credenziali di rete Google Thread per l'utilizzo.

Integra l'SDK nella tua app per Android

Per iniziare, completa i seguenti passaggi:

  1. Segui le istruzioni fornite in Configurare Google Play Services.

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

    implementation 'com.google.android.gms:play-services-threadnetwork:16.0.0-beta02'
    
  3. Facoltativo: definisci una classe di dati BorderAgent per archiviare le informazioni del router di confine. Utilizzeremo questi dati nel corso della presente Guida:

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

Quindi, vedremo i passaggi consigliati per aggiungere e gestire le credenziali preferite.

Nuove configurazioni di router di confine

Prima di creare una nuova rete per i nuovi router di confine, è importante provare a utilizzare prima le credenziali di rete preferite. Questo assicura che, quando possibile, i dispositivi Thread siano collegati a una singola rete Thread.

Una chiamata a getPreferredCredentials avvia un'attività, chiedendo agli utenti di consentire la richiesta di rete. Se le credenziali di rete sono state archiviate nel portachiavi digitale dell'SDK Thread, vengono restituite alla tua app.

Richiedi credenziali

Per richiedere all'utente le credenziali preferite:

  1. Dichiarare un 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 il numero 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}]") }
    }
    

Creare una nuova rete Thread

Se nella rete Thread di un utente non sono disponibili credenziali di rete preferite, puoi utilizzare l'API addCredentials per aggiungere credenziali a Google Play Services. Per farlo, dovrai creare un ThreadBorderAgent e fornire anche un oggetto ThreadNetworkCredentials.

Per creare una rete casuale, chiama 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 per altri fornitori di Thread, dobbiamo aggiungerle a Google Play Services. Prima di poter aggiungere le nostre nuove credenziali, dobbiamo sapere a quale dispositivo di router di confine appartiene questa rete Thread.

In questo esempio creeremo un ThreadBorderAgent da un ID agente di frontiera e passeremo 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}]") }
}

Rileva ed esegui la migrazione dei router di confine sul campo

Se al momento utilizzi router di confine in campo, puoi utilizzare isPreferredCredentials per determinare se i router di confine appartengono alla rete preferita. Questa API non richiede l'autorizzazione dell'utente e controlla le credenziali del router di confine in base a quanto archiviato nei servizi Google Play.

isPreferredCredentails restituisce 0 per la mancata corrispondenza e 1 per la corrispondenza 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 utilizzare isPreferredCredentials, devi prima creare un oggetto ThreadNetworkCredentials. Esistono diversi modi per creare un'istanza ThreadNetworkCredentials. Nei passaggi successivi, esamineremo queste opzioni.

Crea thread di credenziali di rete in base al set di dati operativo

Esistono alcuni casi in cui il router di confine Thread è già configurato con una rete Thread e vuoi aggiungerla a Google Play Services per condividerlo con altri fornitori. Puoi creare un'istanza ThreadNetworkCredential da un elenco TLV di set di dati operativi non elaborati in thread:

  1. Converti il set di dati operativo in 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 il ThreadNetworkCredentials. Se l'operazione ha esito positivo, potrai ottenere il nome, il canale e altre informazioni sulla rete della rete Thread. 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 supera l'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}]") }
    

Crea thread di credenziali di rete da agente di frontiera

L'ID agente di frontiera identifica in modo univoco un dispositivo router di confine. Per utilizzare l'API getCredentialsByBorderAgent, devi prima creare un oggetto ThreadBorderAgent e passare l'ID agente di frontiera.

Dopo aver creato l'oggetto ThreadBorderAgent, chiama getCredentialsByBorderAgent. Se le credenziali sono state salvate, controlla se sono preferite.

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

Thread di rete delle credenziali per ID panoramica esteso

Analogamente a getPreferredCredentials, puoi richiedere all'utente le credenziali da un ID panoramica esteso di un router di confine. getCredentialsByExtendedPanId restituisce un IntentSender e il risultato dell'attività 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 dispositivo router di confine viene rimosso dalla tua casa o dal ripristino dei dati di fabbrica, devi rimuovere la 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 Thread Network, consulta la documentazione di riferimento dell'API.