El SDK de la red Thread proporciona funciones similares a las de un llavero digital, lo que permite que tus apps para Android compartan credenciales de red de Thread con los Servicios de Google Play. Esto permite que tus apps configuren cualquier dispositivo Thread desde cualquier ecosistema de casa inteligente, sin exponer las credenciales y los datos del usuario directamente.
Con solo unas pocas llamadas a la API, puedes hacer lo siguiente:
- Solicita credenciales preferidas de red de Thread a los Servicios de Google Play.
- Configura routers de borde nuevos y agrega tus credenciales de red de Thread a los Servicios de Google Play.
- Si ya tienes routers de borde en el campo, puedes verificar si están en la red preferida y migrarlos, si es necesario.
Hay varios recorridos del usuario y del desarrollador que se deben tener en cuenta. En esta guía, analizaremos la mayoría de ellas, junto con otras funciones clave y uso recomendado.
Terminología clave y conceptos de API
Antes de comenzar, es útil comprender los siguientes términos:
Credenciales de red de Thread: BLOB binario de TLV de Thread que codifica el nombre de red de Thread, la clave de red y otras propiedades requeridas por un dispositivo Thread para unirse a una red Thread determinada.
Credenciales de red de Thread preferidas: Son las credenciales de red de Thread seleccionadas automáticamente que se pueden compartir con apps de diferentes proveedores mediante la API de
getPreferredCredentials
.ID de agente de borde: Un ID único global de 16 bytes para un dispositivo de router de borde de Thread. Los proveedores de routers fronterizos crean y administran este ID.
App de configuración de router de borde de Thread: Esta es tu app para Android que configura nuevos dispositivos de router de borde de Thread y agrega las credenciales de la red de Thread a los Servicios de Google Play. Tu app es la propietaria autorizada de las credenciales agregadas y tiene acceso a ellas.
Muchas de las API de Thread Network muestran una Task que se completa de manera asíncrona. Puedes usar addOnSuccessListener y addOnFailureListener para registrar devoluciones de llamada a fin de recibir el resultado. Para obtener más información, consulta la documentación de Tareas.
Propiedad y mantenimiento de las credenciales
La app que agrega las credenciales de red de Thread se convierte en la propietaria de las credenciales y tiene permisos completos para acceder a las credenciales. Si intentas acceder a las credenciales que agregan otras apps, recibirás un error PERMISSION_DENIED
.
Como propietario de la app, te recomendamos mantener actualizadas las credenciales almacenadas en los Servicios de Google Play cuando se actualice la red del router de borde de Thread. Esto significa agregar credenciales cuando sea necesario, actualizar las credenciales cuando cambien las credenciales de la red Thread del router de borde y quitarlas cuando se quite o restablezca la configuración de fábrica.
Descubrimiento de agentes fronterizos
Las credenciales deben guardarse con un ID de agente fronterizo. Deberás asegurarte de que la app de configuración del router de borde de Thread pueda determinar los ID de agente de borde de tus routers de borde de Thread.
Los routers de borde de Thread deben usar mDNS para anunciar información de la red de Thread, incluidos el nombre de la red, el ID de desplazamiento extendido y el ID de agente de borde. Los valores txt
correspondientes para estos atributos son nn
, xp
y id
, respectivamente.
En el caso de las redes con routers perimetrales de Google, los Servicios de Google Play obtienen automáticamente las credenciales de red de Google Thread para usarlas.
Cómo integrar el SDK en tu app para Android
Para comenzar, completa los siguientes pasos:
Sigue las instrucciones que se proporcionan en Cómo configurar los Servicios de Google Play.
Agrega la dependencia de los Servicios de Google Play a tu archivo
build.gradle
:implementation 'com.google.android.gms:play-services-threadnetwork:16.0.0'
Opcional: Define una clase de datos
BorderAgent
para almacenar la información del router de borde. Utilizaremos estos datos a lo largo de esta guía:data class BorderAgentInfo( // Network Name max 16 len val networkName: String = "", val extPanId: ByteArray = ByteArray(16), val borderAgentId: ByteArray = ByteArray(16), ... )
A continuación, veremos los pasos recomendados para agregar y administrar las credenciales preferidas.
Nuevas configuraciones de router de borde
Antes de crear una red nueva para routers de borde nuevos, es importante que primero uses las credenciales de red preferidas. Esto garantiza que los dispositivos Thread estén conectados a una sola red Thread cuando sea posible.
Una llamada a getPreferredCredentials
inicia una actividad y les solicita a los usuarios que permitan la solicitud de red. Si se almacenaron las credenciales de red en el llavero digital del SDK de Thread, estas se mostrarán en tu app.
Solicitar credenciales
Para solicitarle al usuario las credenciales preferidas, sigue estos pasos:
Declara un
ActivityLauncher
:private lateinit var preferredCredentialsLauncher: ActivityResultLauncher<IntentSenderRequest>
Controla el resultado de Actividad, que se muestra como
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.") } }
Llama a
preferredCredentials
e inicia la actividad: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}]") } }
Crear una red Thread nueva
Si no hay credenciales de red de Thread preferidas disponibles en la red de Thread de un usuario, puedes usar la API de addCredentials
para agregar credenciales a los Servicios de Google Play. Para ello, deberás crear un ThreadBorderAgent
y también proporcionar un objeto ThreadNetworkCredentials
.
Para crear una red aleatoria, llama al newRandomizeBuilder
:
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder().build()
Para especificar el nombre de red de Thread, haz lo siguiente:
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder()
.setNetworkName("ThreadNetworkSDK")
.build()
Agregar credenciales
A fin de que tus credenciales de red de Thread estén disponibles para otros proveedores de Thread, debemos agregarlas a los Servicios de Google Play. Para poder agregar nuestras credenciales nuevas, también necesitamos saber a qué dispositivo de router de borde pertenece esta red Thread.
En este ejemplo, crearemos un ThreadBorderAgent
a partir de un ID de agente de borde y pasaremos las nuevas credenciales de red de Thread que acabas de crear:
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}]") }
}
Detecta y migra routers de campo en el campo
Si actualmente tienes routers de borde en el campo, puedes usar isPreferredCredentials
para determinar si estos pertenecen a la red preferida. Esta API no le solicita permiso al usuario y compara las credenciales del router perimetral con lo que se almacena en los Servicios de Google Play.
isPreferredCredentails
muestra 0
para no coincidentes y 1
para coincidencias, como un tipo de datos Int
. Puedes usar IsPreferredCredentialsResult
para verificar tus resultados.
public @interface IsPreferredCredentialsResult {
int PREFERRED_CREDENTIALS_NOT_FOUND = -1;
int PREFERRED_CREDENTIALS_NOT_MATCHED = 0;
int PREFERRED_CREDENTIALS_MATCHED = 1;
}
Para usar isPreferredCredentials
, primero deberás crear un objeto ThreadNetworkCredentials
. Existen varias formas de crear instancias de ThreadNetworkCredentials
. En los próximos pasos, revisaremos estas opciones.
Credenciales de red de Thread por conjunto de datos operativo
En algunos casos, el router de borde de Thread ya está configurado con una red de Thread y quieres agregar esta red de Thread a los Servicios de Google Play para compartirla con otros proveedores. Puedes crear una instancia de ThreadNetworkCredential
a partir de una lista sin procesar del TLV del conjunto de datos operativos activos de Thread:
Convierte el conjunto de datos operativo en un
ByteArray
. Por ejemplo:val activeDataset = "0e080000000000010000000300000f35060004001fffe0020833333333...".dsToByteArray()
fun String.dsToByteArray(): ByteArray { return chunked(2).map { it.toInt(16).toByte() }.toByteArray() }
Usa
fromActiveOperationalDataset
para crearThreadNetworkCredentials
. Cuando se complete correctamente, podrás obtener el nombre y el canal de red de Thread, y otra información de red. Para obtener una lista completa de propiedades, consulta ThreadNetworkCredentials.val threadNetworkCredentials = ThreadNetworkCredentials.fromActiveOperationalDataset(activeDataset) Log.d( "threadNetworkCredentials", threadNetworkCredentials.channel.toString() + " - " + threadNetworkCredentials.networkName)
Llama a la API de
isPreferredCredentials
y pasa elThreadNetworkCredentials
.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}]") }
Credenciales de red de Thread del agente de borde
Un ID de agente de borde identifica de forma única un dispositivo de router de borde. Para usar la API de getCredentialsByBorderAgent
, primero debes crear un objeto ThreadBorderAgent
y pasar el ID del agente de borde.
Una vez que hayas creado el objeto ThreadBorderAgent
, llama a getCredentialsByBorderAgent
. Si se guardaron las credenciales, verifica si son preferidas.
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}]") }
}
Credenciales de red de Thread por ID de desplazamiento extendido
Al igual que con getPreferredCredentials
, también puedes pedirle al usuario las credenciales desde el ID de desplazamiento extendido de un router de borde. getCredentialsByExtendedPanId
muestra un IntentSender
, y el resultado de la actividad contiene un objeto ThreadNetworkCredentials
cuando el usuario lo aprueba.
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}]") }
}
Quitar credenciales
Cuando se quita el dispositivo del router de borde del hogar o se restablece la configuración de fábrica, debes quitar su red Thread de los Servicios de 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}]") }
}
Recursos
Para obtener más información sobre el SDK de la red Thread, consulta la Referencia de la API.