mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
[docs] move openthread.io content to openthread/ot-docs (#6415)
This commit is contained in:
@@ -1,210 +0,0 @@
|
||||
# BeagleBone Black
|
||||
|
||||
Contributor: https://github.com/srickardti
|
||||
|
||||
OpenThread Border Router (OTBR) provides support for the [BeagleBone
|
||||
Black](http://www.ti.com/tool/BEAGLEBK) (BBB) platform.
|
||||
|
||||
Hardware requirements:
|
||||
|
||||
* External 5V AC adapter for power
|
||||
* An 8 GB or larger microSD card ("uSD card" in this guide)
|
||||
* A supported OpenThread platform (such as the [TI
|
||||
CC2652](https://openthread.io/vendors/texas-instruments#cc2652)) for Thread
|
||||
network connectivity in an RCP design
|
||||
|
||||
Steps to enable:
|
||||
|
||||
1. Download and install the OS.
|
||||
1. Prepare the Debian Environment for OTBR
|
||||
1. Build and install OTBR
|
||||
1. Set up a Wi-Fi access point
|
||||
|
||||
> Note: The BBB does not have built-in Wi-Fi support. This guide was built and
|
||||
tested with a BBONE-GATEWAY-CAPE for Wi-Fi AP operation. Some BeagleBone
|
||||
variants have onboard Wi-Fi capability, and some of this guide may be
|
||||
applicable.
|
||||
|
||||
## Step 1: Download and install the OS
|
||||
|
||||
1. Download the [latest Debian IoT image for
|
||||
BeagleBone](https://beagleboard.org/latest-images).
|
||||
* The version used for this guide was
|
||||
`bone-debian-10.3-iot-armhf-2020-04-06-4gb.img.xz`
|
||||
1. Install the OS image on a uSD Card by following the [BeagleBone getting
|
||||
started guide](https://beagleboard.org/getting-started).
|
||||
1. Boot the BeagleBone and SSH into the device.
|
||||
* Connectivity over a local Ethernet based network is recommended.
|
||||
* The cloud9 IDE will be disabled later in this guide.
|
||||
* This guide will change the state of BeagleBone network interfaces, be
|
||||
aware your secure shell session may disconnect.
|
||||
* Modern BeagleBone bootloaders will run from the uSD card by default, but
|
||||
some BeagleBone Black devices may try to boot from the internal eMMC.
|
||||
Make sure to press the BOOT Button in this case.
|
||||
|
||||
> Warning: The power requirements of the development kit used for the
|
||||
OpenThread RCP may be too great for the power that can be supplied from a
|
||||
computer's USB port. It is recommended that you use the 5V power adaptor for
|
||||
the BeagleBone where applicable.
|
||||
|
||||
For more detailed information on the BeagleBone, see the [BeagleBoard Support
|
||||
Page](https://beagleboard.org/support).
|
||||
|
||||
## Step 2: Prepare the Debian Environment for OTBR
|
||||
|
||||
Certain parts of the default BeagleBone Debian image run by default. These may
|
||||
conflict with some parts of the OpenThread Border Router software.
|
||||
|
||||
Some packages are running by default on the BeagleBone to enable quick
|
||||
development. These can be found in systemd with the command `sudo systemctl
|
||||
list-units --all` and `sudo systemctl list-sockets --all`.
|
||||
|
||||
Stop and disable the modules:
|
||||
|
||||
```
|
||||
$ sudo systemctl stop bonescript-autorun.service
|
||||
$ sudo systemctl stop bonescript.socket
|
||||
$ sudo systemctl stop bonescript.service
|
||||
$ sudo systemctl stop cloud9.socket
|
||||
$ sudo systemctl stop cloud9.service
|
||||
$ sudo systemctl stop nodered.service
|
||||
$ sudo systemctl disable bonescript-autorun.service
|
||||
$ sudo systemctl disable bonescript.socket
|
||||
$ sudo systemctl disable bonescript.service
|
||||
$ sudo systemctl disable cloud9.socket
|
||||
$ sudo systemctl disable cloud9.service
|
||||
$ sudo systemctl disable nodered.service
|
||||
$ sudo systemctl daemon-reload
|
||||
```
|
||||
|
||||
Disable advertising the Cloud9 IDE and NodeRED services with Avahi by deleting
|
||||
the service files:
|
||||
|
||||
```
|
||||
$ sudo rm /etc/avahi/services/*
|
||||
```
|
||||
|
||||
The filesystem for the uSD BeagleBone image is limited to 4GB to fit on most
|
||||
uSD cards. Expand the partition to enable usage of the entire storage capacity.
|
||||
|
||||
```
|
||||
$ sudo /opt/scripts/tools/grow_partition.sh
|
||||
```
|
||||
|
||||
You are encouraged to read that helper script to find out how the filesystem is
|
||||
expanded. You will have to reboot the BeagleBone and re-login to use this new
|
||||
filesystem definition.
|
||||
|
||||
```
|
||||
$ sudo shutdown -r now
|
||||
```
|
||||
|
||||
This will close your SSH session.
|
||||
|
||||
Once logged back into the BeagleBone, install Network Manager:
|
||||
|
||||
```
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install network-manager
|
||||
```
|
||||
|
||||
Then disable `connman` and enable `network-manager`:
|
||||
|
||||
```
|
||||
$ sudo systemctl disable connman
|
||||
$ sudo systemctl enable network-manager
|
||||
```
|
||||
|
||||
If we were to `stop` connman directly here it would break the SSH session
|
||||
because the network interface is managed by connman. Instead we configure the
|
||||
system to take effect on the next boot. Now reboot the Beaglebone and re-login.
|
||||
|
||||
```
|
||||
$ sudo shutdown -r now
|
||||
```
|
||||
|
||||
Network Manager may not have setup the DNS name servers. Edit `resolv.conf`
|
||||
with the command `sudo vim /etc/resolv.conf` and make sure the contents contain
|
||||
the Google DNS and Cloudflare DNS:
|
||||
|
||||
```
|
||||
nameserver 8.8.8.8
|
||||
nameserver 1.1.1.1
|
||||
```
|
||||
|
||||
Restart to make sure Network Manager is setup correctly.
|
||||
|
||||
```
|
||||
$ sudo shutdown -r now
|
||||
```
|
||||
|
||||
> Note: If your BeagleBone has a WiLink based Wi-Fi module installed, the
|
||||
following steps may be applicable to you. This was tested with a
|
||||
BBONE-GATEWAY-CAPE. Some of these may not be required.
|
||||
|
||||
The WiLink 8 module does not like to have its MAC address changed at runtime.
|
||||
Network Manager will try to do this when scanning. Edit the
|
||||
`NetworkManager.conf` with the command `sudo vim
|
||||
/etc/NetworkManager/NetworkManager.conf` and add the lines below:
|
||||
|
||||
```
|
||||
[device]
|
||||
wifi.scan-rand-mac-address=no
|
||||
```
|
||||
|
||||
The `BBONE-GATEWAY-CAPE` is not recognized by the BeagleBone by default because
|
||||
of a pin conflict. Add the configuration manually by editing the `uEnv.txt`
|
||||
with the command `sudo vim /boot/uEnv.txt` and make sure the following lines
|
||||
match:
|
||||
|
||||
```
|
||||
#Custom Cape
|
||||
dtb_overlay=/lib/firmware/BB-GATEWAY-WL1837-00A0.dtbo
|
||||
#
|
||||
#Disable auto loading of virtual capes (emmc/video/wireless/adc)
|
||||
disable_uboot_overlay_emmc=1
|
||||
disable_uboot_overlay_video=1
|
||||
disable_uboot_overlay_audio=1
|
||||
disable_uboot_overlay_wireless=1
|
||||
disable_uboot_overlay_adc=1
|
||||
```
|
||||
|
||||
The BeagleBone wilink setup scripts try to use connman by default to enable
|
||||
Wi-Fi AP activity. Edit the default configuration folder with the command `sudo
|
||||
vim /etc/default/bb-wl18xx` and make sure the variables match below:
|
||||
|
||||
```
|
||||
TETHER_ENABLED=no
|
||||
USE_CONNMAN_TETHER=no
|
||||
```
|
||||
|
||||
Restart to make sure Network Manager can see the new interface.
|
||||
|
||||
```
|
||||
$ sudo shutdown -r now
|
||||
```
|
||||
|
||||
Once logged back in you can run `ifconfig` or `nmcli` to see the new `wlan`
|
||||
interface.
|
||||
|
||||
> Warning: The startup scripts may take a few moments to enable the `wlan0`
|
||||
interface. If you do not see the interface, check `journalctl` to see if the
|
||||
system is having difficulty bringing up the interface.
|
||||
|
||||
## Step 3: Build and install OTBR
|
||||
|
||||
See [Build and Configuration](https://openthread.io/guides/border-router/build)
|
||||
for instructions on building and installing OTBR.
|
||||
|
||||
> Note: If your BeagleBone has Wi-Fi capabilities, you can enable the OTBR
|
||||
build scripts to configure it as an access point by passing
|
||||
`NETWORK_MANAGER_WIFI=1` to the build scripts.
|
||||
|
||||
## Step 4: Set up a Wi-Fi access point
|
||||
|
||||
If your BeagleBone is Wi-Fi enabled and automatic setup of the Wi-Fi access
|
||||
point by Network Manager is skipped, see [Wi-Fi Access Point
|
||||
Setup](https://openthread.io/guides/border-router/access-point) for manual
|
||||
configuration instructions. The guide is written for Raspberry Pi, but most of
|
||||
the configuration steps are applicable to the BeagleBone Debian distribution.
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
toc:
|
||||
- title: Overview
|
||||
path: /guides/porting/
|
||||
step_group: porting_guide
|
||||
- title: Set up the Build Environment
|
||||
path: /guides/porting/set-up-the-build-environment
|
||||
step_group: porting_guide
|
||||
- title: Implement Platform Abstraction Layer APIs
|
||||
path: /guides/porting/implement-platform-abstraction-layer-apis
|
||||
step_group: porting_guide
|
||||
- title: Implement Advanced Features
|
||||
path: /guides/porting/implement-advanced-features
|
||||
step_group: porting_guide
|
||||
- title: Validate the Port
|
||||
path: /guides/porting/validate-the-port
|
||||
step_group: porting_guide
|
||||
- title: Certification and README
|
||||
path: /guides/porting/certification-and-readme
|
||||
step_group: porting_guide
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
# Certification and README
|
||||
|
||||
## Thread Certification
|
||||
|
||||
To achieve Thread Certification, the port must be tested against the official
|
||||
[Thread Harness](http://graniteriverlabs.com/thread/) and pass all scenarios
|
||||
listed in the Thread Certification Test Plan.
|
||||
|
||||
For more information, see
|
||||
[Certification](https://openthread.io/certification).
|
||||
|
||||
## README
|
||||
|
||||
A detailed README is necessary to demonstrate how to build and run OpenThread on
|
||||
a new hardware platform.
|
||||
|
||||
At a minimum, the README should include:
|
||||
|
||||
- Information about the hardware platform
|
||||
- Links to the required toolchain
|
||||
- How to configure platform-specific vendor software
|
||||
- How to build and flash binaries onto the platform
|
||||
- Versions of libraries and toolchains used for validation of the port
|
||||
|
||||
See the
|
||||
[EFR32MG12 README](https://github.com/openthread/openthread/blob/main/examples/platforms/efr32/efr32mg12/README.md)
|
||||
for an example.
|
||||
@@ -1,135 +0,0 @@
|
||||
# Implement Advanced Features
|
||||
|
||||
Some advanced features are optional, depending on whether or not they are
|
||||
supported on the target hardware platform.
|
||||
|
||||
<a id="auto-frame-pending"></a>
|
||||
|
||||
## Step 1: Auto frame pending
|
||||
|
||||
IEEE 802.15.4 defines two kinds of data transmission methods between parent and
|
||||
child: direct transmission and indirect transmission. The latter is designed
|
||||
primarily for sleepy end devices (SEDs) which sleep most of the time,
|
||||
periodically waking to poll the parent for queued data.
|
||||
|
||||
- **Direct Transmission** — parent sends a data frame directly to the end device
|
||||
<img src="/guides/images/ot-auto-frame-direct.png" srcset="/guides/images/ot-auto-frame-direct.png 1x, /guides/images/ot-auto-frame-direct_2x.png 2x" border="0" alt="Direct Transmission" width="400" />
|
||||
|
||||
- **Indirect Transmission** — parent holds data until requested by its intended end device
|
||||
<img src="/guides/images/ot-auto-frame-indirect.png" srcset="/guides/images/ot-auto-frame-indirect.png 1x, /guides/images/ot-auto-frame-indirect_2x.png 2x" border="0" alt="Direct Transmission" width="400" />
|
||||
|
||||
In the Indirect case, a child end device must first poll the parent to determine
|
||||
whether any data is available for it. To do this, the child sends a data
|
||||
request, which the parent acknowledges. The parent then determines whether it
|
||||
has any data for the child device; if so, it sends a data packet to the child
|
||||
device, which acknowledges receipt of the data.
|
||||
|
||||
If the radio supports dynamically setting the Frame Pending bit in outgoing
|
||||
acknowledgments to SEDs, the drivers must implement the
|
||||
[source address match](https://github.com/openthread/openthread/blob/main/include/openthread/platform/radio.h#L288)
|
||||
API to enable this capability. OpenThread uses this API to tell the radio which
|
||||
SEDs to set the Frame Pending bit for.
|
||||
|
||||
If the radio does not support dynamically setting the Frame Pending bit, the
|
||||
radio might stub out the source address match API to return
|
||||
`OT_ERROR_NOT_IMPLEMENTED`.
|
||||
|
||||
## Step 2: Energy Scan/Detect with radio
|
||||
|
||||
> Note: This feature is optional.
|
||||
|
||||
The Energy Scan/Detect feature requires the radio chip to sample energy
|
||||
presenting on selected channels and return the detected energy value to the
|
||||
upper layer.
|
||||
|
||||
If this feature is not implemented, the IEEE 802.15.4 MAC layer
|
||||
sends/receives a Beacon Request/Response packet to evaluate the current
|
||||
energy value on the channel.
|
||||
|
||||
If the radio chip supports Energy Scan/Detect, make sure to disable software
|
||||
energy scanning logic by setting the macro
|
||||
`OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN = 0`.
|
||||
|
||||
## Step 3: Hardware acceleration for mbedTLS
|
||||
|
||||
> Note: This feature is optional.
|
||||
|
||||
mbedTLS defines several macros in the main configuration header file,
|
||||
[`mbedtls-config.h`](https://github.com/openthread/openthread/blob/main/third_party/mbedtls/mbedtls-config.h),
|
||||
to allow users to enable alternative implementations of AES, SHA1, SHA2, and
|
||||
other modules, as well as individual functions for the Elliptic curve
|
||||
cryptography (ECC) over GF(p) module. See
|
||||
[mbedTLS hardware acceleration](https://docs.mbed.com/docs/mbed-os-handbook/en/latest/advanced/tls_hardware_acceleration/)
|
||||
for more information.
|
||||
|
||||
OpenThread does not enable those macros, therefore the symmetric crypto
|
||||
algorithms, hash algorithms and ECC functions all utilize software
|
||||
implementations by default. These implementations require considerable memory
|
||||
and computational resources. For optimal performance and a better user
|
||||
experience, we recommend enabling hardware acceleration instead of software to
|
||||
implement the above operations.
|
||||
|
||||
To enable hardware acceleration within OpenThread, the following mbedTLS
|
||||
configuration header files should be added to the compile option flags in the
|
||||
platform example's Makefile:
|
||||
|
||||
- Main configuration, which defines all necessary macros used in OpenThread:
|
||||
`/openthread/third-party/mbedtls/mbedtls-config.h`
|
||||
- User-specific configuration, which defines alternate implementations of
|
||||
modules and functions: `/openthread/examples/platforms/{platform-name}/crypto/{platform-name}-mbedtls-config.h`
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
EFR32_MBEDTLS_CPPFLAGS = -DMBEDTLS_CONFIG_FILE='\"mbedtls-config.h\"'
|
||||
EFR32_MBEDTLS_CPPFLAGS += -DMBEDTLS_USER_CONFIG_FILE='\"efr32-mbedtls-config.h\"'
|
||||
```
|
||||
|
||||
Commented macros in `mbedtls-config.h` are not mandatory, and can be enabled in
|
||||
the user-specific configuration header file for hardware acceleration.
|
||||
|
||||
For a complete example user-specific configuration, see the
|
||||
[`mbedtls_config_autogen.h`](https://github.com/openthread/openthread/blob/main/examples/platforms/efr32/efr32mg12/crypto/mbedtls_config_autogen.h)
|
||||
file.
|
||||
|
||||
### AES module
|
||||
|
||||
OpenThread Security applies AES CCM (Counter with CBC-MAC) crypto to
|
||||
encrypt/decrypt the IEEE 802.15.4 or MLE messages and validates the message
|
||||
integration code. Hardware acceleration should at least support basic AES ECB
|
||||
(Electronic Codebook Book) mode for AES CCM basic functional call.
|
||||
|
||||
To utilize an alternative AES module implementation:
|
||||
|
||||
1. Define the `MBEDTLS_AES_ALT` macro in the user-specific mbedTLS
|
||||
configuration header file
|
||||
1. Indicate the path of the `aes_alt.h` file using the `MBEDTLS_CPPFLAGS`
|
||||
variable
|
||||
|
||||
### SHA256 module
|
||||
|
||||
OpenThread Security applies HMAC and SHA256 hash algorithms to calculate the
|
||||
hash value for master key management and PSKc generation according to the Thread
|
||||
Specification.
|
||||
|
||||
To utilize an alternative basic SHA256 module implementation:
|
||||
|
||||
1. Define the `MBEDTLS_SHA256_ALT` macro in the user-specific mbedTLS
|
||||
configuration header file
|
||||
1. Indicate the path of the `sha256_alt.h` file using the `MBEDTLS_CPPFLAGS`
|
||||
variable
|
||||
|
||||
### ECC functions
|
||||
|
||||
Since mbedTLS currently only supports hardware acceleration for parts of ECC
|
||||
functions, rather than the entire module, you can choose to implement some
|
||||
functions defined in
|
||||
`{path-to-mbedtls}/library/ecp.c` to accelerate ECC
|
||||
point multiplication.
|
||||
|
||||
Curve secp256r1 is used in the key exchange algorithm of the
|
||||
[ECJPAKE](https://tools.ietf.org/html/draft-cragie-tls-ecjpake-00) draft. Hence,
|
||||
hardware acceleration should at least support the secp256r1 short weierstrass
|
||||
curve operation. See [SiLabs CRYPTO Hardware Acceleration for
|
||||
mbedTLS](https://siliconlabs.github.io/Gecko_SDK_Doc/mbedtls/html/group__sl__crypto.html)
|
||||
for an example.
|
||||
@@ -1,204 +0,0 @@
|
||||
# Implement Platform Abstraction Layer APIs
|
||||
|
||||
OpenThread is OS and platform agnostic, with a narrow Platform Abstraction Layer
|
||||
(PAL). This PAL defines:
|
||||
|
||||
<figure class="attempt-right">
|
||||
<img src="/guides/images/ot-arch-porting.png" srcset="/guides/images/ot-arch-porting.png 1x, /guides/images/ot-arch-porting_2x.png 2x" border="0" alt="Porting Architecture" />
|
||||
</figure>
|
||||
|
||||
- Alarm interface for free-running timer with alarm
|
||||
- Bus interfaces (UART, SPI) for communicating CLI and Spinel messages
|
||||
- Radio interface for IEEE 802.15.4-2006 communication
|
||||
- GCC-specific initialization routines
|
||||
- Entropy for true random number generation
|
||||
- Settings service for non-volatile configuration storage
|
||||
- Logging interface for delivering OpenThread log messages
|
||||
- System-specific initialization routines
|
||||
|
||||
All APIs should be implemented based on the underlying Hardware Abstraction
|
||||
Layer (HAL) Build Support Package (BSP).
|
||||
|
||||
> Key Point: Unless noted as optional, **Platform Abstraction Layer APIs are
|
||||
mandatory** and must be implemented according to the definitions in each API
|
||||
header file.
|
||||
|
||||
API files should be placed in the following directories:
|
||||
|
||||
Type | Directory
|
||||
------|------
|
||||
Platform-specific PAL implementation | `/openthread/examples/platforms/{platform-name}`
|
||||
Header files — Non-volatile storage API | `/openthread/examples/platforms/utils`
|
||||
All other header files | `/openthread/include/openthread/platform`
|
||||
HAL BSP | `/openthread/third_party/{platform-name}`
|
||||
|
||||
## Step 1: Alarm
|
||||
|
||||
API declaration:
|
||||
|
||||
[`/openthread/include/openthread/platform/alarm-milli.h`](https://github.com/openthread/openthread/blob/main/include/openthread/platform/alarm-milli.h)
|
||||
|
||||
The Alarm API provides fundamental timing and alarm services for the upper layer
|
||||
timer implementation.
|
||||
|
||||
There are two alarm service types,
|
||||
[millisecond](https://github.com/openthread/openthread/blob/main/include/openthread/platform/alarm-milli.h)
|
||||
and [microsecond](https://github.com/openthread/openthread/blob/main/include/openthread/platform/alarm-micro.h).
|
||||
Millisecond is required for a new hardware platform. Microsecond is optional.
|
||||
|
||||
## Step 2: UART
|
||||
|
||||
> Note: This API is optional.
|
||||
|
||||
API declaration:
|
||||
|
||||
[`/openthread/examples/platforms/utils/uart.h`](https://github.com/openthread/openthread/blob/main/examples/platforms/utils/uart.h)
|
||||
|
||||
The UART API implements fundamental serial port communication via the UART
|
||||
interface.
|
||||
|
||||
While the OpenThread
|
||||
[CLI](https://github.com/openthread/openthread/tree/main/examples/apps/cli)
|
||||
and [NCP](https://github.com/openthread/openthread/tree/main/examples/apps/ncp)
|
||||
add-ons depend on the UART interface to interact with the host side, UART API
|
||||
support is optional. However, even if you do not plan to use these add-ons on
|
||||
your new hardware platform example, we highly recommend you add support for a
|
||||
few reasons:
|
||||
|
||||
- The CLI is useful for validating that the port works correctly
|
||||
- The Harness Automation Tool uses the UART interface to control OpenThread for testing and certification purposes
|
||||
|
||||
If the target hardware platform supports a USB CDC module rather than UART, make
|
||||
sure to:
|
||||
|
||||
- Install the correct USB CDC driver on the host side
|
||||
- Replace the UART API implementation with the USB CDC driver (along with BSP)
|
||||
on the OpenThread side, using the same function prototypes
|
||||
|
||||
## Step 3: Radio
|
||||
|
||||
API declaration:
|
||||
|
||||
[`/openthread/include/openthread/platform/radio.h`](https://github.com/openthread/openthread/blob/main/include/openthread/platform/radio.h)
|
||||
|
||||
The Radio API defines all necessary functions called by the upper IEEE 802.15.4
|
||||
MAC layer. The Radio chip must be fully compliant with the 2.4GHz IEEE
|
||||
802.15.4-2006 specification.
|
||||
|
||||
Due to its enhanced low power feature, OpenThread requires all platforms to
|
||||
implement auto frame pending (indirect transmission) by default, and the source
|
||||
address match table should also be implemented in the `radio.h` source file.
|
||||
|
||||
However, if your new hardware platform example is resource limited, the source
|
||||
address table can be defined as zero length. See
|
||||
[Auto Frame Pending](#auto-frame-pending) for more information.
|
||||
|
||||
> Note: The `otPlatRadioGetIeeeEui64` Radio API **MUST** return a unique
|
||||
administered factory-assigned IEEE EUI-64 that includes the manufacturer's OUI.
|
||||
The EUI-64 is used to match to steering data during the Joiner Discovery phase.
|
||||
|
||||
## Step 4: Misc/Reset
|
||||
|
||||
API declaration:
|
||||
|
||||
[`/openthread/include/openthread/platform/misc.h`](https://github.com/openthread/openthread/blob/main/include/openthread/platform/misc.h)
|
||||
|
||||
The Misc/Reset API provides a method to reset the software on the chip, and
|
||||
query the reason for last reset.
|
||||
|
||||
## Step 5: Entropy
|
||||
|
||||
> Note: **Implementation of this API is required in every port of OpenThread.**
|
||||
|
||||
API declaration:
|
||||
|
||||
[`/openthread/include/openthread/platform/entropy.h`](https://github.com/openthread/openthread/blob/main/include/openthread/platform/entropy.h)
|
||||
|
||||
The Entropy API provides a true random number generator (TRNG) for the upper
|
||||
layer, which is used to maintain security assets for the entire OpenThread
|
||||
network. The API should guarantee that a new random number is generated for
|
||||
each function call. Security assets affected by the TRNG include:
|
||||
|
||||
- AES CCM nonce
|
||||
- Random delayed jitter
|
||||
- Devices' extended address
|
||||
- The initial random period in the trickle timer
|
||||
- CoAP token/message IDs
|
||||
|
||||
Note that many platforms have already integrated a random number generator,
|
||||
exposing the API in its BSP package. In the event that the target hardware
|
||||
platform does not support TRNG, consider leveraging ADC module sampling to
|
||||
generate a fixed-length random number. Sample over multiple iterations if
|
||||
necessary to meet the TRNG requirements (uint32_t).
|
||||
|
||||
When the macro `MBEDTLS_ENTROPY_HARDWARE_ALT` is set to `1`, this API should
|
||||
also provide a method to generate the hardware entropy used in the mbedTLS
|
||||
library.
|
||||
|
||||
## Step 6: Non-volatile storage
|
||||
|
||||
> Note: **Only _one_ of these APIs is required to be implemented in every port
|
||||
of OpenThread.**
|
||||
|
||||
API declarations:
|
||||
|
||||
[`/openthread/include/openthread/platform/flash.h`](https://github.com/openthread/openthread/blob/main/include/openthread/platform/flash.h)
|
||||
|
||||
**or**
|
||||
|
||||
[`/openthread/include/openthread/platform/settings.h`](https://github.com/openthread/openthread/blob/main/include/openthread/platform/settings.h)
|
||||
|
||||
The Non-volatile storage requirement can be satisfied by implementing one of the
|
||||
two APIs listed above. The Flash API implements a flash storage driver, while
|
||||
the Settings API provides functions for an underlying flash operation
|
||||
implementation to the upper layer.
|
||||
|
||||
These APIs expose to the upper layer:
|
||||
|
||||
- The available non-volatile storage size used to store application data (for
|
||||
example, active/pending operational dataset, current network parameters and
|
||||
thread devices' credentials for reattachment after reset)
|
||||
- Read, write, erase, and query flash status operations
|
||||
|
||||
Use `OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE` in your platform example's
|
||||
core config file to indicate which API the platform should use. If set to `1`,
|
||||
the Flash API must be implemented. Otherwise, the Settings API must be
|
||||
implemented.
|
||||
|
||||
This flag must be set in your
|
||||
`/openthread/examples/platforms/{platform-name}/openthread-core-{platform-name}-config.h`
|
||||
file.
|
||||
|
||||
## Step 7: Logging
|
||||
|
||||
> Note: This API is optional.
|
||||
|
||||
API declaration:
|
||||
|
||||
[`/openthread/include/openthread/platform/logging.h`](https://github.com/openthread/openthread/blob/main/include/openthread/platform/logging.h)
|
||||
|
||||
The Logging API implements OpenThread's logging and debug functionality, with
|
||||
multiple levels of debug output available. This API is optional if you do not
|
||||
plan to utilize OpenThread's logging on your new hardware platform example.
|
||||
|
||||
The highest and most detailed level is `OPENTHREAD_LOG_LEVEL_DEBG`, which
|
||||
prints all raw packet information and logs lines through the serial port or on
|
||||
the terminal. Choose a debug level that best meets your needs.
|
||||
|
||||
## Step 8: System-specific
|
||||
|
||||
API declaration:
|
||||
|
||||
[`/openthread/examples/platforms/openthread-system.h`](https://github.com/openthread/openthread/blob/main/examples/platforms/openthread-system.h)
|
||||
|
||||
The System-specific API primarily provides initialization and deinitialization
|
||||
operations for the selected hardware platform. This API is not called by the
|
||||
OpenThread library itself, but may be useful for your system/RTOS. You can also
|
||||
implement the initialization of other modules (for example, UART, Radio, Random,
|
||||
Misc/Reset) in this source file.
|
||||
|
||||
Implementation of this API depends on your use case. If you wish to use the
|
||||
generated [CLI and NCP applications](https://openthread.io/guides/build#binaries) for an [example
|
||||
platform](https://github.com/openthread/openthread/tree/main/examples/platforms),
|
||||
you must implement this API. Otherwise, any API can be implemented to integrate
|
||||
the example platform drivers into your system/RTOS.
|
||||
@@ -1,33 +0,0 @@
|
||||
# Porting OpenThread to New Hardware Platforms
|
||||
|
||||
Porting the OpenThread stack to a new hardware platform consists of five steps:
|
||||
|
||||
1. [Set up the build environment](https://github.com/openthread/openthread/blob/main/doc/site/en/guides/porting/set-up-the-build-environment.md)
|
||||
1. [Implement Platform Abstraction Layer APIs](https://github.com/openthread/openthread/blob/main/doc/site/en/guides/porting/implement-platform-abstraction-layer-apis.md)
|
||||
1. [Implement advanced features (Hardware Abstraction Layer)](https://github.com/openthread/openthread/blob/main/doc/site/en/guides/porting/implement-advanced-features.md)
|
||||
1. [Validate the port](https://github.com/openthread/openthread/blob/main/doc/site/en/guides/porting/validate-the-port.md)
|
||||
1. [Certification and README](https://github.com/openthread/openthread/blob/main/doc/site/en/guides/porting/certification-and-readme.md)
|
||||
|
||||
## Hardware platform requirements
|
||||
|
||||
OpenThread requires the following platform services:
|
||||
|
||||
- [IEEE 802.15.4-2006](https://standards.ieee.org/findstds/standard/802.15.4-2006.html)
|
||||
2.4 GHz radio
|
||||
- Send and receive IEEE 802.15.4 frames
|
||||
- Generate IEEE 802.15.4 Acknowledgment frames
|
||||
- Provide Received Signal Strength Indicator (RSSI) measurements on
|
||||
received frames
|
||||
- A millisecond-resolution free-running timer with alarm
|
||||
- Non-volatile storage for storing network configuration settings
|
||||
- A true random number generator (TRNG)
|
||||
|
||||
## Example builds
|
||||
|
||||
Several example builds are provided in the OpenThread repository. For more
|
||||
information, see [Platforms](https://openthread.io/platforms).
|
||||
|
||||
For a complete end-to-end example of how to port OpenThread from scratch, see
|
||||
the [Add support for EFR32](https://github.com/openthread/openthread/pull/1592)
|
||||
pull request.
|
||||
|
||||
@@ -1,216 +0,0 @@
|
||||
# Set Up the Build Environment
|
||||
|
||||
To promote free and open development, OpenThread uses GNU Autotools in the build
|
||||
toolchain. Currently, this toolchain is required for porting OpenThread to a new
|
||||
hardware platform.
|
||||
|
||||
Other build toolchains might be supported in the future, but they are not within
|
||||
the scope of this porting guide.
|
||||
|
||||
> Note: For all path and code examples in this porting
|
||||
guide, always replace {platform-name} with the name of
|
||||
your new platform example. Most of the examples in the guide use a `efr32` platform
|
||||
name.
|
||||
|
||||
## Step 1: GNU Autoconf
|
||||
|
||||
The [Autoconf](https://www.gnu.org/software/autoconf/autoconf.html) script
|
||||
contains the basic system configuration options, including specific
|
||||
platform-relative macro definitions. These macros can be exposed for
|
||||
conditional compilation in other Makefiles during the pre-compiling phase.
|
||||
|
||||
The OpenThread Autoconf script is located at:
|
||||
[`/openthread/configure.ac`](https://github.com/openthread/openthread/blob/main/configure.ac)
|
||||
|
||||
### Platform example name
|
||||
|
||||
In the `AC_ARG_WITH(examples ...)` macro, add the new hardware platform example name. The name
|
||||
should be added in alphabetical order.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
AC_ARG_WITH(examples,
|
||||
[AS_HELP_STRING([--with-examples=TARGET],
|
||||
[Specify the examples from one of: none, simulation, cc2538, efr32, nrf52840 @<:@default=none@:>@.])],
|
||||
[
|
||||
case "${with_examples}" in
|
||||
none)
|
||||
;;
|
||||
simulation|cc2538|efr32|nrf52840)
|
||||
if test ${enable_posix_app} = "yes"; then
|
||||
AC_MSG_ERROR([--with-examples must be none when POSIX apps are enabled by --enable-posix-app])
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([Invalid value ${with_examples} for --with-examples])
|
||||
;;
|
||||
esac
|
||||
],
|
||||
[with_examples=none])
|
||||
```
|
||||
|
||||
### Platform-specific C preprocessor symbol
|
||||
|
||||
Define a platform-specific C preprocessor symbol for the platform example and
|
||||
expose it.
|
||||
|
||||
The platform-specific C preprocessor symbol is exposed at
|
||||
`include/openthread-config.h`. By including the symbol in this header file, we
|
||||
can leverage it in our source code for preprocessor conditional compilation
|
||||
cases.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
case ${with_examples} in
|
||||
|
||||
...
|
||||
|
||||
efr32)
|
||||
OPENTHREAD_EXAMPLES_EFR32=1
|
||||
AC_DEFINE_UNQUOTED([OPENTHREAD_EXAMPLES_EFR32],[${OPENTHREAD_EXAMPLES_EFR32}],[Define to 1 if you want to use efr32 examples])
|
||||
;;
|
||||
|
||||
...
|
||||
|
||||
esac
|
||||
|
||||
...
|
||||
|
||||
AC_SUBST(OPENTHREAD_EXAMPLES_EFR32)
|
||||
AM_CONDITIONAL([OPENTHREAD_EXAMPLES_EFR32], [test "${OPENTHREAD_EXAMPLES}" = "efr32"])
|
||||
```
|
||||
|
||||
### Makefile output directory
|
||||
|
||||
In the `AC_CONFIG_FILES` macro, add a Makefile output directory for the
|
||||
platform example.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
AC_CONFIG_FILES ([
|
||||
examples/platforms/efr32/Makefile
|
||||
])
|
||||
```
|
||||
|
||||
## Step 2: GNU Automake
|
||||
|
||||
Create and modify [Automake](https://www.gnu.org/software/automake/) files to
|
||||
support the new platform example.
|
||||
|
||||
The following platform-specific Automake files need to be created:
|
||||
|
||||
- `/openthread/examples/Makefile-{platform-name}`
|
||||
- `/openthread/examples/platforms/{platform-name}/Makefile.am`
|
||||
- `/openthread/examples/platforms/{platform-name}/Makefile.platform.am`
|
||||
|
||||
See [`/examples`](https://github.com/openthread/openthread/tree/main/examples/) for sample implementations of
|
||||
these files.
|
||||
|
||||
The following Automake files also need to be updated with your platform
|
||||
information:
|
||||
|
||||
- [`/openthread/examples/platforms/Makefile.am`](https://github.com/openthread/openthread/blob/main/examples/platforms/Makefile.am)
|
||||
- [`/openthread/examples/platforms/Makefile.platform.am`](https://github.com/openthread/openthread/blob/main/examples/platforms/Makefile.platform.am)
|
||||
|
||||
### Linker script configuration
|
||||
|
||||
The [GNU Linker](http://www.ece.ufrgs.br/~fetter/eng04476/manuals/ld.pdf) script
|
||||
describes how to map all sections in the input files (`.o` "object" files
|
||||
generated by the GNU Compiler Collection (GCC)) to the final output file (for
|
||||
example, `.elf`). It also determines the storage location of each segment of an
|
||||
executable program, as well as the entry address. The platform-specific linker
|
||||
script is often provided with the platform's BSP.
|
||||
|
||||
Configure the `ld` tool to point to the platform-specific linker script using
|
||||
the `-T` option of the `LDADD_COMMON` variable.
|
||||
|
||||
Create
|
||||
`/openthread/examples/platforms/{platform-name}/Makefile.platform.am`
|
||||
and point the new platform to its linker script:
|
||||
|
||||
```
|
||||
if OPENTHREAD_EXAMPLES_EFR32
|
||||
LDADD_COMMON += \
|
||||
$(top_builddir)/examples/platforms/efr32/libopenthread-efr32.a \
|
||||
$(top_srcdir)/third_party/silabs/gecko_sdk_suite/v1.0/platform/radio/rail_lib/autogen/librail_release/librail_efr32xg12_gcc_release.a \
|
||||
$(NULL)
|
||||
|
||||
LDFLAGS_COMMON += \
|
||||
-T $(top_srcdir)/third_party/silabs/gecko_sdk_suite/v1.0/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/efr32mg12p.ld \
|
||||
$(NULL)
|
||||
endif # OPENTHREAD_EXAMPLES_EFR32
|
||||
```
|
||||
|
||||
Add the platform's linker script configuration to the
|
||||
[`/openthread/examples/platforms/Makefile.platform.am`](https://github.com/openthread/openthread/blob/main/examples/platforms/Makefile.platform.am)
|
||||
utility Makefile:
|
||||
|
||||
```
|
||||
if OPENTHREAD_EXAMPLES_EFR32
|
||||
include $(top_srcdir)/examples/platforms/efr32/Makefile.platform.am
|
||||
endif
|
||||
```
|
||||
|
||||
### Subdirectory configuration
|
||||
|
||||
Modify [`/openthread/examples/platforms/Makefile.am`](https://github.com/openthread/openthread/blob/main/examples/platforms/Makefile.platform.am)
|
||||
to configure the package subdirectories for the new platform example.
|
||||
|
||||
Add the platform subdirectory name in the list for `make dist`, in alphabetical
|
||||
order:
|
||||
|
||||
```
|
||||
# Always package (e.g. for 'make dist') these subdirectories.
|
||||
|
||||
DIST_SUBDIRS = \
|
||||
cc2538 \
|
||||
efr32 \
|
||||
nrf52840 \
|
||||
simulation \
|
||||
utils \
|
||||
$(NULL)
|
||||
```
|
||||
|
||||
Append platform subdirectory name to the `SUBDIRS` variable:
|
||||
|
||||
```
|
||||
# Always build (e.g. for 'make all') these subdirectories.
|
||||
|
||||
if OPENTHREAD_EXAMPLES_EFR32
|
||||
SUBDIRS += efr32
|
||||
endif
|
||||
```
|
||||
|
||||
### Toolchain startup code
|
||||
|
||||
Toolchain startup code is often provided along with the platform's BSP. This
|
||||
code typically:
|
||||
|
||||
1. Implements the entry function (`Reset_Handler`) of the executable program
|
||||
1. Defines the interrupt vector table
|
||||
1. Initializes the Heap and Stack
|
||||
1. Copies the `.data` section from non-volatile memory to RAM
|
||||
1. Jumps to the application main function to execute the application logic
|
||||
|
||||
The startup code (C or assembly source code) must be added to the
|
||||
platform-specific `Makefile.am`, otherwise some key variables used in the linker
|
||||
script cannot be quoted correctly:
|
||||
|
||||
- `/openthread/examples/platforms/{platform-name}/Makefile.am`
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
libopenthread_efr32_a_SOURCES = \
|
||||
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/hardware/kit/common/bsp/bsp_bcc.c \
|
||||
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/hardware/kit/common/bsp/bsp_stk.c \
|
||||
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/Device/SiliconLabs/EFR32MG12P/Source/system_efr32mg12p.c \
|
||||
@top_builddir@/third_party/silabs/gecko_sdk_suite/v1.0/platform/Device/SiliconLabs/EFR32MG12P/Source/GCC/startup_efr32mg12p.c \
|
||||
```
|
||||
|
||||
> Note: Any non-original derivative code (for example, linker script or
|
||||
toolchain startup code) must be contained in
|
||||
[`/openthread/third_party`](https://github.com/openthread/openthread/tree/main/third_party).
|
||||
@@ -1,214 +0,0 @@
|
||||
# Validate the Port
|
||||
|
||||
Basic validation is necessary to verify a successful port of OpenThread to a new
|
||||
hardware platform example.
|
||||
|
||||
## Step 1: Compile for the target platform
|
||||
|
||||
Demonstrate a successful build by compiling the example OpenThread application
|
||||
for the target platform.
|
||||
|
||||
```
|
||||
$ ./bootstrap
|
||||
$ make -f examples/Makefile-efr32 COMMISSIONER=1 JOINER=1
|
||||
```
|
||||
|
||||
## Step 2: Interact with the CLI
|
||||
|
||||
Demonstrate successful OpenThread execution and UART capability by interacting
|
||||
with the CLI.
|
||||
|
||||
Open a terminal to `/dev/ttyACM0` (serial port settings: 115200 8-N-1). Type
|
||||
`help` for a list of commands.
|
||||
|
||||
> Note: The set of CLI commands will vary based on the features enabled in a
|
||||
particular build. The majority of them have been elided in the example output
|
||||
below.
|
||||
|
||||
```
|
||||
> help
|
||||
help
|
||||
autostart
|
||||
bufferinfo
|
||||
...
|
||||
version
|
||||
whitelist
|
||||
```
|
||||
|
||||
## Step 3: Form a Thread network
|
||||
|
||||
Demonstrate successful protocol timers by forming a Thread network and verifying
|
||||
the node has transitioned to the Leader state.
|
||||
|
||||
```
|
||||
> dataset init new
|
||||
Done
|
||||
> dataset
|
||||
Active Timestamp: 1
|
||||
Channel: 13
|
||||
Channel Mask: 07fff800
|
||||
Ext PAN ID: d63e8e3e495ebbc3
|
||||
Mesh Local Prefix: fd3d:b50b:f96d:722d/64
|
||||
Master Key: dfd34f0f05cad978ec4e32b0413038ff
|
||||
Network Name: OpenThread-8f28
|
||||
PAN ID: 0x8f28
|
||||
PSKc: c23a76e98f1a6483639b1ac1271e2e27
|
||||
Security Policy: 0, onrcb
|
||||
Done
|
||||
> dataset commit active
|
||||
Done
|
||||
> ifconfig up
|
||||
Done
|
||||
> thread start
|
||||
Done
|
||||
```
|
||||
|
||||
Wait a couple of seconds...
|
||||
|
||||
```
|
||||
> state
|
||||
leader
|
||||
Done
|
||||
```
|
||||
|
||||
## Step 4: Attach a second node
|
||||
|
||||
Demonstrate successful radio communication by attaching a second node to the
|
||||
newly formed Thread network, using the same Thread Master Key and PAN ID from
|
||||
the first node:
|
||||
|
||||
```
|
||||
> dataset masterkey dfd34f0f05cad978ec4e32b0413038ff
|
||||
Done
|
||||
> dataset panid 0x8f28
|
||||
Done
|
||||
> dataset commit active
|
||||
Done
|
||||
> routerselectionjitter 1
|
||||
Done
|
||||
> ifconfig up
|
||||
Done
|
||||
> thread start
|
||||
Done
|
||||
```
|
||||
|
||||
Wait a couple of seconds...
|
||||
|
||||
```
|
||||
> state
|
||||
router
|
||||
Done
|
||||
```
|
||||
|
||||
## Step 5: Ping between devices
|
||||
|
||||
Demonstrate successful data path communication by sending/receiving ICMPv6 Echo
|
||||
request/response messages.
|
||||
|
||||
List all IPv6 addresses of Leader:
|
||||
|
||||
```
|
||||
> ipaddr
|
||||
fdde:ad00:beef:0:0:ff:fe00:fc00
|
||||
fdde:ad00:beef:0:0:ff:fe00:800
|
||||
fdde:ad00:beef:0:5b:3bcd:deff:7786
|
||||
fe80:0:0:0:6447:6e10:cf7:ee29
|
||||
Done
|
||||
```
|
||||
|
||||
Send an ICMPv6 ping from Router to Leader's Mesh-Local EID IPv6 address:
|
||||
|
||||
```
|
||||
> ping fdde:ad00:beef:0:5b:3bcd:deff:7786
|
||||
16 bytes from fdde:ad00:beef:0:5b:3bcd:deff:7786: icmp_seq=1 hlim=64 time=24ms
|
||||
```
|
||||
|
||||
## Step 6: Reset a device and validate reattachment
|
||||
|
||||
Demonstrate non-volatile functionality by resetting the device and validating
|
||||
its reattachment to the same network without user intervention.
|
||||
|
||||
Start a Thread network:
|
||||
|
||||
```
|
||||
> dataset init new
|
||||
Done
|
||||
> dataset
|
||||
Active Timestamp: 1
|
||||
Channel: 13
|
||||
Channel Mask: 07fff800
|
||||
Ext PAN ID: d63e8e3e495ebbc3
|
||||
Mesh Local Prefix: fd3d:b50b:f96d:722d/64
|
||||
Master Key: dfd34f0f05cad978ec4e32b0413038ff
|
||||
Network Name: OpenThread-8f28
|
||||
PAN ID: 0x8f28
|
||||
PSKc: c23a76e98f1a6483639b1ac1271e2e27
|
||||
Security Policy: 0, onrcb
|
||||
Done
|
||||
> dataset commit active
|
||||
Done
|
||||
> ifconfig up
|
||||
Done
|
||||
> thread start
|
||||
Done
|
||||
```
|
||||
|
||||
Wait a couple of seconds and verify that the active dataset has been stored in
|
||||
non-volatile storage:
|
||||
|
||||
```
|
||||
> dataset active
|
||||
Active Timestamp: 1
|
||||
Channel: 13
|
||||
Channel Mask: 07fff800
|
||||
Ext PAN ID: d63e8e3e495ebbc3
|
||||
Mesh Local Prefix: fd3d:b50b:f96d:722d/64
|
||||
Master Key: dfd34f0f05cad978ec4e32b0413038ff
|
||||
Network Name: OpenThread-8f28
|
||||
PAN ID: 0x8f28
|
||||
PSKc: c23a76e98f1a6483639b1ac1271e2e27
|
||||
Security Policy: 0, onrcb
|
||||
Done
|
||||
```
|
||||
|
||||
Reset the device:
|
||||
|
||||
```
|
||||
> reset
|
||||
> ifconfig up
|
||||
Done
|
||||
> thread start
|
||||
Done
|
||||
```
|
||||
|
||||
Wait a couple of seconds and verify that the device has successfully reattached
|
||||
to the network:
|
||||
|
||||
```
|
||||
> panid
|
||||
0x8f28
|
||||
Done
|
||||
> state
|
||||
router
|
||||
Done
|
||||
```
|
||||
|
||||
## Step 7: Verify random number generation
|
||||
|
||||
Demonstrate random number generation by executing the `factoryreset` command and
|
||||
verifying a new random extended address.
|
||||
|
||||
```
|
||||
> extaddr
|
||||
a660421703f3fdc3
|
||||
Done
|
||||
> factoryreset
|
||||
```
|
||||
|
||||
Wait a couple of seconds...
|
||||
|
||||
```
|
||||
> extaddr
|
||||
9a8ed90715a5f7b6
|
||||
Done
|
||||
```
|
||||
@@ -1,37 +0,0 @@
|
||||
# What is Thread?
|
||||
|
||||
<figure class="attempt-right">
|
||||
<img src="../images/ot-logo-thread.png" srcset="../images/ot-logo-thread.png 1x, ../images/ot-logo-thread_2x.png 2x" border="0" alt="Thread" />
|
||||
</figure>
|
||||
|
||||
<a href="http://threadgroup.org/">Thread<sup>®</sup></a> is an IPv6-based
|
||||
networking protocol designed for low-power Internet of Things devices in an IEEE
|
||||
802.15.4-2006 wireless mesh network, commonly called a Wireless Personal Area
|
||||
Network (WPAN). Thread is independent of other 802.15 mesh networking
|
||||
protocols, such a ZigBee, Z-Wave, and Bluetooth LE.
|
||||
|
||||
Thread's primary features include:
|
||||
|
||||
* Simplicity — Simple installation, start up, and operation
|
||||
* Security — All devices in a Thread network are authenticated and all
|
||||
communications are encrypted
|
||||
* Reliability — Self-healing mesh networking, with no single point of failure,
|
||||
and spread-spectrum techniques to provide immunity to interference
|
||||
* Efficiency — Low-power Thread devices can sleep and operate on battery power
|
||||
for years
|
||||
* Scalability — Thread networks can scale up to hundreds of devices
|
||||
|
||||
If you're new to Thread, understanding the basics are critical to using
|
||||
OpenThread in your own applications. The goal of this primer is to explain the
|
||||
concepts behind Thread and how it works, and provide a springboard to OpenThread
|
||||
development.
|
||||
|
||||
It is assumed you have good working knowledge of the following:
|
||||
|
||||
* IEEE 802.15.4
|
||||
* Networking and routing concepts
|
||||
* IPv6
|
||||
|
||||
This primer is based on version 1.1.1 of the Thread Specification. It does not
|
||||
cover the full specification, which is available at
|
||||
[threadgroup.org](http://threadgroup.org/ThreadSpec).
|
||||
@@ -1,276 +0,0 @@
|
||||
# IPv6 Addressing
|
||||
|
||||
Let's take a look at how Thread identifies each device in the network, and what
|
||||
types of addresses they use to communicate with each other.
|
||||
|
||||
Key Term: In this primer, the term "interface" is used to identify an endpoint
|
||||
of a Thread device within a network. Typically, a single Thread device has
|
||||
a single Thread interface.
|
||||
|
||||
## Scopes
|
||||
|
||||
<figure class="attempt-right">
|
||||
<a href="../images/ot-primer-scopes_2x.png"><img src="../images/ot-primer-scopes.png" srcset="../images/ot-primer-scopes.png 1x, ../images/ot-primer-scopes_2x.png 2x" border="0" alt="OT Scopes" /></a>
|
||||
</figure>
|
||||
|
||||
There are three scopes in a Thread network for unicast addressing:
|
||||
|
||||
* Link-Local — all interfaces reachable by a single radio transmission
|
||||
* Mesh-Local — all interfaces reachable within the same Thread network
|
||||
* Global — all interfaces reachable from outside a Thread network
|
||||
|
||||
The first two scopes correspond to prefixes designated by a Thread network.
|
||||
Link-Local have prefixes of `fe80::/16`, while Mesh-Local have prefixes of
|
||||
`fd00::/8`.
|
||||
|
||||
<h2 style="clear:right">Unicast</h2>
|
||||
|
||||
There are multiple IPv6 unicast addresses that identify a single Thread device.
|
||||
Each has a different function based on the scope and use case.
|
||||
|
||||
Before we detail each type, let's learn more about a common one, called the
|
||||
Routing Locator (RLOC). The RLOC identifies a Thread interface, based on its
|
||||
location in the network topology.
|
||||
|
||||
### How a Routing Locator is generated
|
||||
|
||||
All devices are assigned a Router ID and a Child ID. Each Router maintains a
|
||||
table of all their Children, the combination of which uniquely identifies a
|
||||
device within the topology. For example, consider the highlighted nodes in the
|
||||
following topology, where the number in a Router (pentagon) is the Router ID,
|
||||
and the number in an End Device (circle) is the Child ID:
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-rloc-topology_2x.png"><img src="../images/ot-primer-rloc-topology.png" srcset="../images/ot-primer-rloc-topology.png 1x, ../images/ot-primer-rloc-topology_2x.png 2x" border="0" width="600" alt="OT RLOC Topology" /></a>
|
||||
</figure>
|
||||
|
||||
Each Child's Router ID corresponds to their Parent (Router). Because a Router is
|
||||
not a Child, the Child ID for a Router is always 0. Together, these values are
|
||||
unique for each device in the Thread network, and are used to create the RLOC16,
|
||||
which represents the last 16 bits of the RLOC.
|
||||
|
||||
For example, here's how the RLOC16 is calculated for the upper-left node (Router
|
||||
ID = 1 and Child ID = 1):
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-rloc16_2x.png"><img src="../images/ot-primer-rloc16.png" srcset="../images/ot-primer-rloc16.png 1x, ../images/ot-primer-rloc16_2x.png 2x" border="0" width="400" alt="OT RLOC16" /></a>
|
||||
</figure>
|
||||
|
||||
The RLOC16 is part of the Interface Identifier (IID), which corresponds to the
|
||||
last 64 bits of the IPv6 address. Some IIDs can be used to identify some types
|
||||
of Thread interfaces. For example, the IID for RLOCs is always of the form
|
||||
<code>0000:00ff:fe00:<var>RLOC16</var></code>.
|
||||
|
||||
The IID, combined with a Mesh-Local Prefix, results in the RLOC. For example,
|
||||
using a Mesh-Local Prefix of `fde5:8dba:82e1:1::/64`, the RLOC for a node where
|
||||
RLOC16 = `0x401` is:
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-rloc_2x.png"><img src="../images/ot-primer-rloc.png" srcset="../images/ot-primer-rloc.png 1x, ../images/ot-primer-rloc_2x.png 2x" border="0" width="600" alt="OT RLOC" /></a>
|
||||
</figure>
|
||||
|
||||
This same logic can be used to determine the RLOC for all highlighted nodes in the sample topology above:
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-rloc-topology-address_2x.png"><img src="../images/ot-primer-rloc-topology-address.png" srcset="../images/ot-primer-rloc-topology-address.png 1x, ../images/ot-primer-rloc-topology-address_2x.png 2x" border="0" width="600" alt="OT Topology w/ Address" /></a>
|
||||
</figure>
|
||||
|
||||
However, because the RLOC is based on the location of the node in the topology,
|
||||
the RLOC of a node can change as the topology changes.
|
||||
|
||||
For example, perhaps node `0x400` is removed from the Thread network. Nodes
|
||||
`0x401` and `0x402` establish new links to different Routers, and as a result
|
||||
they are each assigned a new RLOC16 and RLOC:
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-rloc-topology-change_2x.png"><img src="../images/ot-primer-rloc-topology-change.png" srcset="../images/ot-primer-rloc-topology-change.png 1x, ../images/ot-primer-rloc-topology-change_2x.png 2x" border="0" width="600" alt="OT Topology after Change" /></a>
|
||||
</figure>
|
||||
|
||||
## Unicast address types
|
||||
The RLOC is just one of many IPv6 unicast addresses a Thread device can have.
|
||||
Another category of addresses are called Endpoint Identifiers (EIDs), which
|
||||
identify a unique Thread interface within a Thread network partition. EIDs are
|
||||
independent of Thread network topology.
|
||||
|
||||
Common unicast types are detailed below.
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2><h3>Link-Local Address (LLA)</h3></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan=2 style="background-color:rgb(238, 241, 242)">An EID that identifies a Thread interface reachable by a single radio transmission.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Example</b></td><td><code>fe80::54db:881c:3845:57f4</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td>Based on 802.15.4 Extended Address</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Scope</b></td><td>Link-Local</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Details</b></td><td><ul><li>Used to discover neighbors, configure links, and exchange routing information</li><li>Not a routable address</li><li>Always has a prefix of <code>fe80::/16</code></li></ul></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2><h3>Mesh-Local EID (ML-EID)</h3></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan=2 style="background-color:rgb(238, 241, 242)">An EID that identifies a Thread interface, independent of network topology. Used to reach a Thread interface within the same Thread partition. Also called a Unique Local Address (ULA).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Example</b></td><td><code>fde5:8dba:82e1:1:416:993c:8399:35ab</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td>Random, chosen after commissioning is complete</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Scope</b></td><td>Mesh-Local</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Details</b></td><td><ul><li>Does not change as the topology changes</li><li>Should be used by applications</li><li>Always has a prefix <code>fd00::/8</code></li></ul></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2><h3>Routing Locator (RLOC)</h3></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan=2 style="background-color:rgb(238, 241, 242)">Identifies a Thread interface, based on its location in the network topology.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Example</b></td><td><code>fde5:8dba:82e1:1::ff:fe00:1001</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td><code>0000:00ff:fe00:<var>RLOC16</var></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Scope</b></td><td>Mesh-Local</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Details</b></td><td><ul><li>Generated once a device attaches to a network</li><li>For delivering IPv6 datagrams within a Thread network</li><li>Changes as the topology changes</li><li>Generally not used by applications</li></ul></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2><h3>Anycast Locator (ALOC)</h3></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan=2 style="background-color:rgb(238, 241, 242)">Identifies a Thread interface via RLOC lookup, when the RLOC of a destination is not known.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Example</b></td><td><code>fde5:8dba:82e1:1::ff:fe00:fc01</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td><code>0000:00ff:fe00:fc<var>XX</var></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Scope</b></td><td>Mesh-Local</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Details</b></td><td><ul><li><code>fc<var>XX</var></code> = <a href="#anycast">ALOC destination</a>, which looks up the appropriate RLOC</li><li>Generally not used by applications</li></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2><h3>Global Unicast Address (GUA)</h3></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan=2 style="background-color:rgb(238, 241, 242)">An EID that identifies a Thread interface on a global scope, beyond a Thread network.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Example</b></td><td><code>2000::54db:881c:3845:57f4</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td><ul><li>SLAAC — Randomly assigned by the device itself</li><li>DHCP — Assigned by a DHCPv6 server</li><li>Manual — Assigned by the application layer</li></ul></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Scope</b></td><td>Global</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Details</b></td><td><ul><li>A public IPv6 address</li><li>Always has a prefix of <code>2000::/3</code></li></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Multicast
|
||||
|
||||
Multicast is used to communicate information to multiple devices at once. In a
|
||||
Thread network, specific addresses are reserved for multicast use with different
|
||||
groups of devices, depending on the scope.
|
||||
|
||||
| IPv6 Address | Scope | Delivered to |
|
||||
| ------------ | ---------- | ----------------- |
|
||||
| `ff02::1` | Link-Local | All FTDs and MEDs |
|
||||
| `ff02::2` | Link-Local | All FTDs |
|
||||
| `ff03::1` | Mesh-Local | All FTDs and MEDs |
|
||||
| `ff03::2` | Mesh-Local | All FTDs |
|
||||
|
||||
Key Point: A major difference between FTDs and MTDs are that FTDs subscribe to
|
||||
the `ff03::2` multicast address. MTDs do not.
|
||||
|
||||
You might notice that Sleepy End Devices (SEDs) are not included as a
|
||||
recipient in the multicast table above. Instead, Thread defines
|
||||
link-local and realm-local scope unicast prefix-based IPv6 multicast
|
||||
address used for All Thread Nodes, including SEDs. These multicast
|
||||
addresses vary by Thread network, because it is built on the unicast
|
||||
Mesh-Local prefix (see [RFC 3306](https://tools.ietf.org/html/rfc3306)
|
||||
for more details on unicast-prefix-based IPv6 multicast addresses).
|
||||
|
||||
Arbitrary scopes beyond those already listed are also supported for Thread
|
||||
devices.
|
||||
|
||||
|
||||
## Anycast
|
||||
|
||||
Anycast is used to route traffic to a Thread interface when the RLOC of a
|
||||
destination is not known. An Anycast Locator (ALOC) identifies the location of
|
||||
multiple interfaces within a Thread partition. The last 16 bits of an ALOC,
|
||||
called the ALOC16, is in the format of <code>0xfc<var>XX</var></code>, which
|
||||
represents the type of ALOC.
|
||||
|
||||
For example, an ALOC16 between `0xfc01` and `0xfc0f` is reserved for DHCPv6
|
||||
Agents. If the specific DHCPv6 Agent RLOC is unknown (perhaps because the
|
||||
network topology has changed), a message can be sent to a DHCPv6 Agent ALOC to
|
||||
obtain the RLOC.
|
||||
|
||||
Thread defines the following ALOC16 values:
|
||||
|
||||
| ALOC16 | Type |
|
||||
| ------------------------------------------ | ------------------------ |
|
||||
| `0xfc00` | Leader |
|
||||
| `0xfc01` – `0xfc0f` | DHCPv6 Agent |
|
||||
| `0xfc10` – `0xfc2f` | Service |
|
||||
| `0xfc30` – `0xfc37` | Commissioner |
|
||||
| `0xfc40` – `0xfc4e` | Neighbor Discovery Agent |
|
||||
| `0xfc38` – `0xfc3f`<br>`0xfc4f` – `0xfcff` | Reserved |
|
||||
|
||||
## Recap
|
||||
|
||||
What you've learned:
|
||||
|
||||
* A Thread network consists of three scopes: Link-Local, Mesh-Local, and Global
|
||||
* A Thread device has multiple unicast IPv6 addresses
|
||||
* An RLOC represents a device's location in the Thread network
|
||||
* An ML-EID is unique to a Thread device within a partition and should be used by applications
|
||||
* Thread uses multicast to forward data to groups of nodes and routers
|
||||
* Thread uses anycast when the RLOC of a destination is unknown
|
||||
|
||||
To learn more about Thread's IPv6 addressing, see sections 5.2 and 5.3 of the
|
||||
[Thread Specification](http://threadgroup.org/ThreadSpec).
|
||||
@@ -1,292 +0,0 @@
|
||||
# Network Discovery and Formation
|
||||
|
||||
## Thread networks
|
||||
|
||||
Thread networks are identified by three unique identifiers:
|
||||
|
||||
* 2-byte Personal Area Network ID (PAN ID)
|
||||
* 8-byte Extended Personal Area Network ID (XPAN ID)
|
||||
* A human-readable Network Name
|
||||
|
||||
For example, a Thread network may have the following identifiers:
|
||||
|
||||
Identifier | Value
|
||||
---- | ----
|
||||
PAN ID | `0xBEEF`
|
||||
XPAN ID | `0xBEEF1111CAFE2222`
|
||||
Network Name | `yourThreadCafe`
|
||||
|
||||
<figure class="attempt-right">
|
||||
<a href="../images/ot-primer-network-active-scan_2x.png"><img src="../images/ot-primer-network-active-scan.png" srcset="../images/ot-primer-network-active-scan.png 1x, ../images/ot-primer-network-active-scan_2x.png 2x" border="0" alt="OT Active Scan" /></a>
|
||||
</figure>
|
||||
|
||||
When creating a new Thread network, or searching for an existing one to join, a
|
||||
Thread device performs an active scan for 802.15.4 networks within radio range:
|
||||
|
||||
1. The device broadcasts an 802.15.4 Beacon Request on a specific Channel.
|
||||
1. In return, any Routers or Router Eligible End Devices (REEDs) in range
|
||||
broadcast a Beacon that contains their Thread network PAN ID, XPAN ID, and
|
||||
Network Name.
|
||||
1. The device repeats the previous two steps for each Channel.
|
||||
|
||||
Once a Thread device has discovered all networks in range, it can either attach
|
||||
to an existing network, or create a new one if no networks are discovered.
|
||||
|
||||
<h2 style="clear:right">Mesh Link Establishment</h2>
|
||||
|
||||
Thread uses the Mesh Link Establishment (MLE) protocol to configure links and
|
||||
disseminate information about the network to Thread devices.
|
||||
|
||||
In link configuration, MLE is used to:
|
||||
|
||||
* Discover links to neighboring devices
|
||||
* Determine the quality of links to neighboring devices
|
||||
* Establish links to neighboring devices
|
||||
* Negotiate link parameters (device type, frame counters, timeout) with peers
|
||||
|
||||
MLE disseminates the following types of information to devices wishing to
|
||||
establish links:
|
||||
|
||||
* Leader data (Leader RLOC, Partition ID, Partition weight)
|
||||
* Network data (on-mesh prefixes, address autoconfiguration, more-specific
|
||||
routes)
|
||||
* Route propagation
|
||||
|
||||
Route propagation in Thread works similar to the Routing Information Protocol
|
||||
(RIP), a distance-vector routing protocol.
|
||||
|
||||
Note: MLE only proceeds once a Thread device has obtained Thread network
|
||||
credentials through Thread Commissioning. Commissioning and Security will be
|
||||
covered in depth later in this Primer. For now, this page assumes that the
|
||||
device has already been commissioned.
|
||||
|
||||
## Create a new network
|
||||
|
||||
If the device elects to create a new network, it selects the least busy Channel
|
||||
and a PAN ID not in use by other networks, then becomes a Router and elects
|
||||
itself the Leader. This device sends MLE Advertisement messages to other
|
||||
802.15.4 devices to inform them of its link state, and responds to Beacon
|
||||
Requests by other Thread devices performing an active scan.
|
||||
|
||||
## Join an existing network
|
||||
|
||||
If the device elects to join an existing network, it configures its Channel, PAN
|
||||
ID, XPAN ID, and Network Name to match that of the target network via Thread
|
||||
Commissioning, then goes through the MLE Attach process to attach as a Child
|
||||
(End Device). This process is used for Child-Parent links.
|
||||
|
||||
Key Point: Every device, router-capable or not, initially attaches to a Thread
|
||||
network as a Child (End Device).
|
||||
|
||||
1. The Child sends a multicast [Parent Request](#1_parent_request) to all
|
||||
neighboring Routers and REEDs in the target network.
|
||||
1. All neighboring Routers and REEDs (if the Parent Request Scan Mask includes
|
||||
REEDs) send [Parent Responses](#2_parent_response) with information about
|
||||
themselves.
|
||||
1. The Child chooses a Parent device and sends a [Child ID
|
||||
Request](#3_child_id_request) to it.
|
||||
1. The Parent sends a [Child ID Response](#4_child_id_response) to confirm link
|
||||
establishment.
|
||||
|
||||
### 1. Parent Request
|
||||
|
||||
A Parent Request is a multicast request from the attaching device that is used
|
||||
to discover neighboring Routers and Router Eligible End Devices (REEDs) in the
|
||||
target network.
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-network-mle-attach-01_2x.png"><img src="../images/ot-primer-network-mle-attach-01.png" srcset="../images/ot-primer-network-mle-attach-01.png 1x, ../images/ot-primer-network-mle-attach-01_2x.png 2x" width="350" border="0" alt="OT MLE Attach Parent Request" /></a>
|
||||
</figure>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2>Parent Request Message Contents</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Mode</b></td>
|
||||
<td>Describes the attaching device</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Challenge</b></td>
|
||||
<td>Tests the timeliness of the Parent Response to prevent replay
|
||||
attacks</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Scan Mask</b></td>
|
||||
<td>Limits the request to only Routers or to both Routers and REEDs</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### 2. Parent Response
|
||||
|
||||
A Parent Response is a unicast response to a Parent Request that provides
|
||||
information about a Router or REED to the attaching device.
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-network-mle-attach-02_2x.png"><img src="../images/ot-primer-network-mle-attach-02.png" srcset="../images/ot-primer-network-mle-attach-02.png 1x, ../images/ot-primer-network-mle-attach-02_2x.png 2x" width="350" border="0" alt="OT MLE Attach Parent Response" /></a>
|
||||
</figure>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2>Parent Response Message Contents</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Version</b></td>
|
||||
<td>Thread protocol version</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Response</b></td>
|
||||
<td>Copy of the Parent Request Challenge</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Link Frame
|
||||
Counter</b></td>
|
||||
<td>802.15.4 Frame Counter on the Router/REED</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>MLE Frame
|
||||
Counter</b></td>
|
||||
<td>MLE Frame Counter on the Router/REED</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Source
|
||||
Address</b></td>
|
||||
<td>RLOC16 of the Router/REED</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Link
|
||||
Margin</b></td>
|
||||
<td>Receive signal quality of the Router/REED</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Connectivity</b></td>
|
||||
<td>Describes the Router/REED’s level of connectivity</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Leader
|
||||
Data</b></td>
|
||||
<td>Information about the Router/REED’s Leader</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Challenge</b></td>
|
||||
<td>Tests the timeliness of the Child ID Request to prevent replay
|
||||
attacks</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### 3. Child ID Request
|
||||
|
||||
A Child ID Request is a unicast request from the attaching device (Child) that
|
||||
is sent to the Router or REED (Parent) for the purpose of establishing a
|
||||
Child-Parent link. If the request is sent to a REED, it [upgrades itself to a
|
||||
Router](/guides/thread-primer/router-selection#upgrade_to_a_router) before
|
||||
accepting the request.
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-network-mle-attach-03_2x.png"><img src="../images/ot-primer-network-mle-attach-03.png" srcset="../images/ot-primer-network-mle-attach-03.png 1x, ../images/ot-primer-network-mle-attach-03_2x.png 2x" width="350" border="0" alt="OT MLE Attach Child ID Request" /></a>
|
||||
</figure>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2>Child ID Request Message Contents</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Version</b></td>
|
||||
<td>Thread protocol version</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Response</b></td>
|
||||
<td>Copy of the Parent Response Challenge</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Link Frame
|
||||
Counter</b></td>
|
||||
<td>802.15.4 Frame Counter on the Child</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>MLE Frame
|
||||
Counter</b></td><td>MLE Frame Counter on the Child</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Mode</b></td>
|
||||
<td>Describes the Child</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Timeout</b></td>
|
||||
<td>Inactivity duration before the Parent removes the Child</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Address
|
||||
Registration (MEDs and SEDs only)</b></td>
|
||||
<td>Register IPv6 addresses</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### 4. Child ID Response
|
||||
|
||||
A Child ID Response is a unicast response from the Parent that is sent to the
|
||||
Child to confirm that a Child-Parent link has been established.
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-network-mle-attach-04_2x.png"><img src="../images/ot-primer-network-mle-attach-04.png" srcset="../images/ot-primer-network-mle-attach-04.png 1x, ../images/ot-primer-network-mle-attach-04_2x.png 2x" width="350" border="0" alt="OT MLE Attach Child ID Response" /></a>
|
||||
</figure>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2>Child ID Response Message Contents</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Source
|
||||
Address</b></td>
|
||||
<td>Parent's RLOC16</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Address16</b></td>
|
||||
<td>Child's RLOC16</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Leader
|
||||
Data</b></td>
|
||||
<td>Information about the Parent’s Leader (RLOC, Partition ID, Partition
|
||||
weight)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Network
|
||||
Data</b></td>
|
||||
<td>Information about the Thread network (on-mesh prefixes, address
|
||||
autoconfiguration, more-specific routes)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Route
|
||||
(REED only)</b></td>
|
||||
<td>Route propagation</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Timeout</b></td>
|
||||
<td>Inactivity duration before the Parent removes the Child</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Address
|
||||
Registration (MEDs and SEDs only)</b></td>
|
||||
<td>Confirm registered addresses</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Recap
|
||||
|
||||
What you've learned:
|
||||
|
||||
* A Thread device performs an active scan for existing networks
|
||||
* Thread uses Mesh Link Establishment to configure links and disseminate
|
||||
information about network devices
|
||||
* MLE Advertisement messages inform other Thread devices about a device's
|
||||
network and link state
|
||||
* The MLE Attach process establishes Child-Parent links
|
||||
@@ -1,152 +0,0 @@
|
||||
# Node Roles and Types
|
||||
|
||||
## Forwarding roles
|
||||
|
||||
<figure class="attempt-right">
|
||||
<a href="../images/ot-primer-roles_2x.png"><img src="../images/ot-primer-roles.png" srcset="../images/ot-primer-roles.png 1x, ../images/ot-primer-roles_2x.png 2x" border="0" alt="OT Node Roles" /></a>
|
||||
</figure>
|
||||
|
||||
In a Thread network, nodes are split into two forwarding roles:
|
||||
|
||||
### Router
|
||||
|
||||
A Router is a node that:
|
||||
|
||||
* forwards packets for network devices
|
||||
* provides secure commissioning services for devices trying to join the network
|
||||
* keeps its transceiver enabled at all times
|
||||
|
||||
### End Device
|
||||
|
||||
An End Device (ED) is a node that:
|
||||
|
||||
* communicates primarily with a single Router
|
||||
* does not forward packets for other network devices
|
||||
* can disable its transceiver to reduce power
|
||||
|
||||
Key Point: The relationship between Router and End Device is a Parent-Child
|
||||
relationship. An End Device attaches to exactly one Router. The Router is always
|
||||
the Parent, the End Device the Child.
|
||||
|
||||
## Device types
|
||||
|
||||
Furthermore, nodes comprise a number of types.
|
||||
|
||||
<figure class="attempt-right">
|
||||
<a href="../images/ot-primer-taxonomy_2x.png"><img src="../images/ot-primer-taxonomy.png" srcset="../images/ot-primer-taxonomy.png 1x, ../images/ot-primer-taxonomy.png 2x" border="0" alt="OT Device Taxonomy" /></a>
|
||||
</figure>
|
||||
|
||||
### Full Thread Device
|
||||
|
||||
A Full Thread Device (FTD) always has its radio on, subscribes to the
|
||||
all-routers multicast address, and maintains IPv6 address mappings. There are
|
||||
three types of FTDs:
|
||||
|
||||
* Router
|
||||
* Router Eligible End Device (REED) — can be promoted to a Router
|
||||
* Full End Device (FED) — cannot be promoted to a Router
|
||||
|
||||
An FTD can operate as a Router (Parent) or an End Device (Child).
|
||||
|
||||
### Minimal Thread Device
|
||||
|
||||
A Minimal Thread Device does not subscribe to the all-routers
|
||||
multicast address and forwards all messages to its Parent. There are
|
||||
two types of MTDs:
|
||||
|
||||
* Minimal End Device (MED) — transceiver always on, does not need to poll for
|
||||
messages from its parent
|
||||
* Sleepy End Device (SED) — normally disabled, wakes on occasion to poll for
|
||||
messages from its parent
|
||||
|
||||
An MTD can only operate as an End Device (Child).
|
||||
|
||||
### Upgrading and downgrading
|
||||
|
||||
When a REED is the only node in reach of a new End Device wishing to join the
|
||||
Thread network, it can upgrade itself and operate as a Router:
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-router-upgrade_2x.png"><img src="../images/ot-primer-router-upgrade.png" srcset="../images/ot-primer-router-upgrade.png 1x, ../images/ot-primer-router-upgrade_2x.png 2x" border="0" width="400" alt="OT End Device to Router" /></a>
|
||||
</figure>
|
||||
|
||||
Conversely, when a Router has no children, it can downgrade itself and operate
|
||||
as an End Device:
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-router-downgrade_2x.png"><img src="../images/ot-primer-router-downgrade.png" srcset="../images/ot-primer-router-downgrade.png 1x, ../images/ot-primer-router-downgrade_2x.png 2x" border="0" width="400" alt="OT Router to End Device" /></a>
|
||||
</figure>
|
||||
|
||||
## Other roles and types
|
||||
|
||||
### Thread Leader
|
||||
|
||||
<figure class="attempt-right">
|
||||
<a href="../images/ot-primer-leader_2x.png"><img src="../images/ot-primer-leader.png" srcset="../images/ot-primer-leader.png 1x, ../images/ot-primer-leader_2x.png 2x" border="0" alt="OT Leader and Border Router" /></a>
|
||||
</figure>
|
||||
|
||||
The Thread Leader is a Router that is responsible for managing the set of
|
||||
Routers in a Thread network. It is dynamically self-elected for fault tolerance,
|
||||
and aggregates and distributes network-wide configuration information.
|
||||
|
||||
Note: There is always a single Leader in each Thread network
|
||||
[partition](#partitions).
|
||||
|
||||
### Border Router
|
||||
|
||||
A Border Router is a device that can forward information between a Thread
|
||||
network and a non-Thread network (for example, Wi-Fi). It also configures a
|
||||
Thread network for external connectivity.
|
||||
|
||||
Any device may serve as a Border Router.
|
||||
|
||||
Note: There can be multiple Border Routers in a Thread network.
|
||||
|
||||
## Partitions
|
||||
|
||||
<figure class="attempt-right">
|
||||
<a href="../images/ot-primer-partitions_2x.png"><img src="../images/ot-primer-partitions.png" srcset="../images/ot-primer-partitions.png 1x, ../images/ot-primer-partitions_2x.png 2x" border="0" alt="OT Partitions" /></a>
|
||||
</figure>
|
||||
|
||||
A Thread network might be composed of partitions. This occurs when a group of
|
||||
Thread devices can no longer communicate with another group of Thread devices.
|
||||
Each partition logically operates as a distinct Thread network with its own
|
||||
Leader, Router ID assignments, and network data, while retaining the same
|
||||
security credentials for all devices across all partitions.
|
||||
|
||||
Partitions in a Thread network do not have wireless connectivity between each
|
||||
other, and if partitions regain connectivity, they automatically merge into a
|
||||
single partition.
|
||||
|
||||
Key Point: Security credentials define the Thread network. Physical radio
|
||||
connectivity defines partitions within that Thread network.
|
||||
|
||||
Note that the use of "Thread network" in this primer assumes a single partition.
|
||||
Where necessary, key concepts and examples are clarified with the term "partition."
|
||||
Partitions are covered in-depth later in this primer.
|
||||
|
||||
## Device limits
|
||||
|
||||
There are limits to the number of device types a single Thread network supports.
|
||||
|
||||
Role | Limit
|
||||
----|----
|
||||
Leader | 1
|
||||
Router | 32
|
||||
End Device | 511 per Router
|
||||
|
||||
Thread tries to keep the number of Routers between 16 and 23. If a REED attaches
|
||||
as an End Device and the number of Routers in the network is below 16, it
|
||||
automatically promotes itself to a Router.
|
||||
|
||||
## Recap
|
||||
|
||||
What you learned:
|
||||
|
||||
* A Thread device is either a Router (Parent) or an End Device (Child)
|
||||
* A Thread device is either a Full Thread Device (maintains IPv6 address
|
||||
mappings) or a Minimal Thread Device (forwards all messages to its Parent)
|
||||
* A Router Eligible End Device can promote itself to a Router, and vice versa
|
||||
* Every Thread network partition has a Leader to manage Routers
|
||||
* A Border Router is used to connect Thread and non-Thread networks
|
||||
* A Thread network might be composed of multiple partitions
|
||||
@@ -1,176 +0,0 @@
|
||||
# Router Selection
|
||||
|
||||
## Connected Dominating Set
|
||||
|
||||
<figure class="attempt-right">
|
||||
<a href="../images/ot-primer-cds_2x.png"><img src="../images/ot-primer-cds.png" srcset="../images/ot-primer-cds.png 1x, ../images/ot-primer-cds_2x.png 2x" width="350" border="0" alt="OT Connected Dominating Set" /></a><figcaption style="text-align: center"><i>Example of a Connected Dominating Set</i></figcaption>
|
||||
</figure>
|
||||
|
||||
Routers must form a Connected Dominating Set (CDS), which means:
|
||||
|
||||
1. There is a Router-only path between any two Routers.
|
||||
1. Any one Router in a Thread network can reach any other Router by staying
|
||||
entirely within the set of Routers.
|
||||
1. Every End Device in a Thread network is directly connected to a Router.
|
||||
|
||||
A distributed algorithm maintains the CDS, which ensures a minimum level of
|
||||
redundancy. Every device initially attaches to the network as an End Device
|
||||
(Child). As the state of the Thread network changes, the algorithm adds or
|
||||
removes Routers to maintain the CDS.
|
||||
|
||||
Thread adds Routers to:
|
||||
|
||||
* Increase coverage if the network is below the Router threshold of 16
|
||||
* Increase path diversity
|
||||
* Maintain a minimum level of redundancy
|
||||
* Extend connectivity and support more Children
|
||||
|
||||
Thread removes Routers to:
|
||||
|
||||
* Reduce the Routing state below the maximum of 32 Routers
|
||||
* Allow new Routers in other parts of the network when needed
|
||||
|
||||
## Upgrade to a Router
|
||||
|
||||
After attaching to a Thread network, the Child device may elect to become a
|
||||
Router. Before initiating the MLE Link Request process, the Child sends an
|
||||
Address Solicit message to the Leader, asking for a Router ID. If the Leader
|
||||
accepts, it responds with a Router ID and the Child upgrades itself to a Router.
|
||||
|
||||
The MLE Link Request process is then used to establish bi-directional
|
||||
Router-Router links with neighboring Routers.
|
||||
|
||||
1. The new Router sends a multicast [Link Request](#1_link_request) to
|
||||
neighboring Routers.
|
||||
1. Routers respond with [Link Accept and Request](#2_link_accept_and_request)
|
||||
messages.
|
||||
1. The new Router responds to each Router with a unicast [Link
|
||||
Accept](#3_link_accept) to establish the Router-Router link.
|
||||
|
||||
### 1. Link Request
|
||||
|
||||
A Link Request is a request from the Router to all other Routers in the Thread
|
||||
network. When first becoming a Router, the device sends a multicast Link Request
|
||||
to `ff02::2`. Later, after discovering the other Routers via MLE Advertisements,
|
||||
the devices send unicast Link Requests.
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-network-mle-link-request-01_2x.png"><img src="../images/ot-primer-network-mle-link-request-01.png" srcset="../images/ot-primer-network-mle-link-request-01.png 1x, ../images/ot-primer-network-mle-link-request-01_2x.png 2x" width="350" border="0" alt="OT MLE Link Request" /></a>
|
||||
</figure>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2>Link Request Message Contents</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Version</b></td>
|
||||
<td>Thread protocol version</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Challenge</b></td>
|
||||
<td>Tests the timeliness of the Link Response to prevent replay
|
||||
attacks</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Source
|
||||
Address</b></td>
|
||||
<td>RLOC16 of the sender</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Leader
|
||||
Data</b></td>
|
||||
<td>Information about the Router's Leader, as stored on the sender (RLOC,
|
||||
Partition ID, Partition weight)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### 2. Link Accept and Request
|
||||
|
||||
A Link Accept and Request is a combination of the Link Accept and Link Request
|
||||
messages. Thread uses this optimization in the MLE Link Request process to
|
||||
reduce the number of messages from four to three.
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-network-mle-link-request-02_2x.png"><img src="../images/ot-primer-network-mle-link-request-02.png" srcset="../images/ot-primer-network-mle-link-request-02.png 1x, ../images/ot-primer-network-mle-link-request-02_2x.png 2x" width="350" border="0" alt="OT MLE Link Accept and Request" /></a>
|
||||
</figure>
|
||||
|
||||
### 3. Link Accept
|
||||
|
||||
A Link Accept is a unicast response to a Link Request from a neighboring Router
|
||||
that provides information about itself and accepts the link to the neighboring
|
||||
Router.
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-network-mle-link-request-03_2x.png"><img src="../images/ot-primer-network-mle-link-request-03.png" srcset="../images/ot-primer-network-mle-link-request-03.png 1x, ../images/ot-primer-network-mle-link-request-03_2x.png 2x" width="350" border="0" alt="OT MLE Link Accept" /></a>
|
||||
</figure>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2>Link Accept Message Contents</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Version</b></td>
|
||||
<td>Thread protocol version</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Response</b></td>
|
||||
<td>Tests the timeliness of the Link Response to prevent replay
|
||||
attacks</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Link Frame
|
||||
Counter</b></td>
|
||||
<td>802.15.4 Frame Counter on the sender</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>MLE Frame
|
||||
Counter</b></td>
|
||||
<td>MLE Frame Counter on the sender</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Source
|
||||
Address</b></td>
|
||||
<td>RLOC16 of the sender</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Leader
|
||||
Data</b></td>
|
||||
<td>Information about the Router's Leader, as stored on the sender (RLOC,
|
||||
Partition ID, Partition weight)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Downgrade to a REED
|
||||
|
||||
When a Router downgrades to a REED, its Router-Router links are disconnected,
|
||||
and the device initiates the MLE Attach process to establish a Child-Parent
|
||||
link.
|
||||
|
||||
See [Join an existing
|
||||
network](/guides/thread-primer/network-discovery#join_an_existing_network)
|
||||
for more information on the MLE Attach process.
|
||||
|
||||
## One-way receive links
|
||||
|
||||
In some scenarios, it may be necessary to establish a one-way receive link.
|
||||
|
||||
After a Router reset, neighboring Routers may still have a valid receive link
|
||||
with the reset Router. In this case, the reset Router sends a Link Request
|
||||
message to re-establish the Router-Router link.
|
||||
|
||||
An End Device may also wish to establish a receive link with neighboring
|
||||
non-Parent Routers to improve multicast reliability. We'll learn more about this
|
||||
when we get to Multicast Routing.
|
||||
|
||||
## Recap
|
||||
|
||||
What you've learned:
|
||||
|
||||
* Routers in a Thread network must form a Connected Dominating Set (CDS)
|
||||
* Thread devices are upgraded to Routers or downgraded to End Devices to
|
||||
maintain the CDS
|
||||
* The MLE Link Request process is used to establish Router-Router links
|
||||
@@ -1,25 +0,0 @@
|
||||
# 什么是 Thread?
|
||||
|
||||
<figure class="attempt-right">
|
||||
<img src="../images/ot-logo-thread.png" srcset="../images/ot-logo-thread.png 1x, ../images/ot-logo-thread_2x.png 2x" border="0" alt="Thread" />
|
||||
</figure>
|
||||
|
||||
<a href="http://threadgroup.org/">Thread<sup>®</sup></a> 是一个为低功耗物联网(IEEE 802.15.4-2006 WPAN)设备设计的基于 IPv6 的网络协议。Thread 是一个新的网状网络协议,它并不依赖其它的 802.15 网状网络协议(如 ZigBee、Z-Wave 和 Bluetooth LE)。
|
||||
|
||||
Thread 的主要特性包括:
|
||||
|
||||
* 易于部署和维护 — 安装、启动和操作相对简单
|
||||
* 通信安全 — Thread 网络中的设备都必须通过身份验证,并且所有的通信都经过了加密
|
||||
* 稳定可靠 — 具有自愈能力的网状网络,无单点故障,并且采用扩频技术以提高抗干扰能力
|
||||
* 低功耗 — Thread 低功耗设备可以进入休眠并使用电池供电,通常使用一块电池便能工作数年
|
||||
* 规模可扩展 — Thread 网络的规模可以扩展达数百个设备
|
||||
|
||||
如果你不熟悉 Thread,那么了解基本的 Thread 知识对于你在应用中使用 OpenThread 是至关重要的。本入门教程的目的是解释 Thread 的基本概念和工作原理,并为你提供了 OpenThread 开发的起点。
|
||||
|
||||
本教程假定读者已具备如下的基本知识:
|
||||
|
||||
* IEEE 802.15.4
|
||||
* 网络及路由概念
|
||||
* IPv6
|
||||
|
||||
本入门教程基于 Thread Specification V1.1.1。Thread Specification 可以在 [threadgroup.org](http://threadgroup.org/ThreadSpec) 中获取。
|
||||
@@ -1,231 +0,0 @@
|
||||
# IPv6 寻址
|
||||
|
||||
让我们来看一下 Thread 如何识别网络中的每个设备,以及设备间用何种类型的地址进行相互通信。
|
||||
|
||||
Key Term: 在本入门教程中,术语“接口(interface)”用于标识网络内 Thread 设备的端点。通常,单个 Thread 设备具有单个 Thread 接口。
|
||||
|
||||
## 域
|
||||
|
||||
<figure class="attempt-right">
|
||||
<a href="../images/ot-primer-scopes_2x.png"><img src="../images/ot-primer-scopes.png" srcset="../images/ot-primer-scopes.png 1x, ../images/ot-primer-scopes_2x.png 2x" border="0" alt="OT Scopes" /></a>
|
||||
</figure>
|
||||
|
||||
Thread 网络中有三种域用于单播寻址:
|
||||
|
||||
* Link-Local — 所有通过单次射频传输可访问的接口
|
||||
* Mesh-Local — 所有在同一 Thread 网络中可访问的接口
|
||||
* Global — 所有从 Thread 网络外部可以访问的接口
|
||||
|
||||
前两个域与 Thread 网络指定的 Prefix(前缀)相对应。Link-Local 的 Prefix 为 `fe80::/16`,Mesh-Local 的 Prefix 为 `fd00::/8`。
|
||||
|
||||
<h2 style="clear:right">单播</h2>
|
||||
|
||||
单个 Thread 设备可以通过多种 IPv6 单播地址来进行标识。每种地址都有不同的功能(基于域和用例)。
|
||||
|
||||
在介绍每种类型之前,让我们先了解一个共同的概念,它叫作 RLOC(Routing Locator)。RLOC 根据 Thread 接口在网络拓扑中的位置来对其进行标识。
|
||||
|
||||
### 如何生成 RLOC
|
||||
|
||||
所有设备都获得一个 Router ID 和一个 Child ID。每个 Router 维护一个包含其所有子节点的表,两个 ID 的组合唯一地标识拓扑中的设备。例如,请参考以下拓扑中高亮的节点,其中 Router(五边形)中的数字是 Router ID,End Device(圆形)中的数字是 Child ID:
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-rloc-topology_2x.png"><img src="../images/ot-primer-rloc-topology.png" srcset="../images/ot-primer-rloc-topology.png 1x, ../images/ot-primer-rloc-topology_2x.png 2x" border="0" width="600" alt="OT RLOC Topology" /></a>
|
||||
</figure>
|
||||
|
||||
每个子节点的 Router ID 对应于它的父节点(Router)。因为 Router 不会是子节点,所以 Router 的 Child ID 始终为 0。这些值对于 Thread 网络中的每个设备都是唯一的,并用于创建 RLOC16(代表 RLOC 的后 16 位)。
|
||||
|
||||
例如,以下是左上节点(Router ID = 1,Child ID = 1)的 RLOC16 的计算方法:
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-rloc16_2x.png"><img src="../images/ot-primer-rloc16.png" srcset="../images/ot-primer-rloc16.png 1x, ../images/ot-primer-rloc16_2x.png 2x" border="0" width="400" alt="OT RLOC16" /></a>
|
||||
</figure>
|
||||
|
||||
RLOC16 是 IID(Interface Identifier)的一部分,IID 对应的是 IPv6 地址的后 64 位。一些 IID 可用于标识某些类型的 Thread 接口。例如,RLOC 的 IID 始终为 <code>0000:00ff:fe00:<var>RLOC16</var></code> 的形式。
|
||||
|
||||
RLOC 由 Mesh-Local Prefix 和 IID 组成。例如,如果 Mesh-Local Prefix 是 `fde5:8dba:82e1:1::/64`,RLOC16 = `0x401`,那么该节点的 RLOC 就是:
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-rloc_2x.png"><img src="../images/ot-primer-rloc.png" srcset="../images/ot-primer-rloc.png 1x, ../images/ot-primer-rloc_2x.png 2x" border="0" width="600" alt="OT RLOC" /></a>
|
||||
</figure>
|
||||
|
||||
可以使用相同的逻辑来确定以上示例拓扑中所有高亮的节点的 RLOC:
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-rloc-topology-address_2x.png"><img src="../images/ot-primer-rloc-topology-address.png" srcset="../images/ot-primer-rloc-topology-address.png 1x, ../images/ot-primer-rloc-topology-address_2x.png 2x" border="0" width="600" alt="OT Topology w/ Address" /></a>
|
||||
</figure>
|
||||
|
||||
但是,因为 RLOC 是基于节点在拓扑中的位置的,所以节点的 RLOC 会随着拓扑的变化而改变。
|
||||
|
||||
例如,如果 Thread 网络中的 `0x400` 节点离开了网络,那么它的子节点 `0x401` 和 `0x402` 会与其它的 Router 建立新连接,从而获得新的 RLOC16 和 RLOC:
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-rloc-topology-change_2x.png"><img src="../images/ot-primer-rloc-topology-change.png" srcset="../images/ot-primer-rloc-topology-change.png 1x, ../images/ot-primer-rloc-topology-change_2x.png 2x" border="0" width="600" alt="OT Topology after Change" /></a>
|
||||
</figure>
|
||||
|
||||
## 单播地址类型
|
||||
|
||||
RLOC 只是 Thread 设备可以获得的多种 IPv6 单播地址之一。另一类用于在 Thread 网络分区内标识唯一的 Thread 接口的地址称为 EID(Endpoint Identifier)。EID 与 Thread 网络拓扑无关。
|
||||
|
||||
常见的单播类型如下。
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2><h3>Link-Local Address (LLA)</h3></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan=2 style="background-color:rgb(238, 241, 242)">一种用于标识单次射频传输可访问的 Thread 接口的 EID。</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>示例</b></td><td><code>fe80::54db:881c:3845:57f4</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td>基于 802.15.4 Extended Address</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>域</b></td><td>Link-Local</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>详情</b></td><td><ul><li>用于发现邻居、配置链路和交换路由信息</li><li>非可路由地址</li><li>总是带 <code>fe80::/16</code> Prefix</li></ul></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2><h3>Mesh-Local EID (ML-EID)</h3></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan=2 style="background-color:rgb(238, 241, 242)">一种用于标识 Thread 接口的 EID,其与网络拓扑无关。用于访问同一 Thread 分区内的 Thread 接口。也称为 ULA(Unique Local Address)。</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>示例</b></td><td><code>fde5:8dba:82e1:1:416:993c:8399:35ab</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td>在 commissioning 完成后随机生成</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>域</b></td><td>Mesh-Local</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>详情</b></td><td><ul><li>不会随拓扑变化而变化</li><li>应由应用程序使用</li><li>总是带 <code>fd00::/8</code> Prefix</li></ul></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2><h3>Routing Locator (RLOC)</h3></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan=2 style="background-color:rgb(238, 241, 242)">根据 Thread 接口在网络拓扑中的位置来对其进行标识。</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>示例</b></td><td><code>fde5:8dba:82e1:1::ff:fe00:1001</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td><code>0000:00ff:fe00:<var>RLOC16</var></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>域</b></td><td>Mesh-Local</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>详情</b></td><td><ul><li>在设备连接到网络后生成</li><li>用于在 Thread 网络中传递 IPv6 数据报</li><li>随拓扑变化而变化</li><li>通常不会由应用程序使用</li></ul></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2><h3>Anycast Locator (ALOC)</h3></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan=2 style="background-color:rgb(238, 241, 242)">用于标识 Thread 网络分区中一个或多个 Thread 接口的位置。如果始发者不知道目的地的 RLOC,则使用 ALOC 进行查找。</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>示例</b></td><td><code>fde5:8dba:82e1:1::ff:fe00:fc01</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td><code>0000:00ff:fe00:fc<var>XX</var></code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>域</b></td><td>Mesh-Local</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>详情</b></td><td><ul><li><code>fc<var>XX</var></code> = <a href="#anycast">ALOC 目的地址</a>,用于查询对应的 RLOC</li><li>通常不会由应用程序使用</li></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2><h3>Global Unicast Address (GUA)</h3></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan=2 style="background-color:rgb(238, 241, 242)">一个EID,用于标识除 Thread 网络外的全局范围内的 Thread 接口。</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>示例</b></td><td><code>2000::54db:881c:3845:57f4</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>IID</b></td><td><ul><li>SLAAC — 由设备自身随机分配</li><li>DHCP — 由 DHCPv6 服务器分配</li><li>Manual — 由应用层分配</li></ul></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>域</b></td><td>Global</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>详情</b></td><td><ul><li>一个公开的 IPv6 地址</li><li>总是带 <code>2000::/3</code> Prefix</li></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## 多播
|
||||
|
||||
多播用于一次将信息传达给多个设备。Thread 网络中保留了特定的地址,以提供给不同分组的设备在多播时使用。
|
||||
|
||||
| IPv6 地址 | 域 | 传递给 |
|
||||
| --------- | ---------- | --------------- |
|
||||
| `ff02::1` | Link-Local | 所有 FTD 和 MED |
|
||||
| `ff02::2` | Link-Local | 所有 FTD |
|
||||
| `ff03::1` | Mesh-Local | 所有 FTD 和 MED |
|
||||
| `ff03::2` | Mesh-Local | 所有 FTD |
|
||||
|
||||
Key Point: FTD 和 MTD 之间的主要区别在于 FTD 订阅了 `ff03::2` 多播地址。而 MTD 没有订阅。
|
||||
|
||||
你可能会注意到,上面的多播表中没有将 SED 作为接收者包括在内。Thread 为所有 Thread 节点(包括 SED)定义了(link-local 和 realm-local 域)基于单播 prefix 的 IPv6 多播地址。这些多播地址基于单播 Mesh-Local prefix 构成,因 Thread 网络而异。(有关基于单播 prefix 的 IPv6 多播地址的详情,请参阅 [RFC 3306](https://tools.ietf.org/html/rfc3306))。
|
||||
|
||||
Thread 设备还支持除表中所列举域之外的任意域。
|
||||
|
||||
## 任播
|
||||
|
||||
当目的地的 RLOC 未知时,可以使用任播将流量路由到 Thread 接口。ALOC(Anycast Locator)标识 Thread 分区内多个接口的位置。ALOC 的后 16 位,称为 ALOC16,其格式为 <code>0xfc<var>XX</var></code>,表示 ALOC 的类型。
|
||||
|
||||
例如,`0xfc01` 和 `0xfc0f` 之间的 ALOC16 保留给了 DHCPv6 Agent。如果特定的 DHCPv6 Agent RLOC 是未知的(可能是因为网络拓扑已更改),则可以将消息发送到 DHCPv6 Agent ALOC 以获取 RLOC。
|
||||
|
||||
Thread 定义了以下 ALOC16 值:
|
||||
|
||||
| ALOC16 | 类型 |
|
||||
| ------------------------------------------ | ------------------------ |
|
||||
| `0xfc00` | Leader |
|
||||
| `0xfc01` – `0xfc0f` | DHCPv6 Agent |
|
||||
| `0xfc10` – `0xfc2f` | Service |
|
||||
| `0xfc30` – `0xfc37` | Commissioner |
|
||||
| `0xfc40` – `0xfc4e` | Neighbor Discovery Agent |
|
||||
| `0xfc38` – `0xfc3f`<br>`0xfc4f` – `0xfcff` | Reserved |
|
||||
|
||||
## 回顾
|
||||
|
||||
你应该学到了:
|
||||
|
||||
* Thread 网络包含三个域:Link-Local、Mesh-Local 和 Global
|
||||
* Thread 设备具有多种单播 IPv6 地址
|
||||
* RLOC 表示设备在 Thread 网络中的位置
|
||||
* ML-EID 对于分区内的 Thread 设备是唯一的,并且应由应用程序使用
|
||||
* Thread 使用多播将数据转发到节点组和 Router 组
|
||||
* 当目的地的 RLOC 未知时,Thread 可以使用任播
|
||||
|
||||
要了解有关 Thread 的 IPv6 寻址的更多信息,请参阅 [Thread Specification](http://threadgroup.org/ThreadSpec) 的 5.2 和 5.3 节。
|
||||
@@ -1,254 +0,0 @@
|
||||
# 网络发现与形成
|
||||
|
||||
## Thread 网络
|
||||
|
||||
Thread 网络由三个唯一的标识符标识:
|
||||
|
||||
* 2 字节的 PAN ID(Personal Area Network ID,个域网标识符)
|
||||
* 8 字节的 XPAN ID(Extended Personal Area Network ID,扩展个域网标识符)
|
||||
* 方便人类阅读的 Network Name(网络名称)
|
||||
|
||||
例如,一个 Thread 网络可能具有以下标识符:
|
||||
|
||||
| 标识符 | 值 |
|
||||
| ------------ | -------------------- |
|
||||
| PAN ID | `0xBEEF` |
|
||||
| XPAN ID | `0xBEEF1111CAFE2222` |
|
||||
| Network Name | `yourThreadCafe` |
|
||||
|
||||
<figure class="attempt-right">
|
||||
<a href="../images/ot-primer-network-active-scan_2x.png"><img src="../images/ot-primer-network-active-scan.png" srcset="../images/ot-primer-network-active-scan.png 1x, ../images/ot-primer-network-active-scan_2x.png 2x" border="0" alt="OT Active Scan" /></a>
|
||||
</figure>
|
||||
|
||||
在创建新的 Thread 网络或搜索现有的网络时,Thread 设备会主动扫描射频范围内的 802.15.4 网络:
|
||||
|
||||
1. 设备在特定 Channel 上广播 802.15.4 信标请求(Beacon Request)。
|
||||
2. 范围内的所有 Router 或 REED 都会广播包含其 Thread 网络 PAN ID、XPAN ID 和 Network Name 的信标(Beacon),以作为回应。
|
||||
3. 设备为每个 Channel 重复前两个步骤。
|
||||
|
||||
Thread 设备发现范围内的所有网络后,可以选择连接到现有的网络,也可以在未发现任何网络的情况下创建新的网络。
|
||||
|
||||
<h2 style="clear:right">Mesh Link Establishment</h2>
|
||||
|
||||
Thread 使用 MLE(Mesh Link Establishment)协议来配置链路并将网络的相关信息传播到 Thread 设备。
|
||||
|
||||
在链路配置中,MLE 用于:
|
||||
|
||||
* 发现相邻设备的链路
|
||||
* 确认到相邻设备的链路质量
|
||||
* 建立到相邻设备的链路
|
||||
* 与对端协商链路参数(设备类型、帧计数器、超时)
|
||||
|
||||
MLE 将以下类型的信息传播给希望建立链路的设备:
|
||||
|
||||
* Leader data(Leader RLOC, Partition ID(分区标识符), Partition weight(分区权重))
|
||||
* Network data(on-mesh prefixes, address autoconfiguration(地址自动配置), more-specific routes(具体路由))
|
||||
* Route propagation(路由传播)
|
||||
|
||||
Thread 中路由传播的工作原理类似于 RIP(Routing Information Protocol,路由信息协议),RIP 是一种距离矢量路由协议。
|
||||
|
||||
Note: 仅当 Thread 设备通过 Thread Commissioning 获得 Thread 网络凭据后,才会继续进行 MLE 过程。Commissioning 和安全性将在本教程的后续部分中深入介绍。目前,假定设备已通过 Commissioning。
|
||||
|
||||
## 创建新网络
|
||||
|
||||
如果设备选择创建新网络,它将选择最不繁忙的 Channel 和其他网络未使用的 PAN ID,然后成为 Router 并选举自己为 Leader。该设备将 MLE Advertisement 消息发送到其他 802.15.4 设备,以通知其链路状态,并响应其他执行主动扫描的 Thread 设备所发出的信标请求。
|
||||
|
||||
## 加入现有网络
|
||||
|
||||
如果设备选择加入到现有的网络,则会通过 Thread Commissioning 将其 Channel、PAN ID、XPAN ID 和 Network Name 配置为与目标网络相同,然后进行 MLE Attach 过程以作为子节点(End Device)进行加入。此过程用于“父子链路(Child-Parent link)”。
|
||||
|
||||
Key Point: 每个设备(无论是否具有充当 Router 的能力),最初都作为子设备(End Device)连接到 Thread 网络。
|
||||
|
||||
1. 子节点向目标网络中的所有相邻的 Router 和 REED 发送多播 [Parent Request](#1-Parent-Request)。
|
||||
2. 所有相邻的 Router 和 REED(如果 Parent Request Scan Mask(父节点请求扫描掩码)包括了 REED)都应发送 [Parent Response](#2-Parent-Response) 以将其自身的信息告诉给子节点。
|
||||
3. 子节点选择一个父节点,并向其发送 [Child ID Request](#3-Child-ID-Request)。
|
||||
4. 父节点发送 [Child ID Response](#4-Child-ID-Response) 以确认链路建立。
|
||||
|
||||
### 1. Parent Request
|
||||
|
||||
Parent Request 是来自待连接设备的多播请求,用于发现目标网络中的相邻的 Router 和 REED。
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-network-mle-attach-01_2x.png"><img src="../images/ot-primer-network-mle-attach-01.png" srcset="../images/ot-primer-network-mle-attach-01.png 1x, ../images/ot-primer-network-mle-attach-01_2x.png 2x" width="350" border="0" alt="OT MLE Attach Parent Request" /></a>
|
||||
</figure>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2>Parent Request Message Contents</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Mode</b></td>
|
||||
<td>描述待连接设备</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Challenge</b></td>
|
||||
<td>测试 Parent Response 的时效性,以防止重放攻击</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Scan Mask</b></td>
|
||||
<td>将请求限制为仅 Router 或 Router 和 REED</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### 2. Parent Response
|
||||
|
||||
Parent Response 是对 Parent Request 的单播响应,它向待连接设备提供有关 Router 或 REED 的信息。
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-network-mle-attach-02_2x.png"><img src="../images/ot-primer-network-mle-attach-02.png" srcset="../images/ot-primer-network-mle-attach-02.png 1x, ../images/ot-primer-network-mle-attach-02_2x.png 2x" width="350" border="0" alt="OT MLE Attach Parent Response" /></a>
|
||||
</figure>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2>Parent Response Message Contents</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Version</b></td>
|
||||
<td>Thread 协议版本</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Response</b></td>
|
||||
<td>Parent Request Challenge 的副本</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Link Frame
|
||||
Counter</b></td>
|
||||
<td>Router/REED 上的 802.15.4 帧计数器</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>MLE Frame
|
||||
Counter</b></td>
|
||||
<td>Router/REED 上的 MLE 帧计数器</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Source
|
||||
Address</b></td>
|
||||
<td>Router/REED 的 RLOC16</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Link
|
||||
Margin</b></td>
|
||||
<td>Router/REED 的接收信号质量</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Connectivity</b></td>
|
||||
<td>描述 Router/REED 的连通性</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Leader
|
||||
Data</b></td>
|
||||
<td>有关 Router/REED 的 Leader 的信息</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Challenge</b></td>
|
||||
<td>测试 Child ID Request 的时效性,以防止重放攻击</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### 3. Child ID Request
|
||||
|
||||
Child ID Request 是来自待连接设备(子)的单播请求,该单播请求被发送到 Router(父)或 REED(父),目的是建立父子链路。如果将请求发送到 REED,则 REED 会在接受请求之前将自身升级为 Router。
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-network-mle-attach-03_2x.png"><img src="../images/ot-primer-network-mle-attach-03.png" srcset="../images/ot-primer-network-mle-attach-03.png 1x, ../images/ot-primer-network-mle-attach-03_2x.png 2x" width="350" border="0" alt="OT MLE Attach Child ID Request" /></a>
|
||||
</figure>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2>Child ID Request Message Contents</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Version</b></td>
|
||||
<td>Thread 协议版本</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Response</b></td>
|
||||
<td>Parent Response Challenge 的副本</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Link Frame
|
||||
Counter</b></td>
|
||||
<td>Child 上的 802.15.4 帧计数器</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>MLE Frame
|
||||
Counter</b></td><td>Child 上的 MLE 帧计数器</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Mode</b></td>
|
||||
<td>描述子节点</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Timeout</b></td>
|
||||
<td>父节点移除子节点之前的闲置时间</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Address
|
||||
Registration (MEDs and SEDs only)</b></td>
|
||||
<td>注册 IPv6 地址</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### 4. Child ID Response
|
||||
|
||||
Child ID Response 是父节点对 Child ID Request 的单播响应,该响应发送给对应的子节点以确认父子链路的建立。
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-network-mle-attach-04_2x.png"><img src="../images/ot-primer-network-mle-attach-04.png" srcset="../images/ot-primer-network-mle-attach-04.png 1x, ../images/ot-primer-network-mle-attach-04_2x.png 2x" width="350" border="0" alt="OT MLE Attach Child ID Response" /></a>
|
||||
</figure>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2>Child ID Response Message Contents</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Source
|
||||
Address</b></td>
|
||||
<td>父节点的 RLOC16</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Address16</b></td>
|
||||
<td>子节点的 RLOC16</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Leader
|
||||
Data</b></td>
|
||||
<td>父节点的 Leader 的相关信息(RLOC, Partition ID, Partition weight)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Network
|
||||
Data</b></td>
|
||||
<td>Thread 网络的相关信息(on-mesh prefixes, address autoconfiguration, more-specific routes)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Route
|
||||
(REED only)</b></td>
|
||||
<td>路由传播</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Timeout</b></td>
|
||||
<td>父节点移除子节点之前的闲置时间</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Address
|
||||
Registration (MEDs and SEDs only)</b></td>
|
||||
<td>确认已注册地址</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## 回顾
|
||||
|
||||
你应该学到了:
|
||||
|
||||
* Thread 设备通过主动扫描发现现有网络
|
||||
* Thread 使用 MLE 来配置链路并分发有关网络设备的信息
|
||||
* MLE Advertisement 消息通知其他 Thread 设备有关设备的网络和链路状态
|
||||
* MLE Attach 过程建立了父子链路
|
||||
@@ -1,125 +0,0 @@
|
||||
# 节点角色和类型
|
||||
|
||||
## 转发角色
|
||||
|
||||
<figure class="attempt-right">
|
||||
<a href="../images/ot-primer-roles_2x.png"><img src="../images/ot-primer-roles.png" srcset="../images/ot-primer-roles.png 1x, ../images/ot-primer-roles_2x.png 2x" border="0" alt="OT Node Roles" /></a>
|
||||
</figure>
|
||||
|
||||
在 Thread 网络中,节点分成两种转发角色:Router 和 End Device。
|
||||
|
||||
### Router
|
||||
|
||||
Router 节点的行为如下:
|
||||
|
||||
* 为网络设备转发数据包
|
||||
* 为尝试加入网络的设备提供安全的 commissioning 服务
|
||||
* 始终打开它的收发器
|
||||
|
||||
### End Device
|
||||
|
||||
End Device 节点的行为如下:
|
||||
|
||||
* 主要与单个 Router 进行通信
|
||||
* 不会为其他网络设备转发数据包
|
||||
* 可以关闭它的收发器来降低功耗
|
||||
|
||||
Key Point: Router 和 End Device 之间的关系称为父子关系。End Device 正确地依附到一个 Router 上,其中 Router 始终作为父节点,End Device 则始终是子节点。
|
||||
|
||||
## 设备类型
|
||||
|
||||
此外,节点有许多种类型。
|
||||
|
||||
<figure class="attempt-right">
|
||||
<a href="../images/ot-primer-taxonomy_2x.png"><img src="../images/ot-primer-taxonomy.png" srcset="../images/ot-primer-taxonomy.png 1x, ../images/ot-primer-taxonomy.png 2x" border="0" alt="OT Device Taxonomy" /></a>
|
||||
</figure>
|
||||
|
||||
### Full Thread Device
|
||||
|
||||
一个 FTD(Full Thread Device)总是打开它的射频收发器,它订阅所有 Router 的多播地址,并维护 IPv6 地址映射。FTD 有三种类型:
|
||||
|
||||
* Router
|
||||
* REED(Router Eligible End Device)— 可以升级为 Router
|
||||
* FED(Full End Device)— 无法升级为 Router
|
||||
|
||||
FTD 可以作为 Router(父)或 End Device(子)。
|
||||
|
||||
### Minimal Thread Device
|
||||
|
||||
MTD(Minimal Thread Device)不会订阅 all-routers 多播地址,并且它会将它的所有消息发送给它的父节点。MTD 有两种类型:
|
||||
|
||||
* MED(Minimal End Device)— 始终打开自身的收发器,无需从父节点中轮询消息
|
||||
* SED(Sleepy End Device)— 通常会关闭自身的收发器(睡眠),偶然会打开收发器(唤醒)以从父节点中轮询消息
|
||||
|
||||
MTD 只能作为 End Device(子)。
|
||||
|
||||
### 升级和降级
|
||||
|
||||
当待加入设备仅能与某个 REED 通信时, 则该 REED 可以升级成为 Router:
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-router-upgrade_2x.png"><img src="../images/ot-primer-router-upgrade.png" srcset="../images/ot-primer-router-upgrade.png 1x, ../images/ot-primer-router-upgrade_2x.png 2x" border="0" width="400" alt="OT End Device to Router" /></a>
|
||||
</figure>
|
||||
|
||||
相反,当一个 Router 没有子节点时,它可以降级成 End Device:
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-router-downgrade_2x.png"><img src="../images/ot-primer-router-downgrade.png" srcset="../images/ot-primer-router-downgrade.png 1x, ../images/ot-primer-router-downgrade_2x.png 2x" border="0" width="400" alt="OT Router to End Device" /></a>
|
||||
</figure>
|
||||
|
||||
## 其他角色和类型
|
||||
|
||||
### Thread Leader
|
||||
|
||||
<figure class="attempt-right">
|
||||
<a href="../images/ot-primer-leader_2x.png"><img src="../images/ot-primer-leader.png" srcset="../images/ot-primer-leader.png 1x, ../images/ot-primer-leader_2x.png 2x" border="0" alt="OT Leader and Border Router" /></a>
|
||||
</figure>
|
||||
|
||||
Thread Leader 是一个 Router,它负责管理 Thread 网络中的 Router。Thread Leader 是动态自选的(提高容错率),它负责汇总和分发全网络的配置信息。
|
||||
|
||||
Note: 每个 Thread 网络[分区](#分区)中总是只有一个 Leader。
|
||||
|
||||
### Border Router
|
||||
|
||||
Border Router 是一种可以在 Thread 网络和其他网络(如 Wi-Fi)之间转发信息的设备。它还为外部连接配置 Thread 网络。
|
||||
|
||||
任何设备都可以充当 Border Router。
|
||||
|
||||
Note: 一个 Thread 网络中可以有多个 Border Router。
|
||||
|
||||
## 分区
|
||||
|
||||
<figure class="attempt-right">
|
||||
<a href="../images/ot-primer-partitions_2x.png"><img src="../images/ot-primer-partitions.png" srcset="../images/ot-primer-partitions.png 1x, ../images/ot-primer-partitions_2x.png 2x" border="0" alt="OT Partitions" /></a>
|
||||
</figure>
|
||||
|
||||
一个 Thread 网络可能由多个分区组成。当一组 Thread 设备不能再与另一组 Thread 设备通信时,会发生这种情况。每个分区在逻辑上均作为独立的 Thread 网络来运行,它们具有各自的 Leader、Router ID 分配和网络数据,同时分区前相同的安全凭证都将被保留下来。
|
||||
|
||||
当分区之间可以连通时,它们会自动合并。
|
||||
|
||||
Key Point: 安全凭证(security credentials)定义了 Thread 网络。物理无线电的连通性定义了该 Thread 网络中的分区。
|
||||
|
||||
请注意,在本入门教程中一般将 Thread 网络假定成单个分区。在必要时,将使用“分区”一词来阐明关键概念和示例。本教程稍后将详细介绍分区。
|
||||
|
||||
## 设备限制
|
||||
|
||||
单个 Thread 网络所支持的设备类型数量是有限制的。
|
||||
|
||||
| 角色 | 限制 |
|
||||
| ---------- | ------------------ |
|
||||
| Leader | 1 |
|
||||
| Router | 32 |
|
||||
| End Device | 511(每个 Router) |
|
||||
|
||||
Thread 会尝试将 Router 的数量保持在 16 ~ 23 之间。如果一个 REED 作为 End Device 加入,并且网络中的 Router 数量低于 16,那么它将自动升级为 Router。
|
||||
|
||||
## 回顾
|
||||
|
||||
你应该学到了:
|
||||
|
||||
* Thread 设备可以是 Router(父)或 End Device(子)
|
||||
* Thread 设备可以是 FTD(维护 IPv6 地址映射),也可以是 MTD(将所有消息发送给其父节点)
|
||||
* REED 可以升级为 Router,Router 也可以降级为 REED
|
||||
* 每个 Thread 网络分区都有一个 Leader 来管理 Router
|
||||
* Border Router 用于连接 Thread 和其他网络
|
||||
* 一个 Thread 网络可能由多个分区组成
|
||||
@@ -1,145 +0,0 @@
|
||||
# Router 选择
|
||||
|
||||
## Connected Dominating Set
|
||||
|
||||
<figure class="attempt-right">
|
||||
<a href="../images/ot-primer-cds_2x.png"><img src="../images/ot-primer-cds.png" srcset="../images/ot-primer-cds.png 1x, ../images/ot-primer-cds_2x.png 2x" width="350" border="0" alt="OT Connected Dominating Set" /></a><figcaption style="text-align: center"><i>Example of a Connected Dominating Set</i></figcaption>
|
||||
</figure>
|
||||
|
||||
Router 必须形成一个 CDS(Connected Dominating Set,连接支配集),这意味着:
|
||||
|
||||
1. 在任何两个 Router 之间都有一个 Router-only 的路径。
|
||||
2. Thread 网络中的任何一个 Router 都可以通过完全位于 Router 集中而到达其他任何 Router。
|
||||
3. Thread 网络中的每个 End Device 都直接连接到 Router。
|
||||
|
||||
Thread 使用分布式算法维护 CDS,从而确保最低程度的冗余。每个设备最初都作为 End Device(子)连接到网络。随着 Thread 网络状态的更改,算法会增添或移除 Router 以维护 CDS。
|
||||
|
||||
Thread 在下列情况下将会增添 Router:
|
||||
|
||||
* 如果网络低于 Router 阈值(16) —— 为了增加覆盖范围
|
||||
* 增加路径多样性
|
||||
* 保持最低程度的冗余
|
||||
* 扩展连接并支持更多子节点
|
||||
|
||||
Thread 在下列情况下将会移除 Router:
|
||||
|
||||
* 将路由状态减少到最多 32 个 Router 以下
|
||||
* 必要时允许在网络的其他部分使用新 Router
|
||||
|
||||
## 升级成 Router
|
||||
|
||||
子设备连接到 Thread 网络后,可以选择成为 Router。在开始 MLE Link Request 过程之前,子设备会向 Leader 发送 Address Solicit 消息,以请求一个 Router ID。如果 Leader 同意该请求,则它将响应一个 Router ID 给子设备,并且子设备会将自身升级为 Router。
|
||||
|
||||
然后,MLE Link Request 过程用于与相邻的 Router 建立双向 Router-Router 链路。
|
||||
|
||||
1. 新 Router 将发送一个多播 [Link Request](#1-Link-Request) 到相邻的 Router。
|
||||
2. Router 使用 [Link Accept and Request](#2-Link-Accept-and-Request) 消息进行响应。
|
||||
3. 新 Router 使用单播的 [Link Accept](#3-Link-Accept) 响应每个 Router,以建立 Router-Router 链路。
|
||||
|
||||
### 1. Link Request
|
||||
|
||||
Link Request 是从 Router 到 Thread 网络中所有其他 Router 的请求。首次成为 Router 时,设备会发送一个多播 Link Request 到 `ff02::2`。稍后,在通过 MLE Advertisement 发现其他 Router 后,设备将发送单播的 Link Request。
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-network-mle-link-request-01_2x.png"><img src="../images/ot-primer-network-mle-link-request-01.png" srcset="../images/ot-primer-network-mle-link-request-01.png 1x, ../images/ot-primer-network-mle-link-request-01_2x.png 2x" width="350" border="0" alt="OT MLE Link Request" /></a>
|
||||
</figure>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2>Link Request Message Contents</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Version</b></td>
|
||||
<td>Thread 协议版本</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Challenge</b></td>
|
||||
<td>测试 Link Response 的及时性,以防止重放攻击</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Source
|
||||
Address</b></td>
|
||||
<td>发送者的 RLOC16</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Leader
|
||||
Data</b></td>
|
||||
<td>Router 的 Leader 的相关信息(RLOC, Partition ID, Partition weight)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### 2. Link Accept and Request
|
||||
|
||||
Link Accept and Request 是 Link Accept 和 Link Request 消息的组合。Thread 在 MLE Link Request 过程中使用此优化将消息的数量从四减少到三。
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-network-mle-link-request-02_2x.png"><img src="../images/ot-primer-network-mle-link-request-02.png" srcset="../images/ot-primer-network-mle-link-request-02.png 1x, ../images/ot-primer-network-mle-link-request-02_2x.png 2x" width="350" border="0" alt="OT MLE Link Accept and Request" /></a>
|
||||
</figure>
|
||||
|
||||
### 3. Link Accept
|
||||
|
||||
Link Accept 是对来自相邻 Router 的 Link Request 的单播响应,该响应提供有关自身的信息并接受到相邻 Router 的链路。
|
||||
|
||||
<figure>
|
||||
<a href="../images/ot-primer-network-mle-link-request-03_2x.png"><img src="../images/ot-primer-network-mle-link-request-03.png" srcset="../images/ot-primer-network-mle-link-request-03.png 1x, ../images/ot-primer-network-mle-link-request-03_2x.png 2x" width="350" border="0" alt="OT MLE Link Accept" /></a>
|
||||
</figure>
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th colspan=2>Link Accept Message Contents</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Version</b></td>
|
||||
<td>Thread 协议版本</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Response</b></td>
|
||||
<td>测试 Link Response 的及时性,以防止重放攻击</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Link Frame
|
||||
Counter</b></td>
|
||||
<td>发送者上的 802.15.4 帧计数器</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>MLE Frame
|
||||
Counter</b></td>
|
||||
<td>发送者上的 MLE 帧计数器</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Source
|
||||
Address</b></td>
|
||||
<td>发送者的 RLOC16</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" style="background-color:rgb(238, 241, 242)"><b>Leader
|
||||
Data</b></td>
|
||||
<td>Router 的 Leader 的相关信息(RLOC, Partition ID, Partition weight)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## 降级成 REED
|
||||
|
||||
当 Router 降级成 REED 时,其 Router-Router 链路断开,并且设备开始 MLE Attach 过程以建立父子链路。
|
||||
|
||||
有关 MLE Attach 过程的更多信息,请参阅 [加入现有网络](/guides/thread-primer/network-discovery#加入现有网络)。
|
||||
|
||||
## 单向接收链路
|
||||
|
||||
在某些情况下,建立单向接收链路是有必要的。
|
||||
|
||||
在 Router 重置后,相邻 Router 可能仍具有与重置的 Router 的有效接收链路。在这种情况下,重置的 Router 发送 Link Request 消息以重新建立 Router-Router 链路。
|
||||
|
||||
End Device 也可能希望与相邻的 Router(非父节点)建立接收链路,以提高多播可靠性。当我们进入多播路由时,我们将学习更多与此相关的内容。
|
||||
|
||||
## 回顾
|
||||
|
||||
你应该学到了:
|
||||
|
||||
* Thread 网络中的 Router 必须形成 CDS
|
||||
* Thread 设备将升级成 Router 或降级成 REED 以维护 CDS
|
||||
* MLE Link Request 过程用于建立 Router-Router 链路
|
||||
Reference in New Issue
Block a user