[docs] move openthread.io content to openthread/ot-docs (#6415)

This commit is contained in:
Jonathan Hui
2021-05-12 11:29:35 -07:00
committed by GitHub
parent e0a1987336
commit 45a23d89fe
18 changed files with 0 additions and 2772 deletions
@@ -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.
-20
View File
@@ -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.
-33
View File
@@ -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 @&lt;:@default=none@:&gt;@.])],
[
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
```
-37
View File
@@ -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/REEDs 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/REEDs 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 Parents 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 单播地址来进行标识。每种地址都有不同的功能(基于域和用例)。
在介绍每种类型之前,让我们先了解一个共同的概念,它叫作 RLOCRouting 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 = 1Child 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 是 IIDInterface 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 接口的地址称为 EIDEndpoint 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 接口。也称为 ULAUnique 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 接口。ALOCAnycast 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 IDPersonal Area Network ID,个域网标识符)
* 8 字节的 XPAN IDExtended 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 使用 MLEMesh Link Establishment)协议来配置链路并将网络的相关信息传播到 Thread 设备。
在链路配置中,MLE 用于:
* 发现相邻设备的链路
* 确认到相邻设备的链路质量
* 建立到相邻设备的链路
* 与对端协商链路参数(设备类型、帧计数器、超时)
MLE 将以下类型的信息传播给希望建立链路的设备:
* Leader dataLeader RLOC, Partition ID(分区标识符), Partition weight(分区权重))
* Network dataon-mesh prefixes, address autoconfiguration(地址自动配置), more-specific routes(具体路由))
* Route propagation(路由传播)
Thread 中路由传播的工作原理类似于 RIPRouting 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
一个 FTDFull Thread Device)总是打开它的射频收发器,它订阅所有 Router 的多播地址,并维护 IPv6 地址映射。FTD 有三种类型:
* Router
* REEDRouter Eligible End Device)— 可以升级为 Router
* FEDFull End Device)— 无法升级为 Router
FTD 可以作为 Router(父)或 End Device(子)。
### Minimal Thread Device
MTDMinimal Thread Device)不会订阅 all-routers 多播地址,并且它会将它的所有消息发送给它的父节点。MTD 有两种类型:
* MEDMinimal End Device)— 始终打开自身的收发器,无需从父节点中轮询消息
* SEDSleepy 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 可以升级为 RouterRouter 也可以降级为 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 必须形成一个 CDSConnected 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 链路