1. ก่อนเริ่มต้น
ใน Codelab Thread Border Router (TBR) เราจะแสดงวิธีสร้าง Thread Border Router โดยใช้ Raspberry Pi ใน Codelab นั้น เรา
- สร้างการเชื่อมต่อ IP แบบ 2 ทางระหว่างเครือข่าย Thread กับเครือข่าย Wi-Fi/อีเทอร์เน็ต
- ให้บริการค้นพบบริการแบบ 2 ทางผ่าน mDNS (ในลิงก์ Wi-Fi/อีเทอร์เน็ต) และ SRP (ในเครือข่าย Thread)
Codelab นี้ต่อยอดจาก Codelab ก่อนหน้า โดยจะอธิบายวิธีที่ Border Router และแอปของคุณโต้ตอบกับ Google API เพื่อสร้างเครือข่าย Thread เดียว การรวมข้อมูลเข้าสู่ระบบของ Thread เป็นสิ่งสำคัญเนื่องจากจะช่วยเพิ่มความแข็งแกร่งของเครือข่ายและลดความซับซ้อนในการโต้ตอบของผู้ใช้กับแอปพลิเคชันที่ใช้ Thread
ข้อกำหนดเบื้องต้น
- ทำ OTBR Codelab ให้เสร็จสมบูรณ์
- ความรู้พื้นฐานเกี่ยวกับ Linux, Android/Kotlin และการเชื่อมต่อเครือข่าย Thread
สิ่งที่คุณจะได้เรียนรู้
- วิธีใช้ Thread Sharing API เพื่อรับและตั้งค่าชุดข้อมูลเข้าสู่ระบบ
- วิธีตั้งค่า OpenThread Border Router ของคุณเองด้วยข้อมูลเข้าสู่ระบบเดียวกับเครือข่ายของ Google
สิ่งที่คุณต้องมี
- บอร์ด Raspberry Pi 4 หรือบอร์ดที่ใช้ Linux อื่นๆ ที่เรียกใช้ Open Thread Border Router (OTBR)
- บอร์ดที่ให้การเชื่อมต่อ IEEE 802.15.4 เป็นตัวประมวลผลร่วมวิทยุ (RCP) ดูรายการที่เก็บของผู้ให้บริการ SoC ต่างๆ และวิธีการในหน้า OpenThread Github
2. การตั้งค่าบริการ HTTP
องค์ประกอบแรกที่เราต้องการคืออินเทอร์เฟซที่ช่วยให้เราอ่านข้อมูลเข้าสู่ระบบที่ใช้งานอยู่และเขียนข้อมูลเข้าสู่ระบบที่รอดำเนินการไปยัง OTBR ของคุณได้ เมื่อสร้าง TBR ให้ใช้กลไกที่เป็นกรรมสิทธิ์ของคุณเอง ดังที่แสดงที่นี่พร้อมตัวอย่าง 2 รายการ ตัวเลือกแรกแสดงวิธีเชื่อมต่อกับเอเจนต์ OTBR ในเครื่องผ่าน DBUS ส่วนตัวเลือกที่ 2 ใช้ประโยชน์จาก REST API ที่สร้างขึ้นใน OTBR ได้
ทั้ง 2 วิธีนี้ไม่ปลอดภัยและไม่ควรใช้ในสภาพแวดล้อมที่ใช้งานจริง อย่างไรก็ตาม ผู้ให้บริการสามารถสร้างการเข้ารหัสรอบๆ วิธีการใดวิธีการหนึ่งเพื่อใช้ในสภาพแวดล้อมการผลิต หรือคุณจะขยายบริการตรวจสอบของคุณเองเพื่อออกการเรียก HTTP แบบวนรอบหรือการเรียก DBUS ในเครื่องก็ได้
ตัวเลือกที่ 1: DBUS และ HTTP API ในสคริปต์ Python

ขั้นตอนนี้จะสร้างบริการ HTTP แบบพื้นฐานที่แสดงปลายทาง 2 รายการเพื่ออ่านและตั้งค่าข้อมูลเข้าสู่ระบบ ซึ่งจะเรียกใช้คำสั่ง DBUS ในท้ายที่สุด
ใน RPi ที่จะใช้เป็น OTBR ให้ติดตั้งการอ้างอิง Python 3 ดังนี้
$ pip install dbus-python shlex json
เรียกใช้สคริปต์ดังนี้
$ sudo python credentials_server.py 8081 serving at port 8081
ตัวอย่างจะตั้งค่าเซิร์ฟเวอร์ HTTP ในพอร์ต 8081 และรอรับคำขอในเส้นทางรูท ไม่ว่าจะเป็นคำขอ GET เพื่อดึงข้อมูลเข้าสู่ระบบของ Thread หรือคำขอ POST เพื่อตั้งค่าข้อมูลเข้าสู่ระบบของ Thread เพย์โหลดจะเป็นโครงสร้าง JSON ที่มี TLV เสมอ
คำขอ PUT ต่อไปนี้จะตั้งค่าข้อมูลเข้าสู่ระบบ Thread ที่รอดำเนินการใหม่ให้กับ OTBR โดยใช้เส้นทาง /node/dataset/pending ในกรณีนี้ ระบบจะใช้ข้อมูลเข้าสู่ระบบที่รอดำเนินการภายใน 10 วินาที
PUT /node/dataset/pending
Host: <IP>:8081
ContentType: "application/json"
acceptMimeType: "application/json"
...
{
"ActiveDataset": "<TLV encoded new Thread Dataset>"
"PendingTimestamp": {
"Seconds": <Unix timestamp in seconds>,
"Ticks": 0,
"Authoritative": false
},
"Delay": 10000 // in milliseconds
}
คำขอ GET ไปยัง /node/dataset/active จะดึงข้อมูลเข้าสู่ระบบที่ใช้งานอยู่ในปัจจุบัน
GET /node/dataset/active Host: <IP>:8081 ContentType = "application/json" acceptMimeType = "text/plain" ... <TLV encoded Thread Dataset>
สคริปต์จะเรียกใช้คำสั่ง DBUS R/W ไปยังเส้นทางบัส io.openthread.BorderRouter.wpan0, เส้นทางออบเจ็กต์ /io/openthread/BorderRouter/wpan0 ดังนี้
# D-BUS interface
def call_dbus_method(interface, method_name, *arguments):
bus = dbus.SystemBus()
obj = bus.get_object('io.openthread.BorderRouter.wpan0', '/io/openthread/BorderRouter/wpan0')
iface = dbus.Interface(obj, interface)
method = getattr(iface, method_name)
res = method(*arguments)
return res
def get_dbus_property(property_name):
return call_dbus_method('org.freedesktop.DBus.Properties', 'Get', 'io.openthread.BorderRouter',
property_name)
def set_dbus_property(property_name, property_value):
return call_dbus_method('org.freedesktop.DBus.Properties', 'Set', 'io.openthread.BorderRouter',
property_name, property_value)
DBUS อนุญาตให้ตรวจสอบความสามารถของตัวเอง คุณอาจทำสิ่งนี้ในรูปแบบต่อไปนี้
$ sudo dbus-send --system --dest=io.openthread.BorderRouter.wpan0 \
--type=method_call --print-reply /io/openthread/BorderRouter/wpan0 \
org.freedesktop.DBus.Introspectable.Introspect
นอกจากนี้ คุณยังตรวจสอบความสามารถที่รองรับซึ่งระบุไว้ที่นี่ได้ด้วย
ตัวเลือกที่ 2: REST API ของ HTTP แบบเนทีฟของ OTBR Agent

OpenThread Border Router จะสร้างโดยค่าเริ่มต้นด้วยแฟล็ก REST_API=1 ซึ่งจะเปิดใช้ REST API ในกรณีที่บิลด์จาก Codelab ก่อนหน้าไม่ได้เปิดใช้ REST API ให้ตรวจสอบว่าได้สร้าง OTBR ใน RPi ด้วยแฟล็กดังกล่าวแล้ว
$ REST_API=1 INFRA_IF_NAME=wlan0 ./script/setup
คุณรีสตาร์ทตัวแทน OTBR ได้โดยเรียกใช้คำสั่งต่อไปนี้
$ sudo systemctl restart otbr-agent.service
ตัวแทนจะเริ่มเซิร์ฟเวอร์ HTTP ในพอร์ต 8081 เซิร์ฟเวอร์นี้ช่วยให้ผู้ใช้หรือโปรแกรมตรวจสอบทำงานหลายอย่างใน OTBR ได้ (ดูเอกสารประกอบที่นี่) คุณสามารถใช้เบราว์เซอร์ curl หรือ wget เพื่อตรวจสอบเนื้อหาได้ เส้นทางที่รองรับมีมากมาย รวมถึงกรณีการใช้งานที่อธิบายไว้ข้างต้น โดยมีกริยา GET ใน /node/dataset/active และกริยา PUT ใน /node/dataset/pending
3. การตั้งค่ากรอบข้อมูลเข้าสู่ระบบใน Android
ข้อมูลเข้าสู่ระบบที่ต้องการ
บริการ Google Play ใน Android อนุญาตและคาดหวังให้มีการลงทะเบียนข้อมูลเข้าสู่ระบบสำหรับ TBR ทั้งหมดในเครือข่าย แต่ละรายการจะระบุด้วยรหัสตัวแทนเราเตอร์ชายแดน (BAID) คุณจะใช้วิธี addCredentials() ของอินเทอร์เฟซ ThreadNetworkClient เพื่อทำงานนี้ TBR แรกที่เพิ่มลงในที่เก็บข้อมูลของบริการ Google Play จะเป็นตัวกำหนดข้อมูลเข้าสู่ระบบที่ต้องการสำหรับอุปกรณ์เคลื่อนที่นี้
แอปที่เพิ่มชุดข้อมูลเข้าสู่ระบบเครือข่าย Thread ลงใน BAID จะกลายเป็นเจ้าของข้อมูลเข้าสู่ระบบและมีสิทธิ์เข้าถึงข้อมูลดังกล่าวอย่างเต็มที่ หากพยายามเข้าถึงข้อมูลเข้าสู่ระบบที่แอปอื่นเพิ่ม คุณจะได้รับข้อผิดพลาด PERMISSION_DENIED อย่างไรก็ตาม ข้อมูลเข้าสู่ระบบที่ต้องการจะพร้อมใช้งานเสมอสำหรับแอปใดก็ตามเมื่อผู้ใช้ให้ความยินยอม เราขอแนะนำให้คุณอัปเดตข้อมูลเข้าสู่ระบบที่จัดเก็บไว้ในบริการ Google Play อยู่เสมอเมื่อมีการอัปเดตเครือข่าย Thread Border Router แม้ว่าปัจจุบันเราจะไม่ได้ใช้ข้อมูลดังกล่าว แต่เราอาจมอบเส้นทางที่ดียิ่งขึ้นในอนาคต
แม้ว่าในภายหลังจะมีการยกเว้น TBR แรก แต่ข้อมูลเข้าสู่ระบบที่ต้องการจะยังคงอยู่ในอุปกรณ์ Android เมื่อตั้งค่าแล้ว แอปอื่นๆ ที่จัดการข้อมูลเข้าสู่ระบบ Thread จะขอรับข้อมูลเข้าสู่ระบบได้จากการเรียกใช้ getPreferredCredentials()
Google TBR Sync
อุปกรณ์ Android จะซิงค์กับ TBR ของ Google โดยอัตโนมัติ หากไม่มีข้อมูลเข้าสู่ระบบใน Android อุปกรณ์จะดึงข้อมูลดังกล่าวจาก TBR ของ Google ในเครือข่าย และข้อมูลเข้าสู่ระบบเหล่านั้นจะกลายเป็นข้อมูลเข้าสู่ระบบที่ต้องการ การซิงค์ระหว่าง TBR กับอุปกรณ์ Android จะเกิดขึ้นก็ต่อเมื่อ TBR จับคู่กับผู้ใช้รายเดียว หรือจับคู่กับผู้ใช้ 2 รายที่อยู่ในสมาร์ทโฮม (โครงสร้าง) เดียวกัน
กระบวนการนี้จะเกิดขึ้นเมื่อผู้ใช้ Google รายอื่นใช้ GHA สำหรับ Android หรือ GHA สำหรับ iOS ในโครงสร้างเดียวกัน ในกรณีของ GHA สำหรับ iOS ระบบจะตั้งค่าข้อมูลเข้าสู่ระบบที่ต้องการไว้ในที่เก็บข้อมูล iOS หากไม่มีข้อมูลเข้าสู่ระบบที่ต้องการ
หากมีอุปกรณ์ Android 2 เครื่อง (หรือ Android + iGHA) อยู่ในเครือข่ายเดียวกันโดยมีชุดข้อมูลเข้าสู่ระบบที่ต้องการแตกต่างกัน อุปกรณ์ที่กำหนดค่า TBR ในตอนแรกจะยังคงใช้ TBR ต่อไป
การเริ่มต้นใช้งาน TBR ของบุคคลที่สาม
ปัจจุบันระบบไม่ได้กำหนดขอบเขตพื้นที่เก็บข้อมูลของข้อมูลเข้าสู่ระบบตามสมาร์ทโฮม (โครงสร้าง) ของผู้ใช้ อุปกรณ์ Android แต่ละเครื่องจะมีพื้นที่เก็บข้อมูล BAID ของตัวเอง แต่เมื่อมี TBR ของ Google ในเครือข่าย อุปกรณ์ Android เครื่องอื่นๆ และอุปกรณ์ iOS ที่เรียกใช้แอป Google Home สำหรับ iOS จะซิงค์กับ TBR นั้นและพยายามตั้งค่าข้อมูลเข้าสู่ระบบในเครื่องในพื้นที่เก็บข้อมูลของโทรศัพท์
ก่อนที่ OOB TBR ใหม่จะสร้างเครือข่าย คุณควรตรวจสอบว่ามีเครือข่ายที่ต้องการอยู่ในที่เก็บข้อมูลของ Android อยู่แล้วหรือไม่
- หากมีเครือข่ายที่ต้องการ ผู้ให้บริการควรใช้เครือข่ายดังกล่าว ซึ่งจะช่วยให้มั่นใจว่าอุปกรณ์ Thread จะเชื่อมต่อกับเครือข่าย Thread เดียวเมื่อเป็นไปได้
- หากไม่มีเครือข่ายที่ต้องการ ให้สร้างชุดข้อมูลเข้าสู่ระบบใหม่และกำหนดให้กับ TBR ในบริการ Google Play Android จะใช้ข้อมูลเข้าสู่ระบบเหล่านั้นเป็นข้อมูลเข้าสู่ระบบมาตรฐานที่ตั้งค่าไว้ใน TBR ทั้งหมดที่อิงตาม Google และผู้ให้บริการรายอื่นๆ จะสามารถเพิ่มประสิทธิภาพการเข้าถึงและความเสถียรของ Mesh ด้วยอุปกรณ์เพิ่มเติม

4. การโคลนและการแก้ไขแอป Android
เราได้สร้างแอป Android ที่แสดงการเรียกใช้ที่เป็นไปได้หลักๆ ไปยัง Thread API คุณสามารถใช้รูปแบบเหล่านี้ในแอปได้ ใน Codelab นี้ เราจะโคลนแอปตัวอย่าง Google Home สำหรับ Matter จาก Github
ซอร์สโค้ดทั้งหมดที่แสดงที่นี่ได้รับการโค้ดไว้แล้วในแอปตัวอย่าง คุณสามารถแก้ไขให้ตรงกับความต้องการของคุณเองได้ แต่คุณจะโคลนแอปหรือเรียกใช้ไบนารีที่สร้างไว้ล่วงหน้าเพื่อตรวจสอบฟังก์ชันการทำงานก็ได้
- โคลนโดยใช้คำสั่งต่อไปนี้
$ git clone https://github.com/google-home/sample-apps-for-matter-android.git
- ดาวน์โหลดและเปิด Android Studio
- คลิกไฟล์ > เปิด แล้วเลือกที่เก็บที่โคลน
- เปิดใช้โหมดนักพัฒนาแอปในโทรศัพท์ Android
- เชื่อมต่อกับคอมพิวเตอร์ผ่านสาย USB
- เรียกใช้แอปจาก Android Studio ผ่าน <Cmd+R> (OS X) หรือ <Ctrl+R> (Win, Linux)
- ไปที่วงล้อ -> เครื่องมือสำหรับนักพัฒนาแอป -> เครือข่าย Thread
- โต้ตอบกับตัวเลือกต่างๆ ที่มี ในส่วนด้านล่าง เราจะอธิบายโค้ดที่ดำเนินการในทุกปุ่ม
มีข้อมูลเข้าสู่ระบบที่ต้องการไหม
คำถามแรกที่ผู้ผลิต TBR ควรจะถาม Google คือมีชุดข้อมูลเข้าสู่ระบบที่ต้องการอยู่ในอุปกรณ์แล้วหรือไม่ ซึ่งควรเป็นจุดเริ่มต้นของโฟลว์ โค้ดด้านล่างจะค้นหา GPS เกี่ยวกับการมีอยู่ของข้อมูลเข้าสู่ระบบ โดยจะไม่แจ้งให้ขอความยินยอมจากผู้ใช้เนื่องจากไม่มีการแชร์ข้อมูลเข้าสู่ระบบ
/**
* Prompts whether credentials exist in storage or not. Consent from user is not necessary
*/
fun doGPSPreferredCredsExist(activity: FragmentActivity) {
try {
// Uses the ThreadNetwork interface for the preferred credentials, adding
// a listener that will receive an intentSenderResult. If that is NULL,
// preferred credentials don't exist. If that isn't NULL, they exist.
// In this case we'll not use it.
ThreadNetwork.getClient(activity).preferredCredentials.addOnSuccessListener { intentSenderResult ->
intentSenderResult.intentSender?.let { intentSender ->
ToastTimber.d("threadClient: preferred credentials exist", activity)
// don't post the intent on `threadClientIntentSender` as we do when
// we really want to know which are the credentials. That will prompt a
// user consent. In this case we just want to know whether they exist
} ?: ToastTimber.d(
"threadClient: no preferred credentials found, or no thread module found", activity
)
}.addOnFailureListener { e: Exception ->
Timber.d("ERROR: [${e}]")
}
} catch (e: Exception) {
ToastTimber.e("Error $e", activity)
}
}
รับข้อมูลเข้าสู่ระบบที่ต้องการของ GPS
ในกรณีที่มี คุณจะต้องอ่านข้อมูลเข้าสู่ระบบ ความแตกต่างจากโค้ดก่อนหน้ามีเพียงว่าหลังจากได้รับ intentSenderResult แล้ว คุณต้องการสร้างและเปิดใช้ Intent โดยใช้ผลลัพธ์จากผู้ส่ง
ในโค้ดของเรา เราใช้ MutableLiveData<IntentSender?> เพื่อวัตถุประสงค์ในการจัดระเบียบ/สถาปัตยกรรม เนื่องจากโค้ดเดิมอยู่ใน ViewModel (ThreadViewModel.kt) และ Observer ของ Intent อยู่ใน Activity Fragment (ThreadFragment.kt) ดังนั้น เมื่อมีการโพสต์ intentSenderResult ไปยังข้อมูลสด เราจะดำเนินการกับเนื้อหาของ Observer นี้
viewModel.threadClientIntentSender.observe(viewLifecycleOwner) { sender ->
Timber.d(
"threadClient: intent observe is called with [${intentSenderToString(sender)}]"
)
if (sender != null) {
Timber.d("threadClient: Launch GPS activity to get ThreadClient")
threadClientLauncher.launch(IntentSenderRequest.Builder(sender).build())
viewModel.consumeThreadClientIntentSender()
}
}
ซึ่งจะทริกเกอร์ความยินยอมของผู้ใช้ในการแชร์ข้อมูลเข้าสู่ระบบ และหากได้รับอนุมัติ ระบบจะแสดงเนื้อหาผ่านช่องทางต่อไปนี้
threadClientLauncher =
registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result ->
if (result.resultCode == RESULT_OK) {
val threadNetworkCredentials =
ThreadNetworkCredentials.fromIntentSenderResultData(result.data!!)
viewModel.threadPreferredCredentialsOperationalDataset.postValue(
threadNetworkCredentials
)
} else {
val error = "User denied request."
Timber.d(error)
updateThreadInfo(null, "")
}
}
การโพสต์ข้อมูลเข้าสู่ระบบไปยัง MutableLiveData<ThreadNetworkCredentials?> มีคำอธิบายอยู่ด้านล่าง
การตั้งค่าข้อมูลเข้าสู่ระบบ GPS
ไม่ว่าจะมีหรือไม่มี คุณควรลงทะเบียน TBR ในบริการ Google Play แอปของคุณจะเป็นแอปเดียวที่อ่านข้อมูลเข้าสู่ระบบที่เชื่อมโยงกับรหัสตัวแทนชายแดนของ TBR ได้ แต่หาก TBR ของคุณเป็นรายแรกที่ลงทะเบียน ระบบจะคัดลอกข้อมูลเข้าสู่ระบบเหล่านั้นไปยังชุดข้อมูลเข้าสู่ระบบที่ต้องการ แอปใดก็ตามในโทรศัพท์จะเข้าถึงข้อมูลดังกล่าวได้ตราบใดที่ผู้ใช้ให้สิทธิ์
/**
* Last step in setting the GPS thread credentials of a TBR
*/
private fun associateGPSThreadCredentialsToThreadBorderRouterAgent(
credentials: ThreadNetworkCredentials?,
activity: FragmentActivity,
threadBorderAgent: ThreadBorderAgent,
) {
credentials?.let {
ThreadNetwork.getClient(activity).addCredentials(threadBorderAgent, credentials)
.addOnSuccessListener {
ToastTimber.d("threadClient: Credentials added", activity)
}.addOnFailureListener { e: Exception ->
ToastTimber.e("threadClient: Error adding the new credentials: $e", activity)
}
}
}
การตั้งค่าข้อมูลเข้าสู่ระบบสำหรับผลิตภัณฑ์ TBR
ส่วนนี้เป็นกรรมสิทธิ์ของผู้ให้บริการแต่ละราย และใน Codelab นี้ เราจะใช้ DBUS+Python HTTP Rest Server หรือ HTTP Rest Server ดั้งเดิมจาก OTBR
/**
* Creates credentials in the format used by the OTBR HTTP server. See its documentation in
* https://github.com/openthread/ot-br-posix/blob/main/src/rest/openapi.yaml#L215
*/
fun createJsonCredentialsObject(newCredentials: ThreadNetworkCredentials): JSONObject {
val jsonTimestamp = JSONObject()
jsonTimestamp.put("Seconds", System.currentTimeMillis() / 1000)
jsonTimestamp.put("Ticks", 0)
jsonTimestamp.put("Authoritative", false)
val jsonQuery = JSONObject()
jsonQuery.put(
"ActiveDataset",
BaseEncoding.base16().encode(newCredentials.activeOperationalDataset)
)
jsonQuery.put("PendingTimestamp", jsonTimestamp)
// delay of committing the pending set into active set: 10000ms
jsonQuery.put("Delay", 10000)
Timber.d(jsonQuery.toString())
return jsonQuery
}
//(...)
var response = OtbrHttpClient.createJsonHttpRequest(
URL("http://$ipAddress:$otbrPort$otbrDatasetPendingEndpoint"),
activity,
OtbrHttpClient.Verbs.PUT,
jsonQuery.toString()
)
การรับข้อมูลเข้าสู่ระบบจากผลิตภัณฑ์ TBR
ดังที่แสดงไว้ก่อนหน้านี้ ให้ใช้คำกริยา GET HTTP เพื่อรับข้อมูลเข้าสู่ระบบจาก TBR ดูสคริปต์ Python ตัวอย่าง
การสร้างและการนำเข้า
เมื่อสร้างแอป Android คุณจะต้องทำการเปลี่ยนแปลงในไฟล์ Manifest, บิลด์ และการนำเข้าเพื่อรองรับโมดูลเธรดของ Google Play Services ข้อมูลโค้ด 3 รายการต่อไปนี้สรุปการเพิ่มส่วนใหญ่
โปรดทราบว่าแอปตัวอย่างของเราสร้างขึ้นเพื่อการจัดสรร Matter เป็นหลัก ดังนั้นไฟล์ Manifest และ Gradle จึงมีความซับซ้อนมากกว่าส่วนเพิ่มเติมที่จำเป็นสำหรับการใช้ข้อมูลเข้าสู่ระบบ Thread เพียงอย่างเดียว
การเปลี่ยนแปลงไฟล์ Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
(...)
<!-- usesCleartextTraffic needed for OTBR local unencrypted communication -->
<!-- Not needed for Thread Module, only used for HTTP -->
<uses-feature
(...)
android:usesCleartextTraffic="true">
<application>
(...)
<!-- GPS automatically downloads scanner module when app is installed -->
<!-- Not needed for Thread Module, only used for scanning QR Codes -->
<meta-data
android:name="com.google.mlkit.vision.DEPENDENCIES"
android:value="barcode_ui"/>
</application>
</manifest>
Build.gradle
// Thread Network implementation 'com.google.android.gms:play-services-threadnetwork:16.0.0' // Thread QR Code Scanning implementation 'com.google.android.gms:play-services-code-scanner:16.0.0' // Thread QR Code Generation implementation 'com.journeyapps:zxing-android-embedded:4.1.0' // Needed for using BaseEncoding class implementation 'com.google.guava:guava:31.1-jre'
การนำเข้าที่เกี่ยวข้อง
// Thread Network Module import com.google.android.gms.threadnetwork.ThreadNetworkCredentials import com.google.android.gms.threadnetwork.ThreadBorderAgent import com.google.android.gms.threadnetwork.ThreadNetwork // Conversion of credentials to/fro Base16 (hex) import com.google.common.io.BaseEncoding // HTTP import java.io.BufferedInputStream import java.io.InputStream import java.net.HttpURLConnection import java.net.URL import java.nio.charset.StandardCharsets // Co-routines for HTTP calls import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch // JSON import org.json.JSONObject // Logs import timber.log.Timber // mDNS/SD import android.net.nsd.NsdServiceInfo // QR Code reader / writer import com.google.mlkit.vision.barcode.common.Barcode import com.google.mlkit.vision.codescanner.GmsBarcodeScannerOptions import com.google.mlkit.vision.codescanner.GmsBarcodeScanning import com.google.zxing.BarcodeFormat import com.google.zxing.MultiFormatWriter import com.journeyapps.barcodescanner.BarcodeEncoder
5. การค้นหา mDNS/SD
แอปตัวอย่างของเราใช้การค้นหา mDNS/SD เพื่อสร้างรายการ Thread Border Router ที่พร้อมใช้งานในเครือข่าย รวมถึง BAID ของแต่ละรายการ
ซึ่งจะเป็นประโยชน์อย่างยิ่งเมื่อป้อนข้อมูล TBR ลงในที่เก็บข้อมูลของข้อมูลเข้าสู่ระบบ GPS อย่างไรก็ตาม การใช้งานอยู่นอกขอบเขตของ Codelab นี้ เราใช้ไลบรารีการค้นหาบริการของ Android NSDManager และซอร์สโค้ดทั้งหมดมีอยู่ในแอปตัวอย่างใน ServiceDiscovery.kt
6. สรุป
เมื่อใช้งานการเรียกเหล่านี้หรือใช้แอปตัวอย่างแล้ว คุณจะเริ่มต้นใช้งาน RPi OTBR ได้อย่างเต็มรูปแบบ แอปตัวอย่างของเราแสดงปุ่ม 8 ปุ่ม ได้แก่

ลำดับที่เป็นไปได้สำหรับการเริ่มต้นใช้งาน TBR มีดังนี้
- ค้นหาว่ามีข้อมูลเข้าสู่ระบบที่ให้สิทธิพิเศษหรือไม่ (สีน้ำเงิน แถวที่ 1)
- ขึ้นอยู่กับคำตอบ
- รับข้อมูลเข้าสู่ระบบที่ต้องการของ GPS (สีน้ำเงิน แถวที่ 2)
- ตั้งค่าข้อมูลเข้าสู่ระบบ TBR ใน GPS (สีน้ำเงิน แถวที่ 3) -> เลือก TBR -> สร้างแบบสุ่ม -> ป้อนชื่อเครือข่าย -> ตกลง
- ตอนนี้คุณมีข้อมูลเข้าสู่ระบบที่ต้องการแล้ว ให้ตั้งค่าข้อมูลเข้าสู่ระบบเหล่านั้นใน OTBR โดยใช้ตั้งค่าข้อมูลเข้าสู่ระบบ OTBR ของ RPi ซึ่งจะใช้ข้อมูลเข้าสู่ระบบเหล่านั้นกับชุดที่รอดำเนินการ
แอปตัวอย่างจะใช้การหน่วงเวลา 10 วินาทีโดยค่าเริ่มต้น ดังนั้นหลังจากช่วงเวลานี้ ข้อมูลเข้าสู่ระบบของ RPi TBR (และโหนดอื่นๆ ที่อาจอยู่ในเครือข่าย) จะย้ายไปยังชุดข้อมูลใหม่
7. บทสรุป
ใน Codelab นี้ เราได้โคลนแอป Android ตัวอย่างและวิเคราะห์โค้ดหลายๆ ส่วนที่ใช้ Thread Storage API ของบริการ Google Play เราใช้ API เหล่านั้นเพื่อให้มีชุดข้อมูลทั่วไปที่เราสามารถเริ่มต้นใช้งานใน TBR ของ RPi ซึ่งแสดง TBR ของผู้ให้บริการ
การมี TBR ทั้งหมดของผู้ใช้ในเครือข่ายเดียวกันจะช่วยปรับปรุงความยืดหยุ่นและการเข้าถึงของเครือข่าย Thread นอกจากนี้ ยังป้องกันเส้นทางของผู้ใช้ที่มีข้อบกพร่องซึ่งแอปไม่สามารถเริ่มต้นใช้งานอุปกรณ์ Thread ได้เนื่องจากไม่มีสิทธิ์เข้าถึงข้อมูลเข้าสู่ระบบ
เราหวังว่า Codelab และแอปตัวอย่างนี้จะช่วยคุณออกแบบและพัฒนาแอปของคุณเองและผลิตภัณฑ์ Thread Border Router
8. ข้อมูลอ้างอิง
โปรเซสเซอร์ร่วม RCP
DBUS