Android용 보더 라우터 기기 가이드

Android 앱 개발자는 Home API를 사용하여 스레드 보더 라우터를 관리할 수 있습니다.

GoogleBorderRouterDevice는 두 가지 기본 기기 특성인 ThreadNetworkCapabilities(보더 라우터 기능을 검사하는 읽기 전용 속성 제공) 및 ThreadNetworkManagement(커미셔너의 임시 사전 공유 키(ePSKc)를 사용하여 네트워크 수명 주기 명령어 및 사용자 인증 정보 공유 처리)를 사용하여 구현됩니다. 구조 수준 인터넷 액세스 정책은 ThreadNetworkSettings 특성을 사용하여 관리됩니다.

기능을 사용하거나 속성을 업데이트하기 전에 항상 기기의 속성 및 명령어 지원을 확인하세요. 자세한 내용은 의 기기 제어를 참고하세요.Android

Home API 기기 유형 특성 Kotlin 샘플 앱 사용 사례

보더 라우터

GoogleBorderRouterDevice

home.matter.6006.types.0161

필수 특성
     google ThreadNetworkCapabilities
     google ThreadNetworkManagement

보더 라우터

기기에 관한 기본 정보 가져오기

BasicInformation 특성에는 기기의 공급업체 이름, 공급업체 ID, 제품 ID, 제품 이름 (모델 정보 포함), 소프트웨어 버전과 같은 정보가 포함됩니다.

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

보더 라우터 기능 검사

ThreadNetworkCapabilities 특성을 사용하여 보더 라우터의 읽기 전용 기능 (예: ePSKc 지원 및 인터넷 액세스 설정 구성)을 검사할 수 있습니다.

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

스레드 사용자 인증 정보 공유 (ePSKc) 관리

스레드 사용자 인증 정보 공유는 커미셔너의 임시 사전 공유 키 (ePSKc)를 사용하여 이루어집니다. ePSKc 모드는 외부 기기 또는 커미셔너가 스레드 네트워크 데이터 세트를 안전하게 가져오는 데 사용할 수 있는 임시 보안 패스키를 생성합니다.

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

ePSKc 모드 비활성화

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

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

ePSKc 비활성화 이벤트 관찰

스레드 보더 라우터는 ePSKc 세션이 종료될 때 (예: 키가 사용되었거나 세션이 만료되었거나 수동으로 취소되었기 때문에) 이벤트를 내보냅니다.

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

스레드 네트워크 멤버십 관리

활성 운영 데이터 세트 TLV를 제공하여 스레드 보더 라우터에 새 스레드 네트워크에 조인하도록 명령하거나 현재 네트워크에서 나가도록 명령할 수 있습니다.

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

구조 수준 인터넷 액세스 구성

ThreadNetworkSettings 특성은 Structure (주택 또는 건물을 나타냄)에 연결된 업데이트 가능한 특성입니다. 이를 통해 개발자는 스레드 보더 라우터의 구조 전체 인터넷 액세스 정책을 구성할 수 있습니다.

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