스레드 네트워크 SDK는 디지털 키체인과 유사한 기능을 제공하여 Android 앱이 Google Play 서비스와 스레드 네트워크 사용자 인증 정보를 공유할 수 있도록 합니다. 이를 통해 앱은 사용자 인증 정보와 사용자 데이터를 직접 노출하지 않고도 모든 스마트 홈 생태계에서 모든 스레드 기기를 설정할 수 있습니다.
몇 번의 API 호출만으로 다음 작업을 할 수 있습니다.
- Google Play 서비스에서 선호하는 스레드 네트워크 사용자 인증 정보를 요청합니다.
- 새 Thread Border Router (TBR)를 설정하고 스레드 네트워크 사용자 인증 정보 를 Google Play 서비스에 추가합니다.
- 이미 현장 TBR이 있는 경우 TBRTBR이 선호하는 네트워크에 있는지 확인하고 필요한 경우 마이그레이션할 수 있습니다.
고려해야 할 사용자 및 개발자 여정이 여러 가지 있습니다. 이 가이드에서는 다른 주요 기능 및 권장 사용법과 함께 대부분의 여정을 다룹니다.
주요 용어 및 API 개념
시작하기 전에 다음 용어를 이해하는 것이 좋습니다.
스레드 네트워크 사용자 인증 정보: 스레드 기기가 특정 스레드 네트워크에 가입하는 데 필요한 스레드 네트워크 이름, 네트워크 키, 기타 속성을 인코딩하는 스레드 TLV의 바이너리 blob입니다.
선호하는 스레드 네트워크 사용자 인증 정보:
getPreferredCredentialsAPI를 사용하여 다양한 공급업체의 앱과 공유할 수 있는 자동 선택된 스레드 네트워크 사용자 인증 정보입니다.보더 에이전트 ID: TBR 기기의 전역적으로 고유한 16바이트 ID입니다. 이 ID는 border router 공급업체에서 만들고 관리합니다.
TBR 설정 앱: 새 TBR 기기를 설정하고 스레드 네트워크 사용자 인증 정보를 Google Play 서비스에 추가하는 Android 앱입니다. 앱은 추가된 사용자 인증 정보의 권한이 있는 소유자이며 사용자 인증 정보에 액세스할 수 있습니다.
대부분의 스레드 네트워크 API는 비동기식으로 완료되는 작업 을 반환합니다. addOnSuccessListener 및 addOnFailureListener 를 사용하여 결과를 수신하기 위한 콜백을 등록할 수 있습니다. 자세한 내용은 작업 문서를 참고하세요.
사용자 인증 정보 소유권 및 유지보수
스레드 네트워크 사용자 인증 정보를 추가하는 앱은 사용자 인증 정보의 소유자가 되며 사용자 인증 정보에 액세스할 수 있는 모든 권한을 갖습니다. 다른 앱에서 추가한 사용자 인증 정보에 액세스하려고 하면 PERMISSION_DENIED 오류가 발생합니다.
앱 소유자는 TBR 네트워크가 업데이트될 때 Google Play 서비스에 저장된 사용자 인증 정보를 최신 상태로 유지하는 것이 좋습니다. 즉, 필요한 경우 사용자 인증 정보를 추가하고, border router의 스레드 네트워크 사용자 인증 정보가 변경될 때 사용자 인증 정보를 업데이트하고, 사용자 인증 정보를 TBR이 삭제되거나 초기화될 때 삭제합니다.
보더 에이전트 탐색
사용자 인증 정보는 보더 에이전트 ID와 함께 저장해야 합니다. TBR 설정 앱이 TBRTBR의 보더 에이전트 ID를 확인할 수 있는지 확인해야 합니다.TBR
TBR은 mDNS를 사용하여 스레드 네트워크 정보를 알립니다.
네트워크 이름, 확장된 팬 ID, 보더 에이전트 ID를 포함합니다. 이러한 속성의 상응하는 txt 값은 각각 nn, xp, id입니다.
Google Thread Border Router (gTBR)가 있는 네트워크의 경우 Google Play 서비스는 사용할 Google 스레드 네트워크 사용자 인증 정보를 자동으로 가져옵니다.
Android 앱에 SDK 통합
시작하려면 다음 단계를 완료합니다.
build.gradle파일에 Google Play 서비스 종속 항목을 추가합니다.implementation 'com.google.android.gms:play-services-threadnetwork:16.2.1'선택사항:
BorderAgent데이터 클래스를 정의하여 TBR 정보를 저장합니다. 이 가이드 전반에서 이 데이터를 사용합니다.data class BorderAgentInfo( // Network Name max 16 len val networkName: String = "", val extPanId: ByteArray = ByteArray(16), val borderAgentId: ByteArray = ByteArray(16), ... )
다음으로 선호하는 사용자 인증 정보를 추가하고 관리하는 권장 단계를 살펴보겠습니다.
새 스레드 보더 라우터 설정
새 보더 라우터의 새 네트워크를 만들기 전에 먼저 선호하는 네트워크 사용자 인증 정보를 사용해 보는 것이 중요합니다. 이렇게 하면 가능한 경우 스레드 기기가 단일 스레드 네트워크에 연결됩니다.
getPreferredCredentials를 호출하면 활동이 실행되어 사용자에게 네트워크 요청을 허용하라는 메시지가 표시됩니다. 네트워크 사용자 인증 정보가 스레드 SDK 디지털 키체인에 저장된 경우 사용자 인증 정보가 앱에 반환됩니다.
사용자 인증 정보 요청
사용자에게 선호하는 사용자 인증 정보를 묻는 메시지를 표시하려면 다음 단계를 따르세요.
ActivityLauncher를 선언합니다.private lateinit var preferredCredentialsLauncher: ActivityResultLauncher<IntentSenderRequest>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.") } }새 TBR을 설정하는 경우 를 호출하고
preferredCredentials활동을 실행하는 것이 좋습니다. 이 호출은 새 TBR이 휴대전화에 선호로 이미 저장된 동일한 사용자 인증 정보를 사용하도록 하여 다양한 TBR이 동일한 네트워크로 수렴되도록 합니다.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}]") } }사용 사례가 새 Matter-over-Thread 최종 기기와 같은 TBR이 아닌 기기를 설정하는 것과 관련된 경우
allActiveCredentialsAPI를 사용하여 사용자 인증 정보를 가져오는 것이 좋습니다. 이 호출은 로컬 네트워크에서 발견된 TBR을 검사하므로 기존 TBR에서 로컬로 사용할 수 없는 사용자 인증 정보를 반환하지 않습니다.// Creates the IntentSender result launcher for the getAllActiveCredentials API private val getAllActiveCredentialsLauncher = registerForActivityResult( StartIntentSenderForResult() ) { result: ActivityResult -> if (result.resultCode == RESULT_OK) { val activeCredentials: List<ThreadNetworkCredentials> = ThreadNetworkCredentials.parseListFromIntentSenderResultData( result.data!! ) // Use the activeCredentials list } else { // The user denied to share! } } // Invokes the getAllActiveCredentials API and starts the dialog activity with the returned // IntentSender threadNetworkClient .getAllActiveCredentials() .addOnSuccessListener { intentSenderResult: IntentSenderResult -> val intentSender = intentSenderResult.intentSender if (intentSender != null) { getAllActiveCredentialsLauncher.launch( IntentSenderRequest.Builder(intentSender).build() ) } else { // No active network credentials found! } } // Handles the failure .addOnFailureListener { e: Exception -> // Handle the exception }
새 스레드 네트워크 만들기
사용자의 스레드 네트워크에서 선호하는 스레드 네트워크 사용자 인증 정보나 활성 스레드 사용자 인증 정보를 사용할 수 없는 경우 addCredentials API를 사용하여 Google Play 서비스에 사용자 인증 정보를 추가할 수 있습니다. 이렇게 하려면 ThreadBorderAgent를 만들고 ThreadNetworkCredentials 객체도 제공해야 합니다.
임의 네트워크를 만들려면 newRandomizeBuilder를 호출합니다.
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder().build()
스레드 네트워크 이름을 지정하려면 다음 단계를 따르세요.
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder()
.setNetworkName("ThreadNetworkSDK")
.build()
사용자 인증 정보 추가
스레드 네트워크 사용자 인증 정보를 다른 스레드 공급업체에서 사용할 수 있도록 하려면 Google Play 서비스에 추가해야 합니다. 새 사용자 인증 정보를 추가하기 전에 이 스레드 네트워크가 속한 TBR 기기도 알아야 합니다.
이 예에서는 보더 에이전트 ID에서 ThreadBorderAgent를 만들고 방금 만든 새 스레드 네트워크 사용자 인증 정보를 전달합니다.
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}]") }
}
현장 border router 감지 및 마이그레이션
현장 border router가 있는 경우
isPreferredCredentials를 사용하여 border router가 선호하는 네트워크에 속하는지 확인할 수 있습니다. 이 API는 사용자에게 권한을 묻는 메시지를 표시하지 않으며 border router 사용자 인증 정보를 Google Play 서비스에 저장된 내용과 비교합니다.
isPreferredCredentials 는 일치하지 않는 경우 0을, 일치하는 경우 1을 Int 데이터 유형으로 반환합니다. IsPreferredCredentialsResult를 사용하여 결과를 확인할 수 있습니다.
public @interface IsPreferredCredentialsResult {
int PREFERRED_CREDENTIALS_NOT_FOUND = -1;
int PREFERRED_CREDENTIALS_NOT_MATCHED = 0;
int PREFERRED_CREDENTIALS_MATCHED = 1;
}
isPreferredCredentials를 사용하려면 먼저 ThreadNetworkCredentials 객체를 만들어야 합니다. ThreadNetworkCredentials를 인스턴스화하는 방법은 여러 가지가 있습니다. 다음 단계에서는 이러한 옵션을 살펴보겠습니다.
운영 데이터세트별 스레드 네트워크 사용자 인증 정보
TBR이 이미 스레드 네트워크로 설정되어 있고 이 스레드 네트워크를 Google Play 서비스
에 추가하여 다른 공급업체와 공유하려는 경우가 있습니다. 원시 스레드 활성 운영 데이터세트 TLV 목록에서 ThreadNetworkCredential 인스턴스를 만들 수 있습니다.
운영 데이터세트를
ByteArray로 변환합니다. 예를 들면 다음과 같습니다.val activeDataset = "0e080000000000010000000300000f35060004001fffe0020833333333...".dsToByteArray()fun String.dsToByteArray(): ByteArray { return chunked(2).map { it.toInt(16).toByte() }.toByteArray() }fromActiveOperationalDataset를 사용하여ThreadNetworkCredentials를 만듭니다. 성공하면 스레드 네트워크 이름, 채널, 기타 네트워크 정보를 가져올 수 있습니다. 속성의 전체 목록은 ThreadNetworkCredentials를 참고하세요.val threadNetworkCredentials = ThreadNetworkCredentials.fromActiveOperationalDataset(activeDataset) Log.d( "threadNetworkCredentials", threadNetworkCredentials.channel.toString() + " - " + threadNetworkCredentials.networkName)isPreferredCredentialsAPI를 호출하고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}]") }
보더 에이전트별 스레드 네트워크 사용자 인증 정보
보더 에이전트 ID는 TBR 기기를 고유하게 식별합니다. getCredentialsByBorderAgent API를 사용하려면 먼저 ThreadBorderAgent 객체를 만들고 보더 에이전트 ID를 전달해야 합니다.
ThreadBorderAgent 객체를 만든 후 getCredentialsByBorderAgent를 호출합니다. 사용자 인증 정보가 저장된 경우 선호하는지 확인합니다.
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}]") }
}
확장된 팬 ID별 스레드 네트워크 사용자 인증 정보
getPreferredCredentials와 마찬가지로
의 확장된 팬 IDTBR에서 사용자에게 사용자 인증 정보를 묻는 메시지를 표시할 수도 있습니다. getCredentialsByExtendedPanId는 IntentSender를 반환하며 사용자가 승인하면 활동 결과에 ThreadNetworkCredentials 객체가 포함됩니다.
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}]") }
}
사용자 인증 정보 삭제
border router 기기가 집에서 삭제되거나 초기화되면 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}]") }
}
리소스
스레드 네트워크 SDK에 관한 자세한 내용은 API 참조를 참고하세요.