Guide des routeurs de bordure pour Android

Les développeurs d'applications Android peuvent utiliser les API Home pour gérer un routeur de bordure Thread.

L'GoogleBorderRouterDevice est implémenté à l'aide de deux traits d'appareil principaux : ThreadNetworkCapabilities, qui fournit des attributs en lecture seule pour inspecter les fonctionnalités du routeur de bordure, et ThreadNetworkManagement, qui gère les commandes du 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 du trait 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 des API Home Traits Exemple d'application Kotlin Cas d'utilisation

Routeur de bordure

GoogleBorderRouterDevice

home.matter.6006.types.0161

Traits requis
     google ThreadNetworkCapabilities
     google ThreadNetworkManagement

Routeur de bordure

Obtenir des informations de base sur un appareil

Le trait BasicInformation inclut des informations telles que le nom du fournisseur, son ID, l'ID du 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 capacités en lecture seule d'un routeur de bordure (telles que la compatibilité ePSKc et la configuration du paramètre d'accès à Internet) à l'aide du trait 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 de manière sécurisée l'ensemble de données du réseau Thread.

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 d'ePSKc

Les routeurs de bordure Thread é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 demander à un routeur de bordure Thread de rejoindre un nouveau réseau Thread en fournissant les TLV du jeu 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 pour l'ensemble de la structure pour les routeurs de bordure Thread.

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