ערכת ה-SDK של Thread Network מספקת פונקציונליות שדומה למחזיק מפתחות דיגיטלי, ומאפשרת לאפליקציות Android לשתף את פרטי הכניסה לרשת Thread עם Google Play Services. ההרשאה הזו מאפשרת לאפליקציות להגדיר כל מכשיר Thread מכל מערכת אקולוגית של בית חכם, בלי לחשוף ישירות את פרטי הכניסה ואת נתוני המשתמש.
בעזרת כמה קריאות ל-API, אפשר:
- שליחת בקשה לפרטי הכניסה המועדפים של רשת Thread מ-Google Play Services.
- מגדירים Thread Border Router (TBR) חדשים ומוסיפים את פרטי הכניסה לרשת Thread ל-Google Play Services.
- אם כבר יש לכם מכשירי TBR בשטח, אתם יכולים לבדוק אם מכשירי TBR נמצאים ברשת המועדפת ולהעביר אותם, אם צריך.
יש כמה תהליכים שעוברים משתמשים ומפתחים שכדאי להביא בחשבון. במדריך הזה נסביר על רוב התכונות האלה, וגם על תכונות חשובות אחרות ועל אופן השימוש המומלץ בהן.
מונחים חשובים ומושגים שקשורים ל-API
לפני שמתחילים, כדאי להבין את המונחים הבאים:
פרטי הכניסה לרשת Thread: Blob בינארי של Thread TLV שמקודד את שם רשת Thread, מפתח הרשת ומאפיינים אחרים שנדרשים למכשיר Thread כדי להצטרף לרשת Thread נתונה.
פרטי הכניסה המועדפים לרשת Thread: פרטי הכניסה לרשת Thread שנבחרו באופן אוטומטי שאפשר לשתף עם אפליקציות של ספקים שונים באמצעות
getPreferredCredentialsAPI.Border Agent ID: מזהה ייחודי בעולם של 16 בייט למכשיר TBR. המזהה הזה נוצר ומנוהל על ידי ספקי border router.
TBR אפליקציית ההגדרה: זו אפליקציית Android שמגדירה מכשירי TBR חדשים ומוסיפה את פרטי הכניסה לרשת Thread ל-Google Play Services. האפליקציה שלכם היא הבעלים הסמכותי של פרטי הכניסה שנוספו ויש לה גישה אליהם.
הרבה ממשקי Thread Network API מחזירים Task שמושלם באופן אסינכרוני. אפשר להשתמש ב-addOnSuccessListener וב-addOnFailureListener כדי לרשום קריאות חוזרות לקבלת התוצאה. מידע נוסף מופיע במאמר בנושא משימות.
בעלות על פרטי הכניסה ותחזוקה שלהם
האפליקציה שמוסיפה את פרטי הכניסה לרשת Thread הופכת לבעלים של פרטי הכניסה, ויש לה הרשאות מלאות לגשת אליהם. אם תנסו לגשת לפרטי כניסה שנוספו על ידי אפליקציות אחרות, תקבלו הודעת שגיאה PERMISSION_DENIED
בתור בעלי האפליקציה, מומלץ לעדכן את פרטי הכניסה שמאוחסנים ב-Google Play Services כשמתבצע עדכון של רשת TBR. זה אומר שצריך להוסיף פרטי כניסה כשנדרש, לעדכן את פרטי הכניסה כשפרטי הכניסה של רשת Thread של border router משתנים, ולהסיר את פרטי הכניסה כשמסירים את TBR או מאפסים אותו להגדרות המקוריות.
גילוי של סוכני גבול
צריך לשמור את פרטי הכניסה עם מזהה סוכן Border. צריך לוודא שאפליקציית ההגדרה של TBR יכולה לקבוע את מזהי סוכן הגבול של TBR.
TBRs חייבים להשתמש ב-mDNS כדי לפרסם מידע על רשת Thread, כולל שם הרשת, מזהה PAN מורחב ומזהה סוכן הגבול. הערכים התואמים של txt למאפיינים האלה הם nn, xp ו-id, בהתאמה.
OTBR_PUBLISH_MESHCOP_BA_ID מופעלת.
ברשתות עם Google Thread Border Router (gTBR)s, שירות Google Play Services מקבל באופן אוטומטי את פרטי הכניסה לרשת Google Thread לשימוש.
שילוב ה-SDK באפליקציה ל-Android
כדי להתחיל, מבצעים את השלבים הבאים:
פועלים לפי ההוראות שמופיעות במאמר בנושא הגדרת Google Play Services.
מוסיפים את התלות ב-Google Play Services לקובץ
build.gradle: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), ... )
בשלב הבא נסביר איך מוסיפים ומנהלים את פרטי הכניסה המועדפים.
הגדרות חדשות של נתבי גבולות לרשת Thread
לפני שיוצרים רשת חדשה לנתבי גבול חדשים, חשוב לנסות להשתמש קודם בהרשאות של הרשת המועדפת. כך מוודאים שמכשירי Thread מחוברים לרשת Thread אחת, כשזה אפשרי.
קריאה ל-getPreferredCredentials מפעילה Activity, ומבקשת מהמשתמשים לאשר את בקשה לאחזור מהרשת. אם פרטי הכניסה לרשת אוחסנו במחזיק המפתחות הדיגיטלי של Thread 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}]") } }אם תרחיש השימוש שלכם קשור להגדרת מכשירים שלא תומכים ב-TBR, כמו מכשיר קצה חדש עם Matter-over-Thread, מומלץ להשתמש ב-
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 }
יצירת רשת Thread חדשה
אם אין פרטי כניסה מועדפים לרשת Thread או פרטי כניסה פעילים לרשת Thread שזמינים ברשת Thread של המשתמש, אפשר להשתמש בממשק ה-API של addCredentials כדי להוסיף פרטי כניסה ל-Google Play Services. כדי לעשות את זה, צריך ליצור ThreadBorderAgent ולספק גם אובייקט ThreadNetworkCredentials.
כדי ליצור רשת אקראית, קוראים ל-newRandomizeBuilder:
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder().build()
כדי לציין את השם של רשת Thread:
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder()
.setNetworkName("ThreadNetworkSDK")
.build()
הוספת פרטי כניסה
כדי שספקים אחרים של Thread יוכלו לגשת לפרטי הכניסה לרשת Thread, אנחנו צריכים להוסיף אותם ל-Google Play Services. לפני שנוסיף את פרטי הכניסה החדשים, נצטרך לדעת לאיזה TBR מכשיר שייכת רשת Thread הזו.
בדוגמה הזו, ניצור ThreadBorderAgent ממזהה של סוכן גבולות, ונעביר את פרטי הכניסה החדשים לרשת Thread שיצרתם:
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 routers בשדה, אתם יכולים להשתמש ב-isPreferredCredentials כדי לקבוע אם ה-border routers שייכים לרשת המועדפת. ה-API הזה לא מבקש מהמשתמש הרשאה, והוא בודק border router את פרטי הכניסה מול מה שמאוחסן ב-Google Play Services.
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. בשלבים הבאים נסביר על האפשרויות האלה.
פרטי הכניסה של רשת Thread לפי מערך נתונים תפעולי
יש מקרים שבהם TBR כבר מוגדר עם רשת Thread, ואתם רוצים להוסיף את רשת Thread הזו לשירותי Google Play כדי לשתף אותה עם ספקים אחרים. אפשר ליצור ThreadNetworkCredentialמופע מרשימת TLV של מערך נתונים תפעולי פעיל של Thread:
ממירים את מערך הנתונים התפעולי ל-
ByteArray. לדוגמה:val activeDataset = "0e080000000000010000000300000f35060004001fffe0020833333333...".dsToByteArray()fun String.dsToByteArray(): ByteArray { return chunked(2).map { it.toInt(16).toByte() }.toByteArray() }אפשר להשתמש ב-
fromActiveOperationalDatasetכדי ליצור אתThreadNetworkCredentials. כשהפעולה תושלם, תוכלו לקבל את השם, הערוץ ופרטי רשת אחרים של רשת Thread. רשימה מלאה של מאפיינים זמינה במאמר בנושא ThreadNetworkCredentials.val threadNetworkCredentials = ThreadNetworkCredentials.fromActiveOperationalDataset(activeDataset) Log.d( "threadNetworkCredentials", threadNetworkCredentials.channel.toString() + " - " + threadNetworkCredentials.networkName)שולחים קריאה ל-API של
isPreferredCredentialsומעבירים את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}]") }
פרטי הכניסה לרשת Thread לפי Border Agent
מזהה סוכן גבולות מזהה באופן ייחודי מכשיר TBR. כדי להשתמש ב-getCredentialsByBorderAgent API, קודם צריך ליצור אובייקט ThreadBorderAgent ולהעביר את מזהה סוכן הגבול.
אחרי שיוצרים את האובייקט 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}]") }
}
פרטי הכניסה של Thread Network לפי מזהה רשת אישית (PAN) מורחב
בדומה ל-getPreferredCredentials, אפשר גם לבקש מהמשתמש פרטי כניסה מTBRמזהה רשת אישית (PAN) מורחב. הפונקציה
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 מהבית או מאפסים אותו להגדרות המקוריות, צריך להסיר את רשת Thread שלו משירותי 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}]") }
}
משאבים
מידע נוסף על Thread Network SDK מפורט בהפניית API.