upmerge: merge up to commit 5cfbcfc
This commit is contained in:
commit
4881ea3910
|
@ -46,7 +46,7 @@ jobs:
|
||||||
REFERENCE_DEVICE: 1
|
REFERENCE_DEVICE: 1
|
||||||
VIRTUAL_TIME: 0
|
VIRTUAL_TIME: 0
|
||||||
PACKET_VERIFICATION: 1
|
PACKET_VERIFICATION: 1
|
||||||
THREAD_VERSION: 1.2
|
THREAD_VERSION: 1.3
|
||||||
INTER_OP: 1
|
INTER_OP: 1
|
||||||
COVERAGE: 1
|
COVERAGE: 1
|
||||||
MULTIPLY: 1
|
MULTIPLY: 1
|
||||||
|
@ -83,12 +83,12 @@ jobs:
|
||||||
sudo -E ./script/test cert_suite ./tests/scripts/thread-cert/backbone/*.py || (sudo chmod a+r *.log *.json *.pcap && false)
|
sudo -E ./script/test cert_suite ./tests/scripts/thread-cert/backbone/*.py || (sudo chmod a+r *.log *.json *.pcap && false)
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: cov-thread-1-2-backbone-docker
|
name: cov-thread-1-3-backbone-docker
|
||||||
path: /tmp/coverage/
|
path: /tmp/coverage/
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
if: ${{ failure() }}
|
if: ${{ failure() }}
|
||||||
with:
|
with:
|
||||||
name: thread-1-2-backbone-results
|
name: thread-1-3-backbone-results
|
||||||
path: |
|
path: |
|
||||||
*.pcap
|
*.pcap
|
||||||
*.json
|
*.json
|
||||||
|
@ -100,7 +100,7 @@ jobs:
|
||||||
./script/test generate_coverage gcc
|
./script/test generate_coverage gcc
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: cov-thread-1-2-backbone
|
name: cov-thread-1-3-backbone
|
||||||
path: tmp/coverage.info
|
path: tmp/coverage.info
|
||||||
|
|
||||||
thread-border-router:
|
thread-border-router:
|
||||||
|
@ -144,7 +144,7 @@ jobs:
|
||||||
REFERENCE_DEVICE: 1
|
REFERENCE_DEVICE: 1
|
||||||
VIRTUAL_TIME: 0
|
VIRTUAL_TIME: 0
|
||||||
PACKET_VERIFICATION: ${{ matrix.packet_verification }}
|
PACKET_VERIFICATION: ${{ matrix.packet_verification }}
|
||||||
THREAD_VERSION: 1.2
|
THREAD_VERSION: 1.3
|
||||||
INTER_OP: 1
|
INTER_OP: 1
|
||||||
COVERAGE: 1
|
COVERAGE: 1
|
||||||
MULTIPLY: 1
|
MULTIPLY: 1
|
||||||
|
@ -220,7 +220,7 @@ jobs:
|
||||||
script/test combine_coverage
|
script/test combine_coverage
|
||||||
- name: Upload Coverage
|
- name: Upload Coverage
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
uses: codecov/codecov-action@v1
|
uses: codecov/codecov-action@v2
|
||||||
with:
|
with:
|
||||||
files: final.info
|
files: final.info
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
|
|
|
@ -61,7 +61,7 @@ jobs:
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
./bootstrap
|
./bootstrap
|
||||||
make -f examples/Makefile-simulation THREAD_VERSION=1.2 DUA=1 MLR=1 BACKBONE_ROUTER=1 CSL_RECEIVER=1
|
make -f examples/Makefile-simulation THREAD_VERSION=1.3 DUA=1 MLR=1 BACKBONE_ROUTER=1 CSL_RECEIVER=1
|
||||||
- name: Install OTCI Python Library
|
- name: Install OTCI Python Library
|
||||||
run: |
|
run: |
|
||||||
(cd tools/otci && python3 setup.py install --user)
|
(cd tools/otci && python3 setup.py install --user)
|
||||||
|
|
|
@ -293,7 +293,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
script/test combine_coverage
|
script/test combine_coverage
|
||||||
- name: Upload Coverage
|
- name: Upload Coverage
|
||||||
uses: codecov/codecov-action@v1
|
uses: codecov/codecov-action@v2
|
||||||
with:
|
with:
|
||||||
files: final.info
|
files: final.info
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
|
|
|
@ -372,7 +372,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
script/test combine_coverage
|
script/test combine_coverage
|
||||||
- name: Upload Coverage
|
- name: Upload Coverage
|
||||||
uses: codecov/codecov-action@v1
|
uses: codecov/codecov-action@v2
|
||||||
with:
|
with:
|
||||||
files: final.info
|
files: final.info
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
#
|
#
|
||||||
|
|
||||||
name: Simulation 1.2
|
name: Simulation 1.3
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
@ -40,15 +40,15 @@ jobs:
|
||||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
if: "github.ref != 'refs/heads/main'"
|
if: "github.ref != 'refs/heads/main'"
|
||||||
|
|
||||||
thread-1-2:
|
thread-1-3:
|
||||||
name: thread-1-2-${{ matrix.compiler.c }}-${{ matrix.arch }}
|
name: thread-1-3-${{ matrix.compiler.c }}-${{ matrix.arch }}
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
env:
|
env:
|
||||||
CFLAGS: -${{ matrix.arch }}
|
CFLAGS: -${{ matrix.arch }}
|
||||||
CXXFLAGS: -${{ matrix.arch }}
|
CXXFLAGS: -${{ matrix.arch }}
|
||||||
LDFLAGS: -${{ matrix.arch }}
|
LDFLAGS: -${{ matrix.arch }}
|
||||||
COVERAGE: 1
|
COVERAGE: 1
|
||||||
THREAD_VERSION: 1.2
|
THREAD_VERSION: 1.3
|
||||||
VIRTUAL_TIME: 1
|
VIRTUAL_TIME: 1
|
||||||
INTER_OP: 1
|
INTER_OP: 1
|
||||||
CC: ${{ matrix.compiler.c }}
|
CC: ${{ matrix.compiler.c }}
|
||||||
|
@ -87,12 +87,12 @@ jobs:
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
if: ${{ failure() }}
|
if: ${{ failure() }}
|
||||||
with:
|
with:
|
||||||
name: thread-1-2-${{ matrix.compiler.c }}-${{ matrix.arch }}-pcaps
|
name: thread-1-3-${{ matrix.compiler.c }}-${{ matrix.arch }}-pcaps
|
||||||
path: "*.pcap"
|
path: "*.pcap"
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
if: ${{ failure() && env.CRASHED == '1' }}
|
if: ${{ failure() && env.CRASHED == '1' }}
|
||||||
with:
|
with:
|
||||||
name: core-packet-verification-thread-1-2
|
name: core-packet-verification-thread-1-3
|
||||||
path: |
|
path: |
|
||||||
./ot-core-dump/*
|
./ot-core-dump/*
|
||||||
- name: Generate Coverage
|
- name: Generate Coverage
|
||||||
|
@ -100,7 +100,7 @@ jobs:
|
||||||
./script/test generate_coverage "${{ matrix.compiler.gcov }}"
|
./script/test generate_coverage "${{ matrix.compiler.gcov }}"
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: cov-thread-1-2-${{ matrix.compiler.c }}-${{ matrix.arch }}
|
name: cov-thread-1-3-${{ matrix.compiler.c }}-${{ matrix.arch }}
|
||||||
path: tmp/coverage.info
|
path: tmp/coverage.info
|
||||||
|
|
||||||
packet-verification-low-power:
|
packet-verification-low-power:
|
||||||
|
@ -110,7 +110,7 @@ jobs:
|
||||||
VIRTUAL_TIME: 1
|
VIRTUAL_TIME: 1
|
||||||
COVERAGE: 1
|
COVERAGE: 1
|
||||||
PACKET_VERIFICATION: 1
|
PACKET_VERIFICATION: 1
|
||||||
THREAD_VERSION: 1.2
|
THREAD_VERSION: 1.3
|
||||||
MAC_FILTER: 1
|
MAC_FILTER: 1
|
||||||
INTER_OP: 1
|
INTER_OP: 1
|
||||||
INTER_OP_BBR: 0
|
INTER_OP_BBR: 0
|
||||||
|
@ -164,13 +164,13 @@ jobs:
|
||||||
name: cov-packet-verification-low-power
|
name: cov-packet-verification-low-power
|
||||||
path: tmp/coverage.info
|
path: tmp/coverage.info
|
||||||
|
|
||||||
packet-verification-1-1-on-1-2:
|
packet-verification-1-1-on-1-3:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
env:
|
env:
|
||||||
REFERENCE_DEVICE: 1
|
REFERENCE_DEVICE: 1
|
||||||
VIRTUAL_TIME: 1
|
VIRTUAL_TIME: 1
|
||||||
PACKET_VERIFICATION: 1
|
PACKET_VERIFICATION: 1
|
||||||
THREAD_VERSION: 1.2
|
THREAD_VERSION: 1.3
|
||||||
MULTIPLY: 3
|
MULTIPLY: 3
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
@ -193,7 +193,7 @@ jobs:
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
if: ${{ failure() }}
|
if: ${{ failure() }}
|
||||||
with:
|
with:
|
||||||
name: packet-verification-1.1-on-1.2-pcaps
|
name: packet-verification-1.1-on-1.3-pcaps
|
||||||
path: |
|
path: |
|
||||||
*.pcap
|
*.pcap
|
||||||
*.json
|
*.json
|
||||||
|
@ -202,14 +202,14 @@ jobs:
|
||||||
./script/test generate_coverage gcc
|
./script/test generate_coverage gcc
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: cov-packet-verification-1-1-on-1-2
|
name: cov-packet-verification-1-1-on-1-3
|
||||||
path: tmp/coverage.info
|
path: tmp/coverage.info
|
||||||
|
|
||||||
expects:
|
expects:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
env:
|
env:
|
||||||
COVERAGE: 1
|
COVERAGE: 1
|
||||||
THREAD_VERSION: 1.2
|
THREAD_VERSION: 1.3
|
||||||
VIRTUAL_TIME: 0
|
VIRTUAL_TIME: 0
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
@ -232,7 +232,7 @@ jobs:
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
if: ${{ failure() && env.CRASHED == '1' }}
|
if: ${{ failure() && env.CRASHED == '1' }}
|
||||||
with:
|
with:
|
||||||
name: core-expect-1-2
|
name: core-expect-1-3
|
||||||
path: |
|
path: |
|
||||||
./ot-core-dump/*
|
./ot-core-dump/*
|
||||||
- name: Generate Coverage
|
- name: Generate Coverage
|
||||||
|
@ -243,13 +243,13 @@ jobs:
|
||||||
name: cov-expects
|
name: cov-expects
|
||||||
path: tmp/coverage.info
|
path: tmp/coverage.info
|
||||||
|
|
||||||
thread-1-2-posix:
|
thread-1-3-posix:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
env:
|
env:
|
||||||
COVERAGE: 1
|
COVERAGE: 1
|
||||||
PYTHONUNBUFFERED: 1
|
PYTHONUNBUFFERED: 1
|
||||||
READLINE: readline
|
READLINE: readline
|
||||||
THREAD_VERSION: 1.2
|
THREAD_VERSION: 1.3
|
||||||
OT_NODE_TYPE: rcp
|
OT_NODE_TYPE: rcp
|
||||||
USE_MTD: 1
|
USE_MTD: 1
|
||||||
VIRTUAL_TIME: 1
|
VIRTUAL_TIME: 1
|
||||||
|
@ -285,12 +285,12 @@ jobs:
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
if: ${{ failure() }}
|
if: ${{ failure() }}
|
||||||
with:
|
with:
|
||||||
name: thread-1-2-posix-pcaps
|
name: thread-1-3-posix-pcaps
|
||||||
path: "*.pcap"
|
path: "*.pcap"
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
if: ${{ failure() && env.CRASHED == '1' }}
|
if: ${{ failure() && env.CRASHED == '1' }}
|
||||||
with:
|
with:
|
||||||
name: core-thread-1-2-posix
|
name: core-thread-1-3-posix
|
||||||
path: |
|
path: |
|
||||||
./ot-core-dump/*
|
./ot-core-dump/*
|
||||||
- name: Generate Coverage
|
- name: Generate Coverage
|
||||||
|
@ -298,16 +298,16 @@ jobs:
|
||||||
./script/test generate_coverage gcc
|
./script/test generate_coverage gcc
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: cov-thread-1-2-posix
|
name: cov-thread-1-3-posix
|
||||||
path: tmp/coverage.info
|
path: tmp/coverage.info
|
||||||
|
|
||||||
upload-coverage:
|
upload-coverage:
|
||||||
needs:
|
needs:
|
||||||
- thread-1-2
|
- thread-1-3
|
||||||
- packet-verification-low-power
|
- packet-verification-low-power
|
||||||
- packet-verification-1-1-on-1-2
|
- packet-verification-1-1-on-1-3
|
||||||
- expects
|
- expects
|
||||||
- thread-1-2-posix
|
- thread-1-3-posix
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
@ -323,7 +323,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
script/test combine_coverage
|
script/test combine_coverage
|
||||||
- name: Upload Coverage
|
- name: Upload Coverage
|
||||||
uses: codecov/codecov-action@v1
|
uses: codecov/codecov-action@v2
|
||||||
with:
|
with:
|
||||||
files: final.info
|
files: final.info
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
|
|
|
@ -139,7 +139,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
script/test combine_coverage
|
script/test combine_coverage
|
||||||
- name: Upload Coverage
|
- name: Upload Coverage
|
||||||
uses: codecov/codecov-action@v1
|
uses: codecov/codecov-action@v2
|
||||||
with:
|
with:
|
||||||
files: final.info
|
files: final.info
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
|
|
|
@ -220,8 +220,7 @@ LOCAL_SRC_FILES := \
|
||||||
src/core/backbone_router/bbr_manager.cpp \
|
src/core/backbone_router/bbr_manager.cpp \
|
||||||
src/core/backbone_router/multicast_listeners_table.cpp \
|
src/core/backbone_router/multicast_listeners_table.cpp \
|
||||||
src/core/backbone_router/ndproxy_table.cpp \
|
src/core/backbone_router/ndproxy_table.cpp \
|
||||||
src/core/border_router/infra_if_platform.cpp \
|
src/core/border_router/infra_if.cpp \
|
||||||
src/core/border_router/router_advertisement.cpp \
|
|
||||||
src/core/border_router/routing_manager.cpp \
|
src/core/border_router/routing_manager.cpp \
|
||||||
src/core/coap/coap.cpp \
|
src/core/coap/coap.cpp \
|
||||||
src/core/coap/coap_message.cpp \
|
src/core/coap/coap_message.cpp \
|
||||||
|
@ -303,6 +302,7 @@ LOCAL_SRC_FILES := \
|
||||||
src/core/net/ip6_filter.cpp \
|
src/core/net/ip6_filter.cpp \
|
||||||
src/core/net/ip6_headers.cpp \
|
src/core/net/ip6_headers.cpp \
|
||||||
src/core/net/ip6_mpl.cpp \
|
src/core/net/ip6_mpl.cpp \
|
||||||
|
src/core/net/nd6.cpp \
|
||||||
src/core/net/nd_agent.cpp \
|
src/core/net/nd_agent.cpp \
|
||||||
src/core/net/netif.cpp \
|
src/core/net/netif.cpp \
|
||||||
src/core/net/sntp_client.cpp \
|
src/core/net/sntp_client.cpp \
|
||||||
|
|
|
@ -102,12 +102,14 @@ if(OT_PACKAGE_VERSION STREQUAL "")
|
||||||
endif()
|
endif()
|
||||||
message(STATUS "Package Version: ${OT_PACKAGE_VERSION}")
|
message(STATUS "Package Version: ${OT_PACKAGE_VERSION}")
|
||||||
|
|
||||||
set(OT_THREAD_VERSION "1.2" CACHE STRING "Thread version chosen by the user at configure time")
|
set(OT_THREAD_VERSION "1.3" CACHE STRING "Thread version chosen by the user at configure time")
|
||||||
set_property(CACHE OT_THREAD_VERSION PROPERTY STRINGS "1.1" "1.2")
|
set_property(CACHE OT_THREAD_VERSION PROPERTY STRINGS "1.1" "1.2" "1.3")
|
||||||
if(${OT_THREAD_VERSION} EQUAL "1.1")
|
if(${OT_THREAD_VERSION} EQUAL "1.1")
|
||||||
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_1")
|
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_1")
|
||||||
elseif(${OT_THREAD_VERSION} EQUAL "1.2")
|
elseif(${OT_THREAD_VERSION} EQUAL "1.2")
|
||||||
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_2")
|
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_2")
|
||||||
|
elseif(${OT_THREAD_VERSION} EQUAL "1.3")
|
||||||
|
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_3")
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Thread version unknown: ${OT_THREAD_VERSION}")
|
message(FATAL_ERROR "Thread version unknown: ${OT_THREAD_VERSION}")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -59,7 +59,16 @@
|
||||||
* @defgroup api-ip6 IPv6
|
* @defgroup api-ip6 IPv6
|
||||||
* @defgroup api-srp SRP
|
* @defgroup api-srp SRP
|
||||||
* @defgroup api-ping-sender Ping Sender
|
* @defgroup api-ping-sender Ping Sender
|
||||||
|
*
|
||||||
|
* @defgroup api-tcp-group TCP
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*
|
||||||
* @defgroup api-tcp TCP
|
* @defgroup api-tcp TCP
|
||||||
|
* @defgroup api-tcp-ext TCP Abstractions
|
||||||
|
*
|
||||||
|
* @}
|
||||||
|
*
|
||||||
* @defgroup api-udp-group UDP
|
* @defgroup api-udp-group UDP
|
||||||
*
|
*
|
||||||
* @{
|
* @{
|
||||||
|
|
|
@ -360,6 +360,11 @@ if (OT_TREL)
|
||||||
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE=1")
|
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE=1")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
option(OT_TX_BEACON_PAYLOAD "enable Thread beacon payload in outgoing beacons")
|
||||||
|
if (OT_TX_BEACON_PAYLOAD)
|
||||||
|
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_MAC_OUTGOING_BEACON_PAYLOAD_ENABLE=1")
|
||||||
|
endif()
|
||||||
|
|
||||||
option(OT_UDP_FORWARD "enable UDP forward support")
|
option(OT_UDP_FORWARD "enable UDP forward support")
|
||||||
if(OT_UDP_FORWARD)
|
if(OT_UDP_FORWARD)
|
||||||
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1")
|
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1")
|
||||||
|
|
|
@ -37,13 +37,17 @@ if(NOT DEFINED OT_PLATFORM_LIB_RCP)
|
||||||
set(OT_PLATFORM_LIB_RCP ${OT_PLATFORM_LIB})
|
set(OT_PLATFORM_LIB_RCP ${OT_PLATFORM_LIB})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(NOT DEFINED OT_MBEDTLS_RCP)
|
||||||
|
set(OT_MBEDTLS_RCP ${OT_MBEDTLS})
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(ot-cli-radio PRIVATE
|
target_link_libraries(ot-cli-radio PRIVATE
|
||||||
openthread-cli-radio
|
openthread-cli-radio
|
||||||
${OT_PLATFORM_LIB_RCP}
|
${OT_PLATFORM_LIB_RCP}
|
||||||
openthread-radio-cli
|
openthread-radio-cli
|
||||||
${OT_PLATFORM_LIB_RCP}
|
${OT_PLATFORM_LIB_RCP}
|
||||||
openthread-cli-radio
|
openthread-cli-radio
|
||||||
${OT_MBEDTLS}
|
${OT_MBEDTLS_RCP}
|
||||||
ot-config
|
ot-config
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ SLAAC ?= 1
|
||||||
SNTP_CLIENT ?= 0
|
SNTP_CLIENT ?= 0
|
||||||
SRP_CLIENT ?= 0
|
SRP_CLIENT ?= 0
|
||||||
SRP_SERVER ?= 0
|
SRP_SERVER ?= 0
|
||||||
THREAD_VERSION ?= 1.2
|
THREAD_VERSION ?= 1.3
|
||||||
TIME_SYNC ?= 0
|
TIME_SYNC ?= 0
|
||||||
TREL ?= 0
|
TREL ?= 0
|
||||||
UDP_FORWARD ?= 0
|
UDP_FORWARD ?= 0
|
||||||
|
@ -333,6 +333,8 @@ ifeq ($(THREAD_VERSION),1.1)
|
||||||
COMMONCFLAGS += -DOPENTHREAD_CONFIG_THREAD_VERSION=2
|
COMMONCFLAGS += -DOPENTHREAD_CONFIG_THREAD_VERSION=2
|
||||||
else ifeq ($(THREAD_VERSION),1.2)
|
else ifeq ($(THREAD_VERSION),1.2)
|
||||||
COMMONCFLAGS += -DOPENTHREAD_CONFIG_THREAD_VERSION=3
|
COMMONCFLAGS += -DOPENTHREAD_CONFIG_THREAD_VERSION=3
|
||||||
|
else ifeq ($(THREAD_VERSION),1.3)
|
||||||
|
COMMONCFLAGS += -DOPENTHREAD_CONFIG_THREAD_VERSION=4
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(TIME_SYNC),1)
|
ifeq ($(TIME_SYNC),1)
|
||||||
|
|
|
@ -163,10 +163,11 @@ void platformRadioReceive(otInstance *aInstance, uint8_t *aBuf, uint16_t aBufLen
|
||||||
*
|
*
|
||||||
* @param[in,out] aReadFdSet A pointer to the read file descriptors.
|
* @param[in,out] aReadFdSet A pointer to the read file descriptors.
|
||||||
* @param[in,out] aWriteFdSet A pointer to the write file descriptors.
|
* @param[in,out] aWriteFdSet A pointer to the write file descriptors.
|
||||||
|
* @param[in,out] aTimeout A pointer to the timeout.
|
||||||
* @param[in,out] aMaxFd A pointer to the max file descriptor.
|
* @param[in,out] aMaxFd A pointer to the max file descriptor.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMaxFd);
|
void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, struct timeval *aTimeout, int *aMaxFd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function performs radio driver processing.
|
* This function performs radio driver processing.
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "platform-simulation.h"
|
#include "platform-simulation.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <openthread/dataset.h>
|
#include <openthread/dataset.h>
|
||||||
#include <openthread/link.h>
|
#include <openthread/link.h>
|
||||||
|
@ -47,6 +48,9 @@
|
||||||
// The IPv4 group for receiving packets of radio simulation
|
// The IPv4 group for receiving packets of radio simulation
|
||||||
#define OT_RADIO_GROUP "224.0.0.116"
|
#define OT_RADIO_GROUP "224.0.0.116"
|
||||||
|
|
||||||
|
#define MS_PER_S 1000
|
||||||
|
#define US_PER_MS 1000
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
IEEE802154_ACK_LENGTH = 5,
|
IEEE802154_ACK_LENGTH = 5,
|
||||||
|
@ -75,6 +79,10 @@ static uint16_t sPortOffset = 0;
|
||||||
static uint16_t sPort = 0;
|
static uint16_t sPort = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int8_t sEnergyScanResult = OT_RADIO_RSSI_INVALID;
|
||||||
|
static bool sEnergyScanning = false;
|
||||||
|
static uint32_t sEnergyScanEndTime = 0;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
SIM_RADIO_CHANNEL_MIN = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN,
|
SIM_RADIO_CHANNEL_MIN = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN,
|
||||||
|
@ -156,6 +164,13 @@ static otMacKeyMaterial sCurrKey;
|
||||||
static otMacKeyMaterial sNextKey;
|
static otMacKeyMaterial sNextKey;
|
||||||
static otRadioKeyType sKeyType;
|
static otRadioKeyType sKeyType;
|
||||||
|
|
||||||
|
static int8_t GetRssi(uint16_t aChannel);
|
||||||
|
|
||||||
|
static bool IsTimeAfterOrEqual(uint32_t aTimeA, uint32_t aTimeB)
|
||||||
|
{
|
||||||
|
return (aTimeA - aTimeB) < (1U << 31);
|
||||||
|
}
|
||||||
|
|
||||||
static void ReverseExtAddress(otExtAddress *aReversed, const otExtAddress *aOrigin)
|
static void ReverseExtAddress(otExtAddress *aReversed, const otExtAddress *aOrigin)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < sizeof(*aReversed); i++)
|
for (size_t i = 0; i < sizeof(*aReversed); i++)
|
||||||
|
@ -493,20 +508,23 @@ otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
|
||||||
int8_t otPlatRadioGetRssi(otInstance *aInstance)
|
int8_t otPlatRadioGetRssi(otInstance *aInstance)
|
||||||
{
|
{
|
||||||
OT_UNUSED_VARIABLE(aInstance);
|
OT_UNUSED_VARIABLE(aInstance);
|
||||||
|
|
||||||
assert(aInstance != NULL);
|
assert(aInstance != NULL);
|
||||||
|
|
||||||
int8_t rssi = SIM_LOW_RSSI_SAMPLE;
|
return GetRssi(sReceiveFrame.mChannel);
|
||||||
uint8_t channel = sReceiveFrame.mChannel;
|
}
|
||||||
|
|
||||||
|
static int8_t GetRssi(uint16_t aChannel)
|
||||||
|
{
|
||||||
|
int8_t rssi = SIM_LOW_RSSI_SAMPLE;
|
||||||
uint32_t probabilityThreshold;
|
uint32_t probabilityThreshold;
|
||||||
|
|
||||||
otEXPECT((SIM_RADIO_CHANNEL_MIN <= channel) && channel <= (SIM_RADIO_CHANNEL_MAX));
|
otEXPECT((SIM_RADIO_CHANNEL_MIN <= aChannel) && aChannel <= (SIM_RADIO_CHANNEL_MAX));
|
||||||
|
|
||||||
// To emulate a simple interference model, we return either a high or
|
// To emulate a simple interference model, we return either a high or
|
||||||
// a low RSSI value with a fixed probability per each channel. The
|
// a low RSSI value with a fixed probability per each channel. The
|
||||||
// probability is increased per channel by a constant.
|
// probability is increased per channel by a constant.
|
||||||
|
|
||||||
probabilityThreshold = (channel - SIM_RADIO_CHANNEL_MIN) * SIM_HIGH_RSSI_PROB_INC_PER_CHANNEL;
|
probabilityThreshold = (aChannel - SIM_RADIO_CHANNEL_MIN) * SIM_HIGH_RSSI_PROB_INC_PER_CHANNEL;
|
||||||
|
|
||||||
if (otRandomNonCryptoGetUint16() < (probabilityThreshold * 0xffff / 100))
|
if (otRandomNonCryptoGetUint16() < (probabilityThreshold * 0xffff / 100))
|
||||||
{
|
{
|
||||||
|
@ -736,7 +754,7 @@ void platformRadioReceive(otInstance *aInstance, uint8_t *aBuf, uint16_t aBufLen
|
||||||
radioReceive(aInstance);
|
radioReceive(aInstance);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMaxFd)
|
void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, struct timeval *aTimeout, int *aMaxFd)
|
||||||
{
|
{
|
||||||
if (aReadFdSet != NULL && (sState != OT_RADIO_STATE_TRANSMIT || sTxWait))
|
if (aReadFdSet != NULL && (sState != OT_RADIO_STATE_TRANSMIT || sTxWait))
|
||||||
{
|
{
|
||||||
|
@ -757,6 +775,25 @@ void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMax
|
||||||
*aMaxFd = sTxFd;
|
*aMaxFd = sTxFd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sEnergyScanning)
|
||||||
|
{
|
||||||
|
struct timeval tv = {0, 0};
|
||||||
|
uint32_t now = otPlatAlarmMilliGetNow();
|
||||||
|
|
||||||
|
if (IsTimeAfterOrEqual(sEnergyScanEndTime, now))
|
||||||
|
{
|
||||||
|
uint32_t remaining = sEnergyScanEndTime - now;
|
||||||
|
|
||||||
|
tv.tv_sec = remaining / MS_PER_S;
|
||||||
|
tv.tv_usec = (remaining % MS_PER_S) * US_PER_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timercmp(&tv, aTimeout, <))
|
||||||
|
{
|
||||||
|
*aTimeout = tv;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// no need to close in virtual time mode.
|
// no need to close in virtual time mode.
|
||||||
|
@ -811,11 +848,16 @@ void platformRadioProcess(otInstance *aInstance, const fd_set *aReadFdSet, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (platformRadioIsTransmitPending())
|
if (platformRadioIsTransmitPending())
|
||||||
{
|
{
|
||||||
radioSendMessage(aInstance);
|
radioSendMessage(aInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sEnergyScanning && IsTimeAfterOrEqual(otPlatAlarmMilliGetNow(), sEnergyScanEndTime))
|
||||||
|
{
|
||||||
|
sEnergyScanning = false;
|
||||||
|
otPlatRadioEnergyScanDone(aInstance, sEnergyScanResult);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void radioTransmit(struct RadioMessage *aMessage, const struct otRadioFrame *aFrame)
|
void radioTransmit(struct RadioMessage *aMessage, const struct otRadioFrame *aFrame)
|
||||||
|
@ -982,13 +1024,22 @@ otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint1
|
||||||
{
|
{
|
||||||
OT_UNUSED_VARIABLE(aInstance);
|
OT_UNUSED_VARIABLE(aInstance);
|
||||||
OT_UNUSED_VARIABLE(aScanChannel);
|
OT_UNUSED_VARIABLE(aScanChannel);
|
||||||
OT_UNUSED_VARIABLE(aScanDuration);
|
|
||||||
|
otError error = OT_ERROR_NONE;
|
||||||
|
|
||||||
assert(aInstance != NULL);
|
assert(aInstance != NULL);
|
||||||
assert(aScanChannel >= SIM_RADIO_CHANNEL_MIN && aScanChannel <= SIM_RADIO_CHANNEL_MAX);
|
assert(aScanChannel >= SIM_RADIO_CHANNEL_MIN && aScanChannel <= SIM_RADIO_CHANNEL_MAX);
|
||||||
assert(aScanDuration > 0);
|
assert(aScanDuration > 0);
|
||||||
|
|
||||||
return OT_ERROR_NOT_IMPLEMENTED;
|
otEXPECT_ACTION((gRadioCaps & OT_RADIO_CAPS_ENERGY_SCAN), error = OT_ERROR_NOT_IMPLEMENTED);
|
||||||
|
otEXPECT_ACTION(!sEnergyScanning, error = OT_ERROR_BUSY);
|
||||||
|
|
||||||
|
sEnergyScanResult = GetRssi(aScanChannel);
|
||||||
|
sEnergyScanning = true;
|
||||||
|
sEnergyScanEndTime = otPlatAlarmMilliGetNow() + aScanDuration;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
|
otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
|
||||||
|
|
|
@ -70,10 +70,11 @@ static void handleSignal(int aSignal)
|
||||||
*/
|
*/
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
OT_SIM_OPT_HELP = 'h',
|
OT_SIM_OPT_HELP = 'h',
|
||||||
OT_SIM_OPT_SLEEP_TO_TX = 't',
|
OT_SIM_OPT_ENABLE_ENERGY_SCAN = 'E',
|
||||||
OT_SIM_OPT_TIME_SPEED = 's',
|
OT_SIM_OPT_SLEEP_TO_TX = 't',
|
||||||
OT_SIM_OPT_UNKNOWN = '?',
|
OT_SIM_OPT_TIME_SPEED = 's',
|
||||||
|
OT_SIM_OPT_UNKNOWN = '?',
|
||||||
};
|
};
|
||||||
|
|
||||||
static void PrintUsage(const char *aProgramName, int aExitCode)
|
static void PrintUsage(const char *aProgramName, int aExitCode)
|
||||||
|
@ -82,9 +83,10 @@ static void PrintUsage(const char *aProgramName, int aExitCode)
|
||||||
"Syntax:\n"
|
"Syntax:\n"
|
||||||
" %s [Options] NodeId\n"
|
" %s [Options] NodeId\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
" -h --help Display this usage information.\n"
|
" -h --help Display this usage information.\n"
|
||||||
" -t --sleep-to-tx Let radio support direct transition from sleep to TX with CSMA.\n"
|
" -E --enable-energy-scan Enable energy scan capability.\n"
|
||||||
" -s --time-speed=val Speed up the time in simulation.\n",
|
" -t --sleep-to-tx Let radio support direct transition from sleep to TX with CSMA.\n"
|
||||||
|
" -s --time-speed=val Speed up the time in simulation.\n",
|
||||||
aProgramName);
|
aProgramName);
|
||||||
|
|
||||||
exit(aExitCode);
|
exit(aExitCode);
|
||||||
|
@ -97,6 +99,7 @@ void otSysInit(int aArgCount, char *aArgVector[])
|
||||||
|
|
||||||
static const struct option long_options[] = {
|
static const struct option long_options[] = {
|
||||||
{"help", no_argument, 0, OT_SIM_OPT_HELP},
|
{"help", no_argument, 0, OT_SIM_OPT_HELP},
|
||||||
|
{"enable-energy-scan", no_argument, 0, OT_SIM_OPT_SLEEP_TO_TX},
|
||||||
{"sleep-to-tx", no_argument, 0, OT_SIM_OPT_SLEEP_TO_TX},
|
{"sleep-to-tx", no_argument, 0, OT_SIM_OPT_SLEEP_TO_TX},
|
||||||
{"time-speed", required_argument, 0, OT_SIM_OPT_TIME_SPEED},
|
{"time-speed", required_argument, 0, OT_SIM_OPT_TIME_SPEED},
|
||||||
{0, 0, 0, 0},
|
{0, 0, 0, 0},
|
||||||
|
@ -112,7 +115,7 @@ void otSysInit(int aArgCount, char *aArgVector[])
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
int c = getopt_long(aArgCount, aArgVector, "hts:", long_options, NULL);
|
int c = getopt_long(aArgCount, aArgVector, "Ehts:", long_options, NULL);
|
||||||
|
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
{
|
{
|
||||||
|
@ -127,6 +130,9 @@ void otSysInit(int aArgCount, char *aArgVector[])
|
||||||
case OT_SIM_OPT_HELP:
|
case OT_SIM_OPT_HELP:
|
||||||
PrintUsage(aArgVector[0], EXIT_SUCCESS);
|
PrintUsage(aArgVector[0], EXIT_SUCCESS);
|
||||||
break;
|
break;
|
||||||
|
case OT_SIM_OPT_ENABLE_ENERGY_SCAN:
|
||||||
|
gRadioCaps |= OT_RADIO_CAPS_ENERGY_SCAN;
|
||||||
|
break;
|
||||||
case OT_SIM_OPT_SLEEP_TO_TX:
|
case OT_SIM_OPT_SLEEP_TO_TX:
|
||||||
gRadioCaps |= OT_RADIO_CAPS_SLEEP_TO_TX;
|
gRadioCaps |= OT_RADIO_CAPS_SLEEP_TO_TX;
|
||||||
break;
|
break;
|
||||||
|
@ -197,8 +203,8 @@ void otSysProcessDrivers(otInstance *aInstance)
|
||||||
FD_ZERO(&error_fds);
|
FD_ZERO(&error_fds);
|
||||||
|
|
||||||
platformUartUpdateFdSet(&read_fds, &write_fds, &error_fds, &max_fd);
|
platformUartUpdateFdSet(&read_fds, &write_fds, &error_fds, &max_fd);
|
||||||
platformRadioUpdateFdSet(&read_fds, &write_fds, &max_fd);
|
|
||||||
platformAlarmUpdateTimeout(&timeout);
|
platformAlarmUpdateTimeout(&timeout);
|
||||||
|
platformRadioUpdateFdSet(&read_fds, &write_fds, &timeout, &max_fd);
|
||||||
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
|
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
|
||||||
platformTrelUpdateFdSet(&read_fds, &write_fds, &timeout, &max_fd);
|
platformTrelUpdateFdSet(&read_fds, &write_fds, &timeout, &max_fd);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -213,6 +213,17 @@ typedef struct otOperationalDatasetComponents
|
||||||
bool mIsChannelMaskPresent : 1; ///< TRUE if Channel Mask is present, FALSE otherwise.
|
bool mIsChannelMaskPresent : 1; ///< TRUE if Channel Mask is present, FALSE otherwise.
|
||||||
} otOperationalDatasetComponents;
|
} otOperationalDatasetComponents;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This structure represents a Thread Dataset timestamp component.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct otTimestamp
|
||||||
|
{
|
||||||
|
uint64_t mSeconds;
|
||||||
|
uint16_t mTicks;
|
||||||
|
bool mAuthoritative;
|
||||||
|
} otTimestamp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This structure represents an Active or Pending Operational Dataset.
|
* This structure represents an Active or Pending Operational Dataset.
|
||||||
*
|
*
|
||||||
|
@ -221,8 +232,8 @@ typedef struct otOperationalDatasetComponents
|
||||||
*/
|
*/
|
||||||
typedef struct otOperationalDataset
|
typedef struct otOperationalDataset
|
||||||
{
|
{
|
||||||
uint64_t mActiveTimestamp; ///< Active Timestamp
|
otTimestamp mActiveTimestamp; ///< Active Timestamp
|
||||||
uint64_t mPendingTimestamp; ///< Pending Timestamp
|
otTimestamp mPendingTimestamp; ///< Pending Timestamp
|
||||||
otNetworkKey mNetworkKey; ///< Network Key
|
otNetworkKey mNetworkKey; ///< Network Key
|
||||||
otNetworkName mNetworkName; ///< Network Name
|
otNetworkName mNetworkName; ///< Network Name
|
||||||
otExtendedPanId mExtendedPanId; ///< Extended PAN ID
|
otExtendedPanId mExtendedPanId; ///< Extended PAN ID
|
||||||
|
|
|
@ -147,6 +147,22 @@ typedef enum
|
||||||
OT_DNSSD_QUERY_TYPE_RESOLVE_HOST = 3, ///< Service type resolve hostname.
|
OT_DNSSD_QUERY_TYPE_RESOLVE_HOST = 3, ///< Service type resolve hostname.
|
||||||
} otDnssdQueryType;
|
} otDnssdQueryType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This structure contains the counters of DNS-SD server.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct otDnssdCounters
|
||||||
|
{
|
||||||
|
uint32_t mSuccessResponse; ///< The number of successful responses
|
||||||
|
uint32_t mServerFailureResponse; ///< The number of server failure responses
|
||||||
|
uint32_t mFormatErrorResponse; ///< The number of format error responses
|
||||||
|
uint32_t mNameErrorResponse; ///< The number of name error responses
|
||||||
|
uint32_t mNotImplementedResponse; ///< The number of 'not implemented' responses
|
||||||
|
uint32_t mOtherResponse; ///< The number of other responses
|
||||||
|
|
||||||
|
uint32_t mResolvedBySrp; ///< The number of queries completely resolved by the local SRP server
|
||||||
|
} otDnssdCounters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function sets DNS-SD server query callbacks.
|
* This function sets DNS-SD server query callbacks.
|
||||||
*
|
*
|
||||||
|
@ -219,6 +235,16 @@ const otDnssdQuery *otDnssdGetNextQuery(otInstance *aInstance, const otDnssdQuer
|
||||||
*/
|
*/
|
||||||
otDnssdQueryType otDnssdGetQueryTypeAndName(const otDnssdQuery *aQuery, char (*aNameOutput)[OT_DNS_MAX_NAME_SIZE]);
|
otDnssdQueryType otDnssdGetQueryTypeAndName(const otDnssdQuery *aQuery, char (*aNameOutput)[OT_DNS_MAX_NAME_SIZE]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function returns the counters of the DNS-SD server.
|
||||||
|
*
|
||||||
|
* @param[in] aInstance The OpenThread instance structure.
|
||||||
|
*
|
||||||
|
* @returns A pointer to the counters of the DNS-SD server.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const otDnssdCounters *otDnssdGetCounters(otInstance *aInstance);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*
|
*
|
||||||
|
|
|
@ -53,7 +53,7 @@ extern "C" {
|
||||||
* @note This number versions both OpenThread platform and user APIs.
|
* @note This number versions both OpenThread platform and user APIs.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define OPENTHREAD_API_VERSION (207)
|
#define OPENTHREAD_API_VERSION (220)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup api-instance
|
* @addtogroup api-instance
|
||||||
|
|
|
@ -391,6 +391,10 @@ typedef struct otActiveScanResult
|
||||||
unsigned int mVersion : 4; ///< Version
|
unsigned int mVersion : 4; ///< Version
|
||||||
bool mIsNative : 1; ///< Native Commissioner flag
|
bool mIsNative : 1; ///< Native Commissioner flag
|
||||||
bool mDiscover : 1; ///< Result from MLE Discovery
|
bool mDiscover : 1; ///< Result from MLE Discovery
|
||||||
|
|
||||||
|
// Applicable/Required only when beacon payload parsing feature
|
||||||
|
// (`OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE`) is enabled.
|
||||||
|
bool mIsJoinable : 1; ///< Joining Permitted flag
|
||||||
} otActiveScanResult;
|
} otActiveScanResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -486,7 +490,6 @@ bool otLinkIsEnergyScanInProgress(otInstance *aInstance);
|
||||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||||
*
|
*
|
||||||
* @retval OT_ERROR_NONE Successfully enqueued an IEEE 802.15.4 Data Request message.
|
* @retval OT_ERROR_NONE Successfully enqueued an IEEE 802.15.4 Data Request message.
|
||||||
* @retval OT_ERROR_ALREADY An IEEE 802.15.4 Data Request message is already enqueued.
|
|
||||||
* @retval OT_ERROR_INVALID_STATE Device is not in rx-off-when-idle mode.
|
* @retval OT_ERROR_INVALID_STATE Device is not in rx-off-when-idle mode.
|
||||||
* @retval OT_ERROR_NO_BUFS Insufficient message buffers available.
|
* @retval OT_ERROR_NO_BUFS Insufficient message buffers available.
|
||||||
*
|
*
|
||||||
|
|
|
@ -236,6 +236,7 @@ typedef void (*otLinkRawEnergyScanDone)(otInstance *aInstance, int8_t aEnergySca
|
||||||
* @param[in] aCallback A pointer to a function called on completion of a scanned channel.
|
* @param[in] aCallback A pointer to a function called on completion of a scanned channel.
|
||||||
*
|
*
|
||||||
* @retval OT_ERROR_NONE Successfully started scanning the channel.
|
* @retval OT_ERROR_NONE Successfully started scanning the channel.
|
||||||
|
* @retval OT_ERROR_BUSY The radio is performing enery scanning.
|
||||||
* @retval OT_ERROR_NOT_IMPLEMENTED The radio doesn't support energy scanning.
|
* @retval OT_ERROR_NOT_IMPLEMENTED The radio doesn't support energy scanning.
|
||||||
* @retval OT_ERROR_INVALID_STATE If the raw link-layer isn't enabled.
|
* @retval OT_ERROR_INVALID_STATE If the raw link-layer isn't enabled.
|
||||||
*
|
*
|
||||||
|
|
|
@ -192,12 +192,18 @@ void otNetDataUnpublishDnsSrpService(otInstance *aInstance);
|
||||||
*
|
*
|
||||||
* Only stable entries can be published (i.e.,`aConfig.mStable` MUST be TRUE).
|
* Only stable entries can be published (i.e.,`aConfig.mStable` MUST be TRUE).
|
||||||
*
|
*
|
||||||
|
* A subsequent call to this method will replace a previous request for the same prefix. In particular, if the new call
|
||||||
|
* only changes the flags (e.g., preference level) and the prefix is already added in the Network Data, the change to
|
||||||
|
* flags is immediately reflected in the Network Data. This ensures that existing entries in the Network Data are not
|
||||||
|
* abruptly removed. Note that a change in the preference level can potentially later cause the entry to be removed
|
||||||
|
* from the Network Data after determining there are other nodes that are publishing the same prefix with the same or
|
||||||
|
* higher preference.
|
||||||
|
*
|
||||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||||
* @param[in] aConfig The on-mesh prefix config to publish (MUST NOT be NULL).
|
* @param[in] aConfig The on-mesh prefix config to publish (MUST NOT be NULL).
|
||||||
*
|
*
|
||||||
* @retval OT_ERROR_NONE The on-mesh prefix is published successfully.
|
* @retval OT_ERROR_NONE The on-mesh prefix is published successfully.
|
||||||
* @retval OT_ERROR_INVALID_ARGS The @p aConfig is not valid (bad prefix, invalid flag combinations, or not stable).
|
* @retval OT_ERROR_INVALID_ARGS The @p aConfig is not valid (bad prefix, invalid flag combinations, or not stable).
|
||||||
* @retval OT_ERROR_ALREADY An entry with the same prefix is already in the published list.
|
|
||||||
* @retval OT_ERROR_NO_BUFS Could not allocate an entry for the new request. Publisher supports a limited number
|
* @retval OT_ERROR_NO_BUFS Could not allocate an entry for the new request. Publisher supports a limited number
|
||||||
* of entries (shared between on-mesh prefix and external route) determined by config
|
* of entries (shared between on-mesh prefix and external route) determined by config
|
||||||
* `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES`.
|
* `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES`.
|
||||||
|
@ -213,12 +219,18 @@ otError otNetDataPublishOnMeshPrefix(otInstance *aInstance, const otBorderRouter
|
||||||
*
|
*
|
||||||
* Only stable entries can be published (i.e.,`aConfig.mStable` MUST be TRUE).
|
* Only stable entries can be published (i.e.,`aConfig.mStable` MUST be TRUE).
|
||||||
*
|
*
|
||||||
|
* A subsequent call to this method will replace a previous request for the same prefix. In particular, if the new call
|
||||||
|
* only changes the flags (e.g., preference level) and the prefix is already added in the Network Data, the change to
|
||||||
|
* flags is immediately reflected in the Network Data. This ensures that existing entries in the Network Data are not
|
||||||
|
* abruptly removed. Note that a change in the preference level can potentially later cause the entry to be removed
|
||||||
|
* from the Network Data after determining there are other nodes that are publishing the same prefix with the same or
|
||||||
|
* higher preference.
|
||||||
|
*
|
||||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||||
* @param[in] aConfig The external route config to publish (MUST NOT be NULL).
|
* @param[in] aConfig The external route config to publish (MUST NOT be NULL).
|
||||||
*
|
*
|
||||||
* @retval OT_ERROR_NONE The external route is published successfully.
|
* @retval OT_ERROR_NONE The external route is published successfully.
|
||||||
* @retval OT_ERROR_INVALID_ARGS The @p aConfig is not valid (bad prefix, invalid flag combinations, or not stable).
|
* @retval OT_ERROR_INVALID_ARGS The @p aConfig is not valid (bad prefix, invalid flag combinations, or not stable).
|
||||||
* @retval OT_ERROR_ALREADY An entry with the same prefix is already in the published list.
|
|
||||||
* @retval OT_ERROR_NO_BUFS Could not allocate an entry for the new request. Publisher supports a limited number
|
* @retval OT_ERROR_NO_BUFS Could not allocate an entry for the new request. Publisher supports a limited number
|
||||||
* of entries (shared between on-mesh prefix and external route) determined by config
|
* of entries (shared between on-mesh prefix and external route) determined by config
|
||||||
* `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES`.
|
* `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES`.
|
||||||
|
|
|
@ -857,6 +857,7 @@ int8_t otPlatRadioGetRssi(otInstance *aInstance);
|
||||||
* @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned.
|
* @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned.
|
||||||
*
|
*
|
||||||
* @retval OT_ERROR_NONE Successfully started scanning the channel.
|
* @retval OT_ERROR_NONE Successfully started scanning the channel.
|
||||||
|
* @retval OT_ERROR_BUSY The radio is performing enery scanning.
|
||||||
* @retval OT_ERROR_NOT_IMPLEMENTED The radio doesn't support energy scanning.
|
* @retval OT_ERROR_NOT_IMPLEMENTED The radio doesn't support energy scanning.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -55,7 +55,8 @@ extern "C" {
|
||||||
* This enumeration defines the keys of settings.
|
* This enumeration defines the keys of settings.
|
||||||
*
|
*
|
||||||
* Note: When adding a new settings key, if the settings corresponding to the key contains security sensitive
|
* Note: When adding a new settings key, if the settings corresponding to the key contains security sensitive
|
||||||
* information, the developer MUST add the key to the array `kSensitiveKeys`.
|
* information, the developer MUST add the key to the array `aSensitiveKeys` which is passed in
|
||||||
|
* `otPlatSettingsInit()`.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
enum
|
enum
|
||||||
|
@ -65,17 +66,20 @@ enum
|
||||||
OT_SETTINGS_KEY_NETWORK_INFO = 0x0003, ///< Thread network information.
|
OT_SETTINGS_KEY_NETWORK_INFO = 0x0003, ///< Thread network information.
|
||||||
OT_SETTINGS_KEY_PARENT_INFO = 0x0004, ///< Parent information.
|
OT_SETTINGS_KEY_PARENT_INFO = 0x0004, ///< Parent information.
|
||||||
OT_SETTINGS_KEY_CHILD_INFO = 0x0005, ///< Child information.
|
OT_SETTINGS_KEY_CHILD_INFO = 0x0005, ///< Child information.
|
||||||
OT_SETTINGS_KEY_RESERVED = 0x0006, ///< Reserved (previously auto-start).
|
|
||||||
OT_SETTINGS_KEY_SLAAC_IID_SECRET_KEY = 0x0007, ///< SLAAC key to generate semantically opaque IID.
|
OT_SETTINGS_KEY_SLAAC_IID_SECRET_KEY = 0x0007, ///< SLAAC key to generate semantically opaque IID.
|
||||||
OT_SETTINGS_KEY_DAD_INFO = 0x0008, ///< Duplicate Address Detection (DAD) information.
|
OT_SETTINGS_KEY_DAD_INFO = 0x0008, ///< Duplicate Address Detection (DAD) information.
|
||||||
OT_SETTINGS_KEY_LEGACY_OMR_PREFIX = 0x0009, ///< Reserved. Legacy Off-mesh routable (OMR) prefix.
|
|
||||||
OT_SETTINGS_KEY_ON_LINK_PREFIX = 0x000a, ///< On-link prefix for infrastructure link.
|
|
||||||
OT_SETTINGS_KEY_SRP_ECDSA_KEY = 0x000b, ///< SRP client ECDSA public/private key pair.
|
OT_SETTINGS_KEY_SRP_ECDSA_KEY = 0x000b, ///< SRP client ECDSA public/private key pair.
|
||||||
OT_SETTINGS_KEY_SRP_CLIENT_INFO = 0x000c, ///< The SRP client info (selected SRP server address).
|
OT_SETTINGS_KEY_SRP_CLIENT_INFO = 0x000c, ///< The SRP client info (selected SRP server address).
|
||||||
OT_SETTINGS_KEY_SRP_SERVER_INFO = 0x000d, ///< The SRP server info (UDP port).
|
OT_SETTINGS_KEY_SRP_SERVER_INFO = 0x000d, ///< The SRP server info (UDP port).
|
||||||
OT_SETTINGS_KEY_LEGACY_NAT64_PREFIX = 0x000e, ///< Reserved. Legacy NAT64 prefix.
|
|
||||||
OT_SETTINGS_KEY_BR_ULA_PREFIX = 0x000f, ///< BR ULA prefix.
|
OT_SETTINGS_KEY_BR_ULA_PREFIX = 0x000f, ///< BR ULA prefix.
|
||||||
|
|
||||||
|
// Deprecated and reserved key values:
|
||||||
|
//
|
||||||
|
// 0x0006 previously auto-start.
|
||||||
|
// 0x0009 previously OMR prefix.
|
||||||
|
// 0x000a previously on-link prefix.
|
||||||
|
// 0x000e previously NAT64 prefix.
|
||||||
|
|
||||||
// Keys in range 0x8000-0xffff are reserved for vendor-specific use.
|
// Keys in range 0x8000-0xffff are reserved for vendor-specific use.
|
||||||
OT_SETTINGS_KEY_VENDOR_RESERVED_MIN = 0x8000,
|
OT_SETTINGS_KEY_VENDOR_RESERVED_MIN = 0x8000,
|
||||||
OT_SETTINGS_KEY_VENDOR_RESERVED_MAX = 0xffff,
|
OT_SETTINGS_KEY_VENDOR_RESERVED_MAX = 0xffff,
|
||||||
|
@ -104,80 +108,100 @@ void otPlatSettingsInit(otInstance *aInstance, const uint16_t *aSensitiveKeys, u
|
||||||
*/
|
*/
|
||||||
void otPlatSettingsDeinit(otInstance *aInstance);
|
void otPlatSettingsDeinit(otInstance *aInstance);
|
||||||
|
|
||||||
/// Fetches the value of a setting
|
/**
|
||||||
/** This function fetches the value of the setting identified
|
* Fetches the value of a setting.
|
||||||
* by aKey and write it to the memory pointed to by aValue.
|
|
||||||
* It then writes the length to the integer pointed to by
|
|
||||||
* aValueLength. The initial value of aValueLength is the
|
|
||||||
* maximum number of bytes to be written to aValue.
|
|
||||||
*
|
*
|
||||||
* This function can be used to check for the existence of
|
* This function fetches the value of the setting identified
|
||||||
* a key without fetching the value by setting aValue and
|
* by @p aKey and write it to the memory pointed to by aValue.
|
||||||
* aValueLength to NULL. You can also check the length of
|
* It then writes the length to the integer pointed to by
|
||||||
* the setting without fetching it by setting only aValue
|
* @p aValueLength. The initial value of @p aValueLength is the
|
||||||
* to NULL.
|
* maximum number of bytes to be written to @p aValue.
|
||||||
*
|
*
|
||||||
* Note that the underlying storage implementation is not
|
* This function can be used to check for the existence of
|
||||||
* required to maintain the order of settings with multiple
|
* a key without fetching the value by setting @p aValue and
|
||||||
* values. The order of such values MAY change after ANY
|
* @p aValueLength to NULL. You can also check the length of
|
||||||
* write operation to the store.
|
* the setting without fetching it by setting only aValue
|
||||||
|
* to NULL.
|
||||||
*
|
*
|
||||||
* @param[in] aInstance The OpenThread instance structure.
|
* Note that the underlying storage implementation is not
|
||||||
* @param[in] aKey The key associated with the requested setting.
|
* required to maintain the order of settings with multiple
|
||||||
* @param[in] aIndex The index of the specific item to get.
|
* values. The order of such values MAY change after ANY
|
||||||
* @param[out] aValue A pointer to where the value of the setting should be written. May be set to NULL if
|
* write operation to the store.
|
||||||
* just testing for the presence or length of a setting.
|
|
||||||
* @param[in,out] aValueLength A pointer to the length of the value. When called, this pointer should point to an
|
|
||||||
* integer containing the maximum value size that can be written to aValue. At return,
|
|
||||||
* the actual length of the setting is written. This may be set to NULL if performing
|
|
||||||
* a presence check.
|
|
||||||
*
|
*
|
||||||
* @retval OT_ERROR_NONE The given setting was found and fetched successfully.
|
* @param[in] aInstance The OpenThread instance structure.
|
||||||
* @retval OT_ERROR_NOT_FOUND The given setting was not found in the setting store.
|
* @param[in] aKey The key associated with the requested setting.
|
||||||
* @retval OT_ERROR_NOT_IMPLEMENTED This function is not implemented on this platform.
|
* @param[in] aIndex The index of the specific item to get.
|
||||||
|
* @param[out] aValue A pointer to where the value of the setting should be written. May be set to NULL if
|
||||||
|
* just testing for the presence or length of a setting.
|
||||||
|
* @param[in,out] aValueLength A pointer to the length of the value. When called, this pointer should point to an
|
||||||
|
* integer containing the maximum value size that can be written to @p aValue. At return,
|
||||||
|
* the actual length of the setting is written. This may be set to NULL if performing
|
||||||
|
* a presence check.
|
||||||
|
*
|
||||||
|
* @retval OT_ERROR_NONE The given setting was found and fetched successfully.
|
||||||
|
* @retval OT_ERROR_NOT_FOUND The given setting was not found in the setting store.
|
||||||
|
* @retval OT_ERROR_NOT_IMPLEMENTED This function is not implemented on this platform.
|
||||||
*/
|
*/
|
||||||
otError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength);
|
otError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength);
|
||||||
|
|
||||||
/// Sets or replaces the value of a setting
|
/**
|
||||||
/** This function sets or replaces the value of a setting
|
* Sets or replaces the value of a setting.
|
||||||
* identified by aKey. If there was more than one
|
|
||||||
* value previously associated with aKey, then they are
|
|
||||||
* all deleted and replaced with this single entry.
|
|
||||||
*
|
*
|
||||||
* Calling this function successfully may cause unrelated
|
* This function sets or replaces the value of a setting
|
||||||
* settings with multiple values to be reordered.
|
* identified by @p aKey.
|
||||||
*
|
*
|
||||||
* @param[in] aInstance The OpenThread instance structure.
|
* Calling this function successfully may cause unrelated
|
||||||
* @param[in] aKey The key associated with the setting to change.
|
* settings with multiple values to be reordered.
|
||||||
* @param[in] aValue A pointer to where the new value of the setting should be read from. MUST NOT be NULL if
|
|
||||||
* aValueLength is non-zero.
|
|
||||||
* @param[in] aValueLength The length of the data pointed to by aValue. May be zero.
|
|
||||||
*
|
*
|
||||||
* @retval OT_ERROR_NONE The given setting was changed or staged.
|
* OpenThread stack guarantees to use `otPlatSettingsSet()`
|
||||||
* @retval OT_ERROR_NOT_IMPLEMENTED This function is not implemented on this platform.
|
* method for a @p aKey that was either previously set using
|
||||||
* @retval OT_ERROR_NO_BUFS No space remaining to store the given setting.
|
* `otPlatSettingsSet()` (i.e., contains a single value) or
|
||||||
|
* is empty and/or fully deleted (contains no value).
|
||||||
|
*
|
||||||
|
* Platform layer can rely and use this fact for optimizing
|
||||||
|
* its implementation.
|
||||||
|
*
|
||||||
|
* @param[in] aInstance The OpenThread instance structure.
|
||||||
|
* @param[in] aKey The key associated with the setting to change.
|
||||||
|
* @param[in] aValue A pointer to where the new value of the setting should be read from. MUST NOT be NULL if
|
||||||
|
* @p aValueLength is non-zero.
|
||||||
|
* @param[in] aValueLength The length of the data pointed to by aValue. May be zero.
|
||||||
|
*
|
||||||
|
* @retval OT_ERROR_NONE The given setting was changed or staged.
|
||||||
|
* @retval OT_ERROR_NOT_IMPLEMENTED This function is not implemented on this platform.
|
||||||
|
* @retval OT_ERROR_NO_BUFS No space remaining to store the given setting.
|
||||||
*/
|
*/
|
||||||
otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
|
otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
|
||||||
|
|
||||||
/// Adds a value to a setting
|
/**
|
||||||
/** This function adds the value to a setting
|
* Adds a value to a setting.
|
||||||
* identified by aKey, without replacing any existing
|
|
||||||
* values.
|
|
||||||
*
|
*
|
||||||
* Note that the underlying implementation is not required
|
* This function adds the value to a setting
|
||||||
* to maintain the order of the items associated with a
|
* identified by @p aKey, without replacing any existing
|
||||||
* specific key. The added value may be added to the end,
|
* values.
|
||||||
* the beginning, or even somewhere in the middle. The order
|
|
||||||
* of any pre-existing values may also change.
|
|
||||||
*
|
*
|
||||||
* Calling this function successfully may cause unrelated
|
* Note that the underlying implementation is not required
|
||||||
* settings with multiple values to be reordered.
|
* to maintain the order of the items associated with a
|
||||||
|
* specific key. The added value may be added to the end,
|
||||||
|
* the beginning, or even somewhere in the middle. The order
|
||||||
|
* of any pre-existing values may also change.
|
||||||
|
*
|
||||||
|
* Calling this function successfully may cause unrelated
|
||||||
|
* settings with multiple values to be reordered.
|
||||||
|
*
|
||||||
|
* OpenThread stack guarantees to use `otPlatSettingsAdd()`
|
||||||
|
* method for a @p aKey that was either previously managed by
|
||||||
|
* `otPlatSettingsAdd()` (i.e., contains one or more items) or
|
||||||
|
* is empty and/or fully deleted (contains no value).
|
||||||
|
*
|
||||||
|
* Platform layer can rely and use this fact for optimizing
|
||||||
|
* its implementation.
|
||||||
*
|
*
|
||||||
* @param[in] aInstance The OpenThread instance structure.
|
* @param[in] aInstance The OpenThread instance structure.
|
||||||
* @param[in] aKey The key associated with the setting to change.
|
* @param[in] aKey The key associated with the setting to change.
|
||||||
* @param[in] aValue A pointer to where the new value of the setting should be read from. MUST NOT be NULL
|
* @param[in] aValue A pointer to where the new value of the setting should be read from. MUST NOT be NULL
|
||||||
* if aValueLength is non-zero.
|
* if @p aValueLength is non-zero.
|
||||||
* @param[in] aValueLength The length of the data pointed to by aValue. May be zero.
|
* @param[in] aValueLength The length of the data pointed to by @p aValue. May be zero.
|
||||||
*
|
*
|
||||||
* @retval OT_ERROR_NONE The given setting was added or staged to be added.
|
* @retval OT_ERROR_NONE The given setting was added or staged to be added.
|
||||||
* @retval OT_ERROR_NOT_IMPLEMENTED This function is not implemented on this platform.
|
* @retval OT_ERROR_NOT_IMPLEMENTED This function is not implemented on this platform.
|
||||||
|
@ -185,29 +209,34 @@ otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *a
|
||||||
*/
|
*/
|
||||||
otError otPlatSettingsAdd(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
|
otError otPlatSettingsAdd(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
|
||||||
|
|
||||||
/// Removes a setting from the setting store
|
/**
|
||||||
/** This function deletes a specific value from the
|
* Removes a setting from the setting store.
|
||||||
* setting identified by aKey from the settings store.
|
|
||||||
*
|
*
|
||||||
* Note that the underlying implementation is not required
|
* This function deletes a specific value from the
|
||||||
* to maintain the order of the items associated with a
|
* setting identified by aKey from the settings store.
|
||||||
* specific key.
|
|
||||||
*
|
*
|
||||||
* @param[in] aInstance The OpenThread instance structure.
|
* Note that the underlying implementation is not required
|
||||||
* @param[in] aKey The key associated with the requested setting.
|
* to maintain the order of the items associated with a
|
||||||
* @param[in] aIndex The index of the value to be removed. If set to -1, all values for this aKey will be removed.
|
* specific key.
|
||||||
*
|
*
|
||||||
* @retval OT_ERROR_NONE The given key and index was found and removed successfully.
|
* @param[in] aInstance The OpenThread instance structure.
|
||||||
* @retval OT_ERROR_NOT_FOUND The given key or index was not found in the setting store.
|
* @param[in] aKey The key associated with the requested setting.
|
||||||
* @retval OT_ERROR_NOT_IMPLEMENTED This function is not implemented on this platform.
|
* @param[in] aIndex The index of the value to be removed. If set to -1, all values for this @p aKey will be
|
||||||
|
* removed.
|
||||||
|
*
|
||||||
|
* @retval OT_ERROR_NONE The given key and index was found and removed successfully.
|
||||||
|
* @retval OT_ERROR_NOT_FOUND The given key or index was not found in the setting store.
|
||||||
|
* @retval OT_ERROR_NOT_IMPLEMENTED This function is not implemented on this platform.
|
||||||
*/
|
*/
|
||||||
otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex);
|
otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex);
|
||||||
|
|
||||||
/// Removes all settings from the setting store
|
/**
|
||||||
/** This function deletes all settings from the settings
|
* Removes all settings from the setting store.
|
||||||
* store, resetting it to its initial factory state.
|
|
||||||
*
|
*
|
||||||
* @param[in] aInstance The OpenThread instance structure.
|
* This function deletes all settings from the settings
|
||||||
|
* store, resetting it to its initial factory state.
|
||||||
|
*
|
||||||
|
* @param[in] aInstance The OpenThread instance structure.
|
||||||
*/
|
*/
|
||||||
void otPlatSettingsWipe(otInstance *aInstance);
|
void otPlatSettingsWipe(otInstance *aInstance);
|
||||||
|
|
||||||
|
|
|
@ -75,8 +75,9 @@ typedef enum
|
||||||
typedef struct otSrpClientHostInfo
|
typedef struct otSrpClientHostInfo
|
||||||
{
|
{
|
||||||
const char * mName; ///< Host name (label) string (NULL if not yet set).
|
const char * mName; ///< Host name (label) string (NULL if not yet set).
|
||||||
const otIp6Address * mAddresses; ///< Pointer to an array of host IPv6 addresses (NULL if not yet set).
|
const otIp6Address * mAddresses; ///< Array of host IPv6 addresses (NULL if not set or auto address is enabled).
|
||||||
uint8_t mNumAddresses; ///< Number of IPv6 addresses in `mAddresses` array.
|
uint8_t mNumAddresses; ///< Number of IPv6 addresses in `mAddresses` array.
|
||||||
|
bool mAutoAddress; ///< Indicates whether auto address mode is enabled or not.
|
||||||
otSrpClientItemState mState; ///< Host info state.
|
otSrpClientItemState mState; ///< Host info state.
|
||||||
} otSrpClientHostInfo;
|
} otSrpClientHostInfo;
|
||||||
|
|
||||||
|
@ -315,6 +316,34 @@ void otSrpClientDisableAutoStartMode(otInstance *aInstance);
|
||||||
*/
|
*/
|
||||||
bool otSrpClientIsAutoStartModeEnabled(otInstance *aInstance);
|
bool otSrpClientIsAutoStartModeEnabled(otInstance *aInstance);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function gets the TTL value in every record included in SRP update requests.
|
||||||
|
*
|
||||||
|
* Note that this is the TTL requested by the SRP client. The server may choose to accept a different TTL.
|
||||||
|
*
|
||||||
|
* By default, the TTL will equal the lease interval. Passing 0 or a value larger than the lease interval via
|
||||||
|
* `otSrpClientSetTtl()` will also cause the TTL to equal the lease interval.
|
||||||
|
*
|
||||||
|
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||||
|
*
|
||||||
|
* @returns The TTL (in seconds).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t otSrpClientGetTtl(otInstance *aInstance);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function sets the TTL value in every record included in SRP update requests.
|
||||||
|
*
|
||||||
|
* Changing the TTL does not impact the TTL of already registered services/host-info.
|
||||||
|
* It only affects future SRP update messages (i.e., adding new services and/or refreshes of the existing services).
|
||||||
|
*
|
||||||
|
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||||
|
* @param[in] aTtl The TTL (in seconds). If value is zero or greater than lease interval, the TTL is set to the
|
||||||
|
* lease interval.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void otSrpClientSetTtl(otInstance *aInstance, uint32_t aTtl);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function gets the lease interval used in SRP update requests.
|
* This function gets the lease interval used in SRP update requests.
|
||||||
*
|
*
|
||||||
|
@ -400,6 +429,27 @@ const otSrpClientHostInfo *otSrpClientGetHostInfo(otInstance *aInstance);
|
||||||
*/
|
*/
|
||||||
otError otSrpClientSetHostName(otInstance *aInstance, const char *aName);
|
otError otSrpClientSetHostName(otInstance *aInstance, const char *aName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function enables auto host address mode.
|
||||||
|
*
|
||||||
|
* When enabled host IPv6 addresses are automatically set by SRP client using all the unicast addresses on Thread netif
|
||||||
|
* excluding all link-local and mesh-local addresses. If there is no valid address, then Mesh Local EID address is
|
||||||
|
* added. The SRP client will automatically re-register when/if addresses on Thread netif are updated (new addresses
|
||||||
|
* are added or existing addresses are removed).
|
||||||
|
*
|
||||||
|
* The auto host address mode can be enabled before start or during operation of SRP client except when the host info
|
||||||
|
* is being removed (client is busy handling a remove request from an call to `otSrpClientRemoveHostAndServices()` and
|
||||||
|
* host info still being in either `STATE_TO_REMOVE` or `STATE_REMOVING` states).
|
||||||
|
*
|
||||||
|
* After auto host address mode is enabled, it can be disabled by a call to `otSrpClientSetHostAddresses()` which
|
||||||
|
* then explicitly sets the host addresses.
|
||||||
|
*
|
||||||
|
* @retval OT_ERROR_NONE Successfully enabled auto host address mode.
|
||||||
|
* @retval OT_ERROR_INVALID_STATE Host is being removed and therefore cannot enable auto host address mode.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
otError otSrpClientEnableAutoHostAddress(otInstance *aInstance);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function sets/updates the list of host IPv6 address.
|
* This function sets/updates the list of host IPv6 address.
|
||||||
*
|
*
|
||||||
|
@ -414,6 +464,9 @@ otError otSrpClientSetHostName(otInstance *aInstance, const char *aName);
|
||||||
* After a successful call to this function, `otSrpClientCallback` will be called to report the status of the address
|
* After a successful call to this function, `otSrpClientCallback` will be called to report the status of the address
|
||||||
* registration with SRP server.
|
* registration with SRP server.
|
||||||
*
|
*
|
||||||
|
* Calling this function disables auto host address mode if it was previously enabled from a successful call to
|
||||||
|
* `otSrpClientEnableAutoHostAddress()`.
|
||||||
|
*
|
||||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||||
* @param[in] aIp6Addresses A pointer to the an array containing the host IPv6 addresses.
|
* @param[in] aIp6Addresses A pointer to the an array containing the host IPv6 addresses.
|
||||||
* @param[in] aNumAddresses The number of addresses in the @p aIp6Addresses array.
|
* @param[in] aNumAddresses The number of addresses in the @p aIp6Addresses array.
|
||||||
|
|
|
@ -155,6 +155,16 @@ typedef enum otSrpServerAddressMode
|
||||||
OT_SRP_SERVER_ADDRESS_MODE_ANYCAST = 1, ///< Anycast address mode.
|
OT_SRP_SERVER_ADDRESS_MODE_ANYCAST = 1, ///< Anycast address mode.
|
||||||
} otSrpServerAddressMode;
|
} otSrpServerAddressMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This structure includes SRP server TTL configurations.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct otSrpServerTtlConfig
|
||||||
|
{
|
||||||
|
uint32_t mMinTtl; ///< The minimum TTL in seconds.
|
||||||
|
uint32_t mMaxTtl; ///< The maximum TTL in seconds.
|
||||||
|
} otSrpServerTtlConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This structure includes SRP server LEASE and KEY-LEASE configurations.
|
* This structure includes SRP server LEASE and KEY-LEASE configurations.
|
||||||
*
|
*
|
||||||
|
@ -167,6 +177,32 @@ typedef struct otSrpServerLeaseConfig
|
||||||
uint32_t mMaxKeyLease; ///< The maximum KEY-LEASE interval in seconds.
|
uint32_t mMaxKeyLease; ///< The maximum KEY-LEASE interval in seconds.
|
||||||
} otSrpServerLeaseConfig;
|
} otSrpServerLeaseConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This structure includes SRP server lease information of a host/service.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct otSrpServerLeaseInfo
|
||||||
|
{
|
||||||
|
uint32_t mLease; ///< The lease time of a host/service in milliseconds.
|
||||||
|
uint32_t mKeyLease; ///< The key lease time of a host/service in milliseconds.
|
||||||
|
uint32_t mRemainingLease; ///< The remaining lease time of the host/service in milliseconds.
|
||||||
|
uint32_t mRemainingKeyLease; ///< The remaining key lease time of a host/service in milliseconds.
|
||||||
|
} otSrpServerLeaseInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This structure includes the statistics of SRP server responses.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct otSrpServerResponseCounters
|
||||||
|
{
|
||||||
|
uint32_t mSuccess; ///< The number of successful responses.
|
||||||
|
uint32_t mServerFailure; ///< The number of server failure responses.
|
||||||
|
uint32_t mFormatError; ///< The number of format error responses.
|
||||||
|
uint32_t mNameExists; ///< The number of 'name exists' responses.
|
||||||
|
uint32_t mRefused; ///< The number of refused responses.
|
||||||
|
uint32_t mOther; ///< The number of other responses.
|
||||||
|
} otSrpServerResponseCounters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function returns the domain authorized to the SRP server.
|
* This function returns the domain authorized to the SRP server.
|
||||||
*
|
*
|
||||||
|
@ -207,6 +243,16 @@ otError otSrpServerSetDomain(otInstance *aInstance, const char *aDomain);
|
||||||
*/
|
*/
|
||||||
otSrpServerState otSrpServerGetState(otInstance *aInstance);
|
otSrpServerState otSrpServerGetState(otInstance *aInstance);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function returns the port the SRP server is listening to.
|
||||||
|
*
|
||||||
|
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||||
|
*
|
||||||
|
* @returns The port of the SRP server. It returns 0 if the server is not running.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint16_t otSrpServerGetPort(otInstance *aInstance);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function returns the address mode being used by the SRP server.
|
* This function returns the address mode being used by the SRP server.
|
||||||
*
|
*
|
||||||
|
@ -262,6 +308,30 @@ otError otSrpServerSetAnycastModeSequenceNumber(otInstance *aInstance, uint8_t a
|
||||||
*/
|
*/
|
||||||
void otSrpServerSetEnabled(otInstance *aInstance, bool aEnabled);
|
void otSrpServerSetEnabled(otInstance *aInstance, bool aEnabled);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function returns SRP server TTL configuration.
|
||||||
|
*
|
||||||
|
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||||
|
* @param[out] aTtlConfig A pointer to an `otSrpServerTtlConfig` instance.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void otSrpServerGetTtlConfig(otInstance *aInstance, otSrpServerTtlConfig *aTtlConfig);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function sets SRP server TTL configuration.
|
||||||
|
*
|
||||||
|
* The granted TTL will always be no greater than the max lease interval configured via `otSrpServerSetLeaseConfig()`,
|
||||||
|
* regardless of the minimum and maximum TTL configuration.
|
||||||
|
*
|
||||||
|
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||||
|
* @param[in] aTtlConfig A pointer to an `otSrpServerTtlConfig` instance.
|
||||||
|
*
|
||||||
|
* @retval OT_ERROR_NONE Successfully set the TTL configuration.
|
||||||
|
* @retval OT_ERROR_INVALID_ARGS The TTL configuration is not valid.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
otError otSrpServerSetTtlConfig(otInstance *aInstance, const otSrpServerTtlConfig *aTtlConfig);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function returns SRP server LEASE and KEY-LEASE configurations.
|
* This function returns SRP server LEASE and KEY-LEASE configurations.
|
||||||
*
|
*
|
||||||
|
@ -365,6 +435,16 @@ void otSrpServerHandleServiceUpdateResult(otInstance *aInstance, otSrpServerServ
|
||||||
*/
|
*/
|
||||||
const otSrpServerHost *otSrpServerGetNextHost(otInstance *aInstance, const otSrpServerHost *aHost);
|
const otSrpServerHost *otSrpServerGetNextHost(otInstance *aInstance, const otSrpServerHost *aHost);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function returns the response counters of the SRP server.
|
||||||
|
*
|
||||||
|
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||||
|
*
|
||||||
|
* @returns A pointer to the response counters of the SRP server.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const otSrpServerResponseCounters *otSrpServerGetResponseCounters(otInstance *aInstance);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function tells if the SRP service host has been deleted.
|
* This function tells if the SRP service host has been deleted.
|
||||||
*
|
*
|
||||||
|
@ -399,6 +479,15 @@ const char *otSrpServerHostGetFullName(const otSrpServerHost *aHost);
|
||||||
*/
|
*/
|
||||||
const otIp6Address *otSrpServerHostGetAddresses(const otSrpServerHost *aHost, uint8_t *aAddressesNum);
|
const otIp6Address *otSrpServerHostGetAddresses(const otSrpServerHost *aHost, uint8_t *aAddressesNum);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function returns the LEASE and KEY-LEASE information of a given host.
|
||||||
|
*
|
||||||
|
* @param[in] aHost A pointer to the SRP server host.
|
||||||
|
* @param[out] aLeaseInfo A pointer to where to output the LEASE and KEY-LEASE information.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void otSrpServerHostGetLeaseInfo(const otSrpServerHost *aHost, otSrpServerLeaseInfo *aLeaseInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function returns the next service (excluding any sub-type services) of given host.
|
* This function returns the next service (excluding any sub-type services) of given host.
|
||||||
*
|
*
|
||||||
|
@ -562,6 +651,16 @@ uint16_t otSrpServerServiceGetWeight(const otSrpServerService *aService);
|
||||||
*/
|
*/
|
||||||
uint16_t otSrpServerServiceGetPriority(const otSrpServerService *aService);
|
uint16_t otSrpServerServiceGetPriority(const otSrpServerService *aService);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function returns the TTL of the service instance.
|
||||||
|
*
|
||||||
|
* @param[in] aService A pointer to the SRP service.
|
||||||
|
*
|
||||||
|
* @returns The TTL of the service instance..
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t otSrpServerServiceGetTtl(const otSrpServerService *aService);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function returns the TXT record data of the service instance.
|
* This function returns the TXT record data of the service instance.
|
||||||
*
|
*
|
||||||
|
@ -583,6 +682,14 @@ const uint8_t *otSrpServerServiceGetTxtData(const otSrpServerService *aService,
|
||||||
*/
|
*/
|
||||||
const otSrpServerHost *otSrpServerServiceGetHost(const otSrpServerService *aService);
|
const otSrpServerHost *otSrpServerServiceGetHost(const otSrpServerService *aService);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function returns the LEASE and KEY-LEASE information of a given service.
|
||||||
|
*
|
||||||
|
* @param[in] aService A pointer to the SRP server service.
|
||||||
|
* @param[out] aLeaseInfo A pointer to where to output the LEASE and KEY-LEASE information.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void otSrpServerServiceGetLeaseInfo(const otSrpServerService *aService, otSrpServerLeaseInfo *aLeaseInfo);
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*
|
*
|
||||||
|
|
|
@ -194,11 +194,22 @@ typedef struct otThreadParentResponseInfo
|
||||||
bool mIsAttached; ///< Is the node receiving parent response attached
|
bool mIsAttached; ///< Is the node receiving parent response attached
|
||||||
} otThreadParentResponseInfo;
|
} otThreadParentResponseInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This callback informs the application that the detaching process has finished.
|
||||||
|
*
|
||||||
|
* @param[in] aContext A pointer to application-specific context.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef void (*otDetachGracefullyCallback)(void *aContext);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function starts Thread protocol operation.
|
* This function starts Thread protocol operation.
|
||||||
*
|
*
|
||||||
* The interface must be up when calling this function.
|
* The interface must be up when calling this function.
|
||||||
*
|
*
|
||||||
|
* Calling this function with @p aEnabled set to FALSE stops any ongoing processes of detaching started by
|
||||||
|
* otThreadDetachGracefully(). Its callback will be called.
|
||||||
|
*
|
||||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||||
* @param[in] aEnabled TRUE if Thread is enabled, FALSE otherwise.
|
* @param[in] aEnabled TRUE if Thread is enabled, FALSE otherwise.
|
||||||
*
|
*
|
||||||
|
@ -1009,6 +1020,21 @@ otError otThreadSendProactiveBackboneNotification(otInstance * aIns
|
||||||
otIp6InterfaceIdentifier *aMlIid,
|
otIp6InterfaceIdentifier *aMlIid,
|
||||||
uint32_t aTimeSinceLastTransaction);
|
uint32_t aTimeSinceLastTransaction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function notifies other nodes in the network (if any) and then stops Thread protocol operation.
|
||||||
|
*
|
||||||
|
* It sends an Address Release if it's a router, or sets its child timeout to 0 if it's a child.
|
||||||
|
*
|
||||||
|
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||||
|
* @param[in] aCallback A pointer to a function that is called upon finishing detaching.
|
||||||
|
* @param[in] aContext A pointer to callback application-specific context.
|
||||||
|
*
|
||||||
|
* @retval OT_ERROR_NONE Successfully started detaching.
|
||||||
|
* @retval OT_ERROR_BUSY Detaching is already in progress.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
otError otThreadDetachGracefully(otInstance *aInstance, otDetachGracefullyCallback aCallback, void *aContext);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*
|
*
|
||||||
|
|
|
@ -43,7 +43,7 @@ build_cc2538()
|
||||||
"DNS_CLIENT=1"
|
"DNS_CLIENT=1"
|
||||||
"JOINER=1"
|
"JOINER=1"
|
||||||
"SLAAC=1"
|
"SLAAC=1"
|
||||||
# cc2538 does not have enough resources to support Thread 1.2
|
# cc2538 does not have enough resources to support Thread 1.3
|
||||||
"THREAD_VERSION=1.1"
|
"THREAD_VERSION=1.1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ reset_source()
|
||||||
build_cc2538()
|
build_cc2538()
|
||||||
{
|
{
|
||||||
local options=(
|
local options=(
|
||||||
# cc2538 does not have enough resources to support Thread 1.2
|
# cc2538 does not have enough resources to support Thread 1.3
|
||||||
"-DOT_THREAD_VERSION=1.1"
|
"-DOT_THREAD_VERSION=1.1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -43,10 +43,10 @@ main()
|
||||||
ninja -C gn-out
|
ninja -C gn-out
|
||||||
test -f gn-out/obj/src/core/libopenthread-ftd.a
|
test -f gn-out/obj/src/core/libopenthread-ftd.a
|
||||||
|
|
||||||
# Check GN build for OT1.2
|
# Check GN build for OT1.3
|
||||||
rm gn-out -r || true
|
rm gn-out -r || true
|
||||||
mkdir gn-out
|
mkdir gn-out
|
||||||
echo 'openthread_config_thread_version = "1.2"' >gn-out/args.gn
|
echo 'openthread_config_thread_version = "1.3"' >gn-out/args.gn
|
||||||
gn gen --check gn-out
|
gn gen --check gn-out
|
||||||
gn args gn-out --list
|
gn args gn-out --list
|
||||||
ninja -C gn-out
|
ninja -C gn-out
|
||||||
|
|
|
@ -89,9 +89,11 @@ build_all_features()
|
||||||
"-DOPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1"
|
"-DOPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1"
|
||||||
"-DOPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE=1"
|
"-DOPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE=1"
|
||||||
"-DOPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1"
|
"-DOPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1"
|
||||||
|
"-DOPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE=1"
|
||||||
|
"-DOPENTHREAD_CONFIG_MAC_OUTGOING_BEACON_PAYLOAD_ENABLE=1"
|
||||||
)
|
)
|
||||||
|
|
||||||
local options_1_2=(
|
local options_1_3=(
|
||||||
"-DOPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE=1"
|
"-DOPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE=1"
|
||||||
"-DOPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE=1"
|
"-DOPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE=1"
|
||||||
"-DOPENTHREAD_CONFIG_DUA_ENABLE=1"
|
"-DOPENTHREAD_CONFIG_DUA_ENABLE=1"
|
||||||
|
@ -108,15 +110,15 @@ build_all_features()
|
||||||
reset_source
|
reset_source
|
||||||
make -f examples/Makefile-simulation THREAD_VERSION=1.1 FULL_LOGS=1
|
make -f examples/Makefile-simulation THREAD_VERSION=1.1 FULL_LOGS=1
|
||||||
|
|
||||||
# Build Thread 1.2 with full features and logs
|
# Build Thread 1.3 with full features and logs
|
||||||
export CPPFLAGS="${options[*]} ${options_1_2[*]} -DOPENTHREAD_CONFIG_LOG_OUTPUT=OT_LOG_OUTPUT_NONE"
|
export CPPFLAGS="${options[*]} ${options_1_3[*]} -DOPENTHREAD_CONFIG_LOG_OUTPUT=OT_LOG_OUTPUT_NONE"
|
||||||
reset_source
|
reset_source
|
||||||
make -f examples/Makefile-simulation THREAD_VERSION=1.2
|
make -f examples/Makefile-simulation THREAD_VERSION=1.3
|
||||||
|
|
||||||
# Build Thread 1.2 with full features and full logs
|
# Build Thread 1.3 with full features and full logs
|
||||||
export CPPFLAGS="${options[*]} ${options_1_2[*]}"
|
export CPPFLAGS="${options[*]} ${options_1_3[*]}"
|
||||||
reset_source
|
reset_source
|
||||||
make -f examples/Makefile-simulation THREAD_VERSION=1.2 FULL_LOGS=1
|
make -f examples/Makefile-simulation THREAD_VERSION=1.3 FULL_LOGS=1
|
||||||
|
|
||||||
# Build Thread 1.1 with ASSERT disabled
|
# Build Thread 1.1 with ASSERT disabled
|
||||||
export CPPFLAGS="${options[*]} -DOPENTHREAD_CONFIG_ASSERT_ENABLE=0"
|
export CPPFLAGS="${options[*]} -DOPENTHREAD_CONFIG_ASSERT_ENABLE=0"
|
||||||
|
|
|
@ -53,7 +53,7 @@ build_all_features()
|
||||||
-DOT_FTD=OFF \
|
-DOT_FTD=OFF \
|
||||||
-DOT_MTD=OFF
|
-DOT_MTD=OFF
|
||||||
|
|
||||||
# Thread 1.2 options
|
# Thread 1.3 options
|
||||||
local options=(
|
local options=(
|
||||||
"-DOT_BACKBONE_ROUTER=ON"
|
"-DOT_BACKBONE_ROUTER=ON"
|
||||||
"-DOT_BORDER_ROUTING=ON"
|
"-DOT_BORDER_ROUTING=ON"
|
||||||
|
@ -61,18 +61,18 @@ build_all_features()
|
||||||
"-DOT_MLR=ON"
|
"-DOT_MLR=ON"
|
||||||
"-DOT_OTNS=ON"
|
"-DOT_OTNS=ON"
|
||||||
"-DOT_SIMULATION_VIRTUAL_TIME=ON"
|
"-DOT_SIMULATION_VIRTUAL_TIME=ON"
|
||||||
"-DOT_THREAD_VERSION=1.2"
|
"-DOT_THREAD_VERSION=1.3"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Build Thread 1.2 with full features
|
# Build Thread 1.3 with full features
|
||||||
reset_source
|
reset_source
|
||||||
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_DUA=ON
|
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_DUA=ON
|
||||||
|
|
||||||
# Build Thread 1.2 Backbone Router without DUA ND Proxying
|
# Build Thread 1.3 Backbone Router without DUA ND Proxying
|
||||||
reset_source
|
reset_source
|
||||||
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_BACKBONE_ROUTER_DUA_NDPROXYING=OFF
|
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_BACKBONE_ROUTER_DUA_NDPROXYING=OFF
|
||||||
|
|
||||||
# Build Thread 1.2 Backbone Router without Multicast Routing
|
# Build Thread 1.3 Backbone Router without Multicast Routing
|
||||||
reset_source
|
reset_source
|
||||||
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_BACKBONE_ROUTER_MULTICAST_ROUTING=OFF
|
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_BACKBONE_ROUTER_MULTICAST_ROUTING=OFF
|
||||||
|
|
||||||
|
@ -82,11 +82,11 @@ build_all_features()
|
||||||
-DOT_THREAD_VERSION=1.1 \
|
-DOT_THREAD_VERSION=1.1 \
|
||||||
-DOT_VENDOR_EXTENSION=../../src/core/common/extension_example.cpp
|
-DOT_VENDOR_EXTENSION=../../src/core/common/extension_example.cpp
|
||||||
|
|
||||||
# Build Thread 1.2 with no additional features
|
# Build Thread 1.3 with no additional features
|
||||||
reset_source
|
reset_source
|
||||||
"$(dirname "$0")"/cmake-build simulation -DOT_THREAD_VERSION=1.2
|
"$(dirname "$0")"/cmake-build simulation -DOT_THREAD_VERSION=1.3
|
||||||
|
|
||||||
# Build Thread 1.2 with full features and OT_ASSERT=OFF
|
# Build Thread 1.3 with full features and OT_ASSERT=OFF
|
||||||
reset_source
|
reset_source
|
||||||
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_DUA=ON -DOT_ASSERT=OFF
|
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_DUA=ON -DOT_ASSERT=OFF
|
||||||
|
|
||||||
|
|
|
@ -151,9 +151,9 @@ size_nrf52840_version()
|
||||||
|
|
||||||
local thread_version=$1
|
local thread_version=$1
|
||||||
|
|
||||||
if [[ ${thread_version} == "1.2" ]]; then
|
if [[ ${thread_version} != "1.1" ]]; then
|
||||||
options+=(
|
options+=(
|
||||||
"-DOT_THREAD_VERSION=1.2"
|
"-DOT_THREAD_VERSION=1.3"
|
||||||
"-DOT_BACKBONE_ROUTER=ON"
|
"-DOT_BACKBONE_ROUTER=ON"
|
||||||
"-DOT_DUA=ON"
|
"-DOT_DUA=ON"
|
||||||
"-DOT_MLR=ON"
|
"-DOT_MLR=ON"
|
||||||
|
@ -243,7 +243,7 @@ size_nrf52840()
|
||||||
"${reporter}" init OpenThread
|
"${reporter}" init OpenThread
|
||||||
|
|
||||||
size_nrf52840_version 1.1
|
size_nrf52840_version 1.1
|
||||||
size_nrf52840_version 1.2
|
size_nrf52840_version 1.3
|
||||||
|
|
||||||
"${reporter}" post
|
"${reporter}" post
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,7 +121,7 @@ readonly OT_CLANG_TIDY_BUILD_OPTS=(
|
||||||
'-DOT_SNTP_CLIENT=ON'
|
'-DOT_SNTP_CLIENT=ON'
|
||||||
'-DOT_SRP_CLIENT=ON'
|
'-DOT_SRP_CLIENT=ON'
|
||||||
'-DOT_SRP_SERVER=ON'
|
'-DOT_SRP_SERVER=ON'
|
||||||
'-DOT_THREAD_VERSION=1.2'
|
'-DOT_THREAD_VERSION=1.3'
|
||||||
'-DOT_TREL=ON'
|
'-DOT_TREL=ON'
|
||||||
'-DOT_COVERAGE=ON'
|
'-DOT_COVERAGE=ON'
|
||||||
'-DOT_LOG_LEVEL_DYNAMIC=ON'
|
'-DOT_LOG_LEVEL_DYNAMIC=ON'
|
||||||
|
@ -177,7 +177,7 @@ do_clang_tidy_fix()
|
||||||
|
|
||||||
(mkdir -p ./build/cmake-tidy \
|
(mkdir -p ./build/cmake-tidy \
|
||||||
&& cd ./build/cmake-tidy \
|
&& cd ./build/cmake-tidy \
|
||||||
&& THREAD_VERSION=1.2 cmake "${OT_CLANG_TIDY_BUILD_OPTS[@]}" ../.. \
|
&& THREAD_VERSION=1.3 cmake "${OT_CLANG_TIDY_BUILD_OPTS[@]}" ../.. \
|
||||||
&& ../../script/clang-tidy -header-filter='.*' -checks="${OT_CLANG_TIDY_CHECKS}" -j"$OT_BUILD_JOBS" "${OT_CLANG_TIDY_FIX_DIRS[@]}" -fix)
|
&& ../../script/clang-tidy -header-filter='.*' -checks="${OT_CLANG_TIDY_CHECKS}" -j"$OT_BUILD_JOBS" "${OT_CLANG_TIDY_FIX_DIRS[@]}" -fix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ do_clang_tidy_check()
|
||||||
(
|
(
|
||||||
mkdir -p ./build/cmake-tidy \
|
mkdir -p ./build/cmake-tidy \
|
||||||
&& cd ./build/cmake-tidy \
|
&& cd ./build/cmake-tidy \
|
||||||
&& THREAD_VERSION=1.2 cmake "${OT_CLANG_TIDY_BUILD_OPTS[@]}" ../.. \
|
&& THREAD_VERSION=1.3 cmake "${OT_CLANG_TIDY_BUILD_OPTS[@]}" ../.. \
|
||||||
&& ../../script/clang-tidy -header-filter='.*' -checks="${OT_CLANG_TIDY_CHECKS}" -j"$OT_BUILD_JOBS" "${OT_CLANG_TIDY_FIX_DIRS[@]}" \
|
&& ../../script/clang-tidy -header-filter='.*' -checks="${OT_CLANG_TIDY_CHECKS}" -j"$OT_BUILD_JOBS" "${OT_CLANG_TIDY_FIX_DIRS[@]}" \
|
||||||
| grep -v -E "third_party" >output.txt
|
| grep -v -E "third_party" >output.txt
|
||||||
if grep -q "warning: \|error: " output.txt; then
|
if grep -q "warning: \|error: " output.txt; then
|
||||||
|
|
42
script/test
42
script/test
|
@ -42,7 +42,7 @@ readonly OT_COLOR_NONE='\033[0m'
|
||||||
|
|
||||||
readonly OT_NODE_TYPE="${OT_NODE_TYPE:-cli}"
|
readonly OT_NODE_TYPE="${OT_NODE_TYPE:-cli}"
|
||||||
readonly OT_NATIVE_IP="${OT_NATIVE_IP:-0}"
|
readonly OT_NATIVE_IP="${OT_NATIVE_IP:-0}"
|
||||||
readonly THREAD_VERSION="${THREAD_VERSION:-1.2}"
|
readonly THREAD_VERSION="${THREAD_VERSION:-1.3}"
|
||||||
readonly INTER_OP="${INTER_OP:-0}"
|
readonly INTER_OP="${INTER_OP:-0}"
|
||||||
readonly VERBOSE="${VERBOSE:-0}"
|
readonly VERBOSE="${VERBOSE:-0}"
|
||||||
readonly BORDER_ROUTING="${BORDER_ROUTING:-1}"
|
readonly BORDER_ROUTING="${BORDER_ROUTING:-1}"
|
||||||
|
@ -81,7 +81,7 @@ build_simulation()
|
||||||
options+=("-DOT_FULL_LOGS=ON")
|
options+=("-DOT_FULL_LOGS=ON")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ${version} == "1.2" ]]; then
|
if [[ ${version} != "1.1" ]]; then
|
||||||
options+=("-DOT_DUA=ON")
|
options+=("-DOT_DUA=ON")
|
||||||
options+=("-DOT_MLR=ON")
|
options+=("-DOT_MLR=ON")
|
||||||
fi
|
fi
|
||||||
|
@ -90,7 +90,7 @@ build_simulation()
|
||||||
options+=("-DOT_SIMULATION_VIRTUAL_TIME=ON")
|
options+=("-DOT_SIMULATION_VIRTUAL_TIME=ON")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ${version} == "1.2" ]]; then
|
if [[ ${version} != "1.1" ]]; then
|
||||||
options+=("-DOT_CSL_RECEIVER=ON")
|
options+=("-DOT_CSL_RECEIVER=ON")
|
||||||
options+=("-DOT_LINK_METRICS_INITIATOR=ON")
|
options+=("-DOT_LINK_METRICS_INITIATOR=ON")
|
||||||
options+=("-DOT_LINK_METRICS_SUBJECT=ON")
|
options+=("-DOT_LINK_METRICS_SUBJECT=ON")
|
||||||
|
@ -106,7 +106,7 @@ build_simulation()
|
||||||
OT_CMAKE_NINJA_TARGET=ot-rcp OT_CMAKE_BUILD_DIR="${OT_BUILDDIR}/openthread-simulation-${version}" "${OT_SRCDIR}"/script/cmake-build simulation "${options[@]}" "-DOT_SIMULATION_VIRTUAL_TIME_UART=ON"
|
OT_CMAKE_NINJA_TARGET=ot-rcp OT_CMAKE_BUILD_DIR="${OT_BUILDDIR}/openthread-simulation-${version}" "${OT_SRCDIR}"/script/cmake-build simulation "${options[@]}" "-DOT_SIMULATION_VIRTUAL_TIME_UART=ON"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ${version} == "1.2" && ${INTER_OP_BBR} == 1 ]]; then
|
if [[ ${version} != "1.1" && ${INTER_OP_BBR} == 1 ]]; then
|
||||||
|
|
||||||
options+=("-DOT_BACKBONE_ROUTER=ON")
|
options+=("-DOT_BACKBONE_ROUTER=ON")
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ build_posix()
|
||||||
local version="$1"
|
local version="$1"
|
||||||
local options=("-DOT_MESSAGE_USE_HEAP=ON" "-DOT_THREAD_VERSION=${version}" "-DBUILD_TESTING=ON")
|
local options=("-DOT_MESSAGE_USE_HEAP=ON" "-DOT_THREAD_VERSION=${version}" "-DBUILD_TESTING=ON")
|
||||||
|
|
||||||
if [[ ${version} == "1.2" ]]; then
|
if [[ ${version} != "1.1" ]]; then
|
||||||
options+=("-DOT_DUA=ON")
|
options+=("-DOT_DUA=ON")
|
||||||
options+=("-DOT_MLR=ON")
|
options+=("-DOT_MLR=ON")
|
||||||
fi
|
fi
|
||||||
|
@ -147,7 +147,7 @@ build_posix()
|
||||||
|
|
||||||
OT_CMAKE_BUILD_DIR="${OT_BUILDDIR}/openthread-posix-${version}" "${OT_SRCDIR}"/script/cmake-build posix "${options[@]}"
|
OT_CMAKE_BUILD_DIR="${OT_BUILDDIR}/openthread-posix-${version}" "${OT_SRCDIR}"/script/cmake-build posix "${options[@]}"
|
||||||
|
|
||||||
if [[ ${version} == "1.2" && ${INTER_OP_BBR} == 1 ]]; then
|
if [[ ${version} != "1.1" && ${INTER_OP_BBR} == 1 ]]; then
|
||||||
|
|
||||||
options+=("-DOT_BACKBONE_ROUTER=ON")
|
options+=("-DOT_BACKBONE_ROUTER=ON")
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ do_build()
|
||||||
{
|
{
|
||||||
build_for_one_version "${THREAD_VERSION}"
|
build_for_one_version "${THREAD_VERSION}"
|
||||||
|
|
||||||
if [[ ${THREAD_VERSION} == "1.2" && ${INTER_OP} == "1" ]]; then
|
if [[ ${THREAD_VERSION} != "1.1" && ${INTER_OP} == "1" ]]; then
|
||||||
build_for_one_version 1.1
|
build_for_one_version 1.1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -201,8 +201,8 @@ do_unit()
|
||||||
{
|
{
|
||||||
do_unit_version "${THREAD_VERSION}"
|
do_unit_version "${THREAD_VERSION}"
|
||||||
|
|
||||||
if [[ ${THREAD_VERSION} == "1.2" && ${INTER_OP_BBR} == 1 ]]; then
|
if [[ ${THREAD_VERSION} != "1.1" && ${INTER_OP_BBR} == 1 ]]; then
|
||||||
do_unit_version "1.2-bbr"
|
do_unit_version "1.3-bbr"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,8 +220,8 @@ do_cert()
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [[ ${THREAD_VERSION} == "1.2" ]]; then
|
if [[ ${THREAD_VERSION} != "1.1" ]]; then
|
||||||
export top_builddir_1_2_bbr="${OT_BUILDDIR}/openthread-simulation-1.2-bbr"
|
export top_builddir_1_3_bbr="${OT_BUILDDIR}/openthread-simulation-1.3-bbr"
|
||||||
if [[ ${INTER_OP} == "1" ]]; then
|
if [[ ${INTER_OP} == "1" ]]; then
|
||||||
export top_builddir_1_1="${OT_BUILDDIR}/openthread-simulation-1.1"
|
export top_builddir_1_1="${OT_BUILDDIR}/openthread-simulation-1.1"
|
||||||
fi
|
fi
|
||||||
|
@ -238,8 +238,8 @@ do_cert_suite()
|
||||||
{
|
{
|
||||||
export top_builddir="${OT_BUILDDIR}/openthread-simulation-${THREAD_VERSION}"
|
export top_builddir="${OT_BUILDDIR}/openthread-simulation-${THREAD_VERSION}"
|
||||||
|
|
||||||
if [[ ${THREAD_VERSION} == "1.2" ]]; then
|
if [[ ${THREAD_VERSION} != "1.1" ]]; then
|
||||||
export top_builddir_1_2_bbr="${OT_BUILDDIR}/openthread-simulation-1.2-bbr"
|
export top_builddir_1_3_bbr="${OT_BUILDDIR}/openthread-simulation-1.3-bbr"
|
||||||
if [[ ${INTER_OP} == "1" ]]; then
|
if [[ ${INTER_OP} == "1" ]]; then
|
||||||
export top_builddir_1_1="${OT_BUILDDIR}/openthread-simulation-1.1"
|
export top_builddir_1_1="${OT_BUILDDIR}/openthread-simulation-1.1"
|
||||||
fi
|
fi
|
||||||
|
@ -386,7 +386,7 @@ do_expect()
|
||||||
test_patterns=(-name 'tun-*.exp')
|
test_patterns=(-name 'tun-*.exp')
|
||||||
else
|
else
|
||||||
test_patterns=(-name 'posix-*.exp' -o -name 'cli-*.exp')
|
test_patterns=(-name 'posix-*.exp' -o -name 'cli-*.exp')
|
||||||
if [[ ${THREAD_VERSION} == "1.2" ]]; then
|
if [[ ${THREAD_VERSION} != "1.1" ]]; then
|
||||||
test_patterns+=(-o -name 'v1_2-*.exp')
|
test_patterns+=(-o -name 'v1_2-*.exp')
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -421,9 +421,9 @@ ENVIRONMENTS:
|
||||||
VERBOSE 1 to build or test verbosely. The default is 0.
|
VERBOSE 1 to build or test verbosely. The default is 0.
|
||||||
VIRTUAL_TIME 1 for virtual time, otherwise real time. The default value is 0 when running expect tests,
|
VIRTUAL_TIME 1 for virtual time, otherwise real time. The default value is 0 when running expect tests,
|
||||||
otherwise default value is 1.
|
otherwise default value is 1.
|
||||||
THREAD_VERSION 1.1 for Thread 1.1 stack, 1.2 for Thread 1.2 stack. The default is 1.2.
|
THREAD_VERSION 1.1 for Thread 1.1 stack, 1.3 for Thread 1.3 stack. The default is 1.3.
|
||||||
INTER_OP 1 to build 1.1 together. Only works when THREAD_VERSION is 1.2. The default is 0.
|
INTER_OP 1 to build 1.1 together. Only works when THREAD_VERSION is 1.3. The default is 0.
|
||||||
INTER_OP_BBR 1 to build bbr version together. Only works when THREAD_VERSION is 1.2. The default is 1.
|
INTER_OP_BBR 1 to build bbr version together. Only works when THREAD_VERSION is 1.3. The default is 1.
|
||||||
|
|
||||||
COMMANDS:
|
COMMANDS:
|
||||||
clean Clean built files to prepare for new build.
|
clean Clean built files to prepare for new build.
|
||||||
|
@ -455,7 +455,7 @@ EXAMPLES:
|
||||||
THREAD_VERSION=1.1 VIRTUAL_TIME=0 $0 clean build cert tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py
|
THREAD_VERSION=1.1 VIRTUAL_TIME=0 $0 clean build cert tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py
|
||||||
THREAD_VERSION=1.1 VIRTUAL_TIME=0 $0 cert tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py
|
THREAD_VERSION=1.1 VIRTUAL_TIME=0 $0 cert tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py
|
||||||
|
|
||||||
# Test Thread 1.2 with real time, use 'INTER_OP=1' when the case needs both versions.
|
# Test Thread 1.3 with real time, use 'INTER_OP=1' when the case needs both versions.
|
||||||
VIRTUAL_TIME=0 $0 clean build cert tests/scripts/thread-cert/v1_2_test_enhanced_keep_alive.py
|
VIRTUAL_TIME=0 $0 clean build cert tests/scripts/thread-cert/v1_2_test_enhanced_keep_alive.py
|
||||||
INTER_OP=1 VIRTUAL_TIME=0 $0 clean build cert tests/scripts/thread-cert/v1_2_router_5_1_1.py
|
INTER_OP=1 VIRTUAL_TIME=0 $0 clean build cert tests/scripts/thread-cert/v1_2_router_5_1_1.py
|
||||||
INTER_OP=1 VIRTUAL_TIME=0 $0 clean build cert_suite tests/scripts/thread-cert/v1_2_*
|
INTER_OP=1 VIRTUAL_TIME=0 $0 clean build cert_suite tests/scripts/thread-cert/v1_2_*
|
||||||
|
@ -559,10 +559,10 @@ envsetup()
|
||||||
export RADIO_DEVICE="${OT_BUILDDIR}/openthread-simulation-${THREAD_VERSION}/examples/apps/ncp/ot-rcp"
|
export RADIO_DEVICE="${OT_BUILDDIR}/openthread-simulation-${THREAD_VERSION}/examples/apps/ncp/ot-rcp"
|
||||||
export OT_CLI_PATH="${OT_BUILDDIR}/openthread-posix-${THREAD_VERSION}/src/posix/ot-cli"
|
export OT_CLI_PATH="${OT_BUILDDIR}/openthread-posix-${THREAD_VERSION}/src/posix/ot-cli"
|
||||||
|
|
||||||
if [[ ${THREAD_VERSION} == "1.2" ]]; then
|
if [[ ${THREAD_VERSION} != "1.1" ]]; then
|
||||||
export RADIO_DEVICE_1_1="${OT_BUILDDIR}/openthread-simulation-1.1/examples/apps/ncp/ot-rcp"
|
export RADIO_DEVICE_1_1="${OT_BUILDDIR}/openthread-simulation-1.1/examples/apps/ncp/ot-rcp"
|
||||||
export OT_CLI_PATH_1_1="${OT_BUILDDIR}/openthread-posix-1.1/src/posix/ot-cli"
|
export OT_CLI_PATH_1_1="${OT_BUILDDIR}/openthread-posix-1.1/src/posix/ot-cli"
|
||||||
export OT_CLI_PATH_1_2_BBR="${OT_BUILDDIR}/openthread-posix-1.2-bbr/src/posix/ot-cli"
|
export OT_CLI_PATH_BBR="${OT_BUILDDIR}/openthread-posix-1.3-bbr/src/posix/ot-cli"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -606,7 +606,7 @@ main()
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[[ ${VIRTUAL_TIME} == 1 ]] && echo "Using virtual time" || echo "Using real time"
|
[[ ${VIRTUAL_TIME} == 1 ]] && echo "Using virtual time" || echo "Using real time"
|
||||||
[[ ${THREAD_VERSION} == "1.2" ]] && echo "Using Thread 1.2 stack" || echo "Using Thread 1.1 stack"
|
[[ ${THREAD_VERSION} != "1.1" ]] && echo "Using Thread 1.3 stack" || echo "Using Thread 1.1 stack"
|
||||||
|
|
||||||
while [[ $# != 0 ]]; do
|
while [[ $# != 0 ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
|
|
|
@ -62,7 +62,6 @@ Done
|
||||||
- [leaderdata](#leaderdata)
|
- [leaderdata](#leaderdata)
|
||||||
- [leaderweight](#leaderweight)
|
- [leaderweight](#leaderweight)
|
||||||
- [linkmetrics](#linkmetrics-mgmt-ipaddr-enhanced-ack-clear)
|
- [linkmetrics](#linkmetrics-mgmt-ipaddr-enhanced-ack-clear)
|
||||||
- [linkquality](#linkquality-extaddr)
|
|
||||||
- [locate](#locate)
|
- [locate](#locate)
|
||||||
- [log](#log-filename-filename)
|
- [log](#log-filename-filename)
|
||||||
- [mac](#mac-retries-direct)
|
- [mac](#mac-retries-direct)
|
||||||
|
@ -1627,25 +1626,6 @@ Done
|
||||||
- RSSI: -18 (dBm) (Exponential Moving Average)
|
- RSSI: -18 (dBm) (Exponential Moving Average)
|
||||||
```
|
```
|
||||||
|
|
||||||
### linkquality \<extaddr\>
|
|
||||||
|
|
||||||
Get the link quality on the link to a given extended address.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
> linkquality 36c1dd7a4f5201ff
|
|
||||||
3
|
|
||||||
Done
|
|
||||||
```
|
|
||||||
|
|
||||||
### linkquality \<extaddr\> \<linkquality\>
|
|
||||||
|
|
||||||
Set the link quality on the link to a given extended address.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
> linkquality 36c1dd7a4f5201ff 3
|
|
||||||
Done
|
|
||||||
```
|
|
||||||
|
|
||||||
### locate
|
### locate
|
||||||
|
|
||||||
Gets the current state (`In Progress` or `Idle`) of anycast locator.
|
Gets the current state (`In Progress` or `Idle`) of anycast locator.
|
||||||
|
|
|
@ -196,7 +196,7 @@ Done
|
||||||
|
|
||||||
Usage: `dataset activetimestamp [timestamp]`
|
Usage: `dataset activetimestamp [timestamp]`
|
||||||
|
|
||||||
Get active timestamp.
|
Get active timestamp seconds.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
> dataset activetimestamp
|
> dataset activetimestamp
|
||||||
|
@ -204,7 +204,7 @@ Get active timestamp.
|
||||||
Done
|
Done
|
||||||
```
|
```
|
||||||
|
|
||||||
Set active timestamp.
|
Set active timestamp seconds.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
> dataset activetimestamp 123456789
|
> dataset activetimestamp 123456789
|
||||||
|
@ -457,7 +457,7 @@ Done
|
||||||
|
|
||||||
Usage: `dataset pendingtimestamp [timestamp]`
|
Usage: `dataset pendingtimestamp [timestamp]`
|
||||||
|
|
||||||
Get pending timestamp.
|
Get pending timestamp seconds.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
> dataset pendingtimestamp
|
> dataset pendingtimestamp
|
||||||
|
@ -465,7 +465,7 @@ Get pending timestamp.
|
||||||
Done
|
Done
|
||||||
```
|
```
|
||||||
|
|
||||||
Set pending timestamp.
|
Set pending timestamp seconds.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
> dataset pendingtimestamp 123456789
|
> dataset pendingtimestamp 123456789
|
||||||
|
|
|
@ -15,6 +15,7 @@ Usage : `srp client [command] ...`
|
||||||
- [start](#start)
|
- [start](#start)
|
||||||
- [state](#state)
|
- [state](#state)
|
||||||
- [stop](#stop)
|
- [stop](#stop)
|
||||||
|
- [ttl](#ttl)
|
||||||
|
|
||||||
## Command Details
|
## Command Details
|
||||||
|
|
||||||
|
@ -36,6 +37,7 @@ service
|
||||||
start
|
start
|
||||||
state
|
state
|
||||||
stop
|
stop
|
||||||
|
ttl
|
||||||
Done
|
Done
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -137,6 +139,14 @@ name:"dev4312", state:Registered, addrs:[fd00:0:0:0:0:0:0:1234, fd00:0:0:0:0:0:0
|
||||||
Done
|
Done
|
||||||
```
|
```
|
||||||
|
|
||||||
|
When auto host address mode is enabled.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
srp client host
|
||||||
|
name:"dev1234", state:Registered, addrs:auto
|
||||||
|
Done
|
||||||
|
```
|
||||||
|
|
||||||
### host name
|
### host name
|
||||||
|
|
||||||
Usage: `srp client host name [name]`
|
Usage: `srp client host name [name]`
|
||||||
|
@ -158,9 +168,17 @@ Done
|
||||||
|
|
||||||
### host address
|
### host address
|
||||||
|
|
||||||
Usage : `srp client host address [<address> ...]`
|
Usage : `srp client host address [auto | <address> ...]`
|
||||||
|
|
||||||
Get the list of host addresses.
|
Indicate auto address mode is enabled.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
> srp client host address
|
||||||
|
auto
|
||||||
|
Done
|
||||||
|
```
|
||||||
|
|
||||||
|
Get the list of host addresses (when auto host address is not enabled).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
> srp client host address
|
> srp client host address
|
||||||
|
@ -169,7 +187,14 @@ fd00:0:0:0:0:0:0:beef
|
||||||
Done
|
Done
|
||||||
```
|
```
|
||||||
|
|
||||||
Set the list of host addresses (can be set while client is running to update the host addresses)
|
Enable auto host address mode. When enabled client will automatically use all Thread netif unicast addresses excluding all link-local and mesh-local addresses. If there is no valid address, then Mesh Local EID address is added. SRP client will automatically re-register if/when addresses on Thread netif get changed (e.g., new address is added or existing address is removed).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
> srp client host address auto
|
||||||
|
Done
|
||||||
|
```
|
||||||
|
|
||||||
|
Explicitly set the list of host addresses (can be set while client is running to update the host addresses), also disabled auto host address mode.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
> srp client host address fd00::cafe
|
> srp client host address fd00::cafe
|
||||||
|
@ -409,3 +434,23 @@ Stop the SRP client.
|
||||||
> srp client stop
|
> srp client stop
|
||||||
Done
|
Done
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### ttl
|
||||||
|
|
||||||
|
Usage: `srp client ttl [value]`
|
||||||
|
|
||||||
|
Get the TTL (in seconds).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
> srp client ttl
|
||||||
|
7200
|
||||||
|
Done
|
||||||
|
>
|
||||||
|
```
|
||||||
|
|
||||||
|
Set the TTL.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
> srp client ttl 3600
|
||||||
|
Done
|
||||||
|
```
|
||||||
|
|
|
@ -1453,6 +1453,25 @@ exit:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template <> otError Interpreter::Process<Cmd("detach")>(Arg aArgs[])
|
||||||
|
{
|
||||||
|
otError error = OT_ERROR_NONE;
|
||||||
|
|
||||||
|
if (aArgs[0] == "async")
|
||||||
|
{
|
||||||
|
SuccessOrExit(error = otThreadDetachGracefully(GetInstancePtr(), nullptr, nullptr));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SuccessOrExit(error =
|
||||||
|
otThreadDetachGracefully(GetInstancePtr(), &Interpreter::HandleDetachGracefullyResult, this));
|
||||||
|
error = OT_ERROR_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
template <> otError Interpreter::Process<Cmd("discover")>(Arg aArgs[])
|
template <> otError Interpreter::Process<Cmd("discover")>(Arg aArgs[])
|
||||||
{
|
{
|
||||||
otError error = OT_ERROR_NONE;
|
otError error = OT_ERROR_NONE;
|
||||||
|
@ -4903,6 +4922,17 @@ void Interpreter::OutputChildTableEntry(uint8_t aIndentSize, const otNetworkDiag
|
||||||
}
|
}
|
||||||
#endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
|
#endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
|
||||||
|
|
||||||
|
void Interpreter::HandleDetachGracefullyResult(void *aContext)
|
||||||
|
{
|
||||||
|
static_cast<Interpreter *>(aContext)->HandleDetachGracefullyResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Interpreter::HandleDetachGracefullyResult(void)
|
||||||
|
{
|
||||||
|
OutputLine("Finished detaching");
|
||||||
|
OutputResult(OT_ERROR_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
void Interpreter::HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo &aInfo)
|
void Interpreter::HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo &aInfo)
|
||||||
{
|
{
|
||||||
OutputFormat("~ Discovery Request from ");
|
OutputFormat("~ Discovery Request from ");
|
||||||
|
@ -5017,6 +5047,7 @@ otError Interpreter::ProcessCommand(Arg aArgs[])
|
||||||
#if OPENTHREAD_FTD
|
#if OPENTHREAD_FTD
|
||||||
CmdEntry("delaytimermin"),
|
CmdEntry("delaytimermin"),
|
||||||
#endif
|
#endif
|
||||||
|
CmdEntry("detach"),
|
||||||
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
|
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||||
#if OPENTHREAD_CONFIG_DIAG_ENABLE
|
#if OPENTHREAD_CONFIG_DIAG_ENABLE
|
||||||
CmdEntry("diag"),
|
CmdEntry("diag"),
|
||||||
|
|
|
@ -452,6 +452,9 @@ private:
|
||||||
const char *LinkMetricsStatusToStr(uint8_t aStatus);
|
const char *LinkMetricsStatusToStr(uint8_t aStatus);
|
||||||
#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
|
#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
|
||||||
|
|
||||||
|
static void HandleDetachGracefullyResult(void *aContext);
|
||||||
|
void HandleDetachGracefullyResult(void);
|
||||||
|
|
||||||
static void HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo *aInfo, void *aContext)
|
static void HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo *aInfo, void *aContext)
|
||||||
{
|
{
|
||||||
static_cast<Interpreter *>(aContext)->HandleDiscoveryRequest(*aInfo);
|
static_cast<Interpreter *>(aContext)->HandleDiscoveryRequest(*aInfo);
|
||||||
|
|
|
@ -51,12 +51,12 @@ otError Dataset::Print(otOperationalDataset &aDataset)
|
||||||
{
|
{
|
||||||
if (aDataset.mComponents.mIsPendingTimestampPresent)
|
if (aDataset.mComponents.mIsPendingTimestampPresent)
|
||||||
{
|
{
|
||||||
OutputLine("Pending Timestamp: %lu", aDataset.mPendingTimestamp);
|
OutputLine("Pending Timestamp: %lu", aDataset.mPendingTimestamp.mSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aDataset.mComponents.mIsActiveTimestampPresent)
|
if (aDataset.mComponents.mIsActiveTimestampPresent)
|
||||||
{
|
{
|
||||||
OutputLine("Active Timestamp: %lu", aDataset.mActiveTimestamp);
|
OutputLine("Active Timestamp: %lu", aDataset.mActiveTimestamp.mSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aDataset.mComponents.mIsChannelPresent)
|
if (aDataset.mComponents.mIsChannelPresent)
|
||||||
|
@ -205,12 +205,14 @@ template <> otError Dataset::Process<Cmd("activetimestamp")>(Arg aArgs[])
|
||||||
{
|
{
|
||||||
if (sDataset.mComponents.mIsActiveTimestampPresent)
|
if (sDataset.mComponents.mIsActiveTimestampPresent)
|
||||||
{
|
{
|
||||||
OutputLine("%lu", sDataset.mActiveTimestamp);
|
OutputLine("%lu", sDataset.mActiveTimestamp.mSeconds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SuccessOrExit(error = aArgs[0].ParseAsUint64(sDataset.mActiveTimestamp));
|
SuccessOrExit(error = aArgs[0].ParseAsUint64(sDataset.mActiveTimestamp.mSeconds));
|
||||||
|
sDataset.mActiveTimestamp.mTicks = 0;
|
||||||
|
sDataset.mActiveTimestamp.mAuthoritative = false;
|
||||||
sDataset.mComponents.mIsActiveTimestampPresent = true;
|
sDataset.mComponents.mIsActiveTimestampPresent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,12 +425,14 @@ template <> otError Dataset::Process<Cmd("pendingtimestamp")>(Arg aArgs[])
|
||||||
{
|
{
|
||||||
if (sDataset.mComponents.mIsPendingTimestampPresent)
|
if (sDataset.mComponents.mIsPendingTimestampPresent)
|
||||||
{
|
{
|
||||||
OutputLine("%lu", sDataset.mPendingTimestamp);
|
OutputLine("%lu", sDataset.mPendingTimestamp.mSeconds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SuccessOrExit(error = aArgs[0].ParseAsUint64(sDataset.mPendingTimestamp));
|
SuccessOrExit(error = aArgs[0].ParseAsUint64(sDataset.mPendingTimestamp.mSeconds));
|
||||||
|
sDataset.mPendingTimestamp.mTicks = 0;
|
||||||
|
sDataset.mPendingTimestamp.mAuthoritative = false;
|
||||||
sDataset.mComponents.mIsPendingTimestampPresent = true;
|
sDataset.mComponents.mIsPendingTimestampPresent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,14 +454,18 @@ template <> otError Dataset::Process<Cmd("mgmtsetcommand")>(Arg aArgs[])
|
||||||
if (*arg == "activetimestamp")
|
if (*arg == "activetimestamp")
|
||||||
{
|
{
|
||||||
arg++;
|
arg++;
|
||||||
|
SuccessOrExit(error = arg->ParseAsUint64(dataset.mActiveTimestamp.mSeconds));
|
||||||
|
dataset.mActiveTimestamp.mTicks = 0;
|
||||||
|
dataset.mActiveTimestamp.mAuthoritative = false;
|
||||||
dataset.mComponents.mIsActiveTimestampPresent = true;
|
dataset.mComponents.mIsActiveTimestampPresent = true;
|
||||||
SuccessOrExit(error = arg->ParseAsUint64(dataset.mActiveTimestamp));
|
|
||||||
}
|
}
|
||||||
else if (*arg == "pendingtimestamp")
|
else if (*arg == "pendingtimestamp")
|
||||||
{
|
{
|
||||||
arg++;
|
arg++;
|
||||||
|
SuccessOrExit(error = arg->ParseAsUint64(dataset.mPendingTimestamp.mSeconds));
|
||||||
|
dataset.mPendingTimestamp.mTicks = 0;
|
||||||
|
dataset.mPendingTimestamp.mAuthoritative = false;
|
||||||
dataset.mComponents.mIsPendingTimestampPresent = true;
|
dataset.mComponents.mIsPendingTimestampPresent = true;
|
||||||
SuccessOrExit(error = arg->ParseAsUint64(dataset.mPendingTimestamp));
|
|
||||||
}
|
}
|
||||||
else if (*arg == "networkkey")
|
else if (*arg == "networkkey")
|
||||||
{
|
{
|
||||||
|
|
|
@ -160,10 +160,21 @@ template <> otError SrpClient::Process<Cmd("host")>(Arg aArgs[])
|
||||||
{
|
{
|
||||||
const otSrpClientHostInfo *hostInfo = otSrpClientGetHostInfo(GetInstancePtr());
|
const otSrpClientHostInfo *hostInfo = otSrpClientGetHostInfo(GetInstancePtr());
|
||||||
|
|
||||||
for (uint8_t index = 0; index < hostInfo->mNumAddresses; index++)
|
if (hostInfo->mAutoAddress)
|
||||||
{
|
{
|
||||||
OutputIp6AddressLine(hostInfo->mAddresses[index]);
|
OutputLine("auto");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (uint8_t index = 0; index < hostInfo->mNumAddresses; index++)
|
||||||
|
{
|
||||||
|
OutputIp6AddressLine(hostInfo->mAddresses[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (aArgs[1] == "auto")
|
||||||
|
{
|
||||||
|
error = otSrpClientEnableAutoHostAddress(GetInstancePtr());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -447,19 +458,28 @@ void SrpClient::OutputHostInfo(uint8_t aIndentSize, const otSrpClientHostInfo &a
|
||||||
OutputFormat("(null)");
|
OutputFormat("(null)");
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputFormat(", state:%s, addrs:[", otSrpClientItemStateToString(aHostInfo.mState));
|
OutputFormat(", state:%s, addrs:", otSrpClientItemStateToString(aHostInfo.mState));
|
||||||
|
|
||||||
for (uint8_t index = 0; index < aHostInfo.mNumAddresses; index++)
|
if (aHostInfo.mAutoAddress)
|
||||||
{
|
{
|
||||||
if (index > 0)
|
OutputLine("auto");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OutputFormat("[");
|
||||||
|
|
||||||
|
for (uint8_t index = 0; index < aHostInfo.mNumAddresses; index++)
|
||||||
{
|
{
|
||||||
OutputFormat(", ");
|
if (index > 0)
|
||||||
|
{
|
||||||
|
OutputFormat(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputIp6Address(aHostInfo.mAddresses[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputIp6Address(aHostInfo.mAddresses[index]);
|
OutputLine("]");
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputLine("]");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrpClient::OutputServiceList(uint8_t aIndentSize, const otSrpClientService *aServices)
|
void SrpClient::OutputServiceList(uint8_t aIndentSize, const otSrpClientService *aServices)
|
||||||
|
@ -525,6 +545,11 @@ exit:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <> otError SrpClient::Process<Cmd("ttl")>(Arg aArgs[])
|
||||||
|
{
|
||||||
|
return Interpreter::GetInterpreter().ProcessGetSet(aArgs, otSrpClientGetTtl, otSrpClientSetTtl);
|
||||||
|
}
|
||||||
|
|
||||||
void SrpClient::HandleCallback(otError aError,
|
void SrpClient::HandleCallback(otError aError,
|
||||||
const otSrpClientHostInfo *aHostInfo,
|
const otSrpClientHostInfo *aHostInfo,
|
||||||
const otSrpClientService * aServices,
|
const otSrpClientService * aServices,
|
||||||
|
@ -578,7 +603,7 @@ otError SrpClient::Process(Arg aArgs[])
|
||||||
static constexpr Command kCommands[] = {
|
static constexpr Command kCommands[] = {
|
||||||
CmdEntry("autostart"), CmdEntry("callback"), CmdEntry("host"), CmdEntry("keyleaseinterval"),
|
CmdEntry("autostart"), CmdEntry("callback"), CmdEntry("host"), CmdEntry("keyleaseinterval"),
|
||||||
CmdEntry("leaseinterval"), CmdEntry("server"), CmdEntry("service"), CmdEntry("start"),
|
CmdEntry("leaseinterval"), CmdEntry("server"), CmdEntry("service"), CmdEntry("start"),
|
||||||
CmdEntry("state"), CmdEntry("stop"),
|
CmdEntry("state"), CmdEntry("stop"), CmdEntry("ttl"),
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted");
|
static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted");
|
||||||
|
|
|
@ -149,6 +149,30 @@ otError SrpServer::ProcessDisable(Arg aArgs[])
|
||||||
return OT_ERROR_NONE;
|
return OT_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
otError SrpServer::ProcessTtl(Arg aArgs[])
|
||||||
|
{
|
||||||
|
otError error = OT_ERROR_NONE;
|
||||||
|
otSrpServerTtlConfig ttlConfig;
|
||||||
|
|
||||||
|
if (aArgs[0].IsEmpty())
|
||||||
|
{
|
||||||
|
otSrpServerGetTtlConfig(GetInstancePtr(), &ttlConfig);
|
||||||
|
OutputLine("min ttl: %u", ttlConfig.mMinTtl);
|
||||||
|
OutputLine("max ttl: %u", ttlConfig.mMaxTtl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SuccessOrExit(error = aArgs[0].ParseAsUint32(ttlConfig.mMinTtl));
|
||||||
|
SuccessOrExit(error = aArgs[1].ParseAsUint32(ttlConfig.mMaxTtl));
|
||||||
|
VerifyOrExit(aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
||||||
|
|
||||||
|
error = otSrpServerSetTtlConfig(GetInstancePtr(), &ttlConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
otError SrpServer::ProcessLease(Arg aArgs[])
|
otError SrpServer::ProcessLease(Arg aArgs[])
|
||||||
{
|
{
|
||||||
otError error = OT_ERROR_NONE;
|
otError error = OT_ERROR_NONE;
|
||||||
|
@ -289,6 +313,7 @@ otError SrpServer::ProcessService(Arg aArgs[])
|
||||||
OutputLine(kIndentSize, "port: %hu", otSrpServerServiceGetPort(service));
|
OutputLine(kIndentSize, "port: %hu", otSrpServerServiceGetPort(service));
|
||||||
OutputLine(kIndentSize, "priority: %hu", otSrpServerServiceGetPriority(service));
|
OutputLine(kIndentSize, "priority: %hu", otSrpServerServiceGetPriority(service));
|
||||||
OutputLine(kIndentSize, "weight: %hu", otSrpServerServiceGetWeight(service));
|
OutputLine(kIndentSize, "weight: %hu", otSrpServerServiceGetWeight(service));
|
||||||
|
OutputLine(kIndentSize, "ttl: %hu", otSrpServerServiceGetTtl(service));
|
||||||
|
|
||||||
txtData = otSrpServerServiceGetTxtData(service, &txtDataLength);
|
txtData = otSrpServerServiceGetTxtData(service, &txtDataLength);
|
||||||
OutputFormat(kIndentSize, "TXT: ");
|
OutputFormat(kIndentSize, "TXT: ");
|
||||||
|
|
|
@ -90,6 +90,7 @@ private:
|
||||||
otError ProcessHost(Arg aArgs[]);
|
otError ProcessHost(Arg aArgs[]);
|
||||||
otError ProcessService(Arg aArgs[]);
|
otError ProcessService(Arg aArgs[]);
|
||||||
otError ProcessSeqNum(Arg aArgs[]);
|
otError ProcessSeqNum(Arg aArgs[]);
|
||||||
|
otError ProcessTtl(Arg aArgs[]);
|
||||||
otError ProcessHelp(Arg aArgs[]);
|
otError ProcessHelp(Arg aArgs[]);
|
||||||
|
|
||||||
void OutputHostAddresses(const otSrpServerHost *aHost);
|
void OutputHostAddresses(const otSrpServerHost *aHost);
|
||||||
|
@ -100,6 +101,7 @@ private:
|
||||||
{"help", &SrpServer::ProcessHelp}, {"host", &SrpServer::ProcessHost},
|
{"help", &SrpServer::ProcessHelp}, {"host", &SrpServer::ProcessHost},
|
||||||
{"lease", &SrpServer::ProcessLease}, {"seqnum", &SrpServer::ProcessSeqNum},
|
{"lease", &SrpServer::ProcessLease}, {"seqnum", &SrpServer::ProcessSeqNum},
|
||||||
{"service", &SrpServer::ProcessService}, {"state", &SrpServer::ProcessState},
|
{"service", &SrpServer::ProcessService}, {"state", &SrpServer::ProcessState},
|
||||||
|
{"ttl", &SrpServer::ProcessTtl},
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted");
|
static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted");
|
||||||
|
|
|
@ -46,10 +46,14 @@ target_sources(openthread-cli-radio
|
||||||
cli_output.cpp
|
cli_output.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(NOT DEFINED OT_MBEDTLS_RCP)
|
||||||
|
set(OT_MBEDTLS_RCP ${OT_MBEDTLS})
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(openthread-cli-radio
|
target_link_libraries(openthread-cli-radio
|
||||||
PUBLIC
|
PUBLIC
|
||||||
openthread-radio
|
openthread-radio
|
||||||
PRIVATE
|
PRIVATE
|
||||||
${OT_MBEDTLS}
|
${OT_MBEDTLS_RCP}
|
||||||
ot-config
|
ot-config
|
||||||
)
|
)
|
||||||
|
|
|
@ -37,6 +37,8 @@ if (openthread_enable_core_config_args) {
|
||||||
defines += [ "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_1" ]
|
defines += [ "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_1" ]
|
||||||
} else if (openthread_config_thread_version == "1.2") {
|
} else if (openthread_config_thread_version == "1.2") {
|
||||||
defines += [ "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_2" ]
|
defines += [ "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_2" ]
|
||||||
|
} else if (openthread_config_thread_version == "1.3") {
|
||||||
|
defines += [ "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_3" ]
|
||||||
} else if (openthread_config_thread_version != "") {
|
} else if (openthread_config_thread_version != "") {
|
||||||
assert(false,
|
assert(false,
|
||||||
"Unrecognized Thread version: ${openthread_config_thread_version}")
|
"Unrecognized Thread version: ${openthread_config_thread_version}")
|
||||||
|
@ -363,9 +365,8 @@ openthread_core_files = [
|
||||||
"backbone_router/multicast_listeners_table.hpp",
|
"backbone_router/multicast_listeners_table.hpp",
|
||||||
"backbone_router/ndproxy_table.cpp",
|
"backbone_router/ndproxy_table.cpp",
|
||||||
"backbone_router/ndproxy_table.hpp",
|
"backbone_router/ndproxy_table.hpp",
|
||||||
"border_router/infra_if_platform.cpp",
|
"border_router/infra_if.cpp",
|
||||||
"border_router/router_advertisement.cpp",
|
"border_router/infra_if.hpp",
|
||||||
"border_router/router_advertisement.hpp",
|
|
||||||
"border_router/routing_manager.cpp",
|
"border_router/routing_manager.cpp",
|
||||||
"border_router/routing_manager.hpp",
|
"border_router/routing_manager.hpp",
|
||||||
"coap/coap.cpp",
|
"coap/coap.cpp",
|
||||||
|
@ -557,6 +558,8 @@ openthread_core_files = [
|
||||||
"net/ip6_mpl.cpp",
|
"net/ip6_mpl.cpp",
|
||||||
"net/ip6_mpl.hpp",
|
"net/ip6_mpl.hpp",
|
||||||
"net/ip6_types.hpp",
|
"net/ip6_types.hpp",
|
||||||
|
"net/nd6.cpp",
|
||||||
|
"net/nd6.hpp",
|
||||||
"net/nd_agent.cpp",
|
"net/nd_agent.cpp",
|
||||||
"net/nd_agent.hpp",
|
"net/nd_agent.hpp",
|
||||||
"net/netif.cpp",
|
"net/netif.cpp",
|
||||||
|
|
|
@ -86,8 +86,7 @@ set(COMMON_SOURCES
|
||||||
backbone_router/bbr_manager.cpp
|
backbone_router/bbr_manager.cpp
|
||||||
backbone_router/multicast_listeners_table.cpp
|
backbone_router/multicast_listeners_table.cpp
|
||||||
backbone_router/ndproxy_table.cpp
|
backbone_router/ndproxy_table.cpp
|
||||||
border_router/infra_if_platform.cpp
|
border_router/infra_if.cpp
|
||||||
border_router/router_advertisement.cpp
|
|
||||||
border_router/routing_manager.cpp
|
border_router/routing_manager.cpp
|
||||||
coap/coap.cpp
|
coap/coap.cpp
|
||||||
coap/coap_message.cpp
|
coap/coap_message.cpp
|
||||||
|
@ -169,6 +168,7 @@ set(COMMON_SOURCES
|
||||||
net/ip6_filter.cpp
|
net/ip6_filter.cpp
|
||||||
net/ip6_headers.cpp
|
net/ip6_headers.cpp
|
||||||
net/ip6_mpl.cpp
|
net/ip6_mpl.cpp
|
||||||
|
net/nd6.cpp
|
||||||
net/nd_agent.cpp
|
net/nd_agent.cpp
|
||||||
net/netif.cpp
|
net/netif.cpp
|
||||||
net/sntp_client.cpp
|
net/sntp_client.cpp
|
||||||
|
|
|
@ -176,8 +176,7 @@ SOURCES_COMMON = \
|
||||||
backbone_router/bbr_manager.cpp \
|
backbone_router/bbr_manager.cpp \
|
||||||
backbone_router/multicast_listeners_table.cpp \
|
backbone_router/multicast_listeners_table.cpp \
|
||||||
backbone_router/ndproxy_table.cpp \
|
backbone_router/ndproxy_table.cpp \
|
||||||
border_router/infra_if_platform.cpp \
|
border_router/infra_if.cpp \
|
||||||
border_router/router_advertisement.cpp \
|
|
||||||
border_router/routing_manager.cpp \
|
border_router/routing_manager.cpp \
|
||||||
coap/coap.cpp \
|
coap/coap.cpp \
|
||||||
coap/coap_message.cpp \
|
coap/coap_message.cpp \
|
||||||
|
@ -259,6 +258,7 @@ SOURCES_COMMON = \
|
||||||
net/ip6_filter.cpp \
|
net/ip6_filter.cpp \
|
||||||
net/ip6_headers.cpp \
|
net/ip6_headers.cpp \
|
||||||
net/ip6_mpl.cpp \
|
net/ip6_mpl.cpp \
|
||||||
|
net/nd6.cpp \
|
||||||
net/nd_agent.cpp \
|
net/nd_agent.cpp \
|
||||||
net/netif.cpp \
|
net/netif.cpp \
|
||||||
net/sntp_client.cpp \
|
net/sntp_client.cpp \
|
||||||
|
@ -415,7 +415,7 @@ HEADERS_COMMON = \
|
||||||
backbone_router/bbr_manager.hpp \
|
backbone_router/bbr_manager.hpp \
|
||||||
backbone_router/multicast_listeners_table.hpp \
|
backbone_router/multicast_listeners_table.hpp \
|
||||||
backbone_router/ndproxy_table.hpp \
|
backbone_router/ndproxy_table.hpp \
|
||||||
border_router/router_advertisement.hpp \
|
border_router/infra_if.hpp \
|
||||||
border_router/routing_manager.hpp \
|
border_router/routing_manager.hpp \
|
||||||
coap/coap.hpp \
|
coap/coap.hpp \
|
||||||
coap/coap_message.hpp \
|
coap/coap_message.hpp \
|
||||||
|
@ -563,6 +563,7 @@ HEADERS_COMMON = \
|
||||||
net/ip6_headers.hpp \
|
net/ip6_headers.hpp \
|
||||||
net/ip6_mpl.hpp \
|
net/ip6_mpl.hpp \
|
||||||
net/ip6_types.hpp \
|
net/ip6_types.hpp \
|
||||||
|
net/nd6.hpp \
|
||||||
net/nd_agent.hpp \
|
net/nd_agent.hpp \
|
||||||
net/netif.hpp \
|
net/netif.hpp \
|
||||||
net/sntp_client.hpp \
|
net/sntp_client.hpp \
|
||||||
|
|
|
@ -81,4 +81,9 @@ otDnssdQueryType otDnssdGetQueryTypeAndName(const otDnssdQuery *aQuery, char (*a
|
||||||
return MapEnum(Dns::ServiceDiscovery::Server::GetQueryTypeAndName(aQuery, *aNameOutput));
|
return MapEnum(Dns::ServiceDiscovery::Server::GetQueryTypeAndName(aQuery, *aNameOutput));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const otDnssdCounters *otDnssdGetCounters(otInstance *aInstance)
|
||||||
|
{
|
||||||
|
return &AsCoreType(aInstance).Get<Dns::ServiceDiscovery::Server>().GetCounters();
|
||||||
|
}
|
||||||
|
|
||||||
#endif // OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE
|
#endif // OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE
|
||||||
|
|
|
@ -84,6 +84,16 @@ bool otSrpClientIsAutoStartModeEnabled(otInstance *aInstance)
|
||||||
}
|
}
|
||||||
#endif // OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
|
#endif // OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
|
||||||
|
|
||||||
|
uint32_t otSrpClientGetTtl(otInstance *aInstance)
|
||||||
|
{
|
||||||
|
return AsCoreType(aInstance).Get<Srp::Client>().GetTtl();
|
||||||
|
}
|
||||||
|
|
||||||
|
void otSrpClientSetTtl(otInstance *aInstance, uint32_t aTtl)
|
||||||
|
{
|
||||||
|
return AsCoreType(aInstance).Get<Srp::Client>().SetTtl(aTtl);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t otSrpClientGetLeaseInterval(otInstance *aInstance)
|
uint32_t otSrpClientGetLeaseInterval(otInstance *aInstance)
|
||||||
{
|
{
|
||||||
return AsCoreType(aInstance).Get<Srp::Client>().GetLeaseInterval();
|
return AsCoreType(aInstance).Get<Srp::Client>().GetLeaseInterval();
|
||||||
|
@ -114,6 +124,11 @@ otError otSrpClientSetHostName(otInstance *aInstance, const char *aName)
|
||||||
return AsCoreType(aInstance).Get<Srp::Client>().SetHostName(aName);
|
return AsCoreType(aInstance).Get<Srp::Client>().SetHostName(aName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
otError otSrpClientEnableAutoHostAddress(otInstance *aInstance)
|
||||||
|
{
|
||||||
|
return AsCoreType(aInstance).Get<Srp::Client>().EnableAutoHostAddress();
|
||||||
|
}
|
||||||
|
|
||||||
otError otSrpClientSetHostAddresses(otInstance *aInstance, const otIp6Address *aIp6Addresses, uint8_t aNumAddresses)
|
otError otSrpClientSetHostAddresses(otInstance *aInstance, const otIp6Address *aIp6Addresses, uint8_t aNumAddresses)
|
||||||
{
|
{
|
||||||
return AsCoreType(aInstance).Get<Srp::Client>().SetHostAddresses(AsCoreTypePtr(aIp6Addresses), aNumAddresses);
|
return AsCoreType(aInstance).Get<Srp::Client>().SetHostAddresses(AsCoreTypePtr(aIp6Addresses), aNumAddresses);
|
||||||
|
|
|
@ -57,6 +57,11 @@ otSrpServerState otSrpServerGetState(otInstance *aInstance)
|
||||||
return MapEnum(AsCoreType(aInstance).Get<Srp::Server>().GetState());
|
return MapEnum(AsCoreType(aInstance).Get<Srp::Server>().GetState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t otSrpServerGetPort(otInstance *aInstance)
|
||||||
|
{
|
||||||
|
return AsCoreType(aInstance).Get<Srp::Server>().GetPort();
|
||||||
|
}
|
||||||
|
|
||||||
otSrpServerAddressMode otSrpServerGetAddressMode(otInstance *aInstance)
|
otSrpServerAddressMode otSrpServerGetAddressMode(otInstance *aInstance)
|
||||||
{
|
{
|
||||||
return MapEnum(AsCoreType(aInstance).Get<Srp::Server>().GetAddressMode());
|
return MapEnum(AsCoreType(aInstance).Get<Srp::Server>().GetAddressMode());
|
||||||
|
@ -82,6 +87,16 @@ void otSrpServerSetEnabled(otInstance *aInstance, bool aEnabled)
|
||||||
AsCoreType(aInstance).Get<Srp::Server>().SetEnabled(aEnabled);
|
AsCoreType(aInstance).Get<Srp::Server>().SetEnabled(aEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void otSrpServerGetTtlConfig(otInstance *aInstance, otSrpServerTtlConfig *aTtlConfig)
|
||||||
|
{
|
||||||
|
AsCoreType(aInstance).Get<Srp::Server>().GetTtlConfig(AsCoreType(aTtlConfig));
|
||||||
|
}
|
||||||
|
|
||||||
|
otError otSrpServerSetTtlConfig(otInstance *aInstance, const otSrpServerTtlConfig *aTtlConfig)
|
||||||
|
{
|
||||||
|
return AsCoreType(aInstance).Get<Srp::Server>().SetTtlConfig(AsCoreType(aTtlConfig));
|
||||||
|
}
|
||||||
|
|
||||||
void otSrpServerGetLeaseConfig(otInstance *aInstance, otSrpServerLeaseConfig *aLeaseConfig)
|
void otSrpServerGetLeaseConfig(otInstance *aInstance, otSrpServerLeaseConfig *aLeaseConfig)
|
||||||
{
|
{
|
||||||
AsCoreType(aInstance).Get<Srp::Server>().GetLeaseConfig(AsCoreType(aLeaseConfig));
|
AsCoreType(aInstance).Get<Srp::Server>().GetLeaseConfig(AsCoreType(aLeaseConfig));
|
||||||
|
@ -109,6 +124,11 @@ const otSrpServerHost *otSrpServerGetNextHost(otInstance *aInstance, const otSrp
|
||||||
return AsCoreType(aInstance).Get<Srp::Server>().GetNextHost(AsCoreTypePtr(aHost));
|
return AsCoreType(aInstance).Get<Srp::Server>().GetNextHost(AsCoreTypePtr(aHost));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const otSrpServerResponseCounters *otSrpServerGetResponseCounters(otInstance *aInstance)
|
||||||
|
{
|
||||||
|
return AsCoreType(aInstance).Get<Srp::Server>().GetResponseCounters();
|
||||||
|
}
|
||||||
|
|
||||||
bool otSrpServerHostIsDeleted(const otSrpServerHost *aHost)
|
bool otSrpServerHostIsDeleted(const otSrpServerHost *aHost)
|
||||||
{
|
{
|
||||||
return AsCoreType(aHost).IsDeleted();
|
return AsCoreType(aHost).IsDeleted();
|
||||||
|
@ -124,6 +144,16 @@ const otIp6Address *otSrpServerHostGetAddresses(const otSrpServerHost *aHost, ui
|
||||||
return AsCoreType(aHost).GetAddresses(*aAddressesNum);
|
return AsCoreType(aHost).GetAddresses(*aAddressesNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void otSrpServerHostGetLeaseInfo(const otSrpServerHost *aHost, otSrpServerLeaseInfo *aLeaseInfo)
|
||||||
|
{
|
||||||
|
AsCoreType(aHost).GetLeaseInfo(*aLeaseInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t otSrpServerHostGetKeyLease(const otSrpServerHost *aHost)
|
||||||
|
{
|
||||||
|
return AsCoreType(aHost).GetKeyLease();
|
||||||
|
}
|
||||||
|
|
||||||
const otSrpServerService *otSrpServerHostGetNextService(const otSrpServerHost * aHost,
|
const otSrpServerService *otSrpServerHostGetNextService(const otSrpServerHost * aHost,
|
||||||
const otSrpServerService *aService)
|
const otSrpServerService *aService)
|
||||||
{
|
{
|
||||||
|
@ -184,6 +214,11 @@ uint16_t otSrpServerServiceGetPriority(const otSrpServerService *aService)
|
||||||
return AsCoreType(aService).GetPriority();
|
return AsCoreType(aService).GetPriority();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t otSrpServerServiceGetTtl(const otSrpServerService *aService)
|
||||||
|
{
|
||||||
|
return AsCoreType(aService).GetTtl();
|
||||||
|
}
|
||||||
|
|
||||||
const uint8_t *otSrpServerServiceGetTxtData(const otSrpServerService *aService, uint16_t *aDataLength)
|
const uint8_t *otSrpServerServiceGetTxtData(const otSrpServerService *aService, uint16_t *aDataLength)
|
||||||
{
|
{
|
||||||
*aDataLength = AsCoreType(aService).GetTxtDataLength();
|
*aDataLength = AsCoreType(aService).GetTxtDataLength();
|
||||||
|
@ -196,4 +231,9 @@ const otSrpServerHost *otSrpServerServiceGetHost(const otSrpServerService *aServ
|
||||||
return &AsCoreType(aService).GetHost();
|
return &AsCoreType(aService).GetHost();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void otSrpServerServiceGetLeaseInfo(const otSrpServerService *aService, otSrpServerLeaseInfo *aLeaseInfo)
|
||||||
|
{
|
||||||
|
AsCoreType(aService).GetLeaseInfo(*aLeaseInfo);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
#endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
||||||
|
|
|
@ -497,4 +497,9 @@ bool otThreadIsAnycastLocateInProgress(otInstance *aInstance)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
otError otThreadDetachGracefully(otInstance *aInstance, otDetachGracefullyCallback aCallback, void *aContext)
|
||||||
|
{
|
||||||
|
return AsCoreType(aInstance).Get<Mle::MleRouter>().DetachGracefully(aCallback, aContext);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
|
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||||
|
|
|
@ -251,7 +251,7 @@ void NdProxyTable::HandleTimer(void)
|
||||||
|
|
||||||
for (NdProxy &proxy : Iterate(kFilterDadInProcess))
|
for (NdProxy &proxy : Iterate(kFilterDadInProcess))
|
||||||
{
|
{
|
||||||
if (proxy.IsDadAttamptsComplete())
|
if (proxy.IsDadAttemptsComplete())
|
||||||
{
|
{
|
||||||
proxy.mDadFlag = false;
|
proxy.mDadFlag = false;
|
||||||
NotifyDuaRegistrationOnBackboneLink(proxy, /* aIsRenew */ false);
|
NotifyDuaRegistrationOnBackboneLink(proxy, /* aIsRenew */ false);
|
||||||
|
@ -262,7 +262,7 @@ void NdProxyTable::HandleTimer(void)
|
||||||
|
|
||||||
if (Get<BackboneRouter::Manager>().SendBackboneQuery(GetDua(proxy)) == kErrorNone)
|
if (Get<BackboneRouter::Manager>().SendBackboneQuery(GetDua(proxy)) == kErrorNone)
|
||||||
{
|
{
|
||||||
proxy.IncreaseDadAttampts();
|
proxy.IncreaseDadAttempts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,8 +111,8 @@ public:
|
||||||
uint32_t aTimeSinceLastTransaction);
|
uint32_t aTimeSinceLastTransaction);
|
||||||
|
|
||||||
void Update(uint16_t aRloc16, uint32_t aTimeSinceLastTransaction);
|
void Update(uint16_t aRloc16, uint32_t aTimeSinceLastTransaction);
|
||||||
void IncreaseDadAttampts(void) { mDadAttempts++; }
|
void IncreaseDadAttempts(void) { mDadAttempts++; }
|
||||||
bool IsDadAttamptsComplete() const { return mDadAttempts == Mle::kDuaDadRepeats; }
|
bool IsDadAttemptsComplete() const { return mDadAttempts == Mle::kDuaDadRepeats; }
|
||||||
|
|
||||||
Ip6::InterfaceIdentifier mAddressIid;
|
Ip6::InterfaceIdentifier mAddressIid;
|
||||||
Ip6::InterfaceIdentifier mMeshLocalIid;
|
Ip6::InterfaceIdentifier mMeshLocalIid;
|
||||||
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, The OpenThread Authors.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the copyright holder nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* This file implements infrastructure network interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "infra_if.hpp"
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||||
|
|
||||||
|
#include "border_router/routing_manager.hpp"
|
||||||
|
#include "common/as_core_type.hpp"
|
||||||
|
#include "common/instance.hpp"
|
||||||
|
#include "common/locator_getters.hpp"
|
||||||
|
#include "common/logging.hpp"
|
||||||
|
#include "net/icmp6.hpp"
|
||||||
|
|
||||||
|
namespace ot {
|
||||||
|
namespace BorderRouter {
|
||||||
|
|
||||||
|
RegisterLogModule("InfraIf");
|
||||||
|
|
||||||
|
InfraIf::InfraIf(Instance &aInstance)
|
||||||
|
: InstanceLocator(aInstance)
|
||||||
|
, mInitialized(false)
|
||||||
|
, mIsRunning(false)
|
||||||
|
, mIfIndex(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Error InfraIf::Init(uint32_t aIfIndex)
|
||||||
|
{
|
||||||
|
Error error = kErrorNone;
|
||||||
|
|
||||||
|
VerifyOrExit(!mInitialized, error = kErrorInvalidState);
|
||||||
|
VerifyOrExit(aIfIndex > 0, error = kErrorInvalidArgs);
|
||||||
|
|
||||||
|
mIfIndex = aIfIndex;
|
||||||
|
mInitialized = true;
|
||||||
|
|
||||||
|
LogInfo("Init %s", ToString().AsCString());
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InfraIf::Deinit(void)
|
||||||
|
{
|
||||||
|
mInitialized = false;
|
||||||
|
mIsRunning = false;
|
||||||
|
mIfIndex = 0;
|
||||||
|
|
||||||
|
LogInfo("Deinit");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InfraIf::HasAddress(const Ip6::Address &aAddress)
|
||||||
|
{
|
||||||
|
OT_ASSERT(mInitialized);
|
||||||
|
|
||||||
|
return otPlatInfraIfHasAddress(mIfIndex, &aAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error InfraIf::Send(const Icmp6Packet &aPacket, const Ip6::Address &aDestination)
|
||||||
|
{
|
||||||
|
OT_ASSERT(mInitialized);
|
||||||
|
|
||||||
|
return otPlatInfraIfSendIcmp6Nd(mIfIndex, &aDestination, aPacket.GetBytes(), aPacket.GetLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
void InfraIf::HandledReceived(uint32_t aIfIndex, const Ip6::Address &aSource, const Icmp6Packet &aPacket)
|
||||||
|
{
|
||||||
|
Error error = kErrorNone;
|
||||||
|
|
||||||
|
VerifyOrExit(mInitialized && mIsRunning, error = kErrorInvalidState);
|
||||||
|
VerifyOrExit(aIfIndex == mIfIndex, error = kErrorDrop);
|
||||||
|
VerifyOrExit(aPacket.GetBytes() != nullptr, error = kErrorInvalidArgs);
|
||||||
|
VerifyOrExit(aPacket.GetLength() >= sizeof(Ip6::Icmp::Header), error = kErrorParse);
|
||||||
|
|
||||||
|
Get<RoutingManager>().HandleReceived(aPacket, aSource);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (error != kErrorNone)
|
||||||
|
{
|
||||||
|
LogDebg("Dropped ICMPv6 message: %s", ErrorToString(error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Error InfraIf::HandleStateChanged(uint32_t aIfIndex, bool aIsRunning)
|
||||||
|
{
|
||||||
|
Error error = kErrorNone;
|
||||||
|
|
||||||
|
VerifyOrExit(mInitialized, error = kErrorInvalidState);
|
||||||
|
VerifyOrExit(aIfIndex == mIfIndex, error = kErrorInvalidArgs);
|
||||||
|
|
||||||
|
VerifyOrExit(aIsRunning != mIsRunning);
|
||||||
|
LogInfo("State changed: %sRUNNING -> %sRUNNING", mIsRunning ? "" : "NOT ", aIsRunning ? "" : "NOT ");
|
||||||
|
|
||||||
|
mIsRunning = aIsRunning;
|
||||||
|
|
||||||
|
Get<RoutingManager>().HandleInfraIfStateChanged();
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
InfraIf::InfoString InfraIf::ToString(void) const
|
||||||
|
{
|
||||||
|
InfoString string;
|
||||||
|
|
||||||
|
string.Append("infra netif %u", mIfIndex);
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
extern "C" void otPlatInfraIfRecvIcmp6Nd(otInstance * aInstance,
|
||||||
|
uint32_t aInfraIfIndex,
|
||||||
|
const otIp6Address *aSrcAddress,
|
||||||
|
const uint8_t * aBuffer,
|
||||||
|
uint16_t aBufferLength)
|
||||||
|
{
|
||||||
|
InfraIf::Icmp6Packet packet;
|
||||||
|
|
||||||
|
packet.Init(aBuffer, aBufferLength);
|
||||||
|
AsCoreType(aInstance).Get<InfraIf>().HandledReceived(aInfraIfIndex, AsCoreType(aSrcAddress), packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" otError otPlatInfraIfStateChanged(otInstance *aInstance, uint32_t aInfraIfIndex, bool aIsRunning)
|
||||||
|
{
|
||||||
|
return AsCoreType(aInstance).Get<InfraIf>().HandleStateChanged(aInfraIfIndex, aIsRunning);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BorderRouter
|
||||||
|
} // namespace ot
|
||||||
|
|
||||||
|
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
|
@ -0,0 +1,186 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, The OpenThread Authors.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the copyright holder nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* This file includes definitions for infrastructure network interface.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INFRA_IF_HPP_
|
||||||
|
#define INFRA_IF_HPP_
|
||||||
|
|
||||||
|
#include "openthread-core-config.h"
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||||
|
|
||||||
|
#include <openthread/platform/infra_if.h>
|
||||||
|
|
||||||
|
#include "common/data.hpp"
|
||||||
|
#include "common/error.hpp"
|
||||||
|
#include "common/locator.hpp"
|
||||||
|
#include "common/string.hpp"
|
||||||
|
#include "net/ip6.hpp"
|
||||||
|
|
||||||
|
namespace ot {
|
||||||
|
namespace BorderRouter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the infrastructure network interface on a border router.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class InfraIf : public InstanceLocator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr uint16_t kInfoStringSize = 20; ///< Max chars for the info string (`ToString()`).
|
||||||
|
|
||||||
|
typedef String<kInfoStringSize> InfoString; ///< String type returned from `ToString()`.
|
||||||
|
typedef Data<kWithUint16Length> Icmp6Packet; ///< An IMCPv6 packet (data containing the IP payload)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructor initializes the `InfraIf`.
|
||||||
|
*
|
||||||
|
* @param[in] aInstance A OpenThread instance.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
explicit InfraIf(Instance &aInstance);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method initializes the `InfraIf`.
|
||||||
|
*
|
||||||
|
* @param[in] aIfIndex The infrastructure interface index.
|
||||||
|
*
|
||||||
|
* @retval kErrorNone Successfully initialized the `InfraIf`.
|
||||||
|
* @retval kErrorInvalidArgs The index of the infra interface is not valid.
|
||||||
|
* @retval kErrorInvalidState The `InfraIf` is already initialized.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Error Init(uint32_t aIfIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method deinitilaizes the `InfraIf`.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void Deinit(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicates whether or not the `InfraIf` is initialized.
|
||||||
|
*
|
||||||
|
* @retval TRUE The `InfraIf` is initialized.
|
||||||
|
* @retval FALSE The `InfraIf` is not initialized.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool IsInitialized(void) const { return mInitialized; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicates whether or not the infra interface is running.
|
||||||
|
*
|
||||||
|
* @retval TRUE The infrastructure interface is running.
|
||||||
|
* @retval FALSE The infrastructure interface is not running.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool IsRunning(void) const { return mIsRunning; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the infrastructure interface index.
|
||||||
|
*
|
||||||
|
* @returns The interface index or zero if not initialized.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t GetIfIndex(void) const { return mIfIndex; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicates whether or not the infra interface has the given IPv6 address assigned.
|
||||||
|
*
|
||||||
|
* This method MUST be used when interface is initialized.
|
||||||
|
*
|
||||||
|
* @param[in] aAddress The IPv6 address.
|
||||||
|
*
|
||||||
|
* @retval TRUE The infrastructure interface has @p aAddress.
|
||||||
|
* @retval FALSE The infrastructure interface does not have @p aAddress.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool HasAddress(const Ip6::Address &aAddress);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sends an ICMPv6 Neighbor Discovery packet on the infrastructure interface.
|
||||||
|
*
|
||||||
|
* This method MUST be used when interface is initialized.
|
||||||
|
*
|
||||||
|
* @param[in] aPacket The ICMPv6 packet to send.
|
||||||
|
* @param[in] aDestination The destination address.
|
||||||
|
*
|
||||||
|
* @retval kErrorNone Successfully sent the ICMPv6 message.
|
||||||
|
* @retval kErrorFailed Failed to send the ICMPv6 message.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Error Send(const Icmp6Packet &aPacket, const Ip6::Address &aDestination);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method processes a received ICMPv6 Neighbor Discovery packet from an infrastructure interface.
|
||||||
|
*
|
||||||
|
* @param[in] aIfIndex The infrastructure interface index on which the ICMPv6 message is received.
|
||||||
|
* @param[in] aSource The IPv6 source address.
|
||||||
|
* @param[in] aPacket The ICMPv6 packet.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void HandledReceived(uint32_t aIfIndex, const Ip6::Address &aSource, const Icmp6Packet &aPacket);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method handles infrastructure interface state changes.
|
||||||
|
*
|
||||||
|
* @param[in] aIfIndex The infrastructure interface index.
|
||||||
|
* @param[in] aIsRunning A boolean that indicates whether the infrastructure interface is running.
|
||||||
|
*
|
||||||
|
* @retval kErrorNone Successfully updated the infra interface status.
|
||||||
|
* @retval kErrorInvalidState The `InfraIf` is not initialized.
|
||||||
|
* @retval kErrorInvalidArgs The @p IfIndex does not match the interface index of `InfraIf`.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Error HandleStateChanged(uint32_t aIfIndex, bool aIsRunning);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method converts the `InfraIf` to a human-readable string.
|
||||||
|
*
|
||||||
|
* @returns The string representation of `InfraIf`.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
InfoString ToString(void) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool mInitialized : 1;
|
||||||
|
bool mIsRunning : 1;
|
||||||
|
uint32_t mIfIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BorderRouter
|
||||||
|
} // namespace ot
|
||||||
|
|
||||||
|
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||||
|
|
||||||
|
#endif // INFRA_IF_HPP_
|
|
@ -1,61 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020, The OpenThread Authors.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of the copyright holder nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* This file implements infrastructure interface platform APIs.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "openthread-core-config.h"
|
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
|
||||||
|
|
||||||
#include <openthread/platform/infra_if.h>
|
|
||||||
|
|
||||||
#include "border_router/routing_manager.hpp"
|
|
||||||
#include "common/as_core_type.hpp"
|
|
||||||
#include "common/instance.hpp"
|
|
||||||
|
|
||||||
using namespace ot;
|
|
||||||
|
|
||||||
extern "C" void otPlatInfraIfRecvIcmp6Nd(otInstance * aInstance,
|
|
||||||
uint32_t aInfraIfIndex,
|
|
||||||
const otIp6Address *aSrcAddress,
|
|
||||||
const uint8_t * aBuffer,
|
|
||||||
uint16_t aBufferLength)
|
|
||||||
{
|
|
||||||
AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().RecvIcmp6Message(aInfraIfIndex, AsCoreType(aSrcAddress),
|
|
||||||
aBuffer, aBufferLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" otError otPlatInfraIfStateChanged(otInstance *aInstance, uint32_t aInfraIfIndex, bool aIsRunning)
|
|
||||||
{
|
|
||||||
return AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().HandleInfraIfStateChanged(aInfraIfIndex,
|
|
||||||
aIsRunning);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
|
|
@ -1,211 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020, The OpenThread Authors.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of the copyright holder nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* This file includes implementations for ICMPv6 Router Advertisement.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "border_router/router_advertisement.hpp"
|
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
|
||||||
|
|
||||||
#include "common/as_core_type.hpp"
|
|
||||||
#include "common/code_utils.hpp"
|
|
||||||
|
|
||||||
namespace ot {
|
|
||||||
|
|
||||||
namespace BorderRouter {
|
|
||||||
|
|
||||||
namespace RouterAdv {
|
|
||||||
|
|
||||||
const Option *Option::GetNextOption(const Option *aCurOption, const uint8_t *aBuffer, uint16_t aBufferLength)
|
|
||||||
{
|
|
||||||
const uint8_t *nextOption = nullptr;
|
|
||||||
const uint8_t *bufferEnd = aBuffer + aBufferLength;
|
|
||||||
|
|
||||||
VerifyOrExit(aBuffer != nullptr, nextOption = nullptr);
|
|
||||||
|
|
||||||
if (aCurOption == nullptr)
|
|
||||||
{
|
|
||||||
nextOption = aBuffer;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nextOption = reinterpret_cast<const uint8_t *>(aCurOption) + aCurOption->GetSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
VerifyOrExit(nextOption + sizeof(Option) <= bufferEnd, nextOption = nullptr);
|
|
||||||
VerifyOrExit(reinterpret_cast<const Option *>(nextOption)->GetSize() > 0, nextOption = nullptr);
|
|
||||||
VerifyOrExit(nextOption + reinterpret_cast<const Option *>(nextOption)->GetSize() <= bufferEnd,
|
|
||||||
nextOption = nullptr);
|
|
||||||
|
|
||||||
exit:
|
|
||||||
return reinterpret_cast<const Option *>(nextOption);
|
|
||||||
}
|
|
||||||
|
|
||||||
PrefixInfoOption::PrefixInfoOption(void)
|
|
||||||
: Option(Type::kPrefixInfo, sizeof(*this) / kLengthUnit)
|
|
||||||
, mPrefixLength(0)
|
|
||||||
, mReserved1(0)
|
|
||||||
, mValidLifetime(0)
|
|
||||||
, mPreferredLifetime(0)
|
|
||||||
, mReserved2(0)
|
|
||||||
{
|
|
||||||
OT_UNUSED_VARIABLE(mReserved2);
|
|
||||||
|
|
||||||
mPrefix.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrefixInfoOption::SetOnLink(bool aOnLink)
|
|
||||||
{
|
|
||||||
if (aOnLink)
|
|
||||||
{
|
|
||||||
mReserved1 |= kOnLinkFlagMask;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mReserved1 &= ~kOnLinkFlagMask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrefixInfoOption::SetAutoAddrConfig(bool aAutoAddrConfig)
|
|
||||||
{
|
|
||||||
if (aAutoAddrConfig)
|
|
||||||
{
|
|
||||||
mReserved1 |= kAutoConfigFlagMask;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mReserved1 &= ~kAutoConfigFlagMask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrefixInfoOption::SetPrefix(const Ip6::Prefix &aPrefix)
|
|
||||||
{
|
|
||||||
mPrefixLength = aPrefix.mLength;
|
|
||||||
mPrefix = AsCoreType(&aPrefix.mPrefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ip6::Prefix PrefixInfoOption::GetPrefix(void) const
|
|
||||||
{
|
|
||||||
Ip6::Prefix prefix;
|
|
||||||
|
|
||||||
prefix.Set(mPrefix.GetBytes(), mPrefixLength);
|
|
||||||
return prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
RouteInfoOption::RouteInfoOption(void)
|
|
||||||
: Option(Type::kRouteInfo, 0)
|
|
||||||
, mPrefixLength(0)
|
|
||||||
, mReserved(0)
|
|
||||||
, mRouteLifetime(0)
|
|
||||||
{
|
|
||||||
OT_UNUSED_VARIABLE(mReserved);
|
|
||||||
|
|
||||||
mPrefix.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RouteInfoOption::SetPreference(RoutePreference aPreference)
|
|
||||||
{
|
|
||||||
mReserved &= ~kPreferenceMask;
|
|
||||||
mReserved |= (NetworkData::RoutePreferenceToValue(aPreference) << kPreferenceOffset) & kPreferenceMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
RouteInfoOption::RoutePreference RouteInfoOption::GetPreference(void) const
|
|
||||||
{
|
|
||||||
return NetworkData::RoutePreferenceFromValue((mReserved & kPreferenceMask) >> kPreferenceOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RouteInfoOption::SetPrefix(const Ip6::Prefix &aPrefix)
|
|
||||||
{
|
|
||||||
// The total length (in bytes) of a Router Information Option
|
|
||||||
// is: (8 bytes fixed option header) + (0, 8, or 16 bytes prefix).
|
|
||||||
// Because the length of the option must be padded with 8 bytes,
|
|
||||||
// the length of the prefix (in bits) must be padded with 64 bits.
|
|
||||||
SetLength((aPrefix.mLength + kLengthUnit * CHAR_BIT - 1) / (kLengthUnit * CHAR_BIT) + 1);
|
|
||||||
|
|
||||||
mPrefixLength = aPrefix.mLength;
|
|
||||||
mPrefix = AsCoreType(&aPrefix.mPrefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ip6::Prefix RouteInfoOption::GetPrefix(void) const
|
|
||||||
{
|
|
||||||
Ip6::Prefix prefix;
|
|
||||||
|
|
||||||
prefix.Set(mPrefix.GetBytes(), mPrefixLength);
|
|
||||||
return prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RouteInfoOption::IsValid(void) const
|
|
||||||
{
|
|
||||||
return (GetLength() == 1 || GetLength() == 2 || GetLength() == 3) &&
|
|
||||||
(mPrefixLength <= OT_IP6_ADDRESS_SIZE * CHAR_BIT) && NetworkData::IsRoutePreferenceValid(GetPreference());
|
|
||||||
}
|
|
||||||
|
|
||||||
void RouterAdvMessage::SetToDefault(void)
|
|
||||||
{
|
|
||||||
mHeader.Clear();
|
|
||||||
mHeader.SetType(Ip6::Icmp::Header::kTypeRouterAdvert);
|
|
||||||
mReachableTime = 0;
|
|
||||||
mRetransTimer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const RouterAdvMessage &RouterAdvMessage::operator=(const RouterAdvMessage &aOther)
|
|
||||||
{
|
|
||||||
mHeader = aOther.mHeader;
|
|
||||||
|
|
||||||
// Set zero value and let platform do the calculation.
|
|
||||||
mHeader.SetChecksum(0);
|
|
||||||
|
|
||||||
mReachableTime = aOther.mReachableTime;
|
|
||||||
mRetransTimer = aOther.mRetransTimer;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RouterAdvMessage::operator==(const RouterAdvMessage &aOther) const
|
|
||||||
{
|
|
||||||
return memcmp(&mHeader.mData, &aOther.mHeader.mData, sizeof(mHeader.mData)) == 0 &&
|
|
||||||
mReachableTime == aOther.mReachableTime && mRetransTimer == aOther.mRetransTimer;
|
|
||||||
}
|
|
||||||
|
|
||||||
RouterSolicitMessage::RouterSolicitMessage(void)
|
|
||||||
{
|
|
||||||
mHeader.Clear();
|
|
||||||
mHeader.SetType(Ip6::Icmp::Header::kTypeRouterSolicit);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace RouterAdv
|
|
||||||
|
|
||||||
} // namespace BorderRouter
|
|
||||||
|
|
||||||
} // namespace ot
|
|
||||||
|
|
||||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
|
|
@ -1,511 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020, The OpenThread Authors.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of the copyright holder nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* This file includes definitions for IPv6 Router Advertisement.
|
|
||||||
*
|
|
||||||
* See RFC 4861: Neighbor Discovery for IP version 6 (https://tools.ietf.org/html/rfc4861).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ROUTER_ADVERTISEMENT_HPP_
|
|
||||||
#define ROUTER_ADVERTISEMENT_HPP_
|
|
||||||
|
|
||||||
#include "openthread-core-config.h"
|
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <openthread/netdata.h>
|
|
||||||
#include <openthread/platform/toolchain.h>
|
|
||||||
|
|
||||||
#include "common/encoding.hpp"
|
|
||||||
#include "common/equatable.hpp"
|
|
||||||
#include "net/icmp6.hpp"
|
|
||||||
#include "net/ip6.hpp"
|
|
||||||
#include "thread/network_data_types.hpp"
|
|
||||||
|
|
||||||
using ot::Encoding::BigEndian::HostSwap16;
|
|
||||||
using ot::Encoding::BigEndian::HostSwap32;
|
|
||||||
|
|
||||||
namespace ot {
|
|
||||||
|
|
||||||
namespace BorderRouter {
|
|
||||||
|
|
||||||
namespace RouterAdv {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class represents the variable length options in Neighbor
|
|
||||||
* Discovery messages.
|
|
||||||
*
|
|
||||||
* @sa PrefixInfoOption
|
|
||||||
* @sa RouteInfoOption
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
OT_TOOL_PACKED_BEGIN
|
|
||||||
class Option
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum class Type : uint8_t
|
|
||||||
{
|
|
||||||
kPrefixInfo = 3, ///< Prefix Information Option.
|
|
||||||
kRouteInfo = 24, ///< Route Information Option.
|
|
||||||
};
|
|
||||||
|
|
||||||
static constexpr uint8_t kLengthUnit = 8; ///< The unit of length in octets.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This constructor initializes the option with given type and length.
|
|
||||||
*
|
|
||||||
* @param[in] aType The type of this option.
|
|
||||||
* @param[in] aLength The length of this option in unit of 8 octets.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
explicit Option(Type aType, uint8_t aLength = 0)
|
|
||||||
: mType(aType)
|
|
||||||
, mLength(aLength)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns the type of this option.
|
|
||||||
*
|
|
||||||
* @returns The option type.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
Type GetType(void) const { return mType; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method sets the size of the option (in bytes).
|
|
||||||
*
|
|
||||||
* Since the option must end on their natural 64-bits boundaries,
|
|
||||||
* the actual length set to the option is padded to (aSize + 7) / 8 * 8.
|
|
||||||
*
|
|
||||||
* @param[in] aSize The size of the option in unit of 1 byte.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void SetSize(uint16_t aSize) { mLength = static_cast<uint8_t>((aSize + kLengthUnit - 1) / kLengthUnit); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns the size of the option (in bytes).
|
|
||||||
*
|
|
||||||
* @returns The size of the option in unit of 1 byte.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
uint16_t GetSize(void) const { return mLength * kLengthUnit; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method sets the length of the option (in unit of 8 bytes).
|
|
||||||
*
|
|
||||||
* @param[in] aLength The length of the option in unit of 8 bytes.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void SetLength(uint8_t aLength) { mLength = aLength; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns the length of the option (in unit of 8 bytes).
|
|
||||||
*
|
|
||||||
* @returns The length of the option in unit of 8 bytes.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
uint16_t GetLength(void) const { return mLength; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This helper method returns a pointer to the next valid option in the buffer.
|
|
||||||
*
|
|
||||||
* @param[in] aCurOption The current option. Use `nullptr` to get the first option.
|
|
||||||
* @param[in] aBuffer The buffer within which the options are held.
|
|
||||||
* @param[in] aBufferLength The length of the buffer.
|
|
||||||
*
|
|
||||||
* @returns A pointer to the next option if there are a valid one. Otherwise, `nullptr`.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static const Option *GetNextOption(const Option *aCurOption, const uint8_t *aBuffer, uint16_t aBufferLength);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method tells whether this option is valid.
|
|
||||||
*
|
|
||||||
* @return A boolean that indicates whether this option is valid.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
bool IsValid(void) const { return mLength > 0; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Type mType; // Type of the option.
|
|
||||||
uint8_t mLength; // Length of the option in unit of 8 octets,
|
|
||||||
// including the `type` and `length` fields.
|
|
||||||
} OT_TOOL_PACKED_END;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class represents the Prefix Information Option.
|
|
||||||
*
|
|
||||||
* See section 4.6.2 of RFC 4861 for definition of this option.
|
|
||||||
* https://tools.ietf.org/html/rfc4861#section-4.6.2
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
OT_TOOL_PACKED_BEGIN
|
|
||||||
class PrefixInfoOption : public Option
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* This constructor initializes this option with zero prefix
|
|
||||||
* length, valid lifetime and preferred lifetime.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
PrefixInfoOption(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns the on-link flag.
|
|
||||||
*
|
|
||||||
* @returns A boolean which indicates whether the on-link flag is set.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
bool GetOnLink(void) const { return (mReserved1 & kOnLinkFlagMask) != 0; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method sets the on-link (L) flag.
|
|
||||||
*
|
|
||||||
* @param[in] aOnLink A boolean indicates whether the prefix is on-link or off-link.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void SetOnLink(bool aOnLink);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns the autonomous address-configuration (A) flag.
|
|
||||||
*
|
|
||||||
* @returns A boolean which indicates whether the A flag is set.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
bool GetAutoAddrConfig(void) const { return (mReserved1 & kAutoConfigFlagMask) != 0; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method sets the autonomous address-configuration (A) flag.
|
|
||||||
*
|
|
||||||
* @param[in] aAutoAddrConfig A boolean indicates whether this prefix can be used
|
|
||||||
* for SLAAC.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void SetAutoAddrConfig(bool aAutoAddrConfig);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method set the valid lifetime of the prefix in seconds.
|
|
||||||
*
|
|
||||||
* @param[in] aValidLifetime The valid lifetime in seconds.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void SetValidLifetime(uint32_t aValidLifetime) { mValidLifetime = HostSwap32(aValidLifetime); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* THis method returns the valid lifetime of the prefix in seconds.
|
|
||||||
*
|
|
||||||
* @returns The valid lifetime in seconds.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
uint32_t GetValidLifetime(void) const { return HostSwap32(mValidLifetime); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method sets the preferred lifetime of the prefix in seconds.
|
|
||||||
*
|
|
||||||
* @param[in] aPreferredLifetime The preferred lifetime in seconds.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void SetPreferredLifetime(uint32_t aPreferredLifetime) { mPreferredLifetime = HostSwap32(aPreferredLifetime); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* THis method returns the preferred lifetime of the prefix in seconds.
|
|
||||||
*
|
|
||||||
* @returns The preferred lifetime in seconds.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
uint32_t GetPreferredLifetime(void) const { return HostSwap32(mPreferredLifetime); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method sets the prefix.
|
|
||||||
*
|
|
||||||
* @param[in] aPrefix The prefix contained in this option.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void SetPrefix(const Ip6::Prefix &aPrefix);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns the prefix in this option.
|
|
||||||
*
|
|
||||||
* @returns The IPv6 prefix in this option.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
Ip6::Prefix GetPrefix(void) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method tells whether this option is valid.
|
|
||||||
*
|
|
||||||
* @returns A boolean indicates whether this option is valid.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
bool IsValid(void) const
|
|
||||||
{
|
|
||||||
return (GetSize() == sizeof(*this)) && (mPrefixLength <= OT_IP6_ADDRESS_SIZE * CHAR_BIT) &&
|
|
||||||
(GetPreferredLifetime() <= GetValidLifetime());
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static constexpr uint8_t kAutoConfigFlagMask = 0x40; // Bit mask of the Automatic Address Configure flag.
|
|
||||||
static constexpr uint8_t kOnLinkFlagMask = 0x80; // Bit mask of the On-link flag.
|
|
||||||
|
|
||||||
uint8_t mPrefixLength; // The prefix length in bits.
|
|
||||||
uint8_t mReserved1; // The reserved field.
|
|
||||||
uint32_t mValidLifetime; // The valid lifetime of the prefix.
|
|
||||||
uint32_t mPreferredLifetime; // The preferred lifetime of the prefix.
|
|
||||||
uint32_t mReserved2; // The reserved field.
|
|
||||||
Ip6::Address mPrefix; // The prefix.
|
|
||||||
} OT_TOOL_PACKED_END;
|
|
||||||
|
|
||||||
static_assert(sizeof(PrefixInfoOption) == 32, "invalid PrefixInfoOption structure");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class represents the Route Information Option.
|
|
||||||
*
|
|
||||||
* See section 2.3 of RFC 4191 for definition of this option.
|
|
||||||
* https://tools.ietf.org/html/rfc4191#section-2.3
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
OT_TOOL_PACKED_BEGIN
|
|
||||||
class RouteInfoOption : public Option
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* This type represents a route preference.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
typedef NetworkData::RoutePreference RoutePreference;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This constructor initializes this option with zero prefix length.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
RouteInfoOption(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method sets the route preference.
|
|
||||||
*
|
|
||||||
* @param[in] aPreference The route preference.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void SetPreference(RoutePreference aPreference);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns the route preference.
|
|
||||||
*
|
|
||||||
* @returns The route preference.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
RoutePreference GetPreference(void) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method sets the lifetime of the route in seconds.
|
|
||||||
*
|
|
||||||
* @param[in] aLifetime The lifetime of the route in seconds.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void SetRouteLifetime(uint32_t aLifetime) { mRouteLifetime = HostSwap32(aLifetime); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns Route Lifetime in seconds.
|
|
||||||
*
|
|
||||||
* @returns The Route Lifetime in seconds.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
uint32_t GetRouteLifetime(void) const { return HostSwap32(mRouteLifetime); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method sets the prefix.
|
|
||||||
*
|
|
||||||
* @param[in] aPrefix The prefix contained in this option.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void SetPrefix(const Ip6::Prefix &aPrefix);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns the prefix in this option.
|
|
||||||
*
|
|
||||||
* @returns The IPv6 prefix in this option.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
Ip6::Prefix GetPrefix(void) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method tells whether this option is valid.
|
|
||||||
*
|
|
||||||
* @returns A boolean indicates whether this option is valid.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
bool IsValid(void) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static constexpr uint8_t kPreferenceOffset = 3;
|
|
||||||
static constexpr uint8_t kPreferenceMask = 3 << kPreferenceOffset;
|
|
||||||
|
|
||||||
uint8_t mPrefixLength; // The prefix length in bits.
|
|
||||||
uint8_t mReserved; // The reserved field.
|
|
||||||
uint32_t mRouteLifetime; // The lifetime in seconds.
|
|
||||||
Ip6::Address mPrefix; // The prefix.
|
|
||||||
} OT_TOOL_PACKED_END;
|
|
||||||
|
|
||||||
static_assert(sizeof(RouteInfoOption) == 24, "invalid RouteInfoOption structure");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class implements the Router Advertisement message.
|
|
||||||
*
|
|
||||||
* See section 4.2 of RFC 4861 for definition of this message.
|
|
||||||
* https://tools.ietf.org/html/rfc4861#section-4.2
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
OT_TOOL_PACKED_BEGIN
|
|
||||||
class RouterAdvMessage : public Unequatable<RouterAdvMessage>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* This constructor initializes the Router Advertisement message with
|
|
||||||
* zero router lifetime, reachable time and retransmission timer.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
RouterAdvMessage(void) { SetToDefault(); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method sets the RA message to default values.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void SetToDefault(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method sets the checksum value.
|
|
||||||
*
|
|
||||||
* @param[in] aChecksum The checksum value.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void SetChecksum(uint16_t aChecksum) { mHeader.SetChecksum(aChecksum); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method sets the Router Lifetime in seconds.
|
|
||||||
*
|
|
||||||
* Zero Router Lifetime means we are not a default router.
|
|
||||||
*
|
|
||||||
* @param[in] aRouterLifetime The router lifetime in seconds.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void SetRouterLifetime(uint16_t aRouterLifetime)
|
|
||||||
{
|
|
||||||
mHeader.mData.m16[kRouteLifetimeIdx] = HostSwap16(aRouterLifetime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns the Router Lifetime.
|
|
||||||
*
|
|
||||||
* Zero Router Lifetime means we are not a default router.
|
|
||||||
*
|
|
||||||
* @returns The router lifetime in seconds.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
uint16_t GetRouterLifetime(void) const { return HostSwap16(mHeader.mData.m16[kRouteLifetimeIdx]); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns the Managed Address Configuration ('m') flag.
|
|
||||||
*
|
|
||||||
* @returns A boolean which indicates whether the 'm' flag is set.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
bool GetManagedAddrConfig(void) const { return (mHeader.mData.m8[kReservedIdx] & kManagedAddressConfigMask) != 0; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method overloads the assignment operator.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
const RouterAdvMessage &operator=(const RouterAdvMessage &aOther);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method overloads operator `==` to evaluate whether or not
|
|
||||||
* two instances of `RouterAdvMessage` are equal.
|
|
||||||
*
|
|
||||||
* @param[in] aOther The other `RouterAdvMessage` instance to compare with.
|
|
||||||
*
|
|
||||||
* @retval TRUE If the two `RouterAdvMessage` instances are equal.
|
|
||||||
* @retval FALSE If the two `RouterAdvMessage` instances are not equal.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
bool operator==(const RouterAdvMessage &aOther) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// The index of Route Lifetime in ICMPv6 Header Data. In unit of 2 octets.
|
|
||||||
static constexpr uint8_t kRouteLifetimeIdx = 1;
|
|
||||||
|
|
||||||
// The index of Reserved byte in ICMPv6 Header Data. In unit of 1 octet.
|
|
||||||
static constexpr uint8_t kReservedIdx = 1;
|
|
||||||
|
|
||||||
// The bitmask of the Managed Address Configuration ('m') flag.
|
|
||||||
static constexpr uint8_t kManagedAddressConfigMask = 0x80;
|
|
||||||
|
|
||||||
Ip6::Icmp::Header mHeader; // The common ICMPv6 header.
|
|
||||||
uint32_t mReachableTime; // The reachable time. In milliseconds.
|
|
||||||
uint32_t mRetransTimer; // The retransmission timer. In milliseconds.
|
|
||||||
} OT_TOOL_PACKED_END;
|
|
||||||
|
|
||||||
static_assert(sizeof(RouterAdvMessage) == 16, "invalid RouterAdvMessage structure");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class implements the Router Solicitation message.
|
|
||||||
*
|
|
||||||
* See section 4.1 of RFC 4861 for definition of this message.
|
|
||||||
* https://tools.ietf.org/html/rfc4861#section-4.1
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
OT_TOOL_PACKED_BEGIN
|
|
||||||
class RouterSolicitMessage
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* This constructor initializes the Router Solicitation message.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
RouterSolicitMessage(void);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ip6::Icmp::Header mHeader; // The common ICMPv6 header.
|
|
||||||
} OT_TOOL_PACKED_END;
|
|
||||||
|
|
||||||
static_assert(sizeof(RouterSolicitMessage) == 8, "invalid RouterSolicitMessage structure");
|
|
||||||
|
|
||||||
} // namespace RouterAdv
|
|
||||||
|
|
||||||
} // namespace BorderRouter
|
|
||||||
|
|
||||||
} // namespace ot
|
|
||||||
|
|
||||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
|
||||||
|
|
||||||
#endif // ROUTER_ADVERTISEMENT_HPP_
|
|
File diff suppressed because it is too large
Load Diff
|
@ -48,15 +48,16 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <openthread/netdata.h>
|
#include <openthread/netdata.h>
|
||||||
#include <openthread/platform/infra_if.h>
|
|
||||||
|
|
||||||
#include "border_router/router_advertisement.hpp"
|
#include "border_router/infra_if.hpp"
|
||||||
#include "common/array.hpp"
|
#include "common/array.hpp"
|
||||||
#include "common/error.hpp"
|
#include "common/error.hpp"
|
||||||
#include "common/locator.hpp"
|
#include "common/locator.hpp"
|
||||||
#include "common/notifier.hpp"
|
#include "common/notifier.hpp"
|
||||||
|
#include "common/string.hpp"
|
||||||
#include "common/timer.hpp"
|
#include "common/timer.hpp"
|
||||||
#include "net/ip6.hpp"
|
#include "net/ip6.hpp"
|
||||||
|
#include "net/nd6.hpp"
|
||||||
#include "thread/network_data.hpp"
|
#include "thread/network_data.hpp"
|
||||||
|
|
||||||
namespace ot {
|
namespace ot {
|
||||||
|
@ -73,6 +74,7 @@ namespace BorderRouter {
|
||||||
class RoutingManager : public InstanceLocator
|
class RoutingManager : public InstanceLocator
|
||||||
{
|
{
|
||||||
friend class ot::Notifier;
|
friend class ot::Notifier;
|
||||||
|
friend class ot::Instance;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -155,35 +157,21 @@ public:
|
||||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE
|
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method receives an ICMPv6 message on the infrastructure interface.
|
* This method processes a received ICMPv6 message from the infrastructure interface.
|
||||||
*
|
*
|
||||||
* Malformed or undesired messages are dropped silently.
|
* Malformed or undesired messages are dropped silently.
|
||||||
*
|
*
|
||||||
* @param[in] aInfraIfIndex The infrastructure interface index.
|
* @param[in] aPacket The received ICMPv6 packet.
|
||||||
* @param[in] aSrcAddress The source address this message is sent from.
|
* @param[in] aSrcAddress The source address this message is sent from.
|
||||||
* @param[in] aBuffer THe ICMPv6 message buffer.
|
|
||||||
* @param[in] aLength The length of the ICMPv6 message buffer.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void RecvIcmp6Message(uint32_t aInfraIfIndex,
|
void HandleReceived(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress);
|
||||||
const Ip6::Address &aSrcAddress,
|
|
||||||
const uint8_t * aBuffer,
|
|
||||||
uint16_t aBufferLength);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method handles infrastructure interface state changes.
|
* This method handles infrastructure interface state changes.
|
||||||
*
|
*
|
||||||
* @param[in] aInfraIfIndex The index of the infrastructure interface.
|
|
||||||
* @param[in] aIsRunning A boolean that indicates whether the infrastructure
|
|
||||||
* interface is running.
|
|
||||||
*
|
|
||||||
* @retval kErrorNone Successfully updated the infra interface status.
|
|
||||||
* @retval kErrorInvalidState The Routing Manager is not initialized.
|
|
||||||
* @retval kErrorInvalidArgs The @p aInfraIfIndex doesn't match the infra interface
|
|
||||||
* the Routing Manager is initialized with.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
Error HandleInfraIfStateChanged(uint32_t aInfraIfIndex, bool aIsRunning);
|
void HandleInfraIfStateChanged(void) { EvaluateState(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method checks if the on-mesh prefix configuration is a valid OMR prefix.
|
* This method checks if the on-mesh prefix configuration is a valid OMR prefix.
|
||||||
|
@ -250,76 +238,162 @@ private:
|
||||||
// The value is chosen in range of [`kMaxRtrAdvInterval` upper bound (1800s), `kDefaultOnLinkPrefixLifetime`].
|
// The value is chosen in range of [`kMaxRtrAdvInterval` upper bound (1800s), `kDefaultOnLinkPrefixLifetime`].
|
||||||
static constexpr uint32_t kRtrAdvStaleTime = 1800;
|
static constexpr uint32_t kRtrAdvStaleTime = 1800;
|
||||||
|
|
||||||
// The VICARIOUS_SOLICIT_TIME in seconds. The Routing Manager will consider
|
|
||||||
// the discovered prefixes invalid if they are not refreshed after receiving
|
|
||||||
// a Router Solicitation message.
|
|
||||||
// The value is equal to Router Solicitation timeout.
|
|
||||||
static constexpr uint32_t kVicariousSolicitationTime =
|
|
||||||
kRtrSolicitationInterval * (kMaxRtrSolicitations - 1) + kMaxRtrSolicitationDelay;
|
|
||||||
|
|
||||||
static_assert(kMinRtrAdvInterval <= 3 * kMaxRtrAdvInterval / 4, "invalid RA intervals");
|
static_assert(kMinRtrAdvInterval <= 3 * kMaxRtrAdvInterval / 4, "invalid RA intervals");
|
||||||
static_assert(kDefaultOmrPrefixLifetime >= kMaxRtrAdvInterval, "invalid default OMR prefix lifetime");
|
static_assert(kDefaultOmrPrefixLifetime >= kMaxRtrAdvInterval, "invalid default OMR prefix lifetime");
|
||||||
static_assert(kDefaultOnLinkPrefixLifetime >= kMaxRtrAdvInterval, "invalid default on-link prefix lifetime");
|
static_assert(kDefaultOnLinkPrefixLifetime >= kMaxRtrAdvInterval, "invalid default on-link prefix lifetime");
|
||||||
static_assert(kRtrAdvStaleTime >= 1800 && kRtrAdvStaleTime <= kDefaultOnLinkPrefixLifetime,
|
static_assert(kRtrAdvStaleTime >= 1800 && kRtrAdvStaleTime <= kDefaultOnLinkPrefixLifetime,
|
||||||
"invalid RA STALE time");
|
"invalid RA STALE time");
|
||||||
|
|
||||||
// This struct represents an external prefix which is
|
class DiscoveredPrefixTable : public InstanceLocator
|
||||||
// discovered on the infrastructure interface.
|
|
||||||
struct ExternalPrefix : public Clearable<ExternalPrefix>, public Unequatable<ExternalPrefix>
|
|
||||||
{
|
{
|
||||||
Ip6::Prefix mPrefix;
|
// This class maintains the discovered on-link and route prefixes
|
||||||
uint32_t mValidLifetime;
|
// from the received RA messages by processing PIO and RIO options
|
||||||
|
// from the message. It takes care of processing the RA message but
|
||||||
|
// delegates the decision whether to include or exclude a prefix to
|
||||||
|
// `RoutingManager` by calling its `ShouldProcessPrefixInfoOption()`
|
||||||
|
// and `ShouldProcessRouteInfoOption()` methods.
|
||||||
|
//
|
||||||
|
// It manages the lifetime of the discovered entries and publishes
|
||||||
|
// and unpublishes the prefixes in the Network Data (as external
|
||||||
|
// route) as they are added or removed.
|
||||||
|
//
|
||||||
|
// When there is any change in the table (an entry is added, removed,
|
||||||
|
// or modified), it signals the change to `RoutingManager` by calling
|
||||||
|
// `HandleDiscoveredPrefixTableChanged()` callback. A `Tasklet` is
|
||||||
|
// used for signalling which ensures that if there are multiple
|
||||||
|
// changes within the same flow of execution, the callback is
|
||||||
|
// invoked after all the changes are processed.
|
||||||
|
|
||||||
union
|
public:
|
||||||
|
enum NetDataMode : uint8_t // Used in `Remove{}` methods
|
||||||
{
|
{
|
||||||
// Preferred Lifetime of on-link prefix, available
|
kUnpublishFromNetData, // Unpublish the entry from Network Data if previously published.
|
||||||
// only when `mIsOnLinkPrefix` is TRUE.
|
kKeepInNetData, // Keep entry in Network Data if previously published.
|
||||||
uint32_t mPreferredLifetime;
|
|
||||||
|
|
||||||
// The preference of this route, available
|
|
||||||
// only when `mIsOnLinkPrefix` is FALSE.
|
|
||||||
RoutePreference mRoutePreference;
|
|
||||||
};
|
};
|
||||||
TimeMilli mTimeLastUpdate;
|
|
||||||
bool mIsOnLinkPrefix;
|
|
||||||
|
|
||||||
bool operator==(const ExternalPrefix &aPrefix) const
|
explicit DiscoveredPrefixTable(Instance &aInstance);
|
||||||
|
|
||||||
|
void ProcessRouterAdvertMessage(const Ip6::Nd::RouterAdvertMessage &aRaMessage,
|
||||||
|
const Ip6::Address & aSrcAddress);
|
||||||
|
|
||||||
|
void FindFavoredOnLinkPrefix(Ip6::Prefix &aPrefix) const;
|
||||||
|
bool ContainsOnLinkPrefix(const Ip6::Prefix &aPrefix) const;
|
||||||
|
void RemoveOnLinkPrefix(const Ip6::Prefix &aPrefix, NetDataMode aNetDataMode);
|
||||||
|
|
||||||
|
bool ContainsRoutePrefix(const Ip6::Prefix &aPrefix) const;
|
||||||
|
void RemoveRoutePrefix(const Ip6::Prefix &aPrefix, NetDataMode aNetDataMode);
|
||||||
|
|
||||||
|
void RemoveAllEntries(void);
|
||||||
|
void RemoveOrDeprecateOldEntries(TimeMilli aTimeThreshold);
|
||||||
|
|
||||||
|
TimeMilli CalculateNextStaleTime(TimeMilli aNow) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr uint8_t kMaxEntries = OPENTHREAD_CONFIG_BORDER_ROUTING_MAX_DISCOVERED_PREFIXES;
|
||||||
|
|
||||||
|
struct Entry : private Clearable<Entry>, public Unequatable<Entry>
|
||||||
{
|
{
|
||||||
return mPrefix == aPrefix.mPrefix && mIsOnLinkPrefix == aPrefix.mIsOnLinkPrefix;
|
public:
|
||||||
}
|
enum Type : uint8_t
|
||||||
|
{
|
||||||
|
kTypeOnLink,
|
||||||
|
kTypeRoute,
|
||||||
|
};
|
||||||
|
|
||||||
bool IsDeprecated(void) const
|
struct Matcher
|
||||||
{
|
{
|
||||||
OT_ASSERT(mIsOnLinkPrefix);
|
Matcher(const Ip6::Prefix &aPrefix, Type aType)
|
||||||
|
: mPrefix(aPrefix)
|
||||||
|
, mType(aType)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
return mTimeLastUpdate + TimeMilli::SecToMsec(mPreferredLifetime) <= TimerMilli::GetNow();
|
const Ip6::Prefix &mPrefix;
|
||||||
}
|
bool mType;
|
||||||
|
};
|
||||||
|
|
||||||
TimeMilli GetExpireTime(void) const { return mTimeLastUpdate + GetPrefixExpireDelay(mValidLifetime); }
|
void InitFrom(const Ip6::Nd::PrefixInfoOption &aPio);
|
||||||
TimeMilli GetStaleTime(void) const
|
void InitFrom(const Ip6::Nd::RouteInfoOption &aRio);
|
||||||
{
|
bool IsOnLinkPrefix(void) const { return (mType == kTypeOnLink); }
|
||||||
uint32_t delay = OT_MIN(kRtrAdvStaleTime, mIsOnLinkPrefix ? mPreferredLifetime : mValidLifetime);
|
const Ip6::Prefix &GetPrefix(void) const { return mPrefix; }
|
||||||
|
const TimeMilli & GetLastUpdateTime(void) const { return mLastUpdateTime; }
|
||||||
|
uint32_t GetValidLifetime(void) const { return mValidLifetime; }
|
||||||
|
void ClearValidLifetime(void) { mValidLifetime = 0; }
|
||||||
|
TimeMilli GetExpireTime(void) const;
|
||||||
|
TimeMilli GetStaleTime(void) const;
|
||||||
|
bool operator==(const Entry &aOther) const;
|
||||||
|
bool Matches(const Matcher &aMatcher) const;
|
||||||
|
|
||||||
return mTimeLastUpdate + TimeMilli::SecToMsec(delay);
|
// Methods to use when `IsOnLinkPrefix()`
|
||||||
}
|
uint32_t GetPreferredLifetime(void) const { return mPreferredLifetime; }
|
||||||
|
void ClearPreferredLifetime(void) { mPreferredLifetime = 0; }
|
||||||
|
bool IsDeprecated(void) const;
|
||||||
|
void AdoptValidAndPreferredLiftimesFrom(const Entry &aEntry);
|
||||||
|
|
||||||
static uint32_t GetPrefixExpireDelay(uint32_t aValidLifetime);
|
// Method to use when `!IsOnlinkPrefix()`
|
||||||
|
RoutePreference GetRoutePreference(void) const { return mRoutePreference; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static uint32_t CalculateExpireDelay(uint32_t aValidLifetime);
|
||||||
|
|
||||||
|
Ip6::Prefix mPrefix;
|
||||||
|
TimeMilli mLastUpdateTime;
|
||||||
|
uint32_t mValidLifetime;
|
||||||
|
uint32_t mPreferredLifetime; // Applicable when prefix is on-link.
|
||||||
|
RoutePreference mRoutePreference; // Applicable when prefix is not on-link
|
||||||
|
Type mType;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Array<Entry, kMaxEntries> EntryArray;
|
||||||
|
|
||||||
|
void RemovePrefix(const Ip6::Prefix &aPrefix, Entry::Type aType, NetDataMode aNetDataMode);
|
||||||
|
|
||||||
|
void ProcessPrefixInfoOption(const Ip6::Nd::PrefixInfoOption &aPio);
|
||||||
|
void ProcessRouteInfoOption(const Ip6::Nd::RouteInfoOption &aRio);
|
||||||
|
static void HandleTimer(Timer &aTimer);
|
||||||
|
void HandleTimer(void);
|
||||||
|
void RemoveExpiredEntries(void);
|
||||||
|
void SignalTableChanged(void);
|
||||||
|
static void HandleSignalTask(Tasklet &aTasklet);
|
||||||
|
|
||||||
|
EntryArray mEntries;
|
||||||
|
TimerMilli mTimer;
|
||||||
|
Tasklet mSignalTask;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Array<Ip6::Prefix, kMaxOmrPrefixNum> OmrPrefixArray;
|
class OmrPrefix // An OMR Prefix
|
||||||
typedef Array<ExternalPrefix, kMaxDiscoveredPrefixNum> ExternalPrefixArray;
|
{
|
||||||
|
public:
|
||||||
|
static constexpr uint16_t kInfoStringSize = 60;
|
||||||
|
typedef String<kInfoStringSize> InfoString;
|
||||||
|
|
||||||
|
void Init(const Ip6::Prefix &aPrefix, RoutePreference aPreference);
|
||||||
|
void InitFrom(NetworkData::OnMeshPrefixConfig &aOnMeshPrefixConfig);
|
||||||
|
const Ip6::Prefix &GetPrefix(void) const { return mPrefix; }
|
||||||
|
RoutePreference GetPreference(void) const { return mPreference; }
|
||||||
|
void SetPreference(RoutePreference aPreference) { mPreference = aPreference; }
|
||||||
|
bool Matches(const Ip6::Prefix &aPrefix) const { return mPrefix == aPrefix; }
|
||||||
|
bool IsFavoredOver(const OmrPrefix &aOther) const;
|
||||||
|
InfoString ToString(void) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ip6::Prefix mPrefix;
|
||||||
|
RoutePreference mPreference;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Array<OmrPrefix, kMaxOmrPrefixNum> OmrPrefixArray;
|
||||||
|
|
||||||
void EvaluateState(void);
|
void EvaluateState(void);
|
||||||
void Start(void);
|
void Start(void);
|
||||||
void Stop(void);
|
void Stop(void);
|
||||||
void HandleNotifierEvents(Events aEvents);
|
void HandleNotifierEvents(Events aEvents);
|
||||||
bool IsInitialized(void) const { return mInfraIfIndex != 0; }
|
bool IsInitialized(void) const { return mInfraIf.IsInitialized(); }
|
||||||
bool IsEnabled(void) const { return mIsEnabled; }
|
bool IsEnabled(void) const { return mIsEnabled; }
|
||||||
Error LoadOrGenerateRandomBrUlaPrefix(void);
|
Error LoadOrGenerateRandomBrUlaPrefix(void);
|
||||||
void GenerateOmrPrefix(void);
|
void GenerateOmrPrefix(void);
|
||||||
Error LoadOrGenerateRandomOnLinkPrefix(void);
|
void GenerateOnLinkPrefix(void);
|
||||||
|
|
||||||
const Ip6::Prefix *EvaluateOnLinkPrefix(void);
|
void EvaluateOnLinkPrefix(void);
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE
|
#if OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE
|
||||||
void GenerateNat64Prefix(void);
|
void GenerateNat64Prefix(void);
|
||||||
|
@ -333,17 +407,13 @@ private:
|
||||||
Error PublishLocalOmrPrefix(void);
|
Error PublishLocalOmrPrefix(void);
|
||||||
void UnpublishLocalOmrPrefix(void);
|
void UnpublishLocalOmrPrefix(void);
|
||||||
bool IsOmrPrefixAddedToLocalNetworkData(void) const;
|
bool IsOmrPrefixAddedToLocalNetworkData(void) const;
|
||||||
Error AddExternalRoute(const Ip6::Prefix &aPrefix, RoutePreference aRoutePreference, bool aNat64 = false);
|
Error PublishExternalRoute(const Ip6::Prefix &aPrefix, RoutePreference aRoutePreference, bool aNat64 = false);
|
||||||
void RemoveExternalRoute(const Ip6::Prefix &aPrefix);
|
void UnpublishExternalRoute(const Ip6::Prefix &aPrefix);
|
||||||
void StartRouterSolicitationDelay(void);
|
void StartRouterSolicitationDelay(void);
|
||||||
Error SendRouterSolicitation(void);
|
Error SendRouterSolicitation(void);
|
||||||
void SendRouterAdvertisement(const OmrPrefixArray &aNewOmrPrefixes, const Ip6::Prefix *aNewOnLinkPrefix);
|
void SendRouterAdvertisement(const OmrPrefixArray &aNewOmrPrefixes);
|
||||||
bool IsRouterSolicitationInProgress(void) const;
|
bool IsRouterSolicitationInProgress(void) const;
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_VICARIOUS_RS_ENABLE
|
|
||||||
static void HandleVicariousRouterSolicitTimer(Timer &aTimer);
|
|
||||||
void HandleVicariousRouterSolicitTimer(void);
|
|
||||||
#endif
|
|
||||||
static void HandleRouterSolicitTimer(Timer &aTimer);
|
static void HandleRouterSolicitTimer(Timer &aTimer);
|
||||||
void HandleRouterSolicitTimer(void);
|
void HandleRouterSolicitTimer(void);
|
||||||
static void HandleDiscoveredPrefixInvalidTimer(Timer &aTimer);
|
static void HandleDiscoveredPrefixInvalidTimer(Timer &aTimer);
|
||||||
|
@ -355,18 +425,17 @@ private:
|
||||||
static void HandleOnLinkPrefixDeprecateTimer(Timer &aTimer);
|
static void HandleOnLinkPrefixDeprecateTimer(Timer &aTimer);
|
||||||
|
|
||||||
void DeprecateOnLinkPrefix(void);
|
void DeprecateOnLinkPrefix(void);
|
||||||
void HandleRouterSolicit(const Ip6::Address &aSrcAddress, const uint8_t *aBuffer, uint16_t aBufferLength);
|
void HandleRouterSolicit(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress);
|
||||||
void HandleRouterAdvertisement(const Ip6::Address &aSrcAddress, const uint8_t *aBuffer, uint16_t aBufferLength);
|
void HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress);
|
||||||
bool UpdateDiscoveredOnLinkPrefix(const RouterAdv::PrefixInfoOption &aPio);
|
bool ShouldProcessPrefixInfoOption(const Ip6::Nd::PrefixInfoOption &aPio, const Ip6::Prefix &aPrefix);
|
||||||
void UpdateDiscoveredOmrPrefix(const RouterAdv::RouteInfoOption &aRio);
|
bool ShouldProcessRouteInfoOption(const Ip6::Nd::RouteInfoOption &aRio, const Ip6::Prefix &aPrefix);
|
||||||
void InvalidateDiscoveredPrefixes(const Ip6::Prefix *aPrefix = nullptr, bool aIsOnLinkPrefix = true);
|
void HandleDiscoveredPrefixTableChanged(void);
|
||||||
void InvalidateAllDiscoveredPrefixes(void);
|
|
||||||
bool NetworkDataContainsOmrPrefix(const Ip6::Prefix &aPrefix) const;
|
bool NetworkDataContainsOmrPrefix(const Ip6::Prefix &aPrefix) const;
|
||||||
bool UpdateRouterAdvMessage(const RouterAdv::RouterAdvMessage *aRouterAdvMessage);
|
void UpdateRouterAdvertHeader(const Ip6::Nd::RouterAdvertMessage *aRouterAdvertMessage);
|
||||||
void ResetDiscoveredPrefixStaleTimer(void);
|
void ResetDiscoveredPrefixStaleTimer(void);
|
||||||
|
|
||||||
static bool IsValidBrUlaPrefix(const Ip6::Prefix &aBrUlaPrefix);
|
static bool IsValidBrUlaPrefix(const Ip6::Prefix &aBrUlaPrefix);
|
||||||
static bool IsValidOnLinkPrefix(const RouterAdv::PrefixInfoOption &aPio);
|
static bool IsValidOnLinkPrefix(const Ip6::Nd::PrefixInfoOption &aPio);
|
||||||
static bool IsValidOnLinkPrefix(const Ip6::Prefix &aOnLinkPrefix);
|
static bool IsValidOnLinkPrefix(const Ip6::Prefix &aOnLinkPrefix);
|
||||||
|
|
||||||
// Indicates whether the Routing Manager is running (started).
|
// Indicates whether the Routing Manager is running (started).
|
||||||
|
@ -376,13 +445,7 @@ private:
|
||||||
// Manager will be stopped if we are disabled.
|
// Manager will be stopped if we are disabled.
|
||||||
bool mIsEnabled;
|
bool mIsEnabled;
|
||||||
|
|
||||||
// Indicates whether the infra interface is running. The Routing
|
InfraIf mInfraIf;
|
||||||
// Manager will be stopped when the Infra interface is not running.
|
|
||||||
bool mInfraIfIsRunning;
|
|
||||||
|
|
||||||
// The index of the infra interface on which Router Advertisement
|
|
||||||
// messages will be sent.
|
|
||||||
uint32_t mInfraIfIndex;
|
|
||||||
|
|
||||||
// The /48 BR ULA prefix loaded from local persistent storage or
|
// The /48 BR ULA prefix loaded from local persistent storage or
|
||||||
// randomly generated if none is found in persistent storage.
|
// randomly generated if none is found in persistent storage.
|
||||||
|
@ -399,6 +462,10 @@ private:
|
||||||
// advertised on infra link.
|
// advertised on infra link.
|
||||||
OmrPrefixArray mAdvertisedOmrPrefixes;
|
OmrPrefixArray mAdvertisedOmrPrefixes;
|
||||||
|
|
||||||
|
// The currently favored (smallest) discovered on-link prefix.
|
||||||
|
// Prefix length of zero indicates there is none.
|
||||||
|
Ip6::Prefix mFavoredDiscoveredOnLinkPrefix;
|
||||||
|
|
||||||
// The on-link prefix loaded from local persistent storage or
|
// The on-link prefix loaded from local persistent storage or
|
||||||
// randomly generated if non is found in persistent storage.
|
// randomly generated if non is found in persistent storage.
|
||||||
Ip6::Prefix mLocalOnLinkPrefix;
|
Ip6::Prefix mLocalOnLinkPrefix;
|
||||||
|
@ -416,29 +483,20 @@ private:
|
||||||
// True if the local NAT64 prefix is advertised in Thread network.
|
// True if the local NAT64 prefix is advertised in Thread network.
|
||||||
bool mIsAdvertisingLocalNat64Prefix;
|
bool mIsAdvertisingLocalNat64Prefix;
|
||||||
|
|
||||||
// The array of prefixes discovered on the infra link. Those
|
DiscoveredPrefixTable mDiscoveredPrefixTable;
|
||||||
// prefixes consist of on-link prefix(es) and OMR prefixes
|
|
||||||
// advertised by BRs in another Thread Network which is connected to
|
|
||||||
// the same infra link.
|
|
||||||
ExternalPrefixArray mDiscoveredPrefixes;
|
|
||||||
|
|
||||||
// The RA header and parameters for the infra interface.
|
// The RA header and parameters for the infra interface.
|
||||||
// This value is initialized with `RouterAdvMessage::SetToDefault`
|
// This value is initialized with `RouterAdvMessage::SetToDefault`
|
||||||
// and updated with RA messages initiated from infra interface.
|
// and updated with RA messages initiated from infra interface.
|
||||||
RouterAdv::RouterAdvMessage mRouterAdvMessage;
|
Ip6::Nd::RouterAdvertMessage::Header mRouterAdvertHeader;
|
||||||
TimeMilli mTimeRouterAdvMessageLastUpdate;
|
TimeMilli mTimeRouterAdvMessageLastUpdate;
|
||||||
bool mLearntRouterAdvMessageFromHost;
|
bool mLearntRouterAdvMessageFromHost;
|
||||||
|
|
||||||
TimerMilli mDiscoveredPrefixInvalidTimer;
|
|
||||||
TimerMilli mDiscoveredPrefixStaleTimer;
|
TimerMilli mDiscoveredPrefixStaleTimer;
|
||||||
|
|
||||||
uint32_t mRouterAdvertisementCount;
|
uint32_t mRouterAdvertisementCount;
|
||||||
TimeMilli mLastRouterAdvertisementSendTime;
|
TimeMilli mLastRouterAdvertisementSendTime;
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_VICARIOUS_RS_ENABLE
|
|
||||||
TimerMilli mVicariousRouterSolicitTimer;
|
|
||||||
TimeMilli mTimeVicariousRouterSolicitStart;
|
|
||||||
#endif
|
|
||||||
TimerMilli mRouterSolicitTimer;
|
TimerMilli mRouterSolicitTimer;
|
||||||
TimeMilli mTimeRouterSolicitStart;
|
TimeMilli mTimeRouterSolicitStart;
|
||||||
uint8_t mRouterSolicitCount;
|
uint8_t mRouterSolicitCount;
|
||||||
|
|
|
@ -310,6 +310,27 @@ public:
|
||||||
*/
|
*/
|
||||||
IndexType IndexOf(const Type &aElement) const { return static_cast<IndexType>(&aElement - &mElements[0]); }
|
IndexType IndexOf(const Type &aElement) const { return static_cast<IndexType>(&aElement - &mElements[0]); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method removes an element from the array.
|
||||||
|
*
|
||||||
|
* The @p aElement MUST be from the array, otherwise the behavior of this method is undefined.
|
||||||
|
*
|
||||||
|
* To remove @p aElement, it is replaced by the last element in array, so the order of items in the array can
|
||||||
|
* change after a call to this method.
|
||||||
|
*
|
||||||
|
* The method uses assignment `=` operator on `Type` to copy the last element in place of @p aElement.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void Remove(Type &aElement)
|
||||||
|
{
|
||||||
|
Type *lastElement = PopBack();
|
||||||
|
|
||||||
|
if (lastElement != &aElement)
|
||||||
|
{
|
||||||
|
aElement = *lastElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method finds the first match of a given entry in the array.
|
* This method finds the first match of a given entry in the array.
|
||||||
*
|
*
|
||||||
|
@ -430,6 +451,32 @@ public:
|
||||||
return FindMatching(aIndicator) != nullptr;
|
return FindMatching(aIndicator) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This template method removes the first element in the array matching a given indicator.
|
||||||
|
*
|
||||||
|
* This method behaves similar to `Remove()`, i.e., the matched element (if found) is replaced with the last element
|
||||||
|
* in the array (using `=` operator on `Type`). So the order of items in the array can change after a call to this
|
||||||
|
* method.
|
||||||
|
*
|
||||||
|
* The template type `Indicator` specifies the type of @p aIndicator object which is used to match against elements
|
||||||
|
* in the array. To check that an element matches the given indicator, the `Matches()` method is invoked on each
|
||||||
|
* `Type` element in the array. The `Matches()` method should be provided by `Type` class accordingly:
|
||||||
|
*
|
||||||
|
* bool Type::Matches(const Indicator &aIndicator) const
|
||||||
|
*
|
||||||
|
* @param[in] aIndicator An indicator to match with elements in the array.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
template <typename Indicator> void RemoveMatching(const Indicator &aIndicator)
|
||||||
|
{
|
||||||
|
Type *entry = FindMatching(aIndicator);
|
||||||
|
|
||||||
|
if (entry != nullptr)
|
||||||
|
{
|
||||||
|
Remove(*entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method overloads assignment `=` operator to copy elements from another array into the array.
|
* This method overloads assignment `=` operator to copy elements from another array into the array.
|
||||||
*
|
*
|
||||||
|
|
|
@ -972,6 +972,11 @@ template <> inline BorderRouter::RoutingManager &Instance::Get(void)
|
||||||
{
|
{
|
||||||
return mRoutingManager;
|
return mRoutingManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <> inline BorderRouter::InfraIf &Instance::Get(void)
|
||||||
|
{
|
||||||
|
return mRoutingManager.mInfraIf;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
||||||
|
|
|
@ -146,15 +146,15 @@ const char *SettingsBase::KeyToString(Key aKey)
|
||||||
"NetworkInfo", // (3) kKeyNetworkInfo
|
"NetworkInfo", // (3) kKeyNetworkInfo
|
||||||
"ParentInfo", // (4) kKeyParentInfo
|
"ParentInfo", // (4) kKeyParentInfo
|
||||||
"ChildInfo", // (5) kKeyChildInfo
|
"ChildInfo", // (5) kKeyChildInfo
|
||||||
"", // (6) kKeyReserved
|
"", // (6) Removed (previously auto-start).
|
||||||
"SlaacIidSecretKey", // (7) kKeySlaacIidSecretKey
|
"SlaacIidSecretKey", // (7) kKeySlaacIidSecretKey
|
||||||
"DadInfo", // (8) kKeyDadInfo
|
"DadInfo", // (8) kKeyDadInfo
|
||||||
"LegacyOmrPrefix", // (9) kKeyLegacyOmrPrefix
|
"", // (9) Removed (previously OMR prefix).
|
||||||
"OnLinkPrefix", // (10) kKeyOnLinkPrefix
|
"", // (10) Removed (previously on-link prefix).
|
||||||
"SrpEcdsaKey", // (11) kKeySrpEcdsaKey
|
"SrpEcdsaKey", // (11) kKeySrpEcdsaKey
|
||||||
"SrpClientInfo", // (12) kKeySrpClientInfo
|
"SrpClientInfo", // (12) kKeySrpClientInfo
|
||||||
"SrpServerInfo", // (13) kKeySrpServerInfo
|
"SrpServerInfo", // (13) kKeySrpServerInfo
|
||||||
"LegacyNat64Prefix", // (14) kKeyLegacyNat64Prefix
|
"", // (14) Removed (previously NAT64 prefix)
|
||||||
"BrUlaPrefix", // (15) kKeyBrUlaPrefix
|
"BrUlaPrefix", // (15) kKeyBrUlaPrefix
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -163,15 +163,11 @@ const char *SettingsBase::KeyToString(Key aKey)
|
||||||
static_assert(3 == kKeyNetworkInfo, "kKeyNetworkInfo value is incorrect");
|
static_assert(3 == kKeyNetworkInfo, "kKeyNetworkInfo value is incorrect");
|
||||||
static_assert(4 == kKeyParentInfo, "kKeyParentInfo value is incorrect");
|
static_assert(4 == kKeyParentInfo, "kKeyParentInfo value is incorrect");
|
||||||
static_assert(5 == kKeyChildInfo, "kKeyChildInfo value is incorrect");
|
static_assert(5 == kKeyChildInfo, "kKeyChildInfo value is incorrect");
|
||||||
static_assert(6 == kKeyReserved, "kKeyReserved value is incorrect");
|
|
||||||
static_assert(7 == kKeySlaacIidSecretKey, "kKeySlaacIidSecretKey value is incorrect");
|
static_assert(7 == kKeySlaacIidSecretKey, "kKeySlaacIidSecretKey value is incorrect");
|
||||||
static_assert(8 == kKeyDadInfo, "kKeyDadInfo value is incorrect");
|
static_assert(8 == kKeyDadInfo, "kKeyDadInfo value is incorrect");
|
||||||
static_assert(9 == kKeyLegacyOmrPrefix, "kKeyLegacyOmrPrefix value is incorrect");
|
|
||||||
static_assert(10 == kKeyOnLinkPrefix, "kKeyOnLinkPrefix value is incorrect");
|
|
||||||
static_assert(11 == kKeySrpEcdsaKey, "kKeySrpEcdsaKey value is incorrect");
|
static_assert(11 == kKeySrpEcdsaKey, "kKeySrpEcdsaKey value is incorrect");
|
||||||
static_assert(12 == kKeySrpClientInfo, "kKeySrpClientInfo value is incorrect");
|
static_assert(12 == kKeySrpClientInfo, "kKeySrpClientInfo value is incorrect");
|
||||||
static_assert(13 == kKeySrpServerInfo, "kKeySrpServerInfo value is incorrect");
|
static_assert(13 == kKeySrpServerInfo, "kKeySrpServerInfo value is incorrect");
|
||||||
static_assert(14 == kKeyLegacyNat64Prefix, "kKeyLegacyNat64Prefix value is incorrect");
|
|
||||||
static_assert(15 == kKeyBrUlaPrefix, "kKeyBrUlaPrefix value is incorrect");
|
static_assert(15 == kKeyBrUlaPrefix, "kKeyBrUlaPrefix value is incorrect");
|
||||||
|
|
||||||
static_assert(kLastKey == kKeyBrUlaPrefix, "kLastKey is not valid");
|
static_assert(kLastKey == kKeyBrUlaPrefix, "kLastKey is not valid");
|
||||||
|
@ -435,9 +431,6 @@ void Settings::Log(Action aAction, Error aError, Key aKey, const void *aValue)
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||||
case kKeyBrUlaPrefix:
|
case kKeyBrUlaPrefix:
|
||||||
case kKeyLegacyOmrPrefix:
|
|
||||||
case kKeyOnLinkPrefix:
|
|
||||||
case kKeyLegacyNat64Prefix:
|
|
||||||
LogPrefix(aAction, aKey, *reinterpret_cast<const Ip6::Prefix *>(aValue));
|
LogPrefix(aAction, aKey, *reinterpret_cast<const Ip6::Prefix *>(aValue));
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -112,15 +112,11 @@ public:
|
||||||
kKeyNetworkInfo = OT_SETTINGS_KEY_NETWORK_INFO,
|
kKeyNetworkInfo = OT_SETTINGS_KEY_NETWORK_INFO,
|
||||||
kKeyParentInfo = OT_SETTINGS_KEY_PARENT_INFO,
|
kKeyParentInfo = OT_SETTINGS_KEY_PARENT_INFO,
|
||||||
kKeyChildInfo = OT_SETTINGS_KEY_CHILD_INFO,
|
kKeyChildInfo = OT_SETTINGS_KEY_CHILD_INFO,
|
||||||
kKeyReserved = OT_SETTINGS_KEY_RESERVED,
|
|
||||||
kKeySlaacIidSecretKey = OT_SETTINGS_KEY_SLAAC_IID_SECRET_KEY,
|
kKeySlaacIidSecretKey = OT_SETTINGS_KEY_SLAAC_IID_SECRET_KEY,
|
||||||
kKeyDadInfo = OT_SETTINGS_KEY_DAD_INFO,
|
kKeyDadInfo = OT_SETTINGS_KEY_DAD_INFO,
|
||||||
kKeyLegacyOmrPrefix = OT_SETTINGS_KEY_LEGACY_OMR_PREFIX,
|
|
||||||
kKeyOnLinkPrefix = OT_SETTINGS_KEY_ON_LINK_PREFIX,
|
|
||||||
kKeySrpEcdsaKey = OT_SETTINGS_KEY_SRP_ECDSA_KEY,
|
kKeySrpEcdsaKey = OT_SETTINGS_KEY_SRP_ECDSA_KEY,
|
||||||
kKeySrpClientInfo = OT_SETTINGS_KEY_SRP_CLIENT_INFO,
|
kKeySrpClientInfo = OT_SETTINGS_KEY_SRP_CLIENT_INFO,
|
||||||
kKeySrpServerInfo = OT_SETTINGS_KEY_SRP_SERVER_INFO,
|
kKeySrpServerInfo = OT_SETTINGS_KEY_SRP_SERVER_INFO,
|
||||||
kKeyLegacyNat64Prefix = OT_SETTINGS_KEY_LEGACY_NAT64_PREFIX,
|
|
||||||
kKeyBrUlaPrefix = OT_SETTINGS_KEY_BR_ULA_PREFIX,
|
kKeyBrUlaPrefix = OT_SETTINGS_KEY_BR_ULA_PREFIX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -583,37 +579,7 @@ public:
|
||||||
private:
|
private:
|
||||||
BrUlaPrefix(void) = default;
|
BrUlaPrefix(void) = default;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
/**
|
|
||||||
* This class defines constants and types for legacy OMR prefix settings.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class LegacyOmrPrefix
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static constexpr Key kKey = kKeyLegacyOmrPrefix; ///< The associated key.
|
|
||||||
|
|
||||||
typedef Ip6::Prefix ValueType; ///< The associated value type.
|
|
||||||
|
|
||||||
private:
|
|
||||||
LegacyOmrPrefix(void) = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class defines constants and types for on-link prefix settings.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class OnLinkPrefix
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static constexpr Key kKey = kKeyOnLinkPrefix; ///< The associated key.
|
|
||||||
|
|
||||||
typedef Ip6::Prefix ValueType; ///< The associated value type.
|
|
||||||
|
|
||||||
private:
|
|
||||||
OnLinkPrefix(void) = default;
|
|
||||||
};
|
|
||||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -94,6 +94,13 @@ void TimeTicker::HandleTimer(void)
|
||||||
Get<AddressResolver>().HandleTimeTick();
|
Get<AddressResolver>().HandleTimeTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE && OPENTHREAD_CONFIG_BORDER_ROUTER_REQUEST_ROUTER_ROLE
|
||||||
|
if (mReceivers & Mask(kNetworkDataNotifier))
|
||||||
|
{
|
||||||
|
Get<NetworkData::Notifier>().HandleTimeTick();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE
|
#if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE
|
||||||
if (mReceivers & Mask(kChildSupervisor))
|
if (mReceivers & Mask(kChildSupervisor))
|
||||||
{
|
{
|
||||||
|
|
|
@ -71,6 +71,7 @@ public:
|
||||||
kIp6FragmentReassembler, ///< `Ip6::Ip6` (handling of fragmented messages)
|
kIp6FragmentReassembler, ///< `Ip6::Ip6` (handling of fragmented messages)
|
||||||
kDuaManager, ///< `DuaManager`
|
kDuaManager, ///< `DuaManager`
|
||||||
kMlrManager, ///< `MlrManager`
|
kMlrManager, ///< `MlrManager`
|
||||||
|
kNetworkDataNotifier, ///< `NetworkData::Notifier`
|
||||||
|
|
||||||
kNumReceivers, ///< Number of receivers.
|
kNumReceivers, ///< Number of receivers.
|
||||||
};
|
};
|
||||||
|
|
|
@ -55,6 +55,32 @@
|
||||||
#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 0
|
#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def OPENTHREAD_CONFIG_BORDER_ROUTER_REQUEST_ROUTER_ROLE
|
||||||
|
*
|
||||||
|
* Define to 1 to enable mechanism on a Border Router which provides IP connectivity to request router role upgrade.
|
||||||
|
*
|
||||||
|
* This config is applicable on an `OPENTHREAD_FTD` build and when `OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE` is also
|
||||||
|
* enabled.
|
||||||
|
*
|
||||||
|
* A Border Router is considered to provide external IP connectivity if at least one of the below conditions hold:
|
||||||
|
*
|
||||||
|
* - It has added at least one external route entry.
|
||||||
|
* - It has added at least one prefix entry with default-route and on-mesh flags set.
|
||||||
|
* - It has added at least one domain prefix (domain and on-mesh flags set).
|
||||||
|
*
|
||||||
|
* A Border Router which provides IP connectivity and is acting as a REED is eligible to request a router role upgrade
|
||||||
|
* by sending an "Address Solicit" request to leader with status reason `BorderRouterRequest`. This reason is used when
|
||||||
|
* the number of active routers in the Thread mesh is above the threshold, and only if the number of existing eligible
|
||||||
|
* BRs (determined from the Thread Network Data) that are acting as router is less than two. This mechanism allows up
|
||||||
|
* to two eligible Border Routers to request router role upgrade when the number of routers is already above the
|
||||||
|
* threshold.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef OPENTHREAD_CONFIG_BORDER_ROUTER_REQUEST_ROUTER_ROLE
|
||||||
|
#define OPENTHREAD_CONFIG_BORDER_ROUTER_REQUEST_ROUTER_ROLE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @def OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
* @def OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||||
*
|
*
|
||||||
|
@ -75,16 +101,6 @@
|
||||||
#define OPENTHREAD_CONFIG_BORDER_ROUTING_MAX_DISCOVERED_PREFIXES 8
|
#define OPENTHREAD_CONFIG_BORDER_ROUTING_MAX_DISCOVERED_PREFIXES 8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* @def OPENTHREAD_CONFIG_BORDER_ROUTING_VICARIOUS_RS_ENABLE
|
|
||||||
*
|
|
||||||
* Define to 1 to enable Border Routing Vicarious Router Solicitation.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifndef OPENTHREAD_CONFIG_BORDER_ROUTING_VICARIOUS_RS_ENABLE
|
|
||||||
#define OPENTHREAD_CONFIG_BORDER_ROUTING_VICARIOUS_RS_ENABLE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @def OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE
|
* @def OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE
|
||||||
*
|
*
|
||||||
|
|
|
@ -499,4 +499,26 @@
|
||||||
#define OPENTHREAD_CONFIG_MAC_SCAN_DURATION 300
|
#define OPENTHREAD_CONFIG_MAC_SCAN_DURATION 300
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE
|
||||||
|
*
|
||||||
|
* This setting configures if the beacon payload parsing needs to be enabled in MAC. This is optional and is disabled by
|
||||||
|
* default because Thread 1.2.1 has removed support for beacon payloads.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE
|
||||||
|
#define OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def OPENTHREAD_CONFIG_MAC_OUTGOING_BEACON_PAYLOAD_ENABLE
|
||||||
|
*
|
||||||
|
* This setting configures if the beacon payload needs to be enabled in outgoing beacon frames. This is optional and is
|
||||||
|
* disabled by default because Thread 1.2.1 has removed support for beacon payloads.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef OPENTHREAD_CONFIG_MAC_OUTGOING_BEACON_PAYLOAD_ENABLE
|
||||||
|
#define OPENTHREAD_CONFIG_MAC_OUTGOING_BEACON_PAYLOAD_ENABLE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // CONFIG_MAC_H_
|
#endif // CONFIG_MAC_H_
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#ifndef CONFIG_NETDATA_PUBLISHER_H_
|
#ifndef CONFIG_NETDATA_PUBLISHER_H_
|
||||||
#define CONFIG_NETDATA_PUBLISHER_H_
|
#define CONFIG_NETDATA_PUBLISHER_H_
|
||||||
|
|
||||||
|
#include "config/border_router.h"
|
||||||
#include "config/srp_server.h"
|
#include "config/srp_server.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,7 +49,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifndef OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE
|
#ifndef OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE
|
||||||
#define OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
#define OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE \
|
||||||
|
(OPENTHREAD_CONFIG_SRP_SERVER_ENABLE || OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -149,7 +151,13 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifndef OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES
|
#ifndef OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||||
|
#define OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES \
|
||||||
|
(OPENTHREAD_CONFIG_BORDER_ROUTING_MAX_DISCOVERED_PREFIXES + 5)
|
||||||
|
#else
|
||||||
#define OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES 3
|
#define OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES 3
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // CONFIG_NETDATA_PUBLISHER_H_
|
#endif // CONFIG_NETDATA_PUBLISHER_H_
|
||||||
|
|
|
@ -623,4 +623,8 @@
|
||||||
#error "OPENTHREAD_CONFIG_PLATFORM_CSL_UNCERT was removed and no longer supported"
|
#error "OPENTHREAD_CONFIG_PLATFORM_CSL_UNCERT was removed and no longer supported"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPENTHREAD_CONFIG_BORDER_ROUTING_VICARIOUS_RS_ENABLE
|
||||||
|
#error "OPENTHREAD_CONFIG_BORDER_ROUTING_VICARIOUS_RS_ENABLE was removed and no longer supported"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // OPENTHREAD_CORE_CONFIG_CHECK_H_
|
#endif // OPENTHREAD_CORE_CONFIG_CHECK_H_
|
||||||
|
|
|
@ -123,11 +123,6 @@ exit:
|
||||||
StopPolling();
|
StopPolling();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kErrorAlready:
|
|
||||||
LogDebg("Data poll tx requested when a previous data request still in send queue.");
|
|
||||||
ScheduleNextPoll(kUsePreviousPollPeriod);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LogWarn("Unexpected error %s requesting data poll", ErrorToString(error));
|
LogWarn("Unexpected error %s requesting data poll", ErrorToString(error));
|
||||||
ScheduleNextPoll(kRecalculatePollPeriod);
|
ScheduleNextPoll(kRecalculatePollPeriod);
|
||||||
|
|
|
@ -164,6 +164,7 @@ public:
|
||||||
* @param[in] aCallback A pointer to a function called on completion of a scanned channel.
|
* @param[in] aCallback A pointer to a function called on completion of a scanned channel.
|
||||||
*
|
*
|
||||||
* @retval kErrorNone Successfully started scanning the channel.
|
* @retval kErrorNone Successfully started scanning the channel.
|
||||||
|
* @retval kErrorBusy The radio is performing energy scanning.
|
||||||
* @retval kErrorNotImplemented The radio doesn't support energy scanning.
|
* @retval kErrorNotImplemented The radio doesn't support energy scanning.
|
||||||
* @retval kErrorInvalidState If the raw link-layer isn't enabled.
|
* @retval kErrorInvalidState If the raw link-layer isn't enabled.
|
||||||
*
|
*
|
||||||
|
|
|
@ -210,6 +210,11 @@ Error Mac::ConvertBeaconToActiveScanResult(const RxFrame *aBeaconFrame, ActiveSc
|
||||||
{
|
{
|
||||||
Error error = kErrorNone;
|
Error error = kErrorNone;
|
||||||
Address address;
|
Address address;
|
||||||
|
#if OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE
|
||||||
|
const BeaconPayload *beaconPayload = nullptr;
|
||||||
|
const Beacon * beacon = nullptr;
|
||||||
|
uint16_t payloadLength;
|
||||||
|
#endif
|
||||||
|
|
||||||
memset(&aResult, 0, sizeof(ActiveScanResult));
|
memset(&aResult, 0, sizeof(ActiveScanResult));
|
||||||
|
|
||||||
|
@ -229,6 +234,23 @@ Error Mac::ConvertBeaconToActiveScanResult(const RxFrame *aBeaconFrame, ActiveSc
|
||||||
aResult.mRssi = aBeaconFrame->GetRssi();
|
aResult.mRssi = aBeaconFrame->GetRssi();
|
||||||
aResult.mLqi = aBeaconFrame->GetLqi();
|
aResult.mLqi = aBeaconFrame->GetLqi();
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE
|
||||||
|
payloadLength = aBeaconFrame->GetPayloadLength();
|
||||||
|
|
||||||
|
beacon = reinterpret_cast<const Beacon *>(aBeaconFrame->GetPayload());
|
||||||
|
beaconPayload = reinterpret_cast<const BeaconPayload *>(beacon->GetPayload());
|
||||||
|
|
||||||
|
if ((payloadLength >= (sizeof(*beacon) + sizeof(*beaconPayload))) && beacon->IsValid() && beaconPayload->IsValid())
|
||||||
|
{
|
||||||
|
aResult.mVersion = beaconPayload->GetProtocolVersion();
|
||||||
|
aResult.mIsJoinable = beaconPayload->IsJoiningPermitted();
|
||||||
|
aResult.mIsNative = beaconPayload->IsNative();
|
||||||
|
IgnoreError(AsCoreType(&aResult.mNetworkName).Set(beaconPayload->GetNetworkName()));
|
||||||
|
VerifyOrExit(IsValidUtf8String(aResult.mNetworkName.m8), error = kErrorParse);
|
||||||
|
aResult.mExtendedPanId = beaconPayload->GetExtendedPanId();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
LogBeacon("Received");
|
LogBeacon("Received");
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
@ -482,7 +504,7 @@ Error Mac::RequestDataPollTransmission(void)
|
||||||
Error error = kErrorNone;
|
Error error = kErrorNone;
|
||||||
|
|
||||||
VerifyOrExit(IsEnabled(), error = kErrorInvalidState);
|
VerifyOrExit(IsEnabled(), error = kErrorInvalidState);
|
||||||
VerifyOrExit(!IsActiveOrPending(kOperationTransmitPoll), error = kErrorAlready);
|
VerifyOrExit(!IsActiveOrPending(kOperationTransmitPoll));
|
||||||
|
|
||||||
// We ensure data frame and data poll tx requests are handled in the
|
// We ensure data frame and data poll tx requests are handled in the
|
||||||
// order they are requested. So if we have a pending direct data frame
|
// order they are requested. So if we have a pending direct data frame
|
||||||
|
@ -715,6 +737,10 @@ TxFrame *Mac::PrepareBeacon(void)
|
||||||
TxFrame *frame;
|
TxFrame *frame;
|
||||||
uint16_t fcf;
|
uint16_t fcf;
|
||||||
Beacon * beacon = nullptr;
|
Beacon * beacon = nullptr;
|
||||||
|
#if OPENTHREAD_CONFIG_MAC_OUTGOING_BEACON_PAYLOAD_ENABLE
|
||||||
|
uint8_t beaconLength;
|
||||||
|
BeaconPayload *beaconPayload = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_MULTI_RADIO
|
#if OPENTHREAD_CONFIG_MULTI_RADIO
|
||||||
OT_ASSERT(!mTxBeaconRadioLinks.IsEmpty());
|
OT_ASSERT(!mTxBeaconRadioLinks.IsEmpty());
|
||||||
|
@ -732,6 +758,30 @@ TxFrame *Mac::PrepareBeacon(void)
|
||||||
beacon = reinterpret_cast<Beacon *>(frame->GetPayload());
|
beacon = reinterpret_cast<Beacon *>(frame->GetPayload());
|
||||||
beacon->Init();
|
beacon->Init();
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_MAC_OUTGOING_BEACON_PAYLOAD_ENABLE
|
||||||
|
beaconLength = sizeof(*beacon);
|
||||||
|
|
||||||
|
beaconPayload = reinterpret_cast<BeaconPayload *>(beacon->GetPayload());
|
||||||
|
|
||||||
|
beaconPayload->Init();
|
||||||
|
|
||||||
|
if (IsJoinable())
|
||||||
|
{
|
||||||
|
beaconPayload->SetJoiningPermitted();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
beaconPayload->ClearJoiningPermitted();
|
||||||
|
}
|
||||||
|
|
||||||
|
beaconPayload->SetNetworkName(Get<MeshCoP::NetworkNameManager>().GetNetworkName().GetAsData());
|
||||||
|
beaconPayload->SetExtendedPanId(Get<MeshCoP::ExtendedPanIdManager>().GetExtPanId());
|
||||||
|
|
||||||
|
beaconLength += sizeof(*beaconPayload);
|
||||||
|
|
||||||
|
frame->SetPayloadLength(beaconLength);
|
||||||
|
#endif
|
||||||
|
|
||||||
LogBeacon("Sending");
|
LogBeacon("Sending");
|
||||||
|
|
||||||
return frame;
|
return frame;
|
||||||
|
|
|
@ -228,7 +228,6 @@ public:
|
||||||
* This method requests transmission of a data poll (MAC Data Request) frame.
|
* This method requests transmission of a data poll (MAC Data Request) frame.
|
||||||
*
|
*
|
||||||
* @retval kErrorNone Data poll transmission request is scheduled successfully.
|
* @retval kErrorNone Data poll transmission request is scheduled successfully.
|
||||||
* @retval kErrorAlready MAC is busy sending earlier poll transmission request.
|
|
||||||
* @retval kErrorInvalidState The MAC layer is not enabled.
|
* @retval kErrorInvalidState The MAC layer is not enabled.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "common/const_cast.hpp"
|
#include "common/const_cast.hpp"
|
||||||
#include "common/encoding.hpp"
|
#include "common/encoding.hpp"
|
||||||
#include "mac/mac_types.hpp"
|
#include "mac/mac_types.hpp"
|
||||||
|
#include "meshcop/network_name.hpp"
|
||||||
|
|
||||||
namespace ot {
|
namespace ot {
|
||||||
namespace Mac {
|
namespace Mac {
|
||||||
|
@ -1482,6 +1483,145 @@ private:
|
||||||
uint8_t mPendingAddressSpec;
|
uint8_t mPendingAddressSpec;
|
||||||
} OT_TOOL_PACKED_END;
|
} OT_TOOL_PACKED_END;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements IEEE 802.15.4 Beacon Payload generation and parsing.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
OT_TOOL_PACKED_BEGIN
|
||||||
|
class BeaconPayload
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr uint8_t kProtocolId = 3; ///< Thread Protocol ID.
|
||||||
|
static constexpr uint8_t kProtocolVersion = 2; ///< Thread Protocol version.
|
||||||
|
static constexpr uint8_t kVersionOffset = 4; ///< Version field bit offset.
|
||||||
|
static constexpr uint8_t kVersionMask = 0xf << kVersionOffset; ///< Version field mask.
|
||||||
|
static constexpr uint8_t kNativeFlag = 1 << 3; ///< Native Commissioner flag.
|
||||||
|
static constexpr uint8_t kJoiningFlag = 1 << 0; ///< Joining Permitted flag.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method initializes the Beacon Payload.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void Init(void)
|
||||||
|
{
|
||||||
|
mProtocolId = kProtocolId;
|
||||||
|
mFlags = kProtocolVersion << kVersionOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicates whether or not the beacon appears to be a valid Thread Beacon Payload.
|
||||||
|
*
|
||||||
|
* @retval TRUE If the beacon appears to be a valid Thread Beacon Payload.
|
||||||
|
* @retval FALSE If the beacon does not appear to be a valid Thread Beacon Payload.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool IsValid(void) const { return (mProtocolId == kProtocolId); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the Protocol ID value.
|
||||||
|
*
|
||||||
|
* @returns the Protocol ID value.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint8_t GetProtocolId(void) const { return mProtocolId; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the Protocol Version value.
|
||||||
|
*
|
||||||
|
* @returns The Protocol Version value.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint8_t GetProtocolVersion(void) const { return mFlags >> kVersionOffset; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicates whether or not the Native Commissioner flag is set.
|
||||||
|
*
|
||||||
|
* @retval TRUE If the Native Commissioner flag is set.
|
||||||
|
* @retval FALSE If the Native Commissioner flag is not set.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool IsNative(void) const { return (mFlags & kNativeFlag) != 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method clears the Native Commissioner flag.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ClearNative(void) { mFlags &= ~kNativeFlag; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the Native Commissioner flag.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetNative(void) { mFlags |= kNativeFlag; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicates whether or not the Joining Permitted flag is set.
|
||||||
|
*
|
||||||
|
* @retval TRUE If the Joining Permitted flag is set.
|
||||||
|
* @retval FALSE If the Joining Permitted flag is not set.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool IsJoiningPermitted(void) const { return (mFlags & kJoiningFlag) != 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method clears the Joining Permitted flag.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ClearJoiningPermitted(void) { mFlags &= ~kJoiningFlag; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the Joining Permitted flag.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetJoiningPermitted(void)
|
||||||
|
{
|
||||||
|
mFlags |= kJoiningFlag;
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_MAC_JOIN_BEACON_VERSION != 2 // check against kProtocolVersion
|
||||||
|
mFlags &= ~kVersionMask;
|
||||||
|
mFlags |= OPENTHREAD_CONFIG_MAC_JOIN_BEACON_VERSION << kVersionOffset;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the Network Name field.
|
||||||
|
*
|
||||||
|
* @returns The Network Name field as `NameData`.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MeshCoP::NameData GetNetworkName(void) const { return MeshCoP::NameData(mNetworkName, sizeof(mNetworkName)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the Network Name field.
|
||||||
|
*
|
||||||
|
* @param[in] aNameData The Network Name (as a `NameData`).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetNetworkName(const MeshCoP::NameData &aNameData) { aNameData.CopyTo(mNetworkName, sizeof(mNetworkName)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the Extended PAN ID field.
|
||||||
|
*
|
||||||
|
* @returns The Extended PAN ID field.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const otExtendedPanId &GetExtendedPanId(void) const { return mExtendedPanId; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the Extended PAN ID field.
|
||||||
|
*
|
||||||
|
* @param[in] aExtPanId An Extended PAN ID.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetExtendedPanId(const otExtendedPanId &aExtPanId) { mExtendedPanId = aExtPanId; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t mProtocolId;
|
||||||
|
uint8_t mFlags;
|
||||||
|
char mNetworkName[MeshCoP::NetworkName::kMaxSize];
|
||||||
|
otExtendedPanId mExtendedPanId;
|
||||||
|
} OT_TOOL_PACKED_END;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class implements CSL IE data structure.
|
* This class implements CSL IE data structure.
|
||||||
*
|
*
|
||||||
|
|
|
@ -572,6 +572,7 @@ public:
|
||||||
* @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned.
|
* @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned.
|
||||||
*
|
*
|
||||||
* @retval kErrorNone Successfully started scanning the channel.
|
* @retval kErrorNone Successfully started scanning the channel.
|
||||||
|
* @retval kErrorBusy The radio is performing energy scanning.
|
||||||
* @retval kErrorInvalidState The radio was disabled or transmitting.
|
* @retval kErrorInvalidState The radio was disabled or transmitting.
|
||||||
* @retval kErrorNotImplemented Energy scan is not supported by radio link.
|
* @retval kErrorNotImplemented Energy scan is not supported by radio link.
|
||||||
*
|
*
|
||||||
|
|
|
@ -379,6 +379,7 @@ public:
|
||||||
* @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned.
|
* @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned.
|
||||||
*
|
*
|
||||||
* @retval kErrorNone Successfully started scanning the channel.
|
* @retval kErrorNone Successfully started scanning the channel.
|
||||||
|
* @retval kErrorBusy The radio is performing energy scanning.
|
||||||
* @retval kErrorInvalidState The radio was disabled or transmitting.
|
* @retval kErrorInvalidState The radio was disabled or transmitting.
|
||||||
* @retval kErrorNotImplemented Energy scan is not supported (applicable in link-raw/radio mode only).
|
* @retval kErrorNotImplemented Energy scan is not supported (applicable in link-raw/radio mode only).
|
||||||
*
|
*
|
||||||
|
|
|
@ -588,7 +588,7 @@ void BorderAgent::Start(void)
|
||||||
mState = kStateStarted;
|
mState = kStateStarted;
|
||||||
mUdpProxyPort = 0;
|
mUdpProxyPort = 0;
|
||||||
|
|
||||||
LogInfo("Border Agent start listening on port %d", kBorderAgentUdpPort);
|
LogInfo("Border Agent start listening on port %u", GetUdpPort());
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (error != kErrorNone)
|
if (error != kErrorNone)
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "common/log.hpp"
|
#include "common/log.hpp"
|
||||||
#include "mac/mac_types.hpp"
|
#include "mac/mac_types.hpp"
|
||||||
#include "meshcop/meshcop_tlvs.hpp"
|
#include "meshcop/meshcop_tlvs.hpp"
|
||||||
|
#include "meshcop/timestamp.hpp"
|
||||||
#include "thread/mle_tlvs.hpp"
|
#include "thread/mle_tlvs.hpp"
|
||||||
|
|
||||||
namespace ot {
|
namespace ot {
|
||||||
|
@ -69,10 +70,12 @@ Error Dataset::Info::GenerateRandom(Instance &aInstance)
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
mActiveTimestamp = 1;
|
mActiveTimestamp.mSeconds = 1;
|
||||||
mChannel = preferredChannels.ChooseRandomChannel();
|
mActiveTimestamp.mTicks = 0;
|
||||||
mChannelMask = supportedChannels.GetMask();
|
mActiveTimestamp.mAuthoritative = false;
|
||||||
mPanId = Mac::GenerateRandomPanId();
|
mChannel = preferredChannels.ChooseRandomChannel();
|
||||||
|
mChannelMask = supportedChannels.GetMask();
|
||||||
|
mPanId = Mac::GenerateRandomPanId();
|
||||||
AsCoreType(&mSecurityPolicy).SetToDefault();
|
AsCoreType(&mSecurityPolicy).SetToDefault();
|
||||||
|
|
||||||
SuccessOrExit(error = AsCoreType(&mNetworkKey).GenerateRandom());
|
SuccessOrExit(error = AsCoreType(&mNetworkKey).GenerateRandom());
|
||||||
|
@ -193,7 +196,7 @@ void Dataset::ConvertTo(Info &aDatasetInfo) const
|
||||||
switch (cur->GetType())
|
switch (cur->GetType())
|
||||||
{
|
{
|
||||||
case Tlv::kActiveTimestamp:
|
case Tlv::kActiveTimestamp:
|
||||||
aDatasetInfo.SetActiveTimestamp(As<ActiveTimestampTlv>(cur)->GetTimestamp().GetSeconds());
|
aDatasetInfo.SetActiveTimestamp(As<ActiveTimestampTlv>(cur)->GetTimestamp());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Tlv::kChannel:
|
case Tlv::kChannel:
|
||||||
|
@ -237,7 +240,7 @@ void Dataset::ConvertTo(Info &aDatasetInfo) const
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Tlv::kPendingTimestamp:
|
case Tlv::kPendingTimestamp:
|
||||||
aDatasetInfo.SetPendingTimestamp(As<PendingTimestampTlv>(cur)->GetTimestamp().GetSeconds());
|
aDatasetInfo.SetPendingTimestamp(As<PendingTimestampTlv>(cur)->GetTimestamp());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Tlv::kPskc:
|
case Tlv::kPskc:
|
||||||
|
@ -286,20 +289,18 @@ Error Dataset::SetFrom(const Info &aDatasetInfo)
|
||||||
|
|
||||||
if (aDatasetInfo.IsActiveTimestampPresent())
|
if (aDatasetInfo.IsActiveTimestampPresent())
|
||||||
{
|
{
|
||||||
Timestamp timestamp;
|
Timestamp activeTimestamp;
|
||||||
|
|
||||||
timestamp.Clear();
|
aDatasetInfo.GetActiveTimestamp(activeTimestamp);
|
||||||
timestamp.SetSeconds(aDatasetInfo.GetActiveTimestamp());
|
IgnoreError(SetTlv(Tlv::kActiveTimestamp, activeTimestamp));
|
||||||
IgnoreError(SetTlv(Tlv::kActiveTimestamp, timestamp));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aDatasetInfo.IsPendingTimestampPresent())
|
if (aDatasetInfo.IsPendingTimestampPresent())
|
||||||
{
|
{
|
||||||
Timestamp timestamp;
|
Timestamp pendingTimestamp;
|
||||||
|
|
||||||
timestamp.Clear();
|
aDatasetInfo.GetPendingTimestamp(pendingTimestamp);
|
||||||
timestamp.SetSeconds(aDatasetInfo.GetPendingTimestamp());
|
IgnoreError(SetTlv(Tlv::kPendingTimestamp, pendingTimestamp));
|
||||||
IgnoreError(SetTlv(Tlv::kPendingTimestamp, timestamp));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aDatasetInfo.IsDelayPresent())
|
if (aDatasetInfo.IsDelayPresent())
|
||||||
|
|
|
@ -203,7 +203,7 @@ public:
|
||||||
* @returns The Active Timestamp in the Dataset.
|
* @returns The Active Timestamp in the Dataset.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
uint64_t GetActiveTimestamp(void) const { return mActiveTimestamp; }
|
void GetActiveTimestamp(Timestamp &aTimestamp) const { aTimestamp.SetFromTimestamp(mActiveTimestamp); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method sets the Active Timestamp in the Dataset.
|
* This method sets the Active Timestamp in the Dataset.
|
||||||
|
@ -211,9 +211,9 @@ public:
|
||||||
* @param[in] aTimestamp A Timestamp value.
|
* @param[in] aTimestamp A Timestamp value.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void SetActiveTimestamp(uint64_t aTimestamp)
|
void SetActiveTimestamp(const Timestamp &aTimestamp)
|
||||||
{
|
{
|
||||||
mActiveTimestamp = aTimestamp;
|
aTimestamp.ConvertTo(mActiveTimestamp);
|
||||||
mComponents.mIsActiveTimestampPresent = true;
|
mComponents.mIsActiveTimestampPresent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ public:
|
||||||
* @returns The Pending Timestamp in the Dataset.
|
* @returns The Pending Timestamp in the Dataset.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
uint64_t GetPendingTimestamp(void) const { return mPendingTimestamp; }
|
void GetPendingTimestamp(Timestamp &aTimestamp) const { aTimestamp.SetFromTimestamp(mPendingTimestamp); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method sets the Pending Timestamp in the Dataset.
|
* This method sets the Pending Timestamp in the Dataset.
|
||||||
|
@ -242,9 +242,9 @@ public:
|
||||||
* @param[in] aTimestamp A Timestamp value.
|
* @param[in] aTimestamp A Timestamp value.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void SetPendingTimestamp(uint64_t aTimestamp)
|
void SetPendingTimestamp(const Timestamp &aTimestamp)
|
||||||
{
|
{
|
||||||
mPendingTimestamp = aTimestamp;
|
aTimestamp.ConvertTo(mPendingTimestamp);
|
||||||
mComponents.mIsPendingTimestampPresent = true;
|
mComponents.mIsPendingTimestampPresent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "common/locator_getters.hpp"
|
#include "common/locator_getters.hpp"
|
||||||
#include "common/log.hpp"
|
#include "common/log.hpp"
|
||||||
#include "common/random.hpp"
|
#include "common/random.hpp"
|
||||||
|
#include "meshcop/timestamp.hpp"
|
||||||
|
|
||||||
namespace ot {
|
namespace ot {
|
||||||
namespace MeshCoP {
|
namespace MeshCoP {
|
||||||
|
@ -193,9 +194,17 @@ void DatasetUpdater::HandleNotifierEvents(Events aEvents)
|
||||||
{
|
{
|
||||||
Finish(kErrorNone);
|
Finish(kErrorNone);
|
||||||
}
|
}
|
||||||
else if (requestedDataset.GetActiveTimestamp() <= dataset.GetActiveTimestamp())
|
else
|
||||||
{
|
{
|
||||||
Finish(kErrorAlready);
|
Timestamp requestedDatasetTimestamp;
|
||||||
|
Timestamp activeDatasetTimestamp;
|
||||||
|
|
||||||
|
requestedDataset.GetActiveTimestamp(requestedDatasetTimestamp);
|
||||||
|
dataset.GetActiveTimestamp(activeDatasetTimestamp);
|
||||||
|
if (Timestamp::Compare(requestedDatasetTimestamp, activeDatasetTimestamp) <= 0)
|
||||||
|
{
|
||||||
|
Finish(kErrorAlready);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,13 +38,23 @@
|
||||||
namespace ot {
|
namespace ot {
|
||||||
namespace MeshCoP {
|
namespace MeshCoP {
|
||||||
|
|
||||||
|
void Timestamp::ConvertTo(otTimestamp &aTimestamp) const
|
||||||
|
{
|
||||||
|
aTimestamp.mSeconds = GetSeconds();
|
||||||
|
aTimestamp.mTicks = GetTicks();
|
||||||
|
aTimestamp.mAuthoritative = GetAuthoritative();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timestamp::SetFromTimestamp(const otTimestamp &aTimestamp)
|
||||||
|
{
|
||||||
|
SetSeconds(aTimestamp.mSeconds);
|
||||||
|
SetTicks(aTimestamp.mTicks);
|
||||||
|
SetAuthoritative(aTimestamp.mAuthoritative);
|
||||||
|
}
|
||||||
|
|
||||||
int Timestamp::Compare(const Timestamp *aFirst, const Timestamp *aSecond)
|
int Timestamp::Compare(const Timestamp *aFirst, const Timestamp *aSecond)
|
||||||
{
|
{
|
||||||
int rval;
|
int rval;
|
||||||
uint64_t firstSeconds;
|
|
||||||
uint64_t secondSeconds;
|
|
||||||
uint16_t firstTicks;
|
|
||||||
uint16_t secondTicks;
|
|
||||||
|
|
||||||
if (aFirst == nullptr)
|
if (aFirst == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -62,22 +72,46 @@ int Timestamp::Compare(const Timestamp *aFirst, const Timestamp *aSecond)
|
||||||
|
|
||||||
// Both are non-null.
|
// Both are non-null.
|
||||||
|
|
||||||
firstSeconds = aFirst->GetSeconds();
|
rval = Compare(*aFirst, *aSecond);
|
||||||
secondSeconds = aSecond->GetSeconds();
|
|
||||||
|
exit:
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Timestamp::Compare(const Timestamp &aFirst, const Timestamp &aSecond)
|
||||||
|
{
|
||||||
|
int rval;
|
||||||
|
uint64_t firstSeconds;
|
||||||
|
uint64_t secondSeconds;
|
||||||
|
uint16_t firstTicks;
|
||||||
|
uint16_t secondTicks;
|
||||||
|
bool firstAuthoritative;
|
||||||
|
bool secondAuthoritative;
|
||||||
|
|
||||||
|
firstSeconds = aFirst.GetSeconds();
|
||||||
|
secondSeconds = aSecond.GetSeconds();
|
||||||
|
|
||||||
if (firstSeconds != secondSeconds)
|
if (firstSeconds != secondSeconds)
|
||||||
{
|
{
|
||||||
ExitNow(rval = (firstSeconds > secondSeconds) ? 1 : -1);
|
ExitNow(rval = (firstSeconds > secondSeconds) ? 1 : -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
firstTicks = aFirst->GetTicks();
|
firstTicks = aFirst.GetTicks();
|
||||||
secondTicks = aSecond->GetTicks();
|
secondTicks = aSecond.GetTicks();
|
||||||
|
|
||||||
if (firstTicks != secondTicks)
|
if (firstTicks != secondTicks)
|
||||||
{
|
{
|
||||||
ExitNow(rval = (firstTicks > secondTicks) ? 1 : -1);
|
ExitNow(rval = (firstTicks > secondTicks) ? 1 : -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
firstAuthoritative = aFirst.GetAuthoritative();
|
||||||
|
secondAuthoritative = aSecond.GetAuthoritative();
|
||||||
|
|
||||||
|
if (firstAuthoritative != secondAuthoritative)
|
||||||
|
{
|
||||||
|
ExitNow(rval = firstAuthoritative ? 1 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
rval = 0;
|
rval = 0;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <openthread/dataset.h>
|
||||||
#include <openthread/platform/toolchain.h>
|
#include <openthread/platform/toolchain.h>
|
||||||
|
|
||||||
#include "common/clearable.hpp"
|
#include "common/clearable.hpp"
|
||||||
|
@ -59,6 +60,18 @@ OT_TOOL_PACKED_BEGIN
|
||||||
class Timestamp : public Clearable<Timestamp>
|
class Timestamp : public Clearable<Timestamp>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* This method converts the timestamp to `otTimestamp`.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ConvertTo(otTimestamp &aTimestamp) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the timestamp from `otTimestamp`.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetFromTimestamp(const otTimestamp &aTimestamp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the Seconds value.
|
* This method returns the Seconds value.
|
||||||
*
|
*
|
||||||
|
@ -127,6 +140,15 @@ public:
|
||||||
*/
|
*/
|
||||||
void AdvanceRandomTicks(void);
|
void AdvanceRandomTicks(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicates whether the timestamp indicates an MLE Orphan Announce message.
|
||||||
|
*
|
||||||
|
* @retval TRUE The timestamp indicates an Orphan Announce message.
|
||||||
|
* @retval FALSE If the timestamp does not indicate an Orphan Announce message.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool IsOrphanTimestamp(void) const { return GetSeconds() == 0 && GetTicks() == 0 && GetAuthoritative(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This static method compares two timestamps.
|
* This static method compares two timestamps.
|
||||||
*
|
*
|
||||||
|
@ -143,6 +165,19 @@ public:
|
||||||
*/
|
*/
|
||||||
static int Compare(const Timestamp *aFirst, const Timestamp *aSecond);
|
static int Compare(const Timestamp *aFirst, const Timestamp *aSecond);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This static method compares two timestamps.
|
||||||
|
*
|
||||||
|
* @param[in] aFirst A reference to the first timestamp to compare.
|
||||||
|
* @param[in] aSecond A reference to the second timestamp to compare.
|
||||||
|
*
|
||||||
|
* @retval -1 if @p aFirst is less than @p aSecond (`aFirst < aSecond`).
|
||||||
|
* @retval 0 if @p aFirst is equal to @p aSecond (`aFirst == aSecond`).
|
||||||
|
* @retval 1 if @p aFirst is greater than @p aSecond (`aFirst > aSecond`).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static int Compare(const Timestamp &aFirst, const Timestamp &aSecond);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr uint8_t kTicksOffset = 1;
|
static constexpr uint8_t kTicksOffset = 1;
|
||||||
static constexpr uint16_t kTicksMask = 0x7fff << kTicksOffset;
|
static constexpr uint16_t kTicksMask = 0x7fff << kTicksOffset;
|
||||||
|
|
|
@ -1409,20 +1409,7 @@ exit:
|
||||||
|
|
||||||
void Dso::Connection::PendingRequests::Remove(MessageId aMessageId)
|
void Dso::Connection::PendingRequests::Remove(MessageId aMessageId)
|
||||||
{
|
{
|
||||||
Entry *entry = mRequests.FindMatching(aMessageId);
|
mRequests.RemoveMatching(aMessageId);
|
||||||
Entry *lastEntry;
|
|
||||||
|
|
||||||
VerifyOrExit(entry != nullptr);
|
|
||||||
|
|
||||||
// Remove last entry from the `mRequests` array, if it is not the
|
|
||||||
// `entry` we want to remove, replace `entry` with `lastEntry.
|
|
||||||
|
|
||||||
lastEntry = mRequests.PopBack();
|
|
||||||
VerifyOrExit(lastEntry != entry);
|
|
||||||
*entry = *lastEntry;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Dso::Connection::PendingRequests::HasAnyTimedOut(TimeMilli aNow) const
|
bool Dso::Connection::PendingRequests::HasAnyTimedOut(TimeMilli aNow) const
|
||||||
|
|
|
@ -65,6 +65,7 @@ Server::Server(Instance &aInstance)
|
||||||
, mQueryUnsubscribe(nullptr)
|
, mQueryUnsubscribe(nullptr)
|
||||||
, mTimer(aInstance, Server::HandleTimer)
|
, mTimer(aInstance, Server::HandleTimer)
|
||||||
{
|
{
|
||||||
|
mCounters.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Error Server::Start(void)
|
Error Server::Start(void)
|
||||||
|
@ -173,11 +174,19 @@ void Server::ProcessQuery(const Header &aRequestHeader, Message &aRequestMessage
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Resolve the question using query callbacks if SRP server failed to resolve the questions.
|
// Resolve the question using query callbacks if SRP server failed to resolve the questions.
|
||||||
if (responseHeader.GetAnswerCount() == 0 &&
|
if (responseHeader.GetAnswerCount() == 0)
|
||||||
kErrorNone == ResolveByQueryCallbacks(responseHeader, *responseMessage, compressInfo, aMessageInfo))
|
|
||||||
{
|
{
|
||||||
resolveByQueryCallbacks = true;
|
if (kErrorNone == ResolveByQueryCallbacks(responseHeader, *responseMessage, compressInfo, aMessageInfo))
|
||||||
|
{
|
||||||
|
resolveByQueryCallbacks = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++mCounters.mResolvedBySrp;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (error == kErrorNone && !resolveByQueryCallbacks)
|
if (error == kErrorNone && !resolveByQueryCallbacks)
|
||||||
|
@ -220,6 +229,8 @@ void Server::SendResponse(Header aHeader,
|
||||||
{
|
{
|
||||||
LogInfo("send DNS-SD reply: %s, RCODE=%d", ErrorToString(error), aResponseCode);
|
LogInfo("send DNS-SD reply: %s, RCODE=%d", ErrorToString(error), aResponseCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateResponseCounters(aResponseCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Header::Response Server::AddQuestions(const Header & aRequestHeader,
|
Header::Response Server::AddQuestions(const Header & aRequestHeader,
|
||||||
|
@ -842,7 +853,7 @@ Server::QueryTransaction *Server::NewQuery(const Header & aResponseHead
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
query.Init(aResponseHeader, aResponseMessage, aCompressInfo, aMessageInfo);
|
query.Init(aResponseHeader, aResponseMessage, aCompressInfo, aMessageInfo, GetInstance());
|
||||||
ExitNow(newQuery = &query);
|
ExitNow(newQuery = &query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1194,10 +1205,12 @@ void Server::FinalizeQuery(QueryTransaction &aQuery, Header::Response aResponseC
|
||||||
void Server::QueryTransaction::Init(const Header & aResponseHeader,
|
void Server::QueryTransaction::Init(const Header & aResponseHeader,
|
||||||
Message & aResponseMessage,
|
Message & aResponseMessage,
|
||||||
const NameCompressInfo &aCompressInfo,
|
const NameCompressInfo &aCompressInfo,
|
||||||
const Ip6::MessageInfo &aMessageInfo)
|
const Ip6::MessageInfo &aMessageInfo,
|
||||||
|
Instance & aInstance)
|
||||||
{
|
{
|
||||||
OT_ASSERT(mResponseMessage == nullptr);
|
OT_ASSERT(mResponseMessage == nullptr);
|
||||||
|
|
||||||
|
InstanceLocatorInit::Init(aInstance);
|
||||||
mResponseHeader = aResponseHeader;
|
mResponseHeader = aResponseHeader;
|
||||||
mResponseMessage = &aResponseMessage;
|
mResponseMessage = &aResponseMessage;
|
||||||
mCompressInfo = aCompressInfo;
|
mCompressInfo = aCompressInfo;
|
||||||
|
@ -1209,10 +1222,35 @@ void Server::QueryTransaction::Finalize(Header::Response aResponseMessage, Ip6::
|
||||||
{
|
{
|
||||||
OT_ASSERT(mResponseMessage != nullptr);
|
OT_ASSERT(mResponseMessage != nullptr);
|
||||||
|
|
||||||
SendResponse(mResponseHeader, aResponseMessage, *mResponseMessage, mMessageInfo, aSocket);
|
Get<Server>().SendResponse(mResponseHeader, aResponseMessage, *mResponseMessage, mMessageInfo, aSocket);
|
||||||
mResponseMessage = nullptr;
|
mResponseMessage = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Server::UpdateResponseCounters(Header::Response aResponseCode)
|
||||||
|
{
|
||||||
|
switch (aResponseCode)
|
||||||
|
{
|
||||||
|
case UpdateHeader::kResponseSuccess:
|
||||||
|
++mCounters.mSuccessResponse;
|
||||||
|
break;
|
||||||
|
case UpdateHeader::kResponseServerFailure:
|
||||||
|
++mCounters.mServerFailureResponse;
|
||||||
|
break;
|
||||||
|
case UpdateHeader::kResponseFormatError:
|
||||||
|
++mCounters.mFormatErrorResponse;
|
||||||
|
break;
|
||||||
|
case UpdateHeader::kResponseNameError:
|
||||||
|
++mCounters.mNameErrorResponse;
|
||||||
|
break;
|
||||||
|
case UpdateHeader::kResponseNotImplemented:
|
||||||
|
++mCounters.mNotImplementedResponse;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
++mCounters.mOtherResponse;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ServiceDiscovery
|
} // namespace ServiceDiscovery
|
||||||
} // namespace Dns
|
} // namespace Dns
|
||||||
} // namespace ot
|
} // namespace ot
|
||||||
|
|
|
@ -67,6 +67,14 @@ class Server : public InstanceLocator, private NonCopyable
|
||||||
friend class Srp::Server;
|
friend class Srp::Server;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* This class contains the counters of the DNS-SD server.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Counters : public otDnssdCounters, public Clearable<Counters>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This enumeration specifies a DNS-SD query type.
|
* This enumeration specifies a DNS-SD query type.
|
||||||
*
|
*
|
||||||
|
@ -155,6 +163,14 @@ public:
|
||||||
*/
|
*/
|
||||||
static DnsQueryType GetQueryTypeAndName(const otDnssdQuery *aQuery, char (&aName)[Name::kMaxNameSize]);
|
static DnsQueryType GetQueryTypeAndName(const otDnssdQuery *aQuery, char (&aName)[Name::kMaxNameSize]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the counters of the DNS-SD server.
|
||||||
|
*
|
||||||
|
* @returns A reference to the `Counters` instance.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const Counters &GetCounters(void) const { return mCounters; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class NameCompressInfo : public Clearable<NameCompressInfo>
|
class NameCompressInfo : public Clearable<NameCompressInfo>
|
||||||
{
|
{
|
||||||
|
@ -273,7 +289,7 @@ private:
|
||||||
* This class contains the compress information for a dns packet.
|
* This class contains the compress information for a dns packet.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class QueryTransaction
|
class QueryTransaction : public InstanceLocatorInit
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit QueryTransaction(void)
|
explicit QueryTransaction(void)
|
||||||
|
@ -284,7 +300,8 @@ private:
|
||||||
void Init(const Header & aResponseHeader,
|
void Init(const Header & aResponseHeader,
|
||||||
Message & aResponseMessage,
|
Message & aResponseMessage,
|
||||||
const NameCompressInfo &aCompressInfo,
|
const NameCompressInfo &aCompressInfo,
|
||||||
const Ip6::MessageInfo &aMessageInfo);
|
const Ip6::MessageInfo &aMessageInfo,
|
||||||
|
Instance & aInstance);
|
||||||
bool IsValid(void) const { return mResponseMessage != nullptr; }
|
bool IsValid(void) const { return mResponseMessage != nullptr; }
|
||||||
const Ip6::MessageInfo &GetMessageInfo(void) const { return mMessageInfo; }
|
const Ip6::MessageInfo &GetMessageInfo(void) const { return mMessageInfo; }
|
||||||
const Header & GetResponseHeader(void) const { return mResponseHeader; }
|
const Header & GetResponseHeader(void) const { return mResponseHeader; }
|
||||||
|
@ -347,7 +364,7 @@ private:
|
||||||
static void IncResourceRecordCount(Header &aHeader, bool aAdditional);
|
static void IncResourceRecordCount(Header &aHeader, bool aAdditional);
|
||||||
static Error FindNameComponents(const char *aName, const char *aDomain, NameComponentsOffsetInfo &aInfo);
|
static Error FindNameComponents(const char *aName, const char *aDomain, NameComponentsOffsetInfo &aInfo);
|
||||||
static Error FindPreviousLabel(const char *aName, uint8_t &aStart, uint8_t &aStop);
|
static Error FindPreviousLabel(const char *aName, uint8_t &aStart, uint8_t &aStop);
|
||||||
static void SendResponse(Header aHeader,
|
void SendResponse(Header aHeader,
|
||||||
Header::Response aResponseCode,
|
Header::Response aResponseCode,
|
||||||
Message & aMessage,
|
Message & aMessage,
|
||||||
const Ip6::MessageInfo &aMessageInfo,
|
const Ip6::MessageInfo &aMessageInfo,
|
||||||
|
@ -392,6 +409,8 @@ private:
|
||||||
void HandleTimer(void);
|
void HandleTimer(void);
|
||||||
void ResetTimer(void);
|
void ResetTimer(void);
|
||||||
|
|
||||||
|
void UpdateResponseCounters(Header::Response aResponseCode);
|
||||||
|
|
||||||
static const char kDnssdProtocolUdp[];
|
static const char kDnssdProtocolUdp[];
|
||||||
static const char kDnssdProtocolTcp[];
|
static const char kDnssdProtocolTcp[];
|
||||||
static const char kDnssdSubTypeLabel[];
|
static const char kDnssdSubTypeLabel[];
|
||||||
|
@ -403,6 +422,8 @@ private:
|
||||||
otDnssdQuerySubscribeCallback mQuerySubscribe;
|
otDnssdQuerySubscribeCallback mQuerySubscribe;
|
||||||
otDnssdQueryUnsubscribeCallback mQueryUnsubscribe;
|
otDnssdQueryUnsubscribeCallback mQueryUnsubscribe;
|
||||||
TimerMilli mTimer;
|
TimerMilli mTimer;
|
||||||
|
|
||||||
|
Counters mCounters;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ServiceDiscovery
|
} // namespace ServiceDiscovery
|
||||||
|
|
|
@ -1309,43 +1309,29 @@ exit:
|
||||||
|
|
||||||
bool Ip6::ShouldForwardToThread(const MessageInfo &aMessageInfo, bool aFromHost) const
|
bool Ip6::ShouldForwardToThread(const MessageInfo &aMessageInfo, bool aFromHost) const
|
||||||
{
|
{
|
||||||
OT_UNUSED_VARIABLE(aFromHost);
|
bool shouldForward = false;
|
||||||
|
|
||||||
bool rval = false;
|
if (aMessageInfo.GetSockAddr().IsMulticast() || aMessageInfo.GetSockAddr().IsLinkLocal())
|
||||||
|
|
||||||
if (aMessageInfo.GetSockAddr().IsMulticast())
|
|
||||||
{
|
{
|
||||||
// multicast
|
shouldForward = true;
|
||||||
ExitNow(rval = true);
|
|
||||||
}
|
|
||||||
else if (aMessageInfo.GetSockAddr().IsLinkLocal())
|
|
||||||
{
|
|
||||||
// on-link link-local address
|
|
||||||
ExitNow(rval = true);
|
|
||||||
}
|
}
|
||||||
else if (IsOnLink(aMessageInfo.GetSockAddr()))
|
else if (IsOnLink(aMessageInfo.GetSockAddr()))
|
||||||
{
|
{
|
||||||
// on-link global address
|
|
||||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||||
ExitNow(rval = (aFromHost ||
|
shouldForward =
|
||||||
!Get<BackboneRouter::Manager>().ShouldForwardDuaToBackbone(aMessageInfo.GetSockAddr())));
|
(aFromHost || !Get<BackboneRouter::Manager>().ShouldForwardDuaToBackbone(aMessageInfo.GetSockAddr()));
|
||||||
#else
|
#else
|
||||||
ExitNow(rval = true);
|
OT_UNUSED_VARIABLE(aFromHost);
|
||||||
|
shouldForward = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (Get<ThreadNetif>().RouteLookup(aMessageInfo.GetPeerAddr(), aMessageInfo.GetSockAddr(), nullptr) ==
|
else if (Get<ThreadNetif>().RouteLookup(aMessageInfo.GetPeerAddr(), aMessageInfo.GetSockAddr(), nullptr) ==
|
||||||
kErrorNone)
|
kErrorNone)
|
||||||
{
|
{
|
||||||
// route
|
shouldForward = true;
|
||||||
ExitNow(rval = true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ExitNow(rval = false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
return shouldForward;
|
||||||
return rval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Netif::UnicastAddress *Ip6::SelectSourceAddress(MessageInfo &aMessageInfo)
|
const Netif::UnicastAddress *Ip6::SelectSourceAddress(MessageInfo &aMessageInfo)
|
||||||
|
|
|
@ -77,13 +77,17 @@ bool Prefix::IsEqual(const uint8_t *aPrefixBytes, uint8_t aPrefixLength) const
|
||||||
bool Prefix::operator<(const Prefix &aOther) const
|
bool Prefix::operator<(const Prefix &aOther) const
|
||||||
{
|
{
|
||||||
bool isSmaller;
|
bool isSmaller;
|
||||||
|
uint8_t minLength;
|
||||||
uint8_t matchedLength;
|
uint8_t matchedLength;
|
||||||
|
|
||||||
VerifyOrExit(GetLength() == aOther.GetLength(), isSmaller = GetLength() < aOther.GetLength());
|
minLength = OT_MIN(GetLength(), aOther.GetLength());
|
||||||
|
matchedLength = MatchLength(GetBytes(), aOther.GetBytes(), SizeForLength(minLength));
|
||||||
|
|
||||||
matchedLength = MatchLength(GetBytes(), aOther.GetBytes(), GetBytesSize());
|
if (matchedLength >= minLength)
|
||||||
|
{
|
||||||
VerifyOrExit(matchedLength < GetLength(), isSmaller = false);
|
isSmaller = (GetLength() < aOther.GetLength());
|
||||||
|
ExitNow();
|
||||||
|
}
|
||||||
|
|
||||||
isSmaller = GetBytes()[matchedLength / CHAR_BIT] < aOther.GetBytes()[matchedLength / CHAR_BIT];
|
isSmaller = GetBytes()[matchedLength / CHAR_BIT] < aOther.GetBytes()[matchedLength / CHAR_BIT];
|
||||||
|
|
||||||
|
|
|
@ -266,8 +266,10 @@ public:
|
||||||
/**
|
/**
|
||||||
* This method overloads operator `<` to compare two prefixes.
|
* This method overloads operator `<` to compare two prefixes.
|
||||||
*
|
*
|
||||||
* A prefix with shorter length is considered smaller than the one with longer length. If the prefix lengths are
|
* If the two prefixes have the same length N, then the bytes are compared directly (as two big-endian N-bit
|
||||||
* equal, then the prefix bytes are compared directly.
|
* numbers). If the two prefix have different lengths, the shorter prefix is padded by `0` bit up to the longer
|
||||||
|
* prefix length N before the bytes are compared (as big-endian N-bit numbers). If all bytes are equal, the prefix
|
||||||
|
* with shorter length is considered smaller.
|
||||||
*
|
*
|
||||||
* @param[in] aOther The other prefix to compare against.
|
* @param[in] aOther The other prefix to compare against.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,282 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, The OpenThread Authors.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the copyright holder nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* This file includes implementations for IPv6 Neighbor Discovery (ND6).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nd6.hpp"
|
||||||
|
|
||||||
|
#include "common/as_core_type.hpp"
|
||||||
|
#include "common/code_utils.hpp"
|
||||||
|
|
||||||
|
namespace ot {
|
||||||
|
namespace Ip6 {
|
||||||
|
namespace Nd {
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
// Option::Iterator
|
||||||
|
|
||||||
|
Option::Iterator::Iterator(void)
|
||||||
|
: mOption(nullptr)
|
||||||
|
, mEnd(nullptr)
|
||||||
|
{
|
||||||
|
// An empty iterator (used to indicate `end()` of list).
|
||||||
|
}
|
||||||
|
|
||||||
|
Option::Iterator::Iterator(const void *aStart, const void *aEnd)
|
||||||
|
: mOption(nullptr)
|
||||||
|
, mEnd(reinterpret_cast<const Option *>(aEnd))
|
||||||
|
{
|
||||||
|
// Note that `Validate()` uses `mEnd` so can only be called after
|
||||||
|
// `mEnd` is set.
|
||||||
|
|
||||||
|
mOption = Validate(reinterpret_cast<const Option *>(aStart));
|
||||||
|
}
|
||||||
|
|
||||||
|
const Option *Option::Iterator::Next(const Option *aOption)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<const Option *>(reinterpret_cast<const uint8_t *>(aOption) + aOption->GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Option::Iterator::Advance(void)
|
||||||
|
{
|
||||||
|
mOption = (mOption != nullptr) ? Validate(Next(mOption)) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Option *Option::Iterator::Validate(const Option *aOption) const
|
||||||
|
{
|
||||||
|
// Check if `aOption` is well-formed and fits in the range
|
||||||
|
// up to `mEnd`. Returns `aOption` if it is valid, `nullptr`
|
||||||
|
// otherwise.
|
||||||
|
|
||||||
|
return ((aOption != nullptr) && ((aOption + 1) <= mEnd) && aOption->IsValid() && (Next(aOption) <= mEnd)) ? aOption
|
||||||
|
: nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
// PrefixInfoOption
|
||||||
|
|
||||||
|
void PrefixInfoOption::Init(void)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
SetType(kTypePrefixInfo);
|
||||||
|
SetSize(sizeof(PrefixInfoOption));
|
||||||
|
|
||||||
|
OT_UNUSED_VARIABLE(mReserved2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrefixInfoOption::SetPrefix(const Prefix &aPrefix)
|
||||||
|
{
|
||||||
|
mPrefixLength = aPrefix.mLength;
|
||||||
|
mPrefix = AsCoreType(&aPrefix.mPrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrefixInfoOption::GetPrefix(Prefix &aPrefix) const
|
||||||
|
{
|
||||||
|
aPrefix.Set(mPrefix.GetBytes(), mPrefixLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PrefixInfoOption::IsValid(void) const
|
||||||
|
{
|
||||||
|
return (GetSize() >= sizeof(*this)) && (mPrefixLength <= Prefix::kMaxLength) &&
|
||||||
|
(GetPreferredLifetime() <= GetValidLifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
// RouteInfoOption
|
||||||
|
|
||||||
|
void RouteInfoOption::Init(void)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
SetType(kTypeRouteInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouteInfoOption::SetPreference(RoutePreference aPreference)
|
||||||
|
{
|
||||||
|
mResvdPrf &= ~kPreferenceMask;
|
||||||
|
mResvdPrf |= (NetworkData::RoutePreferenceToValue(aPreference) << kPreferenceOffset) & kPreferenceMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
RoutePreference RouteInfoOption::GetPreference(void) const
|
||||||
|
{
|
||||||
|
return NetworkData::RoutePreferenceFromValue((mResvdPrf & kPreferenceMask) >> kPreferenceOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouteInfoOption::SetPrefix(const Prefix &aPrefix)
|
||||||
|
{
|
||||||
|
SetLength(OptionLengthForPrefix(aPrefix.mLength));
|
||||||
|
mPrefixLength = aPrefix.mLength;
|
||||||
|
memcpy(GetPrefixBytes(), aPrefix.GetBytes(), aPrefix.GetBytesSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouteInfoOption::GetPrefix(Prefix &aPrefix) const
|
||||||
|
{
|
||||||
|
aPrefix.Set(GetPrefixBytes(), mPrefixLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RouteInfoOption::IsValid(void) const
|
||||||
|
{
|
||||||
|
return (GetSize() >= kMinSize) && (mPrefixLength <= Prefix::kMaxLength) &&
|
||||||
|
(GetLength() >= OptionLengthForPrefix(mPrefixLength)) &&
|
||||||
|
NetworkData::IsRoutePreferenceValid(GetPreference());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t RouteInfoOption::OptionLengthForPrefix(uint8_t aPrefixLength)
|
||||||
|
{
|
||||||
|
static constexpr uint8_t kMaxPrefixLenForOptionLen1 = 0;
|
||||||
|
static constexpr uint8_t kMaxPrefixLenForOptionLen2 = 64;
|
||||||
|
|
||||||
|
uint8_t length;
|
||||||
|
|
||||||
|
// The Option Length can be 1, 2, or 3 depending on the prefix
|
||||||
|
// length
|
||||||
|
//
|
||||||
|
// - 1 when prefix len is zero.
|
||||||
|
// - 2 when prefix len is less then or equal to 64.
|
||||||
|
// - 3 otherwise.
|
||||||
|
|
||||||
|
if (aPrefixLength == kMaxPrefixLenForOptionLen1)
|
||||||
|
{
|
||||||
|
length = 1;
|
||||||
|
}
|
||||||
|
else if (aPrefixLength <= kMaxPrefixLenForOptionLen2)
|
||||||
|
{
|
||||||
|
length = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
// RouterAdverMessage::Header
|
||||||
|
|
||||||
|
void RouterAdvertMessage::Header::SetToDefault(void)
|
||||||
|
{
|
||||||
|
OT_UNUSED_VARIABLE(mCode);
|
||||||
|
OT_UNUSED_VARIABLE(mCurHopLimit);
|
||||||
|
OT_UNUSED_VARIABLE(mReachableTime);
|
||||||
|
OT_UNUSED_VARIABLE(mRetransTimer);
|
||||||
|
|
||||||
|
Clear();
|
||||||
|
mType = Icmp::Header::kTypeRouterAdvert;
|
||||||
|
}
|
||||||
|
|
||||||
|
RoutePreference RouterAdvertMessage::Header::GetDefaultRouterPreference(void) const
|
||||||
|
{
|
||||||
|
return NetworkData::RoutePreferenceFromValue((mFlags & kPreferenceMask) >> kPreferenceOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouterAdvertMessage::Header::SetDefaultRouterPreference(RoutePreference aPreference)
|
||||||
|
{
|
||||||
|
mFlags &= ~kPreferenceMask;
|
||||||
|
mFlags |= (NetworkData::RoutePreferenceToValue(aPreference) << kPreferenceOffset) & kPreferenceMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
// RouterAdverMessage
|
||||||
|
|
||||||
|
Option *RouterAdvertMessage::AppendOption(uint16_t aOptionSize)
|
||||||
|
{
|
||||||
|
// This method appends an option with a given size to the RA
|
||||||
|
// message by reserving space in the data buffer if there is
|
||||||
|
// room. On success returns pointer to the option, on failure
|
||||||
|
// returns `nullptr`. The returned option needs to be
|
||||||
|
// initialized and populated by the caller.
|
||||||
|
|
||||||
|
Option * option = nullptr;
|
||||||
|
uint32_t newLength = mData.GetLength();
|
||||||
|
|
||||||
|
newLength += aOptionSize;
|
||||||
|
VerifyOrExit(newLength <= mMaxLength);
|
||||||
|
|
||||||
|
option = reinterpret_cast<Option *>(AsNonConst(GetDataEnd()));
|
||||||
|
mData.SetLength(static_cast<uint16_t>(newLength));
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return option;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error RouterAdvertMessage::AppendPrefixInfoOption(const Prefix &aPrefix,
|
||||||
|
uint32_t aValidLifetime,
|
||||||
|
uint32_t aPreferredLifetime)
|
||||||
|
{
|
||||||
|
Error error = kErrorNone;
|
||||||
|
PrefixInfoOption *pio;
|
||||||
|
|
||||||
|
pio = static_cast<PrefixInfoOption *>(AppendOption(sizeof(PrefixInfoOption)));
|
||||||
|
VerifyOrExit(pio != nullptr, error = kErrorNoBufs);
|
||||||
|
|
||||||
|
pio->Init();
|
||||||
|
pio->SetOnLinkFlag();
|
||||||
|
pio->SetAutoAddrConfigFlag();
|
||||||
|
pio->SetValidLifetime(aValidLifetime);
|
||||||
|
pio->SetPreferredLifetime(aPreferredLifetime);
|
||||||
|
pio->SetPrefix(aPrefix);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error RouterAdvertMessage::AppendRouteInfoOption(const Prefix & aPrefix,
|
||||||
|
uint32_t aRouteLifetime,
|
||||||
|
RoutePreference aPreference)
|
||||||
|
{
|
||||||
|
Error error = kErrorNone;
|
||||||
|
RouteInfoOption *rio;
|
||||||
|
|
||||||
|
rio = static_cast<RouteInfoOption *>(AppendOption(RouteInfoOption::OptionSizeForPrefix(aPrefix.GetLength())));
|
||||||
|
VerifyOrExit(rio != nullptr, error = kErrorNoBufs);
|
||||||
|
|
||||||
|
rio->Init();
|
||||||
|
rio->SetRouteLifetime(aRouteLifetime);
|
||||||
|
rio->SetPreference(aPreference);
|
||||||
|
rio->SetPrefix(aPrefix);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
// RouterAdvMessage
|
||||||
|
|
||||||
|
RouterSolicitMessage::RouterSolicitMessage(void)
|
||||||
|
{
|
||||||
|
mHeader.Clear();
|
||||||
|
mHeader.SetType(Icmp::Header::kTypeRouterSolicit);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Nd
|
||||||
|
} // namespace Ip6
|
||||||
|
} // namespace ot
|
|
@ -0,0 +1,699 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, The OpenThread Authors.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the copyright holder nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* This file includes definitions for IPv6 Neighbor Discovery (ND).
|
||||||
|
*
|
||||||
|
* See RFC 4861 (https://tools.ietf.org/html/rfc4861) and RFC 4191 (https://tools.ietf.org/html/rfc4191).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ND6_HPP_
|
||||||
|
#define ND6_HPP_
|
||||||
|
|
||||||
|
#include "openthread-core-config.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <openthread/netdata.h>
|
||||||
|
#include <openthread/platform/toolchain.h>
|
||||||
|
|
||||||
|
#include "common/const_cast.hpp"
|
||||||
|
#include "common/encoding.hpp"
|
||||||
|
#include "common/equatable.hpp"
|
||||||
|
#include "net/icmp6.hpp"
|
||||||
|
#include "net/ip6.hpp"
|
||||||
|
#include "thread/network_data_types.hpp"
|
||||||
|
|
||||||
|
using ot::Encoding::BigEndian::HostSwap16;
|
||||||
|
using ot::Encoding::BigEndian::HostSwap32;
|
||||||
|
|
||||||
|
namespace ot {
|
||||||
|
namespace Ip6 {
|
||||||
|
namespace Nd {
|
||||||
|
|
||||||
|
typedef NetworkData::RoutePreference RoutePreference; ///< Route Preference
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the variable length options in Neighbor Discovery messages.
|
||||||
|
*
|
||||||
|
* @sa PrefixInfoOption
|
||||||
|
* @sa RouteInfoOption
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
OT_TOOL_PACKED_BEGIN
|
||||||
|
class Option
|
||||||
|
{
|
||||||
|
friend class RouterAdvertMessage;
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum Type : uint8_t
|
||||||
|
{
|
||||||
|
kTypePrefixInfo = 3, ///< Prefix Information Option.
|
||||||
|
kTypeRouteInfo = 24, ///< Route Information Option.
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr uint16_t kLengthUnit = 8; ///< The unit of length in octets.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the option type.
|
||||||
|
*
|
||||||
|
* @returns The option type.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint8_t GetType(void) const { return mType; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the option type.
|
||||||
|
*
|
||||||
|
* @param[in] aType The option type.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetType(Type aType) { mType = aType; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the length based on a given total option size in bytes.
|
||||||
|
*
|
||||||
|
* Th option must end on a 64-bit boundary, so the length is derived as `(aSize + 7) / 8 * 8`.
|
||||||
|
*
|
||||||
|
* @param[in] aSize The size of option in bytes.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetSize(uint16_t aSize) { mLength = static_cast<uint8_t>((aSize + kLengthUnit - 1) / kLengthUnit); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the size of the option in bytes.
|
||||||
|
*
|
||||||
|
* @returns The size of the option in bytes.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint16_t GetSize(void) const { return mLength * kLengthUnit; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the length of the option (in unit of 8 bytes).
|
||||||
|
*
|
||||||
|
* @param[in] aLength The length of the option in unit of 8 bytes.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetLength(uint8_t aLength) { mLength = aLength; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the length of the option (in unit of 8 bytes).
|
||||||
|
*
|
||||||
|
* @returns The length of the option in unit of 8 bytes.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint16_t GetLength(void) const { return mLength; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicates whether or not this option is valid.
|
||||||
|
*
|
||||||
|
* @retval TRUE The option is valid.
|
||||||
|
* @retval FALSE The option is not valid.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool IsValid(void) const { return mLength > 0; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Iterator : public Unequatable<Iterator>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Iterator(void);
|
||||||
|
Iterator(const void *aStart, const void *aEnd);
|
||||||
|
|
||||||
|
const Option &operator*(void) { return *mOption; }
|
||||||
|
void operator++(void) { Advance(); }
|
||||||
|
void operator++(int) { Advance(); }
|
||||||
|
bool operator==(const Iterator &aOther) const { return mOption == aOther.mOption; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const Option *Next(const Option *aOption);
|
||||||
|
void Advance(void);
|
||||||
|
const Option * Validate(const Option *aOption) const;
|
||||||
|
|
||||||
|
const Option *mOption;
|
||||||
|
const Option *mEnd;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t mType; // Type of the option.
|
||||||
|
uint8_t mLength; // Length of the option in unit of 8 octets, including the `mType` and `mLength` fields.
|
||||||
|
} OT_TOOL_PACKED_END;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the Prefix Information Option.
|
||||||
|
*
|
||||||
|
* See section 4.6.2 of RFC 4861 for definition of this option [https://tools.ietf.org/html/rfc4861#section-4.6.2]
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
OT_TOOL_PACKED_BEGIN
|
||||||
|
class PrefixInfoOption : public Option, private Clearable<PrefixInfoOption>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr Type kType = kTypePrefixInfo; ///< Prefix Information Option Type.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method initializes the Prefix Info option with proper type and length and sets all other fields to zero.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void Init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicates whether or not the on-link flag is set.
|
||||||
|
*
|
||||||
|
* @retval TRUE The on-link flag is set.
|
||||||
|
* @retval FALSE The on-link flag is not set.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool IsOnLinkFlagSet(void) const { return (mFlags & kOnLinkFlagMask) != 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the on-link (L) flag.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetOnLinkFlag(void) { mFlags |= kOnLinkFlagMask; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method clears the on-link (L) flag.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ClearOnLinkFlag(void) { mFlags &= ~kOnLinkFlagMask; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicates whether or not the autonomous address-configuration (A) flag is set.
|
||||||
|
*
|
||||||
|
* @retval TRUE The auto address-config flag is set.
|
||||||
|
* @retval FALSE The auto address-config flag is not set.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool IsAutoAddrConfigFlagSet(void) const { return (mFlags & kAutoConfigFlagMask) != 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the autonomous address-configuration (A) flag.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetAutoAddrConfigFlag(void) { mFlags |= kAutoConfigFlagMask; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method clears the autonomous address-configuration (A) flag.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ClearAutoAddrConfigFlag(void) { mFlags &= ~kAutoConfigFlagMask; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the valid lifetime of the prefix in seconds.
|
||||||
|
*
|
||||||
|
* @param[in] aValidLifetime The valid lifetime in seconds.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetValidLifetime(uint32_t aValidLifetime) { mValidLifetime = HostSwap32(aValidLifetime); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* THis method gets the valid lifetime of the prefix in seconds.
|
||||||
|
*
|
||||||
|
* @returns The valid lifetime in seconds.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t GetValidLifetime(void) const { return HostSwap32(mValidLifetime); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the preferred lifetime of the prefix in seconds.
|
||||||
|
*
|
||||||
|
* @param[in] aPreferredLifetime The preferred lifetime in seconds.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetPreferredLifetime(uint32_t aPreferredLifetime) { mPreferredLifetime = HostSwap32(aPreferredLifetime); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* THis method returns the preferred lifetime of the prefix in seconds.
|
||||||
|
*
|
||||||
|
* @returns The preferred lifetime in seconds.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t GetPreferredLifetime(void) const { return HostSwap32(mPreferredLifetime); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the prefix.
|
||||||
|
*
|
||||||
|
* @param[in] aPrefix The prefix contained in this option.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetPrefix(const Prefix &aPrefix);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the prefix in this option.
|
||||||
|
*
|
||||||
|
* @param[out] aPrefix Reference to a `Prefix` to return the prefix.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void GetPrefix(Prefix &aPrefix) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicates whether or not the option is valid.
|
||||||
|
*
|
||||||
|
* @retval TRUE The option is valid
|
||||||
|
* @retval FALSE The option is not valid.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool IsValid(void) const;
|
||||||
|
|
||||||
|
PrefixInfoOption(void) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Prefix Information Option
|
||||||
|
//
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Type | Length | Prefix Length |L|A| Reserved1 |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Valid Lifetime |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Preferred Lifetime |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Reserved2 |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | |
|
||||||
|
// + +
|
||||||
|
// | |
|
||||||
|
// + Prefix +
|
||||||
|
// | |
|
||||||
|
// + +
|
||||||
|
// | |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
static constexpr uint8_t kAutoConfigFlagMask = 0x40; // Autonomous address-configuration flag.
|
||||||
|
static constexpr uint8_t kOnLinkFlagMask = 0x80; // On-link flag.
|
||||||
|
|
||||||
|
uint8_t mPrefixLength; // The prefix length in bits.
|
||||||
|
uint8_t mFlags; // The flags field.
|
||||||
|
uint32_t mValidLifetime; // The valid lifetime of the prefix.
|
||||||
|
uint32_t mPreferredLifetime; // The preferred lifetime of the prefix.
|
||||||
|
uint32_t mReserved2; // The reserved field.
|
||||||
|
Address mPrefix; // The prefix.
|
||||||
|
} OT_TOOL_PACKED_END;
|
||||||
|
|
||||||
|
static_assert(sizeof(PrefixInfoOption) == 32, "invalid PrefixInfoOption structure");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the Route Information Option.
|
||||||
|
*
|
||||||
|
* See section 2.3 of RFC 4191 for definition of this option. [https://tools.ietf.org/html/rfc4191#section-2.3]
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
OT_TOOL_PACKED_BEGIN
|
||||||
|
class RouteInfoOption : public Option, private Clearable<RouteInfoOption>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr uint16_t kMinSize = kLengthUnit; ///< Minimum size (in bytes) of a Route Info Option
|
||||||
|
static constexpr Type kType = kTypeRouteInfo; ///< Route Information Option Type.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method initializes the option setting the type and clearing (setting to zero) all other fields.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void Init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the route preference.
|
||||||
|
*
|
||||||
|
* @param[in] aPreference The route preference.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetPreference(RoutePreference aPreference);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the route preference.
|
||||||
|
*
|
||||||
|
* @returns The route preference.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
RoutePreference GetPreference(void) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the lifetime of the route in seconds.
|
||||||
|
*
|
||||||
|
* @param[in] aLifetime The lifetime of the route in seconds.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetRouteLifetime(uint32_t aLifetime) { mRouteLifetime = HostSwap32(aLifetime); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets Route Lifetime in seconds.
|
||||||
|
*
|
||||||
|
* @returns The Route Lifetime in seconds.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t GetRouteLifetime(void) const { return HostSwap32(mRouteLifetime); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the prefix and adjusts the option length based on the prefix length.
|
||||||
|
*
|
||||||
|
* @param[in] aPrefix The prefix contained in this option.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetPrefix(const Prefix &aPrefix);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the prefix in this option.
|
||||||
|
*
|
||||||
|
* @param[out] aPrefix Reference to a `Prefix` to return the prefix.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void GetPrefix(Prefix &aPrefix) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method tells whether this option is valid.
|
||||||
|
*
|
||||||
|
* @returns A boolean indicates whether this option is valid.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool IsValid(void) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This static method calculates the minimum option length for a given prefix length.
|
||||||
|
*
|
||||||
|
* The option length (which is in unit of 8 octets) can be 1, 2, or 3 depending on the prefix length. It can be 1
|
||||||
|
* for a zero prefix length, 2 if the prefix length is not greater than 64, and 3 otherwise.
|
||||||
|
*
|
||||||
|
* @param[in] aPrefixLength The prefix length (in bits).
|
||||||
|
*
|
||||||
|
* @returns The option length (in unit of 8 octet) for @p aPrefixLength.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static uint8_t OptionLengthForPrefix(uint8_t aPrefixLength);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This static method calculates the minimum option size (in bytes) for a given prefix length.
|
||||||
|
*
|
||||||
|
* @param[in] aPrefixLength The prefix length (in bits).
|
||||||
|
*
|
||||||
|
* @returns The option size (in bytes) for @p aPrefixLength.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static uint16_t OptionSizeForPrefix(uint8_t aPrefixLength)
|
||||||
|
{
|
||||||
|
return kLengthUnit * OptionLengthForPrefix(aPrefixLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
RouteInfoOption(void) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Route Information Option
|
||||||
|
//
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Type | Length | Prefix Length |Resvd|Prf|Resvd|
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Route Lifetime |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Prefix (Variable Length) |
|
||||||
|
// . .
|
||||||
|
// . .
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
static constexpr uint8_t kPreferenceOffset = 3;
|
||||||
|
static constexpr uint8_t kPreferenceMask = 3 << kPreferenceOffset;
|
||||||
|
|
||||||
|
uint8_t * GetPrefixBytes(void) { return AsNonConst(AsConst(this)->GetPrefixBytes()); }
|
||||||
|
const uint8_t *GetPrefixBytes(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); }
|
||||||
|
|
||||||
|
uint8_t mPrefixLength; // The prefix length in bits.
|
||||||
|
uint8_t mResvdPrf; // The preference.
|
||||||
|
uint32_t mRouteLifetime; // The lifetime in seconds.
|
||||||
|
// Followed by prefix bytes (variable length).
|
||||||
|
|
||||||
|
} OT_TOOL_PACKED_END;
|
||||||
|
|
||||||
|
static_assert(sizeof(RouteInfoOption) == 8, "invalid RouteInfoOption structure");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a Router Advertisement message.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class RouterAdvertMessage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* This class implements the RA message header.
|
||||||
|
*
|
||||||
|
* See section 2.2 of RFC 4191 [https://datatracker.ietf.org/doc/html/rfc4191]
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
OT_TOOL_PACKED_BEGIN
|
||||||
|
class Header : public Equatable<Header>, private Clearable<Header>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* This constructor initializes the Router Advertisement message with
|
||||||
|
* zero router lifetime, reachable time and retransmission timer.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Header(void) { SetToDefault(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the RA message to default values.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetToDefault(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the checksum value.
|
||||||
|
*
|
||||||
|
* @param[in] aChecksum The checksum value.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetChecksum(uint16_t aChecksum) { mChecksum = HostSwap16(aChecksum); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the Router Lifetime in seconds.
|
||||||
|
*
|
||||||
|
* @param[in] aRouterLifetime The router lifetime in seconds.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetRouterLifetime(uint16_t aRouterLifetime) { mRouterLifetime = HostSwap16(aRouterLifetime); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the Router Lifetime (in seconds).
|
||||||
|
*
|
||||||
|
* Router Lifetime set to zero indicates that the sender is not a default router.
|
||||||
|
*
|
||||||
|
* @returns The router lifetime in seconds.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint16_t GetRouterLifetime(void) const { return HostSwap16(mRouterLifetime); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the default router preference.
|
||||||
|
*
|
||||||
|
* @param[in] aPreference The router preference.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetDefaultRouterPreference(RoutePreference aPreference);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the default router preference.
|
||||||
|
*
|
||||||
|
* @returns The router preference.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
RoutePreference GetDefaultRouterPreference(void) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Router Advertisement Message
|
||||||
|
//
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Type | Code | Checksum |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Cur Hop Limit |M|O|H|Prf|Resvd| Router Lifetime |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Reachable Time |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Retrans Timer |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | Options ...
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-
|
||||||
|
|
||||||
|
static constexpr uint8_t kPreferenceOffset = 3;
|
||||||
|
static constexpr uint8_t kPreferenceMask = 3 << kPreferenceOffset;
|
||||||
|
|
||||||
|
uint8_t mType;
|
||||||
|
uint8_t mCode;
|
||||||
|
uint16_t mChecksum;
|
||||||
|
uint8_t mCurHopLimit;
|
||||||
|
uint8_t mFlags;
|
||||||
|
uint16_t mRouterLifetime;
|
||||||
|
uint32_t mReachableTime;
|
||||||
|
uint32_t mRetransTimer;
|
||||||
|
} OT_TOOL_PACKED_END;
|
||||||
|
|
||||||
|
static_assert(sizeof(Header) == 16, "Invalid RA `Header`");
|
||||||
|
|
||||||
|
typedef Data<kWithUint16Length> Icmp6Packet; ///< A data buffer containing an ICMPv6 packet.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructor initializes the RA message from a received packet data buffer.
|
||||||
|
*
|
||||||
|
* @param[in] aPacket A received packet data.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
explicit RouterAdvertMessage(const Icmp6Packet &aPacket)
|
||||||
|
: mData(aPacket)
|
||||||
|
, mMaxLength(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This template constructor initializes the RA message with a given header using a given buffer to store the RA
|
||||||
|
* message.
|
||||||
|
*
|
||||||
|
* @tparam kBufferSize The size of the buffer used to store the RA message.
|
||||||
|
*
|
||||||
|
* @param[in] aHeader The RA message header.
|
||||||
|
* @param[in] aBuffer The data buffer to store the RA message in.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
template <uint16_t kBufferSize>
|
||||||
|
RouterAdvertMessage(const Header &aHeader, uint8_t (&aBuffer)[kBufferSize])
|
||||||
|
: mMaxLength(kBufferSize)
|
||||||
|
{
|
||||||
|
static_assert(kBufferSize >= sizeof(Header), "Buffer for RA msg is too small");
|
||||||
|
|
||||||
|
memcpy(aBuffer, &aHeader, sizeof(Header));
|
||||||
|
mData.Init(aBuffer, sizeof(Header));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the RA message as an `Icmp6Packet`.
|
||||||
|
*
|
||||||
|
* @returns The RA message as an `Icmp6Packet`.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const Icmp6Packet &GetAsPacket(void) const { return mData; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicates whether or not the RA message is valid.
|
||||||
|
*
|
||||||
|
* @retval TRUE If the RA message is valid.
|
||||||
|
* @retval FALSE If the RA message is not valid.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool IsValid(void) const { return (mData.GetBytes() != nullptr) && (mData.GetLength() >= sizeof(Header)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the RA message's header.
|
||||||
|
*
|
||||||
|
* @returns The RA message's header.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const Header &GetHeader(void) const { return *reinterpret_cast<const Header *>(mData.GetBytes()); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method appends a Prefix Info Option to the RA message.
|
||||||
|
*
|
||||||
|
* The appended Prefix Info Option will have both on-link (L) and autonomous address-configuration (A) flags set.
|
||||||
|
*
|
||||||
|
* @param[in] aPrefix The prefix.
|
||||||
|
* @param[in] aValidLifetime The valid lifetime in seconds.
|
||||||
|
* @param[in] aPreferredLifetime The preferred lifetime in seconds.
|
||||||
|
*
|
||||||
|
* @retval kErrorNone Option is appended successfully.
|
||||||
|
* @retval kErrorNoBufs No more space in the buffer to append the option.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Error AppendPrefixInfoOption(const Prefix &aPrefix, uint32_t aValidLifetime, uint32_t aPreferredLifetime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method appends a Route Info Option to the RA message.
|
||||||
|
*
|
||||||
|
* @param[in] aPrefix The prefix.
|
||||||
|
* @param[in] aRouteLifetime The route lifetime in seconds.
|
||||||
|
* @param[in] aPreference The route preference.
|
||||||
|
*
|
||||||
|
* @retval kErrorNone Option is appended successfully.
|
||||||
|
* @retval kErrorNoBufs No more space in the buffer to append the option.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Error AppendRouteInfoOption(const Prefix &aPrefix, uint32_t aRouteLifetime, RoutePreference aPreference);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicates whether or not the RA message contains any options.
|
||||||
|
*
|
||||||
|
* @retval TRUE If the RA message contains at least one option.
|
||||||
|
* @retval FALSE If the RA message contains no options.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool ContainsAnyOptions(void) const { return (mData.GetLength() > sizeof(Header)); }
|
||||||
|
|
||||||
|
// The following methods are intended to support range-based `for`
|
||||||
|
// loop iteration over `Option`s in the RA message.
|
||||||
|
|
||||||
|
Option::Iterator begin(void) const { return Option::Iterator(GetOptionStart(), GetDataEnd()); }
|
||||||
|
Option::Iterator end(void) const { return Option::Iterator(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const uint8_t *GetOptionStart(void) const { return (mData.GetBytes() + sizeof(Header)); }
|
||||||
|
const uint8_t *GetDataEnd(void) const { return mData.GetBytes() + mData.GetLength(); }
|
||||||
|
Option * AppendOption(uint16_t aOptionSize);
|
||||||
|
|
||||||
|
Data<kWithUint16Length> mData;
|
||||||
|
uint16_t mMaxLength;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements the Router Solicitation message.
|
||||||
|
*
|
||||||
|
* See section 4.1 of RFC 4861 for definition of this message.
|
||||||
|
* https://tools.ietf.org/html/rfc4861#section-4.1
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
OT_TOOL_PACKED_BEGIN
|
||||||
|
class RouterSolicitMessage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* This constructor initializes the Router Solicitation message.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
RouterSolicitMessage(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Icmp::Header mHeader; // The common ICMPv6 header.
|
||||||
|
} OT_TOOL_PACKED_END;
|
||||||
|
|
||||||
|
static_assert(sizeof(RouterSolicitMessage) == 8, "invalid RouterSolicitMessage structure");
|
||||||
|
|
||||||
|
} // namespace Nd
|
||||||
|
} // namespace Ip6
|
||||||
|
} // namespace ot
|
||||||
|
|
||||||
|
#endif // ND6_HPP_
|
|
@ -76,10 +76,20 @@ void Client::HostInfo::SetState(ItemState aState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::HostInfo::EnableAutoAddress(void)
|
||||||
|
{
|
||||||
|
mAddresses = nullptr;
|
||||||
|
mNumAddresses = 0;
|
||||||
|
mAutoAddress = true;
|
||||||
|
|
||||||
|
LogInfo("HostInfo enabled auto address", GetNumAddresses());
|
||||||
|
}
|
||||||
|
|
||||||
void Client::HostInfo::SetAddresses(const Ip6::Address *aAddresses, uint8_t aNumAddresses)
|
void Client::HostInfo::SetAddresses(const Ip6::Address *aAddresses, uint8_t aNumAddresses)
|
||||||
{
|
{
|
||||||
mAddresses = aAddresses;
|
mAddresses = aAddresses;
|
||||||
mNumAddresses = aNumAddresses;
|
mNumAddresses = aNumAddresses;
|
||||||
|
mAutoAddress = false;
|
||||||
|
|
||||||
LogInfo("HostInfo set %d addrs", GetNumAddresses());
|
LogInfo("HostInfo set %d addrs", GetNumAddresses());
|
||||||
|
|
||||||
|
@ -239,12 +249,14 @@ Client::Client(Instance &aInstance)
|
||||||
, mState(kStateStopped)
|
, mState(kStateStopped)
|
||||||
, mTxFailureRetryCount(0)
|
, mTxFailureRetryCount(0)
|
||||||
, mShouldRemoveKeyLease(false)
|
, mShouldRemoveKeyLease(false)
|
||||||
|
, mAutoHostAddressAddedMeshLocal(false)
|
||||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||||
, mServiceKeyRecordEnabled(false)
|
, mServiceKeyRecordEnabled(false)
|
||||||
#endif
|
#endif
|
||||||
, mUpdateMessageId(0)
|
, mUpdateMessageId(0)
|
||||||
, mRetryWaitInterval(kMinRetryWaitInterval)
|
, mRetryWaitInterval(kMinRetryWaitInterval)
|
||||||
, mAcceptedLeaseInterval(0)
|
, mAcceptedLeaseInterval(0)
|
||||||
|
, mTtl(0)
|
||||||
, mLeaseInterval(kDefaultLease)
|
, mLeaseInterval(kDefaultLease)
|
||||||
, mKeyLeaseInterval(kDefaultKeyLease)
|
, mKeyLeaseInterval(kDefaultKeyLease)
|
||||||
, mSocket(aInstance)
|
, mSocket(aInstance)
|
||||||
|
@ -323,6 +335,8 @@ void Client::Stop(Requester aRequester, StopMode aMode)
|
||||||
|
|
||||||
VerifyOrExit(GetState() != kStateStopped);
|
VerifyOrExit(GetState() != kStateStopped);
|
||||||
|
|
||||||
|
mSingleServiceMode.Disable();
|
||||||
|
|
||||||
// State changes:
|
// State changes:
|
||||||
// kAdding -> kToRefresh
|
// kAdding -> kToRefresh
|
||||||
// kRefreshing -> kToRefresh
|
// kRefreshing -> kToRefresh
|
||||||
|
@ -391,6 +405,8 @@ void Client::Pause(void)
|
||||||
/* (7) kRemoved -> */ kRemoved,
|
/* (7) kRemoved -> */ kRemoved,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mSingleServiceMode.Disable();
|
||||||
|
|
||||||
// State changes:
|
// State changes:
|
||||||
// kAdding -> kToRefresh
|
// kAdding -> kToRefresh
|
||||||
// kRefreshing -> kToRefresh
|
// kRefreshing -> kToRefresh
|
||||||
|
@ -414,6 +430,22 @@ void Client::HandleNotifierEvents(Events aEvents)
|
||||||
ProcessAutoStart();
|
ProcessAutoStart();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (mHostInfo.IsAutoAddressEnabled())
|
||||||
|
{
|
||||||
|
Events::Flags eventFlags = (kEventIp6AddressAdded | kEventIp6AddressRemoved);
|
||||||
|
|
||||||
|
if (mAutoHostAddressAddedMeshLocal)
|
||||||
|
{
|
||||||
|
eventFlags |= kEventThreadMeshLocalAddrChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aEvents.ContainsAny(eventFlags))
|
||||||
|
{
|
||||||
|
IgnoreError(UpdateHostInfoStateOnAddressChange());
|
||||||
|
UpdateState();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::HandleRoleChanged(void)
|
void Client::HandleRoleChanged(void)
|
||||||
|
@ -465,11 +497,37 @@ exit:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Error Client::EnableAutoHostAddress(void)
|
||||||
|
{
|
||||||
|
Error error = kErrorNone;
|
||||||
|
|
||||||
|
VerifyOrExit(!mHostInfo.IsAutoAddressEnabled());
|
||||||
|
SuccessOrExit(error = UpdateHostInfoStateOnAddressChange());
|
||||||
|
|
||||||
|
mHostInfo.EnableAutoAddress();
|
||||||
|
UpdateState();
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
Error Client::SetHostAddresses(const Ip6::Address *aAddresses, uint8_t aNumAddresses)
|
Error Client::SetHostAddresses(const Ip6::Address *aAddresses, uint8_t aNumAddresses)
|
||||||
{
|
{
|
||||||
Error error = kErrorNone;
|
Error error = kErrorNone;
|
||||||
|
|
||||||
VerifyOrExit((aAddresses != nullptr) && (aNumAddresses > 0), error = kErrorInvalidArgs);
|
VerifyOrExit((aAddresses != nullptr) && (aNumAddresses > 0), error = kErrorInvalidArgs);
|
||||||
|
SuccessOrExit(error = UpdateHostInfoStateOnAddressChange());
|
||||||
|
|
||||||
|
mHostInfo.SetAddresses(aAddresses, aNumAddresses);
|
||||||
|
UpdateState();
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error Client::UpdateHostInfoStateOnAddressChange(void)
|
||||||
|
{
|
||||||
|
Error error = kErrorNone;
|
||||||
|
|
||||||
VerifyOrExit((mHostInfo.GetState() != kToRemove) && (mHostInfo.GetState() != kRemoving),
|
VerifyOrExit((mHostInfo.GetState() != kToRemove) && (mHostInfo.GetState() != kRemoving),
|
||||||
error = kErrorInvalidState);
|
error = kErrorInvalidState);
|
||||||
|
@ -483,9 +541,6 @@ Error Client::SetHostAddresses(const Ip6::Address *aAddresses, uint8_t aNumAddre
|
||||||
mHostInfo.SetState(kToRefresh);
|
mHostInfo.SetState(kToRefresh);
|
||||||
}
|
}
|
||||||
|
|
||||||
mHostInfo.SetAddresses(aAddresses, aNumAddresses);
|
|
||||||
UpdateState();
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -659,6 +714,11 @@ void Client::ChangeHostAndServiceStates(const ItemState *aNewStates)
|
||||||
|
|
||||||
for (Service &service : mServices)
|
for (Service &service : mServices)
|
||||||
{
|
{
|
||||||
|
if (mSingleServiceMode.IsEnabled() && mSingleServiceMode.GetService() != &service)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
service.SetState(aNewStates[service.GetState()]);
|
service.SetState(aNewStates[service.GetState()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -717,9 +777,21 @@ void Client::SendUpdate(void)
|
||||||
|
|
||||||
Error error = kErrorNone;
|
Error error = kErrorNone;
|
||||||
Message *message = mSocket.NewMessage(0);
|
Message *message = mSocket.NewMessage(0);
|
||||||
|
uint32_t length;
|
||||||
|
|
||||||
VerifyOrExit(message != nullptr, error = kErrorNoBufs);
|
VerifyOrExit(message != nullptr, error = kErrorNoBufs);
|
||||||
SuccessOrExit(error = PrepareUpdateMessage(*message));
|
SuccessOrExit(error = PrepareUpdateMessage(*message));
|
||||||
|
|
||||||
|
length = message->GetLength() + sizeof(Ip6::Udp::Header) + sizeof(Ip6::Header);
|
||||||
|
|
||||||
|
if (length >= Ip6::kMaxDatagramLength)
|
||||||
|
{
|
||||||
|
LogInfo("Msg len %u is larger than MTU, enabling single service mode", length);
|
||||||
|
mSingleServiceMode.Enable();
|
||||||
|
IgnoreError(message->SetLength(0));
|
||||||
|
SuccessOrExit(error = PrepareUpdateMessage(*message));
|
||||||
|
}
|
||||||
|
|
||||||
SuccessOrExit(error = mSocket.SendTo(*message, Ip6::MessageInfo()));
|
SuccessOrExit(error = mSocket.SendTo(*message, Ip6::MessageInfo()));
|
||||||
|
|
||||||
LogInfo("Send update");
|
LogInfo("Send update");
|
||||||
|
@ -757,6 +829,7 @@ exit:
|
||||||
|
|
||||||
LogInfo("Failed to send update: %s", ErrorToString(error));
|
LogInfo("Failed to send update: %s", ErrorToString(error));
|
||||||
|
|
||||||
|
mSingleServiceMode.Disable();
|
||||||
FreeMessage(message);
|
FreeMessage(message);
|
||||||
|
|
||||||
SetState(kStateToRetry);
|
SetState(kStateToRetry);
|
||||||
|
@ -831,6 +904,11 @@ Error Client::PrepareUpdateMessage(Message &aMessage)
|
||||||
for (Service &service : mServices)
|
for (Service &service : mServices)
|
||||||
{
|
{
|
||||||
SuccessOrExit(error = AppendServiceInstructions(service, aMessage, info));
|
SuccessOrExit(error = AppendServiceInstructions(service, aMessage, info));
|
||||||
|
|
||||||
|
if (mSingleServiceMode.IsEnabled() && (mSingleServiceMode.GetService() != nullptr))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -911,7 +989,7 @@ Error Client::AppendServiceInstructions(Service &aService, Message &aMessage, In
|
||||||
// to NONE and TTL to zero (RFC 2136 - section 2.5.4).
|
// to NONE and TTL to zero (RFC 2136 - section 2.5.4).
|
||||||
|
|
||||||
rr.Init(Dns::ResourceRecord::kTypePtr, removing ? Dns::PtrRecord::kClassNone : Dns::PtrRecord::kClassInternet);
|
rr.Init(Dns::ResourceRecord::kTypePtr, removing ? Dns::PtrRecord::kClassNone : Dns::PtrRecord::kClassInternet);
|
||||||
rr.SetTtl(removing ? 0 : mLeaseInterval);
|
rr.SetTtl(removing ? 0 : GetTtl());
|
||||||
offset = aMessage.GetLength();
|
offset = aMessage.GetLength();
|
||||||
SuccessOrExit(error = aMessage.Append(rr));
|
SuccessOrExit(error = aMessage.Append(rr));
|
||||||
|
|
||||||
|
@ -970,7 +1048,7 @@ Error Client::AppendServiceInstructions(Service &aService, Message &aMessage, In
|
||||||
|
|
||||||
SuccessOrExit(error = Dns::Name::AppendPointerLabel(instanceNameOffset, aMessage));
|
SuccessOrExit(error = Dns::Name::AppendPointerLabel(instanceNameOffset, aMessage));
|
||||||
srv.Init();
|
srv.Init();
|
||||||
srv.SetTtl(mLeaseInterval);
|
srv.SetTtl(GetTtl());
|
||||||
srv.SetPriority(aService.GetPriority());
|
srv.SetPriority(aService.GetPriority());
|
||||||
srv.SetWeight(aService.GetWeight());
|
srv.SetWeight(aService.GetWeight());
|
||||||
srv.SetPort(aService.GetPort());
|
srv.SetPort(aService.GetPort());
|
||||||
|
@ -1003,14 +1081,18 @@ Error Client::AppendServiceInstructions(Service &aService, Message &aMessage, In
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (mSingleServiceMode.IsEnabled())
|
||||||
|
{
|
||||||
|
mSingleServiceMode.SetService(aService);
|
||||||
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error Client::AppendHostDescriptionInstruction(Message &aMessage, Info &aInfo) const
|
Error Client::AppendHostDescriptionInstruction(Message &aMessage, Info &aInfo)
|
||||||
{
|
{
|
||||||
Error error = kErrorNone;
|
Error error = kErrorNone;
|
||||||
Dns::ResourceRecord rr;
|
|
||||||
|
|
||||||
//----------------------------------
|
//----------------------------------
|
||||||
// Host Description Instruction
|
// Host Description Instruction
|
||||||
|
@ -1023,16 +1105,37 @@ Error Client::AppendHostDescriptionInstruction(Message &aMessage, Info &aInfo) c
|
||||||
|
|
||||||
// AAAA RRs
|
// AAAA RRs
|
||||||
|
|
||||||
rr.Init(Dns::ResourceRecord::kTypeAaaa);
|
if (mHostInfo.IsAutoAddressEnabled())
|
||||||
rr.SetTtl(mLeaseInterval);
|
|
||||||
rr.SetLength(sizeof(Ip6::Address));
|
|
||||||
|
|
||||||
for (uint8_t index = 0; index < mHostInfo.GetNumAddresses(); index++)
|
|
||||||
{
|
{
|
||||||
SuccessOrExit(error = AppendHostName(aMessage, aInfo));
|
// Append all addresses on Thread netif excluding link-local and
|
||||||
SuccessOrExit(error = aMessage.Append(rr));
|
// mesh-local addresses. If no address is appended, we include
|
||||||
SuccessOrExit(error = aMessage.Append(mHostInfo.GetAddress(index)));
|
// the mesh local address.
|
||||||
aInfo.mRecordCount++;
|
|
||||||
|
mAutoHostAddressAddedMeshLocal = true;
|
||||||
|
|
||||||
|
for (const Ip6::Netif::UnicastAddress &unicastAddress : Get<ThreadNetif>().GetUnicastAddresses())
|
||||||
|
{
|
||||||
|
if (unicastAddress.GetAddress().IsLinkLocal() ||
|
||||||
|
Get<Mle::Mle>().IsMeshLocalAddress(unicastAddress.GetAddress()))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SuccessOrExit(error = AppendAaaaRecord(unicastAddress.GetAddress(), aMessage, aInfo));
|
||||||
|
mAutoHostAddressAddedMeshLocal = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mAutoHostAddressAddedMeshLocal)
|
||||||
|
{
|
||||||
|
SuccessOrExit(error = AppendAaaaRecord(Get<Mle::Mle>().GetMeshLocal64(), aMessage, aInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (uint8_t index = 0; index < mHostInfo.GetNumAddresses(); index++)
|
||||||
|
{
|
||||||
|
SuccessOrExit(error = AppendAaaaRecord(mHostInfo.GetAddress(index), aMessage, aInfo));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// KEY RR
|
// KEY RR
|
||||||
|
@ -1044,6 +1147,24 @@ exit:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Error Client::AppendAaaaRecord(const Ip6::Address &aAddress, Message &aMessage, Info &aInfo) const
|
||||||
|
{
|
||||||
|
Error error;
|
||||||
|
Dns::ResourceRecord rr;
|
||||||
|
|
||||||
|
rr.Init(Dns::ResourceRecord::kTypeAaaa);
|
||||||
|
rr.SetTtl(GetTtl());
|
||||||
|
rr.SetLength(sizeof(Ip6::Address));
|
||||||
|
|
||||||
|
SuccessOrExit(error = AppendHostName(aMessage, aInfo));
|
||||||
|
SuccessOrExit(error = aMessage.Append(rr));
|
||||||
|
SuccessOrExit(error = aMessage.Append(aAddress));
|
||||||
|
aInfo.mRecordCount++;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
Error Client::AppendKeyRecord(Message &aMessage, Info &aInfo) const
|
Error Client::AppendKeyRecord(Message &aMessage, Info &aInfo) const
|
||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
|
@ -1051,7 +1172,7 @@ Error Client::AppendKeyRecord(Message &aMessage, Info &aInfo) const
|
||||||
Crypto::Ecdsa::P256::PublicKey publicKey;
|
Crypto::Ecdsa::P256::PublicKey publicKey;
|
||||||
|
|
||||||
key.Init();
|
key.Init();
|
||||||
key.SetTtl(mLeaseInterval);
|
key.SetTtl(GetTtl());
|
||||||
key.SetFlags(Dns::KeyRecord::kAuthConfidPermitted, Dns::KeyRecord::kOwnerNonZone,
|
key.SetFlags(Dns::KeyRecord::kAuthConfidPermitted, Dns::KeyRecord::kOwnerNonZone,
|
||||||
Dns::KeyRecord::kSignatoryFlagGeneral);
|
Dns::KeyRecord::kSignatoryFlagGeneral);
|
||||||
key.SetProtocol(Dns::KeyRecord::kProtocolDnsSec);
|
key.SetProtocol(Dns::KeyRecord::kProtocolDnsSec);
|
||||||
|
@ -1384,6 +1505,7 @@ void Client::ProcessResponse(Message &aMessage)
|
||||||
// kRemoving -> kRemoved
|
// kRemoving -> kRemoved
|
||||||
|
|
||||||
ChangeHostAndServiceStates(kNewStateOnUpdateDone);
|
ChangeHostAndServiceStates(kNewStateOnUpdateDone);
|
||||||
|
mSingleServiceMode.Disable();
|
||||||
|
|
||||||
HandleUpdateDone();
|
HandleUpdateDone();
|
||||||
UpdateState();
|
UpdateState();
|
||||||
|
@ -1518,7 +1640,7 @@ void Client::UpdateState(void)
|
||||||
// host address, otherwise no need to send SRP update message.
|
// host address, otherwise no need to send SRP update message.
|
||||||
// The exception is when removing host info where we allow
|
// The exception is when removing host info where we allow
|
||||||
// for empty service list.
|
// for empty service list.
|
||||||
VerifyOrExit(!mServices.IsEmpty() && (mHostInfo.GetNumAddresses() > 0));
|
VerifyOrExit(!mServices.IsEmpty() && (mHostInfo.IsAutoAddressEnabled() || (mHostInfo.GetNumAddresses() > 0)));
|
||||||
|
|
||||||
// Fall through
|
// Fall through
|
||||||
|
|
||||||
|
@ -1653,6 +1775,7 @@ void Client::HandleTimer(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kStateUpdating:
|
case kStateUpdating:
|
||||||
|
mSingleServiceMode.Disable();
|
||||||
LogRetryWaitInterval();
|
LogRetryWaitInterval();
|
||||||
LogInfo("Timed out, no response");
|
LogInfo("Timed out, no response");
|
||||||
GrowRetryWaitInterval();
|
GrowRetryWaitInterval();
|
||||||
|
@ -1782,7 +1905,6 @@ Error Client::SelectUnicastEntry(DnsSrpUnicast::Origin aOrigin, DnsSrpUnicast::I
|
||||||
Error error = kErrorNotFound;
|
Error error = kErrorNotFound;
|
||||||
DnsSrpUnicast::Info unicastInfo;
|
DnsSrpUnicast::Info unicastInfo;
|
||||||
NetworkData::Service::Manager::Iterator iterator;
|
NetworkData::Service::Manager::Iterator iterator;
|
||||||
uint16_t numServers = 0;
|
|
||||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_SAVE_SELECTED_SERVER_ENABLE
|
#if OPENTHREAD_CONFIG_SRP_CLIENT_SAVE_SELECTED_SERVER_ENABLE
|
||||||
Settings::SrpClientInfo savedInfo;
|
Settings::SrpClientInfo savedInfo;
|
||||||
bool hasSavedServerInfo = false;
|
bool hasSavedServerInfo = false;
|
||||||
|
@ -1819,16 +1941,10 @@ Error Client::SelectUnicastEntry(DnsSrpUnicast::Origin aOrigin, DnsSrpUnicast::I
|
||||||
ExitNow();
|
ExitNow();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
numServers++;
|
|
||||||
|
|
||||||
// Choose a server randomly (with uniform distribution) from
|
// Prefer the numerically lowest server address
|
||||||
// the list of servers. As we iterate through server entries,
|
|
||||||
// with probability `1/numServers`, we choose to switch the
|
|
||||||
// current selected server with the new entry. This approach
|
|
||||||
// results in a uniform/same probability of selection among
|
|
||||||
// all server entries.
|
|
||||||
|
|
||||||
if ((numServers == 1) || (Random::NonCrypto::GetUint16InRange(0, numServers) == 0))
|
if ((error == kErrorNotFound) || (unicastInfo.mSockAddr.GetAddress() < aInfo.mSockAddr.GetAddress()))
|
||||||
{
|
{
|
||||||
aInfo = unicastInfo;
|
aInfo = unicastInfo;
|
||||||
error = kErrorNone;
|
error = kErrorNone;
|
||||||
|
|
|
@ -103,7 +103,7 @@ public:
|
||||||
* This type represents an SRP client host info.
|
* This type represents an SRP client host info.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class HostInfo : public otSrpClientHostInfo, public Clearable<HostInfo>
|
class HostInfo : public otSrpClientHostInfo, private Clearable<HostInfo>
|
||||||
{
|
{
|
||||||
friend class Client;
|
friend class Client;
|
||||||
|
|
||||||
|
@ -128,6 +128,15 @@ public:
|
||||||
*/
|
*/
|
||||||
const char *GetName(void) const { return mName; }
|
const char *GetName(void) const { return mName; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicates whether or not the host auto address mode is enabled.
|
||||||
|
*
|
||||||
|
* @retval TRUE If the auto address mode is enabled.
|
||||||
|
* @retval FALSE If the auto address mode is disabled.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool IsAutoAddressEnabled(void) const { return mAutoAddress; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method gets the number of host IPv6 addresses.
|
* This method gets the number of host IPv6 addresses.
|
||||||
*
|
*
|
||||||
|
@ -158,6 +167,7 @@ public:
|
||||||
void SetName(const char *aName) { mName = aName; }
|
void SetName(const char *aName) { mName = aName; }
|
||||||
void SetState(ItemState aState);
|
void SetState(ItemState aState);
|
||||||
void SetAddresses(const Ip6::Address *aAddresses, uint8_t aNumAddresses);
|
void SetAddresses(const Ip6::Address *aAddresses, uint8_t aNumAddresses);
|
||||||
|
void EnableAutoAddress(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -410,6 +420,31 @@ public:
|
||||||
*/
|
*/
|
||||||
void SetCallback(Callback aCallback, void *aContext);
|
void SetCallback(Callback aCallback, void *aContext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the TTL used in SRP update requests.
|
||||||
|
*
|
||||||
|
* Note that this is the TTL requested by the SRP client. The server may choose to accept a different TTL.
|
||||||
|
*
|
||||||
|
* By default, the TTL will equal the lease interval. Passing 0 or a value larger than the lease interval via
|
||||||
|
* `otSrpClientSetTtl()` will also cause the TTL to equal the lease interval.
|
||||||
|
*
|
||||||
|
* @returns The TTL (in seconds).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t GetTtl(void) const { return (0 < mTtl && mTtl < mLeaseInterval) ? mTtl : mLeaseInterval; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the TTL used in SRP update requests.
|
||||||
|
*
|
||||||
|
* Changing the TTL does not impact the TTL of already registered services/host-info.
|
||||||
|
* It only changes any future SRP update messages (i.e adding new services and/or refreshes of existing services).
|
||||||
|
*
|
||||||
|
* @param[in] aTtl The TTL (in seconds). If value is zero or greater than lease interval, the TTL is set to the
|
||||||
|
* lease interval.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void SetTtl(uint32_t aTtl) { mTtl = aTtl; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method gets the lease interval used in SRP update requests.
|
* This method gets the lease interval used in SRP update requests.
|
||||||
*
|
*
|
||||||
|
@ -464,16 +499,16 @@ public:
|
||||||
const HostInfo &GetHostInfo(void) const { return mHostInfo; }
|
const HostInfo &GetHostInfo(void) const { return mHostInfo; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function sets the host name label.
|
* This method sets the host name label.
|
||||||
*
|
*
|
||||||
* After a successful call to this function, `Callback` will be called to report the status of host info
|
* After a successful call to this method, `Callback` will be called to report the status of host info
|
||||||
* registration with SRP server.
|
* registration with SRP server.
|
||||||
*
|
*
|
||||||
* The host name can be set before client is started or after start but before host info is registered with server
|
* The host name can be set before client is started or after start but before host info is registered with server
|
||||||
* (host info should be in either `kToAdd` or `kRemoved`).
|
* (host info should be in either `kToAdd` or `kRemoved`).
|
||||||
*
|
*
|
||||||
* @param[in] aName A pointer to host name label string (MUST NOT be NULL). Pointer the string buffer MUST
|
* @param[in] aName A pointer to host name label string (MUST NOT be NULL). Pointer the string buffer MUST
|
||||||
* persist and remain valid and constant after return from this function.
|
* persist and remain valid and constant after return from this method.
|
||||||
*
|
*
|
||||||
* @retval kErrorNone The host name label was set successfully.
|
* @retval kErrorNone The host name label was set successfully.
|
||||||
* @retval kErrorInvalidArgs The @p aName is NULL.
|
* @retval kErrorInvalidArgs The @p aName is NULL.
|
||||||
|
@ -482,6 +517,27 @@ public:
|
||||||
*/
|
*/
|
||||||
Error SetHostName(const char *aName);
|
Error SetHostName(const char *aName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method enables auto host address mode.
|
||||||
|
*
|
||||||
|
* When enabled host IPv6 addresses are automatically set by SRP client using all the unicast addresses on Thread
|
||||||
|
* netif excluding the link-local and mesh-local addresses. If there is no valid address, then Mesh Local EID
|
||||||
|
* address is added. The SRP client will automatically re-register when/if addresses on Thread netif are updated
|
||||||
|
* (new addresses are added or existing addresses are removed).
|
||||||
|
*
|
||||||
|
* The auto host address mode can be enabled before start or during operation of SRP client except when the host
|
||||||
|
* info is being removed (client is busy handling a remove request from an call to `RemoveHostAndServices()` and
|
||||||
|
* host info still being in either `kStateToRemove` or `kStateRemoving` states).
|
||||||
|
*
|
||||||
|
* After auto host address mode is enabled, it can be disabled by a call to `SetHostAddresses()` which then
|
||||||
|
* explicitly sets the host addresses.
|
||||||
|
*
|
||||||
|
* @retval kErrorNone Successfully enabled auto host address mode.
|
||||||
|
* @retval kErrorInvalidState Host is being removed and therefore cannot enable auto host address mode.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Error EnableAutoHostAddress(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method sets/updates the list of host IPv6 address.
|
* This method sets/updates the list of host IPv6 address.
|
||||||
*
|
*
|
||||||
|
@ -493,6 +549,9 @@ public:
|
||||||
* After a successful call to this method, `Callback` will be called to report the status of the address
|
* After a successful call to this method, `Callback` will be called to report the status of the address
|
||||||
* registration with SRP server.
|
* registration with SRP server.
|
||||||
*
|
*
|
||||||
|
* Calling this method disables auto host address mode if it was previously enabled from a successful call to
|
||||||
|
* `EnableAutoHostAddress()`.
|
||||||
|
*
|
||||||
* @param[in] aAddresses A pointer to the an array containing the host IPv6 addresses.
|
* @param[in] aAddresses A pointer to the an array containing the host IPv6 addresses.
|
||||||
* @param[in] aNumAddresses The number of addresses in the @p aAddresses array.
|
* @param[in] aNumAddresses The number of addresses in the @p aAddresses array.
|
||||||
*
|
*
|
||||||
|
@ -795,6 +854,26 @@ private:
|
||||||
kKeepRetryInterval,
|
kKeepRetryInterval,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SingleServiceMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SingleServiceMode(void)
|
||||||
|
: mEnabled(false)
|
||||||
|
, mService(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Enable(void) { mEnabled = true, mService = nullptr; }
|
||||||
|
void Disable(void) { mEnabled = false; }
|
||||||
|
bool IsEnabled(void) const { return mEnabled; }
|
||||||
|
Service *GetService(void) { return mService; }
|
||||||
|
void SetService(Service &aService) { mService = &aService; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool mEnabled;
|
||||||
|
Service *mService;
|
||||||
|
};
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
|
#if OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
|
||||||
class AutoStart : Clearable<AutoStart>
|
class AutoStart : Clearable<AutoStart>
|
||||||
{
|
{
|
||||||
|
@ -859,6 +938,7 @@ private:
|
||||||
void Pause(void);
|
void Pause(void);
|
||||||
void HandleNotifierEvents(Events aEvents);
|
void HandleNotifierEvents(Events aEvents);
|
||||||
void HandleRoleChanged(void);
|
void HandleRoleChanged(void);
|
||||||
|
Error UpdateHostInfoStateOnAddressChange(void);
|
||||||
void UpdateServiceStateToRemove(Service &aService);
|
void UpdateServiceStateToRemove(Service &aService);
|
||||||
State GetState(void) const { return mState; }
|
State GetState(void) const { return mState; }
|
||||||
void SetState(State aState);
|
void SetState(State aState);
|
||||||
|
@ -870,10 +950,11 @@ private:
|
||||||
Error PrepareUpdateMessage(Message &aMessage);
|
Error PrepareUpdateMessage(Message &aMessage);
|
||||||
Error ReadOrGenerateKey(Crypto::Ecdsa::P256::KeyPair &aKeyPair);
|
Error ReadOrGenerateKey(Crypto::Ecdsa::P256::KeyPair &aKeyPair);
|
||||||
Error AppendServiceInstructions(Service &aService, Message &aMessage, Info &aInfo);
|
Error AppendServiceInstructions(Service &aService, Message &aMessage, Info &aInfo);
|
||||||
Error AppendHostDescriptionInstruction(Message &aMessage, Info &aInfo) const;
|
Error AppendHostDescriptionInstruction(Message &aMessage, Info &aInfo);
|
||||||
Error AppendKeyRecord(Message &aMessage, Info &aInfo) const;
|
Error AppendKeyRecord(Message &aMessage, Info &aInfo) const;
|
||||||
Error AppendDeleteAllRrsets(Message &aMessage) const;
|
Error AppendDeleteAllRrsets(Message &aMessage) const;
|
||||||
Error AppendHostName(Message &aMessage, Info &aInfo, bool aDoNotCompress = false) const;
|
Error AppendHostName(Message &aMessage, Info &aInfo, bool aDoNotCompress = false) const;
|
||||||
|
Error AppendAaaaRecord(const Ip6::Address &aAddress, Message &aMessage, Info &aInfo) const;
|
||||||
Error AppendUpdateLeaseOptRecord(Message &aMessage) const;
|
Error AppendUpdateLeaseOptRecord(Message &aMessage) const;
|
||||||
Error AppendSignature(Message &aMessage, Info &aInfo);
|
Error AppendSignature(Message &aMessage, Info &aInfo);
|
||||||
void UpdateRecordLengthInMessage(Dns::ResourceRecord &aRecord, uint16_t aOffset, Message &aMessage) const;
|
void UpdateRecordLengthInMessage(Dns::ResourceRecord &aRecord, uint16_t aOffset, Message &aMessage) const;
|
||||||
|
@ -913,6 +994,7 @@ private:
|
||||||
State mState;
|
State mState;
|
||||||
uint8_t mTxFailureRetryCount : 4;
|
uint8_t mTxFailureRetryCount : 4;
|
||||||
bool mShouldRemoveKeyLease : 1;
|
bool mShouldRemoveKeyLease : 1;
|
||||||
|
bool mAutoHostAddressAddedMeshLocal : 1;
|
||||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||||
bool mServiceKeyRecordEnabled : 1;
|
bool mServiceKeyRecordEnabled : 1;
|
||||||
#endif
|
#endif
|
||||||
|
@ -922,6 +1004,7 @@ private:
|
||||||
|
|
||||||
TimeMilli mLeaseRenewTime;
|
TimeMilli mLeaseRenewTime;
|
||||||
uint32_t mAcceptedLeaseInterval;
|
uint32_t mAcceptedLeaseInterval;
|
||||||
|
uint32_t mTtl;
|
||||||
uint32_t mLeaseInterval;
|
uint32_t mLeaseInterval;
|
||||||
uint32_t mKeyLeaseInterval;
|
uint32_t mKeyLeaseInterval;
|
||||||
|
|
||||||
|
@ -932,6 +1015,7 @@ private:
|
||||||
const char * mDomainName;
|
const char * mDomainName;
|
||||||
HostInfo mHostInfo;
|
HostInfo mHostInfo;
|
||||||
LinkedList<Service> mServices;
|
LinkedList<Service> mServices;
|
||||||
|
SingleServiceMode mSingleServiceMode;
|
||||||
TimerMilli mTimer;
|
TimerMilli mTimer;
|
||||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
|
#if OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
|
||||||
AutoStart mAutoStart;
|
AutoStart mAutoStart;
|
||||||
|
|
|
@ -168,6 +168,30 @@ exit:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Server::TtlConfig::TtlConfig(void)
|
||||||
|
{
|
||||||
|
mMinTtl = kDefaultMinTtl;
|
||||||
|
mMaxTtl = kDefaultMaxTtl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error Server::SetTtlConfig(const TtlConfig &aTtlConfig)
|
||||||
|
{
|
||||||
|
Error error = kErrorNone;
|
||||||
|
|
||||||
|
VerifyOrExit(aTtlConfig.IsValid(), error = kErrorInvalidArgs);
|
||||||
|
mTtlConfig = aTtlConfig;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Server::TtlConfig::GrantTtl(uint32_t aLease, uint32_t aTtl) const
|
||||||
|
{
|
||||||
|
OT_ASSERT(mMinTtl <= mMaxTtl);
|
||||||
|
|
||||||
|
return OT_MAX(mMinTtl, OT_MIN(OT_MIN(mMaxTtl, aLease), aTtl));
|
||||||
|
}
|
||||||
|
|
||||||
Server::LeaseConfig::LeaseConfig(void)
|
Server::LeaseConfig::LeaseConfig(void)
|
||||||
{
|
{
|
||||||
mMinLease = kDefaultMinLease;
|
mMinLease = kDefaultMinLease;
|
||||||
|
@ -266,7 +290,6 @@ void Server::AddHost(Host &aHost)
|
||||||
OT_ASSERT(mHosts.FindMatching(aHost.GetFullName()) == nullptr);
|
OT_ASSERT(mHosts.FindMatching(aHost.GetFullName()) == nullptr);
|
||||||
IgnoreError(mHosts.Add(aHost));
|
IgnoreError(mHosts.Add(aHost));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::RemoveHost(Host *aHost, RetainName aRetainName, NotifyMode aNotifyServiceHandler)
|
void Server::RemoveHost(Host *aHost, RetainName aRetainName, NotifyMode aNotifyServiceHandler)
|
||||||
{
|
{
|
||||||
VerifyOrExit(aHost != nullptr);
|
VerifyOrExit(aHost != nullptr);
|
||||||
|
@ -374,20 +397,21 @@ void Server::HandleServiceUpdateResult(UpdateMetadata *aUpdate, Error aError)
|
||||||
void Server::CommitSrpUpdate(Error aError, Host &aHost, const MessageMetadata &aMessageMetadata)
|
void Server::CommitSrpUpdate(Error aError, Host &aHost, const MessageMetadata &aMessageMetadata)
|
||||||
{
|
{
|
||||||
CommitSrpUpdate(aError, aHost, aMessageMetadata.mDnsHeader, aMessageMetadata.mMessageInfo,
|
CommitSrpUpdate(aError, aHost, aMessageMetadata.mDnsHeader, aMessageMetadata.mMessageInfo,
|
||||||
aMessageMetadata.mLeaseConfig);
|
aMessageMetadata.mTtlConfig, aMessageMetadata.mLeaseConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::CommitSrpUpdate(Error aError, UpdateMetadata &aUpdateMetadata)
|
void Server::CommitSrpUpdate(Error aError, UpdateMetadata &aUpdateMetadata)
|
||||||
{
|
{
|
||||||
CommitSrpUpdate(aError, aUpdateMetadata.GetHost(), aUpdateMetadata.GetDnsHeader(),
|
CommitSrpUpdate(aError, aUpdateMetadata.GetHost(), aUpdateMetadata.GetDnsHeader(),
|
||||||
aUpdateMetadata.IsDirectRxFromClient() ? &aUpdateMetadata.GetMessageInfo() : nullptr,
|
aUpdateMetadata.IsDirectRxFromClient() ? &aUpdateMetadata.GetMessageInfo() : nullptr,
|
||||||
aUpdateMetadata.GetLeaseConfig());
|
aUpdateMetadata.GetTtlConfig(), aUpdateMetadata.GetLeaseConfig());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::CommitSrpUpdate(Error aError,
|
void Server::CommitSrpUpdate(Error aError,
|
||||||
Host & aHost,
|
Host & aHost,
|
||||||
const Dns::UpdateHeader &aDnsHeader,
|
const Dns::UpdateHeader &aDnsHeader,
|
||||||
const Ip6::MessageInfo * aMessageInfo,
|
const Ip6::MessageInfo * aMessageInfo,
|
||||||
|
const TtlConfig & aTtlConfig,
|
||||||
const LeaseConfig & aLeaseConfig)
|
const LeaseConfig & aLeaseConfig)
|
||||||
{
|
{
|
||||||
Host * existingHost;
|
Host * existingHost;
|
||||||
|
@ -395,6 +419,7 @@ void Server::CommitSrpUpdate(Error aError,
|
||||||
uint32_t hostKeyLease;
|
uint32_t hostKeyLease;
|
||||||
uint32_t grantedLease;
|
uint32_t grantedLease;
|
||||||
uint32_t grantedKeyLease;
|
uint32_t grantedKeyLease;
|
||||||
|
uint32_t grantedTtl;
|
||||||
bool shouldFreeHost = true;
|
bool shouldFreeHost = true;
|
||||||
|
|
||||||
SuccessOrExit(aError);
|
SuccessOrExit(aError);
|
||||||
|
@ -403,14 +428,17 @@ void Server::CommitSrpUpdate(Error aError,
|
||||||
hostKeyLease = aHost.GetKeyLease();
|
hostKeyLease = aHost.GetKeyLease();
|
||||||
grantedLease = aLeaseConfig.GrantLease(hostLease);
|
grantedLease = aLeaseConfig.GrantLease(hostLease);
|
||||||
grantedKeyLease = aLeaseConfig.GrantKeyLease(hostKeyLease);
|
grantedKeyLease = aLeaseConfig.GrantKeyLease(hostKeyLease);
|
||||||
|
grantedTtl = aTtlConfig.GrantTtl(grantedLease, aHost.GetTtl());
|
||||||
|
|
||||||
aHost.SetLease(grantedLease);
|
aHost.SetLease(grantedLease);
|
||||||
aHost.SetKeyLease(grantedKeyLease);
|
aHost.SetKeyLease(grantedKeyLease);
|
||||||
|
aHost.SetTtl(grantedTtl);
|
||||||
|
|
||||||
for (Service &service : aHost.mServices)
|
for (Service &service : aHost.mServices)
|
||||||
{
|
{
|
||||||
service.mDescription->mLease = grantedLease;
|
service.mDescription->mLease = grantedLease;
|
||||||
service.mDescription->mKeyLease = grantedKeyLease;
|
service.mDescription->mKeyLease = grantedKeyLease;
|
||||||
|
service.mDescription->mTtl = grantedTtl;
|
||||||
}
|
}
|
||||||
|
|
||||||
existingHost = mHosts.FindMatching(aHost.GetFullName());
|
existingHost = mHosts.FindMatching(aHost.GetFullName());
|
||||||
|
@ -690,6 +718,8 @@ void Server::ProcessDnsUpdate(Message &aMessage, MessageMetadata &aMetadata)
|
||||||
// Parse lease time and validate signature.
|
// Parse lease time and validate signature.
|
||||||
SuccessOrExit(error = ProcessAdditionalSection(host, aMessage, aMetadata));
|
SuccessOrExit(error = ProcessAdditionalSection(host, aMessage, aMetadata));
|
||||||
|
|
||||||
|
SuccessOrExit(error = ValidateServiceSubTypes(*host, aMetadata));
|
||||||
|
|
||||||
HandleUpdate(*host, aMetadata);
|
HandleUpdate(*host, aMetadata);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
@ -802,6 +832,8 @@ Error Server::ProcessHostDescriptionInstruction(Host & aHost,
|
||||||
|
|
||||||
VerifyOrExit(record.GetClass() == aMetadata.mDnsZone.GetClass(), error = kErrorFailed);
|
VerifyOrExit(record.GetClass() == aMetadata.mDnsZone.GetClass(), error = kErrorFailed);
|
||||||
|
|
||||||
|
SuccessOrExit(error = aHost.ProcessTtl(record.GetTtl()));
|
||||||
|
|
||||||
SuccessOrExit(error = aHost.SetFullName(name));
|
SuccessOrExit(error = aHost.SetFullName(name));
|
||||||
|
|
||||||
SuccessOrExit(error = aMessage.Read(offset, aaaaRecord));
|
SuccessOrExit(error = aMessage.Read(offset, aaaaRecord));
|
||||||
|
@ -816,6 +848,9 @@ Error Server::ProcessHostDescriptionInstruction(Host & aHost,
|
||||||
Dns::Ecdsa256KeyRecord keyRecord;
|
Dns::Ecdsa256KeyRecord keyRecord;
|
||||||
|
|
||||||
VerifyOrExit(record.GetClass() == aMetadata.mDnsZone.GetClass(), error = kErrorFailed);
|
VerifyOrExit(record.GetClass() == aMetadata.mDnsZone.GetClass(), error = kErrorFailed);
|
||||||
|
|
||||||
|
SuccessOrExit(error = aHost.ProcessTtl(record.GetTtl()));
|
||||||
|
|
||||||
SuccessOrExit(error = aMessage.Read(offset, keyRecord));
|
SuccessOrExit(error = aMessage.Read(offset, keyRecord));
|
||||||
VerifyOrExit(keyRecord.IsValid(), error = kErrorParse);
|
VerifyOrExit(keyRecord.IsValid(), error = kErrorParse);
|
||||||
|
|
||||||
|
@ -908,6 +943,11 @@ Error Server::ProcessServiceDiscoveryInstructions(Host & aHost,
|
||||||
|
|
||||||
// This RR is a "Delete an RR from an RRset" update when the CLASS is NONE.
|
// This RR is a "Delete an RR from an RRset" update when the CLASS is NONE.
|
||||||
service->mIsDeleted = (ptrRecord.GetClass() == Dns::ResourceRecord::kClassNone);
|
service->mIsDeleted = (ptrRecord.GetClass() == Dns::ResourceRecord::kClassNone);
|
||||||
|
|
||||||
|
if (!service->mIsDeleted)
|
||||||
|
{
|
||||||
|
SuccessOrExit(error = aHost.ProcessTtl(ptrRecord.GetTtl()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
@ -959,6 +999,9 @@ Error Server::ProcessServiceDescriptionInstructions(Host & aHost,
|
||||||
uint16_t hostNameLength = sizeof(hostName);
|
uint16_t hostNameLength = sizeof(hostName);
|
||||||
|
|
||||||
VerifyOrExit(record.GetClass() == aMetadata.mDnsZone.GetClass(), error = kErrorFailed);
|
VerifyOrExit(record.GetClass() == aMetadata.mDnsZone.GetClass(), error = kErrorFailed);
|
||||||
|
|
||||||
|
SuccessOrExit(error = aHost.ProcessTtl(record.GetTtl()));
|
||||||
|
|
||||||
SuccessOrExit(error = aMessage.Read(offset, srvRecord));
|
SuccessOrExit(error = aMessage.Read(offset, srvRecord));
|
||||||
offset += sizeof(srvRecord);
|
offset += sizeof(srvRecord);
|
||||||
|
|
||||||
|
@ -971,6 +1014,7 @@ Error Server::ProcessServiceDescriptionInstructions(Host & aHost,
|
||||||
|
|
||||||
// Make sure that this is the first SRV RR for this service description
|
// Make sure that this is the first SRV RR for this service description
|
||||||
VerifyOrExit(desc->mPort == 0, error = kErrorFailed);
|
VerifyOrExit(desc->mPort == 0, error = kErrorFailed);
|
||||||
|
desc->mTtl = srvRecord.GetTtl();
|
||||||
desc->mPriority = srvRecord.GetPriority();
|
desc->mPriority = srvRecord.GetPriority();
|
||||||
desc->mWeight = srvRecord.GetWeight();
|
desc->mWeight = srvRecord.GetWeight();
|
||||||
desc->mPort = srvRecord.GetPort();
|
desc->mPort = srvRecord.GetPort();
|
||||||
|
@ -980,6 +1024,8 @@ Error Server::ProcessServiceDescriptionInstructions(Host & aHost,
|
||||||
{
|
{
|
||||||
VerifyOrExit(record.GetClass() == aMetadata.mDnsZone.GetClass(), error = kErrorFailed);
|
VerifyOrExit(record.GetClass() == aMetadata.mDnsZone.GetClass(), error = kErrorFailed);
|
||||||
|
|
||||||
|
SuccessOrExit(error = aHost.ProcessTtl(record.GetTtl()));
|
||||||
|
|
||||||
desc = aHost.FindServiceDescription(name);
|
desc = aHost.FindServiceDescription(name);
|
||||||
VerifyOrExit(desc != nullptr, error = kErrorFailed);
|
VerifyOrExit(desc != nullptr, error = kErrorFailed);
|
||||||
|
|
||||||
|
@ -1155,6 +1201,68 @@ exit:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Error Server::ValidateServiceSubTypes(Host &aHost, const MessageMetadata &aMetadata)
|
||||||
|
{
|
||||||
|
Error error = kErrorNone;
|
||||||
|
Host *existingHost;
|
||||||
|
|
||||||
|
// Verify that there is a matching base type service for all
|
||||||
|
// sub-type services in `aHost` (which is from the received
|
||||||
|
// and parsed SRP Update message).
|
||||||
|
|
||||||
|
for (const Service &service : aHost.GetServices())
|
||||||
|
{
|
||||||
|
if (service.IsSubType() && (aHost.FindBaseService(service.GetInstanceName()) == nullptr))
|
||||||
|
{
|
||||||
|
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)
|
||||||
|
char subLabel[Dns::Name::kMaxLabelSize];
|
||||||
|
|
||||||
|
IgnoreError(service.GetServiceSubTypeLabel(subLabel, sizeof(subLabel)));
|
||||||
|
LogWarn("Message contains instance %s with subtype %s without base type", service.GetInstanceName(),
|
||||||
|
subLabel);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ExitNow(error = kErrorParse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SRP server must treat the update instructions for a service type
|
||||||
|
// and all its sub-types as atomic, i.e., when a service and its
|
||||||
|
// sub-types are being updated, whatever information appears in the
|
||||||
|
// SRP Update is the entirety of information about that service and
|
||||||
|
// its sub-types. Any previously registered sub-type that does not
|
||||||
|
// appear in a new SRP Update, must be removed.
|
||||||
|
//
|
||||||
|
// We go though the list of registered services for the same host
|
||||||
|
// and if the base service is included in the new SRP Update
|
||||||
|
// message, we add any previously registered service sub-type that
|
||||||
|
// does not appear in new Update message as "deleted".
|
||||||
|
|
||||||
|
existingHost = mHosts.FindMatching(aHost.GetFullName());
|
||||||
|
VerifyOrExit(existingHost != nullptr);
|
||||||
|
|
||||||
|
for (const Service &baseService : existingHost->GetServices())
|
||||||
|
{
|
||||||
|
if (baseService.IsSubType() || (aHost.FindBaseService(baseService.GetInstanceName()) == nullptr))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const Service &subService : existingHost->GetServices())
|
||||||
|
{
|
||||||
|
if (!subService.IsSubType() || !subService.MatchesInstanceName(baseService.GetInstanceName()))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SuccessOrExit(error = aHost.AddCopyOfServiceAsDeletedIfNotPresent(subService, aMetadata.mRxTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
void Server::HandleUpdate(Host &aHost, const MessageMetadata &aMetadata)
|
void Server::HandleUpdate(Host &aHost, const MessageMetadata &aMetadata)
|
||||||
{
|
{
|
||||||
Error error = kErrorNone;
|
Error error = kErrorNone;
|
||||||
|
@ -1180,32 +1288,36 @@ void Server::HandleUpdate(Host &aHost, const MessageMetadata &aMetadata)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aHost.FindService(service.GetServiceName(), service.GetInstanceName()) == nullptr)
|
SuccessOrExit(error = aHost.AddCopyOfServiceAsDeletedIfNotPresent(service, aMetadata.mRxTime));
|
||||||
{
|
|
||||||
Service *newService = aHost.AddNewService(service.GetServiceName(), service.GetInstanceName(),
|
|
||||||
service.IsSubType(), aMetadata.mRxTime);
|
|
||||||
|
|
||||||
VerifyOrExit(newService != nullptr, error = kErrorNoBufs);
|
|
||||||
newService->mDescription->mUpdateTime = aMetadata.mRxTime;
|
|
||||||
newService->mIsDeleted = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if ((error == kErrorNone) && (mServiceUpdateHandler != nullptr))
|
InformUpdateHandlerOrCommit(error, aHost, aMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::InformUpdateHandlerOrCommit(Error aError, Host &aHost, const MessageMetadata &aMetadata)
|
||||||
|
{
|
||||||
|
if ((aError == kErrorNone) && (mServiceUpdateHandler != nullptr))
|
||||||
{
|
{
|
||||||
UpdateMetadata *update = UpdateMetadata::Allocate(GetInstance(), aHost, aMetadata);
|
UpdateMetadata *update = UpdateMetadata::Allocate(GetInstance(), aHost, aMetadata);
|
||||||
|
|
||||||
mOutstandingUpdates.Push(*update);
|
if (update != nullptr)
|
||||||
mOutstandingUpdatesTimer.FireAtIfEarlier(update->GetExpireTime());
|
{
|
||||||
|
mOutstandingUpdates.Push(*update);
|
||||||
|
mOutstandingUpdatesTimer.FireAtIfEarlier(update->GetExpireTime());
|
||||||
|
|
||||||
LogInfo("SRP update handler is notified (updatedId = %u)", update->GetId());
|
LogInfo("SRP update handler is notified (updatedId = %u)", update->GetId());
|
||||||
mServiceUpdateHandler(update->GetId(), &aHost, kDefaultEventsHandlerTimeout, mServiceUpdateHandlerContext);
|
mServiceUpdateHandler(update->GetId(), &aHost, kDefaultEventsHandlerTimeout, mServiceUpdateHandlerContext);
|
||||||
}
|
ExitNow();
|
||||||
else
|
}
|
||||||
{
|
|
||||||
CommitSrpUpdate(error, aHost, aMetadata);
|
aError = kErrorNoBufs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CommitSrpUpdate(aError, aHost, aMetadata);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::SendResponse(const Dns::UpdateHeader & aHeader,
|
void Server::SendResponse(const Dns::UpdateHeader & aHeader,
|
||||||
|
@ -1236,6 +1348,8 @@ void Server::SendResponse(const Dns::UpdateHeader & aHeader,
|
||||||
LogInfo("Send success response");
|
LogInfo("Send success response");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateResponseCounters(aResponseCode);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (error != kErrorNone)
|
if (error != kErrorNone)
|
||||||
{
|
{
|
||||||
|
@ -1283,6 +1397,8 @@ void Server::SendResponse(const Dns::UpdateHeader &aHeader,
|
||||||
|
|
||||||
LogInfo("Send success response with granted lease: %u and key lease: %u", aLease, aKeyLease);
|
LogInfo("Send success response with granted lease: %u and key lease: %u", aLease, aKeyLease);
|
||||||
|
|
||||||
|
UpdateResponseCounters(Dns::UpdateHeader::kResponseSuccess);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (error != kErrorNone)
|
if (error != kErrorNone)
|
||||||
{
|
{
|
||||||
|
@ -1308,11 +1424,12 @@ void Server::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessag
|
||||||
|
|
||||||
Error Server::ProcessMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
Error Server::ProcessMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||||
{
|
{
|
||||||
return ProcessMessage(aMessage, TimerMilli::GetNow(), mLeaseConfig, &aMessageInfo);
|
return ProcessMessage(aMessage, TimerMilli::GetNow(), mTtlConfig, mLeaseConfig, &aMessageInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
Error Server::ProcessMessage(Message & aMessage,
|
Error Server::ProcessMessage(Message & aMessage,
|
||||||
TimeMilli aRxTime,
|
TimeMilli aRxTime,
|
||||||
|
const TtlConfig & aTtlConfig,
|
||||||
const LeaseConfig & aLeaseConfig,
|
const LeaseConfig & aLeaseConfig,
|
||||||
const Ip6::MessageInfo *aMessageInfo)
|
const Ip6::MessageInfo *aMessageInfo)
|
||||||
{
|
{
|
||||||
|
@ -1321,6 +1438,7 @@ Error Server::ProcessMessage(Message & aMessage,
|
||||||
|
|
||||||
metadata.mOffset = aMessage.GetOffset();
|
metadata.mOffset = aMessage.GetOffset();
|
||||||
metadata.mRxTime = aRxTime;
|
metadata.mRxTime = aRxTime;
|
||||||
|
metadata.mTtlConfig = aTtlConfig;
|
||||||
metadata.mLeaseConfig = aLeaseConfig;
|
metadata.mLeaseConfig = aLeaseConfig;
|
||||||
metadata.mMessageInfo = aMessageInfo;
|
metadata.mMessageInfo = aMessageInfo;
|
||||||
|
|
||||||
|
@ -1482,6 +1600,31 @@ const char *Server::AddressModeToString(AddressMode aMode)
|
||||||
return kAddressModeStrings[aMode];
|
return kAddressModeStrings[aMode];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Server::UpdateResponseCounters(Dns::UpdateHeader::Response aResponseCode)
|
||||||
|
{
|
||||||
|
switch (aResponseCode)
|
||||||
|
{
|
||||||
|
case Dns::UpdateHeader::kResponseSuccess:
|
||||||
|
++mResponseCounters.mSuccess;
|
||||||
|
break;
|
||||||
|
case Dns::UpdateHeader::kResponseServerFailure:
|
||||||
|
++mResponseCounters.mServerFailure;
|
||||||
|
break;
|
||||||
|
case Dns::UpdateHeader::kResponseFormatError:
|
||||||
|
++mResponseCounters.mFormatError;
|
||||||
|
break;
|
||||||
|
case Dns::UpdateHeader::kResponseNameExists:
|
||||||
|
++mResponseCounters.mNameExists;
|
||||||
|
break;
|
||||||
|
case Dns::UpdateHeader::kResponseRefused:
|
||||||
|
++mResponseCounters.mRefused;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
++mResponseCounters.mOther;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
// Server::Service
|
// Server::Service
|
||||||
|
|
||||||
|
@ -1540,6 +1683,18 @@ TimeMilli Server::Service::GetKeyExpireTime(void) const
|
||||||
return mUpdateTime + Time::SecToMsec(mDescription->mKeyLease);
|
return mUpdateTime + Time::SecToMsec(mDescription->mKeyLease);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Server::Service::GetLeaseInfo(LeaseInfo &aLeaseInfo) const
|
||||||
|
{
|
||||||
|
TimeMilli now = TimerMilli::GetNow();
|
||||||
|
TimeMilli expireTime = GetExpireTime();
|
||||||
|
TimeMilli keyExpireTime = GetKeyExpireTime();
|
||||||
|
|
||||||
|
aLeaseInfo.mLease = Time::SecToMsec(GetLease());
|
||||||
|
aLeaseInfo.mKeyLease = Time::SecToMsec(GetKeyLease());
|
||||||
|
aLeaseInfo.mRemainingLease = (now <= expireTime) ? (expireTime - now) : 0;
|
||||||
|
aLeaseInfo.mRemainingKeyLease = (now <= keyExpireTime) ? (keyExpireTime - now) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool Server::Service::MatchesInstanceName(const char *aInstanceName) const
|
bool Server::Service::MatchesInstanceName(const char *aInstanceName) const
|
||||||
{
|
{
|
||||||
return StringMatch(mDescription->mInstanceName.AsCString(), aInstanceName, kStringCaseInsensitiveMatch);
|
return StringMatch(mDescription->mInstanceName.AsCString(), aInstanceName, kStringCaseInsensitiveMatch);
|
||||||
|
@ -1627,6 +1782,7 @@ Error Server::Service::Description::Init(const char *aInstanceName, Host &aHost)
|
||||||
mHost = &aHost;
|
mHost = &aHost;
|
||||||
mPriority = 0;
|
mPriority = 0;
|
||||||
mWeight = 0;
|
mWeight = 0;
|
||||||
|
mTtl = 0;
|
||||||
mPort = 0;
|
mPort = 0;
|
||||||
mLease = 0;
|
mLease = 0;
|
||||||
mKeyLease = 0;
|
mKeyLease = 0;
|
||||||
|
@ -1655,6 +1811,7 @@ void Server::Service::Description::TakeResourcesFrom(Description &aDescription)
|
||||||
mWeight = aDescription.mWeight;
|
mWeight = aDescription.mWeight;
|
||||||
mPort = aDescription.mPort;
|
mPort = aDescription.mPort;
|
||||||
|
|
||||||
|
mTtl = aDescription.mTtl;
|
||||||
mLease = aDescription.mLease;
|
mLease = aDescription.mLease;
|
||||||
mKeyLease = aDescription.mKeyLease;
|
mKeyLease = aDescription.mKeyLease;
|
||||||
mUpdateTime = TimerMilli::GetNow();
|
mUpdateTime = TimerMilli::GetNow();
|
||||||
|
@ -1683,6 +1840,7 @@ exit:
|
||||||
Server::Host::Host(Instance &aInstance, TimeMilli aUpdateTime)
|
Server::Host::Host(Instance &aInstance, TimeMilli aUpdateTime)
|
||||||
: InstanceLocator(aInstance)
|
: InstanceLocator(aInstance)
|
||||||
, mNext(nullptr)
|
, mNext(nullptr)
|
||||||
|
, mTtl(0)
|
||||||
, mLease(0)
|
, mLease(0)
|
||||||
, mKeyLease(0)
|
, mKeyLease(0)
|
||||||
, mUpdateTime(aUpdateTime)
|
, mUpdateTime(aUpdateTime)
|
||||||
|
@ -1739,6 +1897,38 @@ TimeMilli Server::Host::GetKeyExpireTime(void) const
|
||||||
return mUpdateTime + Time::SecToMsec(mKeyLease);
|
return mUpdateTime + Time::SecToMsec(mKeyLease);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Server::Host::GetLeaseInfo(LeaseInfo &aLeaseInfo) const
|
||||||
|
{
|
||||||
|
TimeMilli now = TimerMilli::GetNow();
|
||||||
|
TimeMilli expireTime = GetExpireTime();
|
||||||
|
TimeMilli keyExpireTime = GetKeyExpireTime();
|
||||||
|
|
||||||
|
aLeaseInfo.mLease = Time::SecToMsec(GetLease());
|
||||||
|
aLeaseInfo.mKeyLease = Time::SecToMsec(GetKeyLease());
|
||||||
|
aLeaseInfo.mRemainingLease = (now <= expireTime) ? (expireTime - now) : 0;
|
||||||
|
aLeaseInfo.mRemainingKeyLease = (now <= keyExpireTime) ? (keyExpireTime - now) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error Server::Host::ProcessTtl(uint32_t aTtl)
|
||||||
|
{
|
||||||
|
// This method processes the TTL value received in a resource record.
|
||||||
|
//
|
||||||
|
// If no TTL value is stored, this method wil set the stored value to @p aTtl and return `kErrorNone`.
|
||||||
|
// If a TTL value is stored and @p aTtl equals the stored value, this method returns `kErrorNone`.
|
||||||
|
// Otherwise, this method returns `kErrorRejected`.
|
||||||
|
|
||||||
|
Error error = kErrorRejected;
|
||||||
|
|
||||||
|
VerifyOrExit(aTtl && (mTtl == 0 || mTtl == aTtl));
|
||||||
|
|
||||||
|
mTtl = aTtl;
|
||||||
|
|
||||||
|
error = kErrorNone;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
const Server::Service *Server::Host::FindNextService(const Service *aPrevService,
|
const Server::Service *Server::Host::FindNextService(const Service *aPrevService,
|
||||||
Service::Flags aFlags,
|
Service::Flags aFlags,
|
||||||
const char * aServiceName,
|
const char * aServiceName,
|
||||||
|
@ -1825,6 +2015,25 @@ exit:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Error Server::Host::AddCopyOfServiceAsDeletedIfNotPresent(const Service &aService, TimeMilli aUpdateTime)
|
||||||
|
{
|
||||||
|
Error error = kErrorNone;
|
||||||
|
Service *newService;
|
||||||
|
|
||||||
|
VerifyOrExit(FindService(aService.GetServiceName(), aService.GetInstanceName()) == nullptr);
|
||||||
|
|
||||||
|
newService =
|
||||||
|
AddNewService(aService.GetServiceName(), aService.GetInstanceName(), aService.IsSubType(), aUpdateTime);
|
||||||
|
|
||||||
|
VerifyOrExit(newService != nullptr, error = kErrorNoBufs);
|
||||||
|
|
||||||
|
newService->mDescription->mUpdateTime = aUpdateTime;
|
||||||
|
newService->mIsDeleted = true;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
void Server::Host::FreeAllServices(void)
|
void Server::Host::FreeAllServices(void)
|
||||||
{
|
{
|
||||||
while (!mServices.IsEmpty())
|
while (!mServices.IsEmpty())
|
||||||
|
@ -1850,6 +2059,7 @@ Error Server::Host::MergeServicesAndResourcesFrom(Host &aHost)
|
||||||
|
|
||||||
mAddresses.TakeFrom(static_cast<Heap::Array<Ip6::Address> &&>(aHost.mAddresses));
|
mAddresses.TakeFrom(static_cast<Heap::Array<Ip6::Address> &&>(aHost.mAddresses));
|
||||||
mKeyRecord = aHost.mKeyRecord;
|
mKeyRecord = aHost.mKeyRecord;
|
||||||
|
mTtl = aHost.mTtl;
|
||||||
mLease = aHost.mLease;
|
mLease = aHost.mLease;
|
||||||
mKeyLease = aHost.mKeyLease;
|
mKeyLease = aHost.mKeyLease;
|
||||||
mUpdateTime = TimerMilli::GetNow();
|
mUpdateTime = TimerMilli::GetNow();
|
||||||
|
@ -1929,6 +2139,17 @@ Server::Service *Server::Host::FindService(const char *aServiceName, const char
|
||||||
return AsNonConst(AsConst(this)->FindService(aServiceName, aInstanceName));
|
return AsNonConst(AsConst(this)->FindService(aServiceName, aInstanceName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Server::Service *Server::Host::FindBaseService(const char *aInstanceName) const
|
||||||
|
{
|
||||||
|
return FindNextService(/*a PrevService */ nullptr, kFlagsBaseTypeServiceOnly, /* aServiceName */ nullptr,
|
||||||
|
aInstanceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
Server::Service *Server::Host::FindBaseService(const char *aInstanceName)
|
||||||
|
{
|
||||||
|
return AsNonConst(AsConst(this)->FindBaseService(aInstanceName));
|
||||||
|
}
|
||||||
|
|
||||||
Error Server::Host::AddIp6Address(const Ip6::Address &aIp6Address)
|
Error Server::Host::AddIp6Address(const Ip6::Address &aIp6Address)
|
||||||
{
|
{
|
||||||
Error error = kErrorNone;
|
Error error = kErrorNone;
|
||||||
|
@ -1963,6 +2184,7 @@ Server::UpdateMetadata::UpdateMetadata(Instance &aInstance, Host &aHost, const M
|
||||||
, mExpireTime(TimerMilli::GetNow() + kDefaultEventsHandlerTimeout)
|
, mExpireTime(TimerMilli::GetNow() + kDefaultEventsHandlerTimeout)
|
||||||
, mDnsHeader(aMessageMetadata.mDnsHeader)
|
, mDnsHeader(aMessageMetadata.mDnsHeader)
|
||||||
, mId(Get<Server>().AllocateId())
|
, mId(Get<Server>().AllocateId())
|
||||||
|
, mTtlConfig(aMessageMetadata.mTtlConfig)
|
||||||
, mLeaseConfig(aMessageMetadata.mLeaseConfig)
|
, mLeaseConfig(aMessageMetadata.mLeaseConfig)
|
||||||
, mHost(aHost)
|
, mHost(aHost)
|
||||||
, mIsDirectRxFromClient(aMessageMetadata.IsDirectRxFromClient())
|
, mIsDirectRxFromClient(aMessageMetadata.IsDirectRxFromClient())
|
||||||
|
|
|
@ -129,6 +129,12 @@ public:
|
||||||
*/
|
*/
|
||||||
typedef otSrpServerServiceUpdateId ServiceUpdateId;
|
typedef otSrpServerServiceUpdateId ServiceUpdateId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The SRP server lease information of a host/service.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef otSrpServerLeaseInfo LeaseInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This enumeration represents the address mode used by the SRP server.
|
* This enumeration represents the address mode used by the SRP server.
|
||||||
*
|
*
|
||||||
|
@ -253,6 +259,14 @@ public:
|
||||||
*/
|
*/
|
||||||
Error GetServiceSubTypeLabel(char *aLabel, uint8_t aMaxSize) const;
|
Error GetServiceSubTypeLabel(char *aLabel, uint8_t aMaxSize) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the TTL of the service instance.
|
||||||
|
*
|
||||||
|
* @returns The TTL of the service instance.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t GetTtl(void) const { return mDescription->mTtl; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the port of the service instance.
|
* This method returns the port of the service instance.
|
||||||
*
|
*
|
||||||
|
@ -301,6 +315,22 @@ public:
|
||||||
*/
|
*/
|
||||||
const Host &GetHost(void) const { return *mDescription->mHost; }
|
const Host &GetHost(void) const { return *mDescription->mHost; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the LEASE time of the service.
|
||||||
|
*
|
||||||
|
* @returns The LEASE time in seconds.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t GetLease(void) const { return mDescription->mLease; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the KEY-LEASE time of the key of the service.
|
||||||
|
*
|
||||||
|
* @returns The KEY-LEASE time in seconds.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t GetKeyLease(void) const { return mDescription->mKeyLease; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the expire time (in milliseconds) of the service.
|
* This method returns the expire time (in milliseconds) of the service.
|
||||||
*
|
*
|
||||||
|
@ -317,6 +347,15 @@ public:
|
||||||
*/
|
*/
|
||||||
TimeMilli GetKeyExpireTime(void) const;
|
TimeMilli GetKeyExpireTime(void) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the LEASE and KEY-LEASE information of a given service.
|
||||||
|
*
|
||||||
|
* @param[out] aLeaseInfo A reference to a LeaseInfo instance. It contains the LEASE time, KEY-LEASE time,
|
||||||
|
* remaining LEASE time and the remaining KEY-LEASE time.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void GetLeaseInfo(LeaseInfo &aLeaseInfo) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method indicates whether this service matches a given service instance name.
|
* This method indicates whether this service matches a given service instance name.
|
||||||
*
|
*
|
||||||
|
@ -359,6 +398,7 @@ public:
|
||||||
uint16_t mPriority;
|
uint16_t mPriority;
|
||||||
uint16_t mWeight;
|
uint16_t mWeight;
|
||||||
uint16_t mPort;
|
uint16_t mPort;
|
||||||
|
uint32_t mTtl; // The TTL in seconds.
|
||||||
uint32_t mLease; // The LEASE time in seconds.
|
uint32_t mLease; // The LEASE time in seconds.
|
||||||
uint32_t mKeyLease; // The KEY-LEASE time in seconds.
|
uint32_t mKeyLease; // The KEY-LEASE time in seconds.
|
||||||
TimeMilli mUpdateTime;
|
TimeMilli mUpdateTime;
|
||||||
|
@ -436,6 +476,14 @@ public:
|
||||||
return mAddresses.AsCArray();
|
return mAddresses.AsCArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the TTL of the host.
|
||||||
|
*
|
||||||
|
* @returns The TTL of the host.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t GetTtl(void) const { return mTtl; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the LEASE time of the host.
|
* This method returns the LEASE time of the host.
|
||||||
*
|
*
|
||||||
|
@ -452,6 +500,15 @@ public:
|
||||||
*/
|
*/
|
||||||
uint32_t GetKeyLease(void) const { return mKeyLease; }
|
uint32_t GetKeyLease(void) const { return mKeyLease; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the LEASE and KEY-LEASE information of a given host.
|
||||||
|
*
|
||||||
|
* @param[out] aLeaseInfo A reference to a LeaseInfo instance. It contains the LEASE time, KEY-LEASE time,
|
||||||
|
* remaining LEASE time and the remaining KEY-LEASE time.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void GetLeaseInfo(LeaseInfo &aLeaseInfo) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the KEY resource record of the host.
|
* This method returns the KEY resource record of the host.
|
||||||
*
|
*
|
||||||
|
@ -515,16 +572,20 @@ public:
|
||||||
Host(Instance &aInstance, TimeMilli aUpdateTime);
|
Host(Instance &aInstance, TimeMilli aUpdateTime);
|
||||||
~Host(void);
|
~Host(void);
|
||||||
|
|
||||||
Error SetFullName(const char *aFullName);
|
Error SetFullName(const char *aFullName);
|
||||||
void SetKeyRecord(Dns::Ecdsa256KeyRecord &aKeyRecord);
|
void SetKeyRecord(Dns::Ecdsa256KeyRecord &aKeyRecord);
|
||||||
void SetLease(uint32_t aLease) { mLease = aLease; }
|
void SetTtl(uint32_t aTtl) { mTtl = aTtl; }
|
||||||
void SetKeyLease(uint32_t aKeyLease) { mKeyLease = aKeyLease; }
|
void SetLease(uint32_t aLease) { mLease = aLease; }
|
||||||
|
void SetKeyLease(uint32_t aKeyLease) { mKeyLease = aKeyLease; }
|
||||||
|
Error ProcessTtl(uint32_t aTtl);
|
||||||
|
|
||||||
LinkedList<Service> &GetServices(void) { return mServices; }
|
LinkedList<Service> &GetServices(void) { return mServices; }
|
||||||
Service * AddNewService(const char *aServiceName,
|
Service * AddNewService(const char *aServiceName,
|
||||||
const char *aInstanceName,
|
const char *aInstanceName,
|
||||||
bool aIsSubType,
|
bool aIsSubType,
|
||||||
TimeMilli aUpdateTime);
|
TimeMilli aUpdateTime);
|
||||||
void RemoveService(Service *aService, RetainName aRetainName, NotifyMode aNotifyServiceHandler);
|
void RemoveService(Service *aService, RetainName aRetainName, NotifyMode aNotifyServiceHandler);
|
||||||
|
Error AddCopyOfServiceAsDeletedIfNotPresent(const Service &aService, TimeMilli aUpdateTime);
|
||||||
void FreeAllServices(void);
|
void FreeAllServices(void);
|
||||||
void ClearResources(void);
|
void ClearResources(void);
|
||||||
Error MergeServicesAndResourcesFrom(Host &aHost);
|
Error MergeServicesAndResourcesFrom(Host &aHost);
|
||||||
|
@ -534,6 +595,8 @@ public:
|
||||||
const RetainPtr<Service::Description> FindServiceDescription(const char *aInstanceName) const;
|
const RetainPtr<Service::Description> FindServiceDescription(const char *aInstanceName) const;
|
||||||
Service * FindService(const char *aServiceName, const char *aInstanceName);
|
Service * FindService(const char *aServiceName, const char *aInstanceName);
|
||||||
const Service * FindService(const char *aServiceName, const char *aInstanceName) const;
|
const Service * FindService(const char *aServiceName, const char *aInstanceName) const;
|
||||||
|
Service * FindBaseService(const char *aInstanceName);
|
||||||
|
const Service * FindBaseService(const char *aInstanceName) const;
|
||||||
|
|
||||||
Host * mNext;
|
Host * mNext;
|
||||||
Heap::String mFullName;
|
Heap::String mFullName;
|
||||||
|
@ -542,12 +605,33 @@ public:
|
||||||
// TODO(wgtdkp): there is no necessary to save the entire resource
|
// TODO(wgtdkp): there is no necessary to save the entire resource
|
||||||
// record, saving only the ECDSA-256 public key should be enough.
|
// record, saving only the ECDSA-256 public key should be enough.
|
||||||
Dns::Ecdsa256KeyRecord mKeyRecord;
|
Dns::Ecdsa256KeyRecord mKeyRecord;
|
||||||
|
uint32_t mTtl; // The TTL in seconds.
|
||||||
uint32_t mLease; // The LEASE time in seconds.
|
uint32_t mLease; // The LEASE time in seconds.
|
||||||
uint32_t mKeyLease; // The KEY-LEASE time in seconds.
|
uint32_t mKeyLease; // The KEY-LEASE time in seconds.
|
||||||
TimeMilli mUpdateTime;
|
TimeMilli mUpdateTime;
|
||||||
LinkedList<Service> mServices;
|
LinkedList<Service> mServices;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class handles TTL configuration.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class TtlConfig : public otSrpServerTtlConfig
|
||||||
|
{
|
||||||
|
friend class Server;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* This constructor initializes to default TTL configuration.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
TtlConfig(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool IsValid(void) const { return mMinTtl <= mMaxTtl; }
|
||||||
|
uint32_t GrantTtl(uint32_t aLease, uint32_t aTtl) const;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class handles LEASE and KEY-LEASE configurations.
|
* This class handles LEASE and KEY-LEASE configurations.
|
||||||
*
|
*
|
||||||
|
@ -704,6 +788,14 @@ public:
|
||||||
*/
|
*/
|
||||||
State GetState(void) const { return mState; }
|
State GetState(void) const { return mState; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method tells the port the SRP server is listening to.
|
||||||
|
*
|
||||||
|
* @returns An integer that represents the port of the server. It returns 0 if the SRP server is not running.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint16_t GetPort(void) const { return IsRunning() ? mPort : 0; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method enables/disables the SRP server.
|
* This method enables/disables the SRP server.
|
||||||
*
|
*
|
||||||
|
@ -712,6 +804,25 @@ public:
|
||||||
*/
|
*/
|
||||||
void SetEnabled(bool aEnabled);
|
void SetEnabled(bool aEnabled);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the TTL configuration.
|
||||||
|
*
|
||||||
|
* @param[out] aTtlConfig A reference to the `TtlConfig` instance.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void GetTtlConfig(TtlConfig &aTtlConfig) const { aTtlConfig = mTtlConfig; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the TTL configuration.
|
||||||
|
*
|
||||||
|
* @param[in] aTtlConfig A reference to the `TtlConfig` instance.
|
||||||
|
*
|
||||||
|
* @retval kErrorNone Successfully set the TTL configuration
|
||||||
|
* @retval kErrorInvalidArgs The TTL range is not valid.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Error SetTtlConfig(const TtlConfig &aTtlConfig);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the LEASE and KEY-LEASE configurations.
|
* This method returns the LEASE and KEY-LEASE configurations.
|
||||||
*
|
*
|
||||||
|
@ -745,6 +856,14 @@ public:
|
||||||
*/
|
*/
|
||||||
const Host *GetNextHost(const Host *aHost);
|
const Host *GetNextHost(const Host *aHost);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the response counters of the SRP server.
|
||||||
|
*
|
||||||
|
* @returns A pointer to the response counters of the SRP server.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const otSrpServerResponseCounters *GetResponseCounters(void) const { return &mResponseCounters; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method receives the service update result from service handler set by
|
* This method receives the service update result from service handler set by
|
||||||
* SetServiceHandler.
|
* SetServiceHandler.
|
||||||
|
@ -758,6 +877,8 @@ public:
|
||||||
private:
|
private:
|
||||||
static constexpr uint16_t kUdpPayloadSize = Ip6::kMaxDatagramLength - sizeof(Ip6::Udp::Header);
|
static constexpr uint16_t kUdpPayloadSize = Ip6::kMaxDatagramLength - sizeof(Ip6::Udp::Header);
|
||||||
|
|
||||||
|
static constexpr uint32_t kDefaultMinTtl = 60u; // 1 min (in seconds).
|
||||||
|
static constexpr uint32_t kDefaultMaxTtl = 3600u * 2; // 2 hours (in seconds).
|
||||||
static constexpr uint32_t kDefaultMinLease = 60u * 30; // 30 min (in seconds).
|
static constexpr uint32_t kDefaultMinLease = 60u * 30; // 30 min (in seconds).
|
||||||
static constexpr uint32_t kDefaultMaxLease = 3600u * 2; // 2 hours (in seconds).
|
static constexpr uint32_t kDefaultMaxLease = 3600u * 2; // 2 hours (in seconds).
|
||||||
static constexpr uint32_t kDefaultMinKeyLease = 3600u * 24; // 1 day (in seconds).
|
static constexpr uint32_t kDefaultMinKeyLease = 3600u * 24; // 1 day (in seconds).
|
||||||
|
@ -780,6 +901,7 @@ private:
|
||||||
Dns::Zone mDnsZone;
|
Dns::Zone mDnsZone;
|
||||||
uint16_t mOffset;
|
uint16_t mOffset;
|
||||||
TimeMilli mRxTime;
|
TimeMilli mRxTime;
|
||||||
|
TtlConfig mTtlConfig;
|
||||||
LeaseConfig mLeaseConfig;
|
LeaseConfig mLeaseConfig;
|
||||||
const Ip6::MessageInfo *mMessageInfo; // Set to `nullptr` when from SRPL.
|
const Ip6::MessageInfo *mMessageInfo; // Set to `nullptr` when from SRPL.
|
||||||
};
|
};
|
||||||
|
@ -797,6 +919,7 @@ private:
|
||||||
TimeMilli GetExpireTime(void) const { return mExpireTime; }
|
TimeMilli GetExpireTime(void) const { return mExpireTime; }
|
||||||
const Dns::UpdateHeader &GetDnsHeader(void) const { return mDnsHeader; }
|
const Dns::UpdateHeader &GetDnsHeader(void) const { return mDnsHeader; }
|
||||||
ServiceUpdateId GetId(void) const { return mId; }
|
ServiceUpdateId GetId(void) const { return mId; }
|
||||||
|
const TtlConfig & GetTtlConfig(void) const { return mTtlConfig; }
|
||||||
const LeaseConfig & GetLeaseConfig(void) const { return mLeaseConfig; }
|
const LeaseConfig & GetLeaseConfig(void) const { return mLeaseConfig; }
|
||||||
Host & GetHost(void) { return mHost; }
|
Host & GetHost(void) { return mHost; }
|
||||||
const Ip6::MessageInfo & GetMessageInfo(void) const { return mMessageInfo; }
|
const Ip6::MessageInfo & GetMessageInfo(void) const { return mMessageInfo; }
|
||||||
|
@ -810,6 +933,7 @@ private:
|
||||||
TimeMilli mExpireTime;
|
TimeMilli mExpireTime;
|
||||||
Dns::UpdateHeader mDnsHeader;
|
Dns::UpdateHeader mDnsHeader;
|
||||||
ServiceUpdateId mId; // The ID of this service update transaction.
|
ServiceUpdateId mId; // The ID of this service update transaction.
|
||||||
|
TtlConfig mTtlConfig; // TTL config to use when processing the message.
|
||||||
LeaseConfig mLeaseConfig; // Lease config to use when processing the message.
|
LeaseConfig mLeaseConfig; // Lease config to use when processing the message.
|
||||||
Host & mHost; // The `UpdateMetadata` has no ownership of this host.
|
Host & mHost; // The `UpdateMetadata` has no ownership of this host.
|
||||||
Ip6::MessageInfo mMessageInfo; // Valid when `mIsDirectRxFromClient` is true.
|
Ip6::MessageInfo mMessageInfo; // Valid when `mIsDirectRxFromClient` is true.
|
||||||
|
@ -831,16 +955,19 @@ private:
|
||||||
|
|
||||||
ServiceUpdateId AllocateId(void) { return mServiceUpdateId++; }
|
ServiceUpdateId AllocateId(void) { return mServiceUpdateId++; }
|
||||||
|
|
||||||
|
void InformUpdateHandlerOrCommit(Error aError, Host &aHost, const MessageMetadata &aMetadata);
|
||||||
void CommitSrpUpdate(Error aError, Host &aHost, const MessageMetadata &aMessageMetadata);
|
void CommitSrpUpdate(Error aError, Host &aHost, const MessageMetadata &aMessageMetadata);
|
||||||
void CommitSrpUpdate(Error aError, UpdateMetadata &aUpdateMetadata);
|
void CommitSrpUpdate(Error aError, UpdateMetadata &aUpdateMetadata);
|
||||||
void CommitSrpUpdate(Error aError,
|
void CommitSrpUpdate(Error aError,
|
||||||
Host & aHost,
|
Host & aHost,
|
||||||
const Dns::UpdateHeader &aDnsHeader,
|
const Dns::UpdateHeader &aDnsHeader,
|
||||||
const Ip6::MessageInfo * aMessageInfo,
|
const Ip6::MessageInfo * aMessageInfo,
|
||||||
|
const TtlConfig & aTtlConfig,
|
||||||
const LeaseConfig & aLeaseConfig);
|
const LeaseConfig & aLeaseConfig);
|
||||||
Error ProcessMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
Error ProcessMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||||
Error ProcessMessage(Message & aMessage,
|
Error ProcessMessage(Message & aMessage,
|
||||||
TimeMilli aRxTime,
|
TimeMilli aRxTime,
|
||||||
|
const TtlConfig & aTtlConfig,
|
||||||
const LeaseConfig & aLeaseConfig,
|
const LeaseConfig & aLeaseConfig,
|
||||||
const Ip6::MessageInfo *aMessageInfo);
|
const Ip6::MessageInfo *aMessageInfo);
|
||||||
void ProcessDnsUpdate(Message &aMessage, MessageMetadata &aMetadata);
|
void ProcessDnsUpdate(Message &aMessage, MessageMetadata &aMetadata);
|
||||||
|
@ -853,6 +980,7 @@ private:
|
||||||
uint16_t aSigRdataOffset,
|
uint16_t aSigRdataOffset,
|
||||||
uint16_t aSigRdataLength,
|
uint16_t aSigRdataLength,
|
||||||
const char * aSignerName) const;
|
const char * aSignerName) const;
|
||||||
|
Error ValidateServiceSubTypes(Host &aHost, const MessageMetadata &aMetadata);
|
||||||
Error ProcessZoneSection(const Message &aMessage, MessageMetadata &aMetadata) const;
|
Error ProcessZoneSection(const Message &aMessage, MessageMetadata &aMetadata) const;
|
||||||
Error ProcessHostDescriptionInstruction(Host & aHost,
|
Error ProcessHostDescriptionInstruction(Host & aHost,
|
||||||
const Message & aMessage,
|
const Message & aMessage,
|
||||||
|
@ -886,12 +1014,15 @@ private:
|
||||||
const UpdateMetadata *FindOutstandingUpdate(const MessageMetadata &aMessageMetadata) const;
|
const UpdateMetadata *FindOutstandingUpdate(const MessageMetadata &aMessageMetadata) const;
|
||||||
static const char * AddressModeToString(AddressMode aMode);
|
static const char * AddressModeToString(AddressMode aMode);
|
||||||
|
|
||||||
|
void UpdateResponseCounters(Dns::Header::Response aResponseCode);
|
||||||
|
|
||||||
Ip6::Udp::Socket mSocket;
|
Ip6::Udp::Socket mSocket;
|
||||||
otSrpServerServiceUpdateHandler mServiceUpdateHandler;
|
otSrpServerServiceUpdateHandler mServiceUpdateHandler;
|
||||||
void * mServiceUpdateHandlerContext;
|
void * mServiceUpdateHandlerContext;
|
||||||
|
|
||||||
Heap::String mDomain;
|
Heap::String mDomain;
|
||||||
|
|
||||||
|
TtlConfig mTtlConfig;
|
||||||
LeaseConfig mLeaseConfig;
|
LeaseConfig mLeaseConfig;
|
||||||
|
|
||||||
LinkedList<Host> mHosts;
|
LinkedList<Host> mHosts;
|
||||||
|
@ -906,10 +1037,13 @@ private:
|
||||||
AddressMode mAddressMode;
|
AddressMode mAddressMode;
|
||||||
uint8_t mAnycastSequenceNumber;
|
uint8_t mAnycastSequenceNumber;
|
||||||
bool mHasRegisteredAnyService : 1;
|
bool mHasRegisteredAnyService : 1;
|
||||||
|
|
||||||
|
otSrpServerResponseCounters mResponseCounters;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Srp
|
} // namespace Srp
|
||||||
|
|
||||||
|
DefineCoreType(otSrpServerTtlConfig, Srp::Server::TtlConfig);
|
||||||
DefineCoreType(otSrpServerLeaseConfig, Srp::Server::LeaseConfig);
|
DefineCoreType(otSrpServerLeaseConfig, Srp::Server::LeaseConfig);
|
||||||
DefineCoreType(otSrpServerHost, Srp::Server::Host);
|
DefineCoreType(otSrpServerHost, Srp::Server::Host);
|
||||||
DefineCoreType(otSrpServerService, Srp::Server::Service);
|
DefineCoreType(otSrpServerService, Srp::Server::Service);
|
||||||
|
|
|
@ -123,11 +123,9 @@ exit:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instance &Tcp::Endpoint::GetInstance(void)
|
Instance &Tcp::Endpoint::GetInstance(void) const
|
||||||
{
|
{
|
||||||
struct tcpcb &tp = GetTcb();
|
return AsNonConst(AsCoreType(GetTcb().instance));
|
||||||
|
|
||||||
return AsCoreType(tp.instance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const SockAddr &Tcp::Endpoint::GetLocalAddress(void) const
|
const SockAddr &Tcp::Endpoint::GetLocalAddress(void) const
|
||||||
|
@ -160,7 +158,7 @@ Error Tcp::Endpoint::Bind(const SockAddr &aSockName)
|
||||||
struct tcpcb &tp = GetTcb();
|
struct tcpcb &tp = GetTcb();
|
||||||
|
|
||||||
VerifyOrExit(!AsCoreType(&aSockName.mAddress).IsUnspecified(), error = kErrorInvalidArgs);
|
VerifyOrExit(!AsCoreType(&aSockName.mAddress).IsUnspecified(), error = kErrorInvalidArgs);
|
||||||
VerifyOrExit(GetInstance().Get<Tcp>().CanBind(aSockName), error = kErrorInvalidState);
|
VerifyOrExit(Get<Tcp>().CanBind(aSockName), error = kErrorInvalidState);
|
||||||
|
|
||||||
memcpy(&tp.laddr, &aSockName.mAddress, sizeof(tp.laddr));
|
memcpy(&tp.laddr, &aSockName.mAddress, sizeof(tp.laddr));
|
||||||
tp.lport = HostSwap16(aSockName.mPort);
|
tp.lport = HostSwap16(aSockName.mPort);
|
||||||
|
@ -275,9 +273,7 @@ Error Tcp::Endpoint::Deinitialize(void)
|
||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
|
|
||||||
Tcp &tcp = GetInstance().Get<Tcp>();
|
SuccessOrExit(error = Get<Tcp>().mEndpoints.Remove(*this));
|
||||||
|
|
||||||
SuccessOrExit(error = tcp.mEndpoints.Remove(*this));
|
|
||||||
SetNext(nullptr);
|
SetNext(nullptr);
|
||||||
|
|
||||||
SuccessOrExit(error = Abort());
|
SuccessOrExit(error = Abort());
|
||||||
|
@ -356,7 +352,7 @@ void Tcp::Endpoint::SetTimer(uint8_t aTimerFlag, uint32_t aDelay)
|
||||||
LogDebg("Endpoint %p set timer %u to %u ms", static_cast<void *>(this), static_cast<unsigned int>(timerIndex),
|
LogDebg("Endpoint %p set timer %u to %u ms", static_cast<void *>(this), static_cast<unsigned int>(timerIndex),
|
||||||
static_cast<unsigned int>(aDelay));
|
static_cast<unsigned int>(aDelay));
|
||||||
|
|
||||||
GetInstance().Get<Tcp>().mTimer.FireAtIfEarlier(newFireTime);
|
Get<Tcp>().mTimer.FireAtIfEarlier(newFireTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tcp::Endpoint::CancelTimer(uint8_t aTimerFlag)
|
void Tcp::Endpoint::CancelTimer(uint8_t aTimerFlag)
|
||||||
|
@ -451,7 +447,7 @@ void Tcp::Endpoint::PostCallbacksAfterSend(size_t aSent, size_t aBacklogBefore)
|
||||||
if (backlogAfter < aBacklogBefore + aSent && mForwardProgressCallback != nullptr)
|
if (backlogAfter < aBacklogBefore + aSent && mForwardProgressCallback != nullptr)
|
||||||
{
|
{
|
||||||
mPendingCallbacks |= kForwardProgressCallbackFlag;
|
mPendingCallbacks |= kForwardProgressCallbackFlag;
|
||||||
GetInstance().Get<Tcp>().mTasklet.Post();
|
Get<Tcp>().mTasklet.Post();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,11 +538,9 @@ exit:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instance &Tcp::Listener::GetInstance(void)
|
Instance &Tcp::Listener::GetInstance(void) const
|
||||||
{
|
{
|
||||||
struct tcpcb_listen *tpl = &GetTcbListen();
|
return AsNonConst(AsCoreType(GetTcbListen().instance));
|
||||||
|
|
||||||
return AsCoreType(tpl->instance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Error Tcp::Listener::Listen(const SockAddr &aSockName)
|
Error Tcp::Listener::Listen(const SockAddr &aSockName)
|
||||||
|
@ -555,7 +549,7 @@ Error Tcp::Listener::Listen(const SockAddr &aSockName)
|
||||||
uint16_t port = HostSwap16(aSockName.mPort);
|
uint16_t port = HostSwap16(aSockName.mPort);
|
||||||
struct tcpcb_listen *tpl = &GetTcbListen();
|
struct tcpcb_listen *tpl = &GetTcbListen();
|
||||||
|
|
||||||
VerifyOrExit(GetInstance().Get<Tcp>().CanBind(aSockName), error = kErrorInvalidState);
|
VerifyOrExit(Get<Tcp>().CanBind(aSockName), error = kErrorInvalidState);
|
||||||
|
|
||||||
memcpy(&tpl->laddr, &aSockName.mAddress, sizeof(tpl->laddr));
|
memcpy(&tpl->laddr, &aSockName.mAddress, sizeof(tpl->laddr));
|
||||||
tpl->lport = port;
|
tpl->lport = port;
|
||||||
|
@ -580,9 +574,7 @@ Error Tcp::Listener::Deinitialize(void)
|
||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
|
|
||||||
Tcp &tcp = GetInstance().Get<Tcp>();
|
SuccessOrExit(error = Get<Tcp>().mListeners.Remove(*this));
|
||||||
|
|
||||||
SuccessOrExit(error = tcp.mListeners.Remove(*this));
|
|
||||||
SetNext(nullptr);
|
SetNext(nullptr);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
@ -812,7 +804,7 @@ bool Tcp::AutoBind(const SockAddr &aPeer, SockAddr &aToBind, bool aBindAddress,
|
||||||
|
|
||||||
peerInfo.Clear();
|
peerInfo.Clear();
|
||||||
peerInfo.SetPeerAddr(aPeer.GetAddress());
|
peerInfo.SetPeerAddr(aPeer.GetAddress());
|
||||||
netifAddress = InstanceLocator::GetInstance().Get<Ip6>().SelectSourceAddress(peerInfo);
|
netifAddress = Get<Ip6>().SelectSourceAddress(peerInfo);
|
||||||
VerifyOrExit(netifAddress != nullptr, success = false);
|
VerifyOrExit(netifAddress != nullptr, success = false);
|
||||||
aToBind.GetAddress() = netifAddress->GetAddress();
|
aToBind.GetAddress() = netifAddress->GetAddress();
|
||||||
}
|
}
|
||||||
|
@ -854,12 +846,12 @@ exit:
|
||||||
|
|
||||||
void Tcp::HandleTimer(Timer &aTimer)
|
void Tcp::HandleTimer(Timer &aTimer)
|
||||||
{
|
{
|
||||||
OT_ASSERT(&aTimer == &aTimer.GetInstance().Get<Tcp>().mTimer);
|
OT_ASSERT(&aTimer == &aTimer.Get<Tcp>().mTimer);
|
||||||
LogDebg("Main TCP timer expired");
|
LogDebg("Main TCP timer expired");
|
||||||
aTimer.GetInstance().Get<Tcp>().ProcessTimers();
|
aTimer.Get<Tcp>().ProcessTimers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tcp::ProcessTimers()
|
void Tcp::ProcessTimers(void)
|
||||||
{
|
{
|
||||||
TimeMilli now = TimerMilli::GetNow();
|
TimeMilli now = TimerMilli::GetNow();
|
||||||
bool pendingTimer;
|
bool pendingTimer;
|
||||||
|
@ -1014,7 +1006,7 @@ void tcplp_sys_stop_timer(struct tcpcb *aTcb, uint8_t aTimerFlag)
|
||||||
struct tcpcb *tcplp_sys_accept_ready(struct tcpcb_listen *aTcbListen, struct in6_addr *aAddr, uint16_t aPort)
|
struct tcpcb *tcplp_sys_accept_ready(struct tcpcb_listen *aTcbListen, struct in6_addr *aAddr, uint16_t aPort)
|
||||||
{
|
{
|
||||||
Tcp::Listener & listener = Tcp::Listener::FromTcbListen(*aTcbListen);
|
Tcp::Listener & listener = Tcp::Listener::FromTcbListen(*aTcbListen);
|
||||||
Tcp & tcp = listener.GetInstance().Get<Tcp>();
|
Tcp & tcp = listener.Get<Tcp>();
|
||||||
struct tcpcb * rv = (struct tcpcb *)-1;
|
struct tcpcb * rv = (struct tcpcb *)-1;
|
||||||
otSockAddr addr;
|
otSockAddr addr;
|
||||||
otTcpEndpoint * endpointPtr;
|
otTcpEndpoint * endpointPtr;
|
||||||
|
@ -1065,7 +1057,7 @@ bool tcplp_sys_accepted_connection(struct tcpcb_listen *aTcbListen,
|
||||||
{
|
{
|
||||||
Tcp::Listener &listener = Tcp::Listener::FromTcbListen(*aTcbListen);
|
Tcp::Listener &listener = Tcp::Listener::FromTcbListen(*aTcbListen);
|
||||||
Tcp::Endpoint &endpoint = Tcp::Endpoint::FromTcb(*aAccepted);
|
Tcp::Endpoint &endpoint = Tcp::Endpoint::FromTcb(*aAccepted);
|
||||||
Tcp & tcp = endpoint.GetInstance().Get<Tcp>();
|
Tcp & tcp = endpoint.Get<Tcp>();
|
||||||
bool accepted = true;
|
bool accepted = true;
|
||||||
|
|
||||||
if (listener.mAcceptDoneCallback != nullptr)
|
if (listener.mAcceptDoneCallback != nullptr)
|
||||||
|
|
|
@ -83,7 +83,7 @@ public:
|
||||||
* This class represents an endpoint of a TCP/IPv6 connection.
|
* This class represents an endpoint of a TCP/IPv6 connection.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Endpoint : public otTcpEndpoint, public LinkedListEntry<Endpoint>
|
class Endpoint : public otTcpEndpoint, public LinkedListEntry<Endpoint>, public GetProvider<Endpoint>
|
||||||
{
|
{
|
||||||
friend class Tcp;
|
friend class Tcp;
|
||||||
friend class LinkedList<Endpoint>;
|
friend class LinkedList<Endpoint>;
|
||||||
|
@ -118,7 +118,7 @@ public:
|
||||||
* @returns The Instance pointer associated with this Endpoint.
|
* @returns The Instance pointer associated with this Endpoint.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
Instance &GetInstance(void);
|
Instance &GetInstance(void) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the context pointer that was associated this Endpoint upon
|
* Obtains the context pointer that was associated this Endpoint upon
|
||||||
|
@ -402,7 +402,7 @@ public:
|
||||||
* This class represents a TCP/IPv6 listener.
|
* This class represents a TCP/IPv6 listener.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Listener : public otTcpListener, public LinkedListEntry<Listener>
|
class Listener : public otTcpListener, public LinkedListEntry<Listener>, public GetProvider<Listener>
|
||||||
{
|
{
|
||||||
friend class LinkedList<Listener>;
|
friend class LinkedList<Listener>;
|
||||||
|
|
||||||
|
@ -436,7 +436,7 @@ public:
|
||||||
* @returns The otInstance pointer associated with this Listener.
|
* @returns The otInstance pointer associated with this Listener.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
Instance &GetInstance(void);
|
Instance &GetInstance(void) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the context pointer that was associated with this Listener upon
|
* Obtains the context pointer that was associated with this Listener upon
|
||||||
|
|
|
@ -37,8 +37,10 @@
|
||||||
#include <openthread/config.h>
|
#include <openthread/config.h>
|
||||||
|
|
||||||
#define OT_THREAD_VERSION_INVALID 0
|
#define OT_THREAD_VERSION_INVALID 0
|
||||||
|
|
||||||
#define OT_THREAD_VERSION_1_1 2
|
#define OT_THREAD_VERSION_1_1 2
|
||||||
#define OT_THREAD_VERSION_1_2 3
|
#define OT_THREAD_VERSION_1_2 3
|
||||||
|
#define OT_THREAD_VERSION_1_3 4
|
||||||
|
|
||||||
#define OPENTHREAD_CORE_CONFIG_H_IN
|
#define OPENTHREAD_CORE_CONFIG_H_IN
|
||||||
|
|
||||||
|
@ -51,7 +53,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef OPENTHREAD_CONFIG_THREAD_VERSION
|
#ifndef OPENTHREAD_CONFIG_THREAD_VERSION
|
||||||
#define OPENTHREAD_CONFIG_THREAD_VERSION OT_THREAD_VERSION_1_2
|
#define OPENTHREAD_CONFIG_THREAD_VERSION OT_THREAD_VERSION_1_3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "config/announce_sender.h"
|
#include "config/announce_sender.h"
|
||||||
|
|
|
@ -522,6 +522,7 @@ public:
|
||||||
* @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned.
|
* @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned.
|
||||||
*
|
*
|
||||||
* @retval kErrorNone Successfully started scanning the channel.
|
* @retval kErrorNone Successfully started scanning the channel.
|
||||||
|
* @retval kErrorBusy The radio is performing energy scanning.
|
||||||
* @retval kErrorNotImplemented The radio doesn't support energy scanning.
|
* @retval kErrorNotImplemented The radio doesn't support energy scanning.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -47,8 +47,12 @@ if(OT_VENDOR_EXTENSION)
|
||||||
target_sources(openthread-radio-cli PRIVATE ${OT_VENDOR_EXTENSION})
|
target_sources(openthread-radio-cli PRIVATE ${OT_VENDOR_EXTENSION})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(NOT DEFINED OT_MBEDTLS_RCP)
|
||||||
|
set(OT_MBEDTLS_RCP ${OT_MBEDTLS})
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(openthread-radio-cli
|
target_link_libraries(openthread-radio-cli
|
||||||
PRIVATE
|
PRIVATE
|
||||||
${OT_MBEDTLS}
|
${OT_MBEDTLS_RCP}
|
||||||
ot-config
|
ot-config
|
||||||
)
|
)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue