Guide des routeurs de bordure pour Android

Les développeurs d'applications Android peuvent utiliser les API Home pour gérer un Thread Border Router (TBR).

GoogleBorderRouterDevice est implémenté à l'aide de deux caractéristiques d'appareil principales : ThreadNetworkCapabilities, qui fournit des attributs en lecture seule pour inspecter les fonctionnalités border router, et ThreadNetworkManagement, qui gère les commandes de cycle de vie du réseau et le partage d'identifiants à l'aide d'une clé pré-partagée éphémère pour le commissaire (ePSKc). Les règles d'accès à Internet au niveau de la structure sont gérées à l'aide de la caractéristique ThreadNetworkSettings.

Assurez-vous toujours qu'un appareil prend en charge les attributs et les commandes nécessaires avant d'utiliser une fonctionnalité ou de tenter de mettre à jour des attributs. Pour en savoir plus, consultez Contrôler les appareils surAndroid.

Type d'appareil pour les API Home Caractéristiques Exemple d'application Kotlin Cas d'utilisation

Routeur de bordure

GoogleBorderRouterDevice

home.matter.6006.types.0161

Caractéristiques requises
     google ThreadNetworkCapabilities
     google ThreadNetworkManagement

Routeur de bordure

Obtenir des informations de base sur un appareil

   Implémenté dans l'application exemple pour Android   

Le trait BasicInformation inclut des informations telles que le nom du fournisseur, l'ID du fournisseur, l'identifiant produit, le nom du produit (y compris les informations sur le modèle) et la version logicielle d'un appareil :

// Get device basic information. All general information traits are on the RootNodeDevice type.
    device.type(RootNodeDevice).first().standardTraits.basicInformation?.let { basicInformation ->
        println("vendorName ${basicInformation.vendorName}")
        println("vendorId ${basicInformation.vendorId}")
        println("productId ${basicInformation.productId}")
        println("productName ${basicInformation.productName}")
        println("softwareVersion ${basicInformation.softwareVersion}")
    }

Inspecter les fonctionnalités du routeur de bordure

Vous pouvez examiner les fonctionnalités en lecture seule d'un border router (comme la compatibilité avec l'ePSKc et la configuration du paramètre d'accès à Internet) à l'aide de la caractéristique ThreadNetworkCapabilities.

suspend fun checkBorderRouterCapabilities(device: HomeDevice) {
    // Filter for GoogleBorderRouterDevice device type
    val gtbrDevice = device.type(GoogleBorderRouterDevice).firstOrNull()
    if (gtbrDevice == null) {
        println("Device is not a Google border router.")
        return
    }

    // Retrieve the ThreadNetworkCapabilities trait
    val capabilitiesTrait = gtbrDevice.trait(ThreadNetworkCapabilities)
    if (capabilitiesTrait == null) {
        println("ThreadNetworkCapabilities trait not found on device.")
        return
    }

    val isEpskcSupported = capabilitiesTrait.epskcSupported ?: false
    val internetAccessOption = capabilitiesTrait.internetAccessOption?.name ?: "None"
    val isIasSupported = !internetAccessOption.equals("None", ignoreCase = true)

    println("ePSKc Supported: $isEpskcSupported")
    println("Internet Access Setting Supported: $isIasSupported")
}

Gérer le partage des identifiants Thread (ePSKc)

Le partage des identifiants Thread s'effectue à l'aide d'une clé pré-partagée éphémère pour le commissaire (ePSKc). Le mode ePSKc génère une clé d'accès temporaire et sécurisée que les appareils ou commissaires externes peuvent utiliser pour obtenir l'ensemble de données du réseau Thread de manière sécurisée.

Activer le mode ePSKc

suspend fun startEpskcSession(device: HomeDevice, durationSeconds: Short): ActivateEpskcModeCommand.Response? {
    val gtbrDevice = device.type(GoogleBorderRouterDevice).firstOrNull()
    val mgmtTrait = gtbrDevice?.trait(ThreadNetworkManagement)

    if (mgmtTrait == null) {
        println("ThreadNetworkManagement trait not found.")
        return null
    }

    return try {
        val response = mgmtTrait.activateEpskcMode(
            optionalArgs = { this.requestedDurationSeconds = durationSeconds }
        )

        println("ePSKc Session Activated!")
        println("Status: ${response.status}")
        println("Ephemeral PSKc: ${response.epskc}")
        println("Valid Duration (s): ${response.validDurationSeconds}")

        response
    } catch (e: Exception) {
        println("Failed to activate ePSKc mode: ${e.message}")
        null
    }
}

Désactiver le mode ePSKc

suspend fun stopEpskcSession(device: HomeDevice) {
    val gtbrDevice = device.type(GoogleBorderRouterDevice).firstOrNull()
    val mgmtTrait = gtbrDevice?.trait(ThreadNetworkManagement)

    mgmtTrait?.deactivateEpskcMode()
    println("ePSKc mode deactivated.")
}

Observer les événements de désactivation des ePSKc

Les TBR émettent des événements lorsqu'une session ePSKc se termine (par exemple, parce que la clé a été utilisée, que la session a expiré ou qu'elle a été annulée manuellement).

suspend fun observeEpskcEvents(device: HomeDevice) {
    val gtbrDevice = device.type(GoogleBorderRouterDevice).firstOrNull()
    val mgmtTrait = gtbrDevice?.trait(ThreadNetworkManagement)

    mgmtTrait?.epskcModeDeactivatedEventFlow()?.collect { event ->
        println("ePSKc Session Ended. Reason: ${event.reason}")
        when (event.reason?.name) {
            "KeyUsed" -> println("Key was successfully used to commission a device.")
            "Expired" -> println("Session timed out before the key was used.")
            "Cancelled" -> println("Session was manually cancelled.")
        }
    }
}

Gérer l'appartenance au réseau Thread

Vous pouvez commander un TBR pour rejoindre un nouveau réseau Thread en fournissant les TLV de l'ensemble de données opérationnel actif, ou lui demander de quitter son réseau actuel.

suspend fun joinNetwork(device: HomeDevice, datasetTlvs: ByteArray) {
    val gtbrDevice = device.type(GoogleBorderRouterDevice).firstOrNull()
    val mgmtTrait = gtbrDevice?.trait(ThreadNetworkManagement)

    try {
        val response = mgmtTrait?.joinNetwork(operationalDatasetTlvs = datasetTlvs)
        println("Join network command sent. Status: ${response?.status}")
    } catch (e: Exception) {
        println("Join network failed: ${e.message}")
    }
}

suspend fun leaveNetwork(device: HomeDevice) {
    val gtbrDevice = device.type(GoogleBorderRouterDevice).firstOrNull()
    val mgmtTrait = gtbrDevice?.trait(ThreadNetworkManagement)

    try {
        mgmtTrait?.leaveNetwork()
        println("Leave network command sent successfully.")
    } catch (e: Exception) {
        println("Leave network failed: ${e.message}")
    }
}

Configurer l'accès à Internet au niveau de la structure

Le trait ThreadNetworkSettings est un trait modifiable associé à un Structure (représentant une maison ou un bâtiment). Il permet aux développeurs de configurer la règle d'accès à Internet à l'échelle de la structure pour les TBR.

suspend fun updateStructureInternetAccess(structure: Structure, enableInternetAccess: Boolean) {
    // Retrieve the ThreadNetworkSettings trait for the structure
    val settingsTrait = structure.trait(ThreadNetworkSettings).firstOrNull()
    if (settingsTrait == null) {
        println("ThreadNetworkSettings trait not found on structure.")
        return
    }

    val option = if (enableInternetAccess) {
        InternetAccessOption.InternetAccessOptionAll
    } else {
        InternetAccessOption.InternetAccessOptionNone
    }

    try {
        settingsTrait.update {
            setInternetAccessOption(option)
        }
        println("Successfully updated Thread internet access policy to: ${option.name}")
    } catch (e: Exception) {
        println("Failed to update Thread internet access policy: ${e.message}")
    }
}