mirror of
https://github.com/espressif/openthread.git
synced 2026-09-17 22:50:07 +00:00
[bbr] add backbone router service (#4430)
- Introduce BACKBONE_ROUTER option for Backbone Router function.
- Implement Backbone Router service registration.
- Add basic Backbone Router service.
- Primary Backbone Router restores its Dataset when reattached after
short reset, increases sequence number and re-register to Leader.
- Add configurable jitter for Backbone Router service registration.
- Add Backbone Router service test.
This commit is contained in:
@@ -125,6 +125,8 @@ LOCAL_CPPFLAGS := \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
src/core/api/backbone_router_api.cpp \
|
||||
src/core/api/backbone_router_ftd_api.cpp \
|
||||
src/core/api/border_router_api.cpp \
|
||||
src/core/api/channel_manager_api.cpp \
|
||||
src/core/api/channel_monitor_api.cpp \
|
||||
@@ -153,6 +155,8 @@ LOCAL_SRC_FILES := \
|
||||
src/core/api/thread_api.cpp \
|
||||
src/core/api/thread_ftd_api.cpp \
|
||||
src/core/api/udp_api.cpp \
|
||||
src/core/backbone_router/leader.cpp \
|
||||
src/core/backbone_router/local.cpp \
|
||||
src/core/coap/coap.cpp \
|
||||
src/core/coap/coap_message.cpp \
|
||||
src/core/coap/coap_secure.cpp \
|
||||
|
||||
@@ -30,6 +30,8 @@ static_library("lib-ot-core") {
|
||||
cflags_cc = [ "-Wno-non-virtual-dtor" ]
|
||||
|
||||
sources = [
|
||||
"src/core/api/backbone_router_api.cpp",
|
||||
"src/core/api/backbone_router_ftd_api.cpp",
|
||||
"src/core/api/border_agent_api.cpp",
|
||||
"src/core/api/border_router_api.cpp",
|
||||
"src/core/api/channel_manager_api.cpp",
|
||||
@@ -64,6 +66,8 @@ static_library("lib-ot-core") {
|
||||
"src/core/api/thread_api.cpp",
|
||||
"src/core/api/thread_ftd_api.cpp",
|
||||
"src/core/api/udp_api.cpp",
|
||||
"src/core/backbone_router/leader.cpp",
|
||||
"src/core/backbone_router/local.cpp",
|
||||
"src/core/coap/coap.cpp",
|
||||
"src/core/coap/coap_message.cpp",
|
||||
"src/core/coap/coap_secure.cpp",
|
||||
|
||||
@@ -26,6 +26,11 @@
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
option(OT_BACKBONE_ROUTER "enable backbone router functionality")
|
||||
if(OT_BACKBONE_ROUTER)
|
||||
list(APPEND OT_PRIVATE_DEFINES "OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE=1")
|
||||
endif()
|
||||
|
||||
option(OT_BIG_ENDIAN "host platform uses big-endian byte order")
|
||||
if(OT_BIG_ENDIAN)
|
||||
list(APPEND OT_PRIVATE_DEFINES "BYTE_ORDER_BIG_ENDIAN=1")
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
# OpenThread Features (Makefile default configuration).
|
||||
|
||||
BACKBONE_ROUTER ?= 0
|
||||
BIG_ENDIAN ?= 0
|
||||
BORDER_AGENT ?= 0
|
||||
BORDER_ROUTER ?= 0
|
||||
@@ -71,6 +72,10 @@ TIME_SYNC ?= 0
|
||||
UDP_FORWARD ?= 0
|
||||
|
||||
|
||||
ifeq ($(BACKBONE_ROUTER),1)
|
||||
COMMONCFLAGS += -DOPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE=1
|
||||
endif
|
||||
|
||||
ifeq ($(BIG_ENDIAN),1)
|
||||
COMMONCFLAGS += -DBYTE_ORDER_BIG_ENDIAN=1
|
||||
endif
|
||||
|
||||
@@ -41,6 +41,10 @@ SUBDIRS = \
|
||||
$(NULL)
|
||||
|
||||
openthread_headers = \
|
||||
backbone_router.h \
|
||||
backbone_router_ftd.h \
|
||||
border_agent.h \
|
||||
border_router.h \
|
||||
channel_manager.h \
|
||||
channel_monitor.h \
|
||||
child_supervision.h \
|
||||
@@ -49,8 +53,6 @@ openthread_headers = \
|
||||
coap.h \
|
||||
commissioner.h \
|
||||
crypto.h \
|
||||
border_agent.h \
|
||||
border_router.h \
|
||||
dataset.h \
|
||||
dataset_ftd.h \
|
||||
diag.h \
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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
|
||||
* @brief
|
||||
* This file defines the OpenThread Backbone Router API (Thread 1.2)
|
||||
*/
|
||||
|
||||
#ifndef OPENTHREAD_BACKBONE_ROUTER_H_
|
||||
#define OPENTHREAD_BACKBONE_ROUTER_H_
|
||||
|
||||
#include <openthread/instance.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup api-backbone-router
|
||||
*
|
||||
* @brief
|
||||
* This module includes functions for the OpenThread Backbone Router Service.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This structure represents Backbone Router configuration.
|
||||
*
|
||||
*/
|
||||
typedef struct otBackboneRouterConfig
|
||||
{
|
||||
uint16_t mServer16; ///< Only used when get Primary Backbone Router information in the Thread Network
|
||||
uint16_t mReregistrationDelay; ///< Reregistration Delay (in seconds)
|
||||
uint32_t mMlrTimeout; ///< Multicast Listener Registration Timeout (in seconds)
|
||||
uint8_t mSequenceNumber; ///< Sequence Number
|
||||
} otBackboneRouterConfig;
|
||||
|
||||
/**
|
||||
* This function gets the Primary Backbone Router information in the Thread Network.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[out] aConfig A pointer to where to put Primary Backbone Router information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully got Primary Backbone Router information.
|
||||
* @retval OT_ERROR_NOT_FOUND No Primary Backbone Router exists.
|
||||
*
|
||||
*/
|
||||
otError otBackboneRouterGetPrimary(otInstance *aInstance, otBackboneRouterConfig *aConfig);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_BACKBONE_ROUTER_H_
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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
|
||||
* @brief
|
||||
* This file defines the OpenThread Backbone Router API (for Thread 1.2 FTD with
|
||||
* `OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE`).
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OPENTHREAD_BACKBONE_ROUTER_FTD_H_
|
||||
#define OPENTHREAD_BACKBONE_ROUTER_FTD_H_
|
||||
|
||||
#include <openthread/backbone_router.h>
|
||||
#include <openthread/ip6.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup api-backbone-router
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents the Backbone Router Status.
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
OT_BACKBONE_ROUTER_STATE_DISABLED = 0, ///< Backbone function is disabled.
|
||||
OT_BACKBONE_ROUTER_STATE_SECONDARY = 1, ///< Secondary Backbone Router.
|
||||
OT_BACKBONE_ROUTER_STATE_PRIMARY = 2, ///< The Primary Backbone Router.
|
||||
} otBackboneRouterState;
|
||||
|
||||
/**
|
||||
* This function enables or disables Backbone functionality.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aEnable TRUE to enable Backbone functionality, FALSE otherwise.
|
||||
*
|
||||
* @sa otBackboneRouterGetState
|
||||
* @sa otBackboneRouterGetConfig
|
||||
* @sa otBackboneRouterSetConfig
|
||||
* @sa otBackboneRouterRegister
|
||||
*
|
||||
*/
|
||||
void otBackboneRouterSetEnabled(otInstance *aInstance, bool aEnable);
|
||||
|
||||
/**
|
||||
* This function gets the Backbone Router state.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @retval OT_BACKBONE_ROUTER_STATE_DISABLED Backbone functionality is disabled.
|
||||
* @retval OT_BACKBONE_ROUTER_STATE_SECONDARY Secondary Backbone Router.
|
||||
* @retval OT_BACKBONE_ROUTER_STATE_PRIMARY The Primary Backbone Router.
|
||||
*
|
||||
* @sa otBackboneRouterSetEnabled
|
||||
* @sa otBackboneRouterGetConfig
|
||||
* @sa otBackboneRouterSetConfig
|
||||
* @sa otBackboneRouterRegister
|
||||
*
|
||||
*/
|
||||
otBackboneRouterState otBackboneRouterGetState(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function gets the local Backbone Router configuration.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[out] aConfig A pointer where to put local Backbone Router configuration.
|
||||
*
|
||||
*
|
||||
* @sa otBackboneRouterSetEnabled
|
||||
* @sa otBackboneRouterGetState
|
||||
* @sa otBackboneRouterSetConfig
|
||||
* @sa otBackboneRouterRegister
|
||||
*
|
||||
*/
|
||||
void otBackboneRouterGetConfig(otInstance *aInstance, otBackboneRouterConfig *aConfig);
|
||||
|
||||
/**
|
||||
* This function sets the local Backbone Router configuration.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aConfig A pointer to the Backbone Router configuration to take effect.
|
||||
*
|
||||
* @sa otBackboneRouterSetEnabled
|
||||
* @sa otBackboneRouterGetState
|
||||
* @sa otBackboneRouterGetConfig
|
||||
* @sa otBackboneRouterRegister
|
||||
*
|
||||
*/
|
||||
void otBackboneRouterSetConfig(otInstance *aInstance, const otBackboneRouterConfig *aConfig);
|
||||
|
||||
/**
|
||||
* This function explicitly registers local Backbone Router configuration.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient space to add the Backbone Router service.
|
||||
* @retval OT_ERROR_NONE Successfully queued a Server Data Request message for delivery.
|
||||
*
|
||||
* @sa otBackboneRouterSetEnabled
|
||||
* @sa otBackboneRouterGetState
|
||||
* @sa otBackboneRouterGetConfig
|
||||
* @sa otBackboneRouterSetConfig
|
||||
*
|
||||
*/
|
||||
otError otBackboneRouterRegister(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This method returns the Backbone Router registration jitter value.
|
||||
*
|
||||
* @returns The Backbone Router registration jitter value.
|
||||
*
|
||||
* @sa otBackboneRouterSetRegistrationJitter
|
||||
*
|
||||
*/
|
||||
uint8_t otBackboneRouterGetRegistrationJitter(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This method sets the Backbone Router registration jitter value.
|
||||
*
|
||||
* @param[in] aJitter the Backbone Router registration jitter value to set.
|
||||
*
|
||||
* @sa otBackboneRouterGetRegistrationJitter
|
||||
*
|
||||
*/
|
||||
void otBackboneRouterSetRegistrationJitter(otInstance *aInstance, uint8_t aJitter);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_BACKBONE_ROUTER_FTD_H_
|
||||
@@ -122,31 +122,33 @@ void otInstanceFinalize(otInstance *aInstance);
|
||||
*/
|
||||
enum
|
||||
{
|
||||
OT_CHANGED_IP6_ADDRESS_ADDED = 1 << 0, ///< IPv6 address was added
|
||||
OT_CHANGED_IP6_ADDRESS_REMOVED = 1 << 1, ///< IPv6 address was removed
|
||||
OT_CHANGED_THREAD_ROLE = 1 << 2, ///< Role (disabled, detached, child, router, leader) changed
|
||||
OT_CHANGED_THREAD_LL_ADDR = 1 << 3, ///< The link-local address changed
|
||||
OT_CHANGED_THREAD_ML_ADDR = 1 << 4, ///< The mesh-local address changed
|
||||
OT_CHANGED_THREAD_RLOC_ADDED = 1 << 5, ///< RLOC was added
|
||||
OT_CHANGED_THREAD_RLOC_REMOVED = 1 << 6, ///< RLOC was removed
|
||||
OT_CHANGED_THREAD_PARTITION_ID = 1 << 7, ///< Partition ID changed
|
||||
OT_CHANGED_THREAD_KEY_SEQUENCE_COUNTER = 1 << 8, ///< Thread Key Sequence changed
|
||||
OT_CHANGED_THREAD_NETDATA = 1 << 9, ///< Thread Network Data changed
|
||||
OT_CHANGED_THREAD_CHILD_ADDED = 1 << 10, ///< Child was added
|
||||
OT_CHANGED_THREAD_CHILD_REMOVED = 1 << 11, ///< Child was removed
|
||||
OT_CHANGED_IP6_MULTICAST_SUBSCRIBED = 1 << 12, ///< Subscribed to a IPv6 multicast address
|
||||
OT_CHANGED_IP6_MULTICAST_UNSUBSCRIBED = 1 << 13, ///< Unsubscribed from a IPv6 multicast address
|
||||
OT_CHANGED_THREAD_CHANNEL = 1 << 14, ///< Thread network channel changed
|
||||
OT_CHANGED_THREAD_PANID = 1 << 15, ///< Thread network PAN Id changed
|
||||
OT_CHANGED_THREAD_NETWORK_NAME = 1 << 16, ///< Thread network name changed
|
||||
OT_CHANGED_THREAD_EXT_PANID = 1 << 17, ///< Thread network extended PAN ID changed
|
||||
OT_CHANGED_MASTER_KEY = 1 << 18, ///< Master key changed
|
||||
OT_CHANGED_PSKC = 1 << 19, ///< PSKc changed
|
||||
OT_CHANGED_SECURITY_POLICY = 1 << 20, ///< Security Policy changed
|
||||
OT_CHANGED_CHANNEL_MANAGER_NEW_CHANNEL = 1 << 21, ///< Channel Manager new pending Thread channel changed
|
||||
OT_CHANGED_SUPPORTED_CHANNEL_MASK = 1 << 22, ///< Supported channel mask changed
|
||||
OT_CHANGED_BORDER_AGENT_STATE = 1 << 23, ///< Border agent state changed
|
||||
OT_CHANGED_THREAD_NETIF_STATE = 1 << 24, ///< Thread network interface state changed
|
||||
OT_CHANGED_IP6_ADDRESS_ADDED = 1 << 0, ///< IPv6 address was added
|
||||
OT_CHANGED_IP6_ADDRESS_REMOVED = 1 << 1, ///< IPv6 address was removed
|
||||
OT_CHANGED_THREAD_ROLE = 1 << 2, ///< Role (disabled, detached, child, router, leader) changed
|
||||
OT_CHANGED_THREAD_LL_ADDR = 1 << 3, ///< The link-local address changed
|
||||
OT_CHANGED_THREAD_ML_ADDR = 1 << 4, ///< The mesh-local address changed
|
||||
OT_CHANGED_THREAD_RLOC_ADDED = 1 << 5, ///< RLOC was added
|
||||
OT_CHANGED_THREAD_RLOC_REMOVED = 1 << 6, ///< RLOC was removed
|
||||
OT_CHANGED_THREAD_PARTITION_ID = 1 << 7, ///< Partition ID changed
|
||||
OT_CHANGED_THREAD_KEY_SEQUENCE_COUNTER = 1 << 8, ///< Thread Key Sequence changed
|
||||
OT_CHANGED_THREAD_NETDATA = 1 << 9, ///< Thread Network Data changed
|
||||
OT_CHANGED_THREAD_CHILD_ADDED = 1 << 10, ///< Child was added
|
||||
OT_CHANGED_THREAD_CHILD_REMOVED = 1 << 11, ///< Child was removed
|
||||
OT_CHANGED_IP6_MULTICAST_SUBSCRIBED = 1 << 12, ///< Subscribed to a IPv6 multicast address
|
||||
OT_CHANGED_IP6_MULTICAST_UNSUBSCRIBED = 1 << 13, ///< Unsubscribed from a IPv6 multicast address
|
||||
OT_CHANGED_THREAD_CHANNEL = 1 << 14, ///< Thread network channel changed
|
||||
OT_CHANGED_THREAD_PANID = 1 << 15, ///< Thread network PAN Id changed
|
||||
OT_CHANGED_THREAD_NETWORK_NAME = 1 << 16, ///< Thread network name changed
|
||||
OT_CHANGED_THREAD_EXT_PANID = 1 << 17, ///< Thread network extended PAN ID changed
|
||||
OT_CHANGED_MASTER_KEY = 1 << 18, ///< Master key changed
|
||||
OT_CHANGED_PSKC = 1 << 19, ///< PSKc changed
|
||||
OT_CHANGED_SECURITY_POLICY = 1 << 20, ///< Security Policy changed
|
||||
OT_CHANGED_CHANNEL_MANAGER_NEW_CHANNEL = 1 << 21, ///< Channel Manager new pending Thread channel changed
|
||||
OT_CHANGED_SUPPORTED_CHANNEL_MASK = 1 << 22, ///< Supported channel mask changed
|
||||
OT_CHANGED_BORDER_AGENT_STATE = 1 << 23, ///< Border agent state changed
|
||||
OT_CHANGED_THREAD_NETIF_STATE = 1 << 24, ///< Thread network interface state changed
|
||||
OT_CHANGED_THREAD_BACKBONE_ROUTER_STATE = 1 << 25, ///< Backbone Router state changed
|
||||
OT_CHANGED_THREAD_BACKBONE_ROUTER_LOCAL = 1 << 26, ///< Local Backbone Router configuration changed
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -179,7 +179,7 @@ typedef struct otServerConfig
|
||||
*/
|
||||
typedef struct otServiceConfig
|
||||
{
|
||||
uint8_t mServiceID; ///< Used to return service ID when iterating over the partition's Network Data.
|
||||
uint8_t mServiceId; ///< Used to return Service ID when iterating over the partition's Network Data.
|
||||
uint32_t mEnterpriseNumber; ///< IANA Enterprise Number.
|
||||
uint8_t mServiceDataLength; ///< Length of service data.
|
||||
uint8_t mServiceData[OT_SERVICE_DATA_MAX_SIZE]; ///< Service data bytes.
|
||||
|
||||
+34
@@ -92,6 +92,21 @@ build_simulation()
|
||||
&& cmake -GNinja "${OT_SRCDIR}" "${options[@]}" \
|
||||
&& ninja)
|
||||
|
||||
if [[ "${version}" == "1.2" ]]; then
|
||||
|
||||
options+=(
|
||||
"-DOT_BACKBONE_ROUTER=ON"
|
||||
"-DOT_BORDER_ROUTER=ON"
|
||||
"-DOT_SERVICE=ON"
|
||||
)
|
||||
|
||||
local builddir="${OT_BUILDDIR}/cmake/openthread-simulation-${version}-bbr"
|
||||
(mkdir -p "${builddir}" \
|
||||
&& cd "${builddir}" \
|
||||
&& cmake -GNinja "${OT_SRCDIR}" "${options[@]}" \
|
||||
&& ninja)
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
build_posix()
|
||||
@@ -114,6 +129,21 @@ build_posix()
|
||||
&& cd "${builddir}" \
|
||||
&& cmake -GNinja "${OT_SRCDIR}" "${options[@]}" \
|
||||
&& ninja)
|
||||
|
||||
if [[ "${version}" == "1.2" ]]; then
|
||||
|
||||
options+=(
|
||||
"-DOT_BACKBONE_ROUTER=ON"
|
||||
"-DOT_BORDER_ROUTER=ON"
|
||||
"-DOT_SERVICE=ON"
|
||||
)
|
||||
|
||||
local builddir="${OT_BUILDDIR}/cmake/openthread-posix-${version}-bbr"
|
||||
(mkdir -p "${builddir}" \
|
||||
&& cd "${builddir}" \
|
||||
&& cmake -GNinja "${OT_SRCDIR}" "${options[@]}" \
|
||||
&& ninja)
|
||||
fi
|
||||
}
|
||||
|
||||
do_build() {
|
||||
@@ -142,6 +172,7 @@ do_cert() {
|
||||
|
||||
if [[ "${THREAD_VERSION}" == "1.2" ]]; then
|
||||
export top_builddir_1_1="${OT_BUILDDIR}/cmake/openthread-simulation-1.1"
|
||||
export top_builddir_1_2_bbr="${OT_BUILDDIR}/cmake/openthread-simulation-1.2-bbr"
|
||||
fi
|
||||
|
||||
[[ ! -d tmp ]] || rm -rvf tmp
|
||||
@@ -153,6 +184,7 @@ do_cert_suite() {
|
||||
|
||||
if [[ "${THREAD_VERSION}" == "1.2" ]]; then
|
||||
export top_builddir_1_1="${OT_BUILDDIR}/cmake/openthread-simulation-1.1"
|
||||
export top_builddir_1_2_bbr="${OT_BUILDDIR}/cmake/openthread-simulation-1.2-bbr"
|
||||
fi
|
||||
|
||||
local pass_count=0
|
||||
@@ -268,6 +300,8 @@ envsetup()
|
||||
export RADIO_DEVICE_1_1="${OT_BUILDDIR}/cmake/openthread-simulation-1.1/examples/apps/ncp/ot-rcp"
|
||||
export OT_CLI_PATH_1_1="${OT_BUILDDIR}/cmake/openthread-posix-1.1/src/posix/ot-cli"
|
||||
export OT_NCP_PATH_1_1="${OT_BUILDDIR}/cmake/openthread-posix-1.1/src/posix/ot-ncp"
|
||||
export OT_CLI_PATH_1_2_BBR="${OT_BUILDDIR}/cmake/openthread-posix-1.2-bbr/src/posix/ot-cli"
|
||||
export OT_NCP_PATH_1_2_BBR="${OT_BUILDDIR}/cmake/openthread-posix-1.2-bbr/src/posix/ot-ncp"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ Done
|
||||
|
||||
## OpenThread Command List
|
||||
|
||||
* [bbr](#bbr)
|
||||
* [bufferinfo](#bufferinfo)
|
||||
* [channel](#channel)
|
||||
* [child](#child-list)
|
||||
@@ -99,6 +100,131 @@ Done
|
||||
|
||||
## OpenThread Command Details
|
||||
|
||||
### bbr
|
||||
|
||||
Show current Primary Backbone Router information for Thread 1.2 device.
|
||||
|
||||
```bash
|
||||
> bbr
|
||||
BBR Primary:
|
||||
server16: 0xE400
|
||||
seqno: 10
|
||||
delay: 120 secs
|
||||
timeout: 300 secs
|
||||
Done
|
||||
```
|
||||
|
||||
```bash
|
||||
> bbr
|
||||
BBR Primary: None
|
||||
Done
|
||||
```
|
||||
|
||||
### bbr state
|
||||
Show local Backbone state ([`Disabled`,`Primary`, `Secondary`]) for Thread 1.2 FTD.
|
||||
|
||||
`OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE` is required.
|
||||
|
||||
|
||||
```bash
|
||||
> bbr state
|
||||
Disabled
|
||||
Done
|
||||
|
||||
> bbr state
|
||||
Primary
|
||||
Done
|
||||
|
||||
> bbr state
|
||||
Secondary
|
||||
Done
|
||||
```
|
||||
|
||||
### bbr enable
|
||||
Enable Backbone Router Service for Thread 1.2 FTD.
|
||||
`SRV_DATA.ntf` would be triggerred for attached device if there is no
|
||||
Backbone Router Service in Thread Network Data.
|
||||
|
||||
`OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE` is required.
|
||||
|
||||
```bash
|
||||
> bbr enable
|
||||
Done
|
||||
```
|
||||
|
||||
### bbr disable
|
||||
Disable Backbone Router Service for Thread 1.2 FTD.
|
||||
`SRV_DATA.ntf` would be triggerred if Backbone Router is Primary state.
|
||||
o
|
||||
`OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE` is required.
|
||||
|
||||
```bash
|
||||
> bbr disable
|
||||
Done
|
||||
```
|
||||
|
||||
### bbr register
|
||||
Register Backbone Router Service for Thread 1.2 FTD.
|
||||
`SRV_DATA.ntf` would be triggerred for attached device.
|
||||
|
||||
`OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE` is required.
|
||||
|
||||
```bash
|
||||
> bbr register
|
||||
Done
|
||||
```
|
||||
|
||||
### bbr config
|
||||
|
||||
Show local Backbone Router configuration for Thread 1.2 FTD.
|
||||
|
||||
`OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE` is required.
|
||||
|
||||
```bash
|
||||
> bbr config
|
||||
seqno: 10
|
||||
delay: 120 secs
|
||||
timeout: 300 secs
|
||||
Done
|
||||
```
|
||||
|
||||
### bbr config \[seqno \<seqno\>\] \[delay \<delay\>\] \[timeout \<timeout\>\]
|
||||
|
||||
Configure local Backbone Router configuration for Thread 1.2 FTD.
|
||||
`bbr register` should be issued explicitly to register Backbone Router service to Leader for
|
||||
Secondary Backbone Router. `SRV_DATA.ntf` would be initiated automatically if BBR Dataset
|
||||
changes for Primary Backbone Router.
|
||||
|
||||
`OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE` is required.
|
||||
|
||||
```bash
|
||||
> bbr config seqno 20 delay 30
|
||||
Done
|
||||
```
|
||||
|
||||
### bbr jitter
|
||||
|
||||
Show jitter (in seconds) for Backbone Router registration for Thread 1.2 FTD.
|
||||
|
||||
`OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE` is required.
|
||||
|
||||
```bash
|
||||
> bbr jitter
|
||||
20
|
||||
Done
|
||||
```
|
||||
|
||||
### bbr jitter \<jitter\>
|
||||
|
||||
Set jitter (in seconds) for Backbone Router registration for Thread 1.2 FTD.
|
||||
|
||||
`OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE` is required.
|
||||
|
||||
```bash
|
||||
> bbr jitter 10
|
||||
Done
|
||||
```
|
||||
|
||||
### bufferinfo
|
||||
|
||||
Show the current message buffer information.
|
||||
|
||||
+144
@@ -66,6 +66,13 @@
|
||||
#include "common/new.hpp"
|
||||
#include "net/ip6.hpp"
|
||||
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
#include <openthread/backbone_router.h>
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
#include <openthread/backbone_router_ftd.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "cli_dataset.hpp"
|
||||
|
||||
#if OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE && OPENTHREAD_FTD
|
||||
@@ -92,6 +99,9 @@ namespace ot {
|
||||
namespace Cli {
|
||||
|
||||
const struct Command Interpreter::sCommands[] = {
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
{"bbr", &Interpreter::ProcessBackboneRouter},
|
||||
#endif
|
||||
{"bufferinfo", &Interpreter::ProcessBufferInfo},
|
||||
{"channel", &Interpreter::ProcessChannel},
|
||||
#if OPENTHREAD_FTD
|
||||
@@ -435,6 +445,140 @@ void Interpreter::ProcessHelp(uint8_t aArgsLength, char *aArgs[])
|
||||
AppendResult(OT_ERROR_NONE);
|
||||
}
|
||||
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
void Interpreter::ProcessBackboneRouter(uint8_t aArgsLength, char *aArgs[])
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aArgs);
|
||||
otError error = OT_ERROR_INVALID_COMMAND;
|
||||
otBackboneRouterConfig config;
|
||||
|
||||
if (aArgsLength == 0)
|
||||
{
|
||||
if (otBackboneRouterGetPrimary(mInstance, &config) == OT_ERROR_NONE)
|
||||
{
|
||||
mServer->OutputFormat("BBR Primary:\r\n");
|
||||
mServer->OutputFormat("server16: 0x%04X\r\n", config.mServer16);
|
||||
mServer->OutputFormat("seqno: %d\r\n", config.mSequenceNumber);
|
||||
mServer->OutputFormat("delay: %d secs\r\n", config.mReregistrationDelay);
|
||||
mServer->OutputFormat("timeout: %d secs\r\n", config.mMlrTimeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
mServer->OutputFormat("BBR Primary: None\r\n");
|
||||
}
|
||||
|
||||
error = OT_ERROR_NONE;
|
||||
}
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
else
|
||||
{
|
||||
error = ProcessBackboneRouterLocal(aArgsLength, aArgs);
|
||||
}
|
||||
#endif
|
||||
|
||||
AppendResult(error);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
otError Interpreter::ProcessBackboneRouterLocal(uint8_t aArgsLength, char *aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
;
|
||||
otBackboneRouterConfig config;
|
||||
unsigned long value;
|
||||
|
||||
if (strcmp(aArgs[0], "disable") == 0)
|
||||
{
|
||||
otBackboneRouterSetEnabled(mInstance, false);
|
||||
}
|
||||
else if (strcmp(aArgs[0], "enable") == 0)
|
||||
{
|
||||
otBackboneRouterSetEnabled(mInstance, true);
|
||||
}
|
||||
else if (strcmp(aArgs[0], "jitter") == 0)
|
||||
{
|
||||
if (aArgsLength == 1)
|
||||
{
|
||||
mServer->OutputFormat("%d\r\n", otBackboneRouterGetRegistrationJitter(mInstance));
|
||||
}
|
||||
else if (aArgsLength == 2)
|
||||
{
|
||||
SuccessOrExit(error = ParseUnsignedLong(aArgs[1], value));
|
||||
otBackboneRouterSetRegistrationJitter(mInstance, static_cast<uint8_t>(value));
|
||||
}
|
||||
}
|
||||
else if (strcmp(aArgs[0], "register") == 0)
|
||||
{
|
||||
SuccessOrExit(error = otBackboneRouterRegister(mInstance));
|
||||
}
|
||||
else if (strcmp(aArgs[0], "state") == 0)
|
||||
{
|
||||
switch (otBackboneRouterGetState(mInstance))
|
||||
{
|
||||
case OT_BACKBONE_ROUTER_STATE_DISABLED:
|
||||
mServer->OutputFormat("Disabled\r\n");
|
||||
break;
|
||||
case OT_BACKBONE_ROUTER_STATE_SECONDARY:
|
||||
mServer->OutputFormat("Secondary\r\n");
|
||||
break;
|
||||
case OT_BACKBONE_ROUTER_STATE_PRIMARY:
|
||||
mServer->OutputFormat("Primary\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (strcmp(aArgs[0], "config") == 0)
|
||||
{
|
||||
otBackboneRouterGetConfig(mInstance, &config);
|
||||
|
||||
if (aArgsLength == 1)
|
||||
{
|
||||
mServer->OutputFormat("seqno: %d\r\n", config.mSequenceNumber);
|
||||
mServer->OutputFormat("delay: %d secs\r\n", config.mReregistrationDelay);
|
||||
mServer->OutputFormat("timeout: %d secs\r\n", config.mMlrTimeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set local Backbone Router configuration.
|
||||
for (int argCur = 1; argCur < aArgsLength; argCur++)
|
||||
{
|
||||
VerifyOrExit(argCur + 1 < aArgsLength, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
if (strcmp(aArgs[argCur], "seqno") == 0)
|
||||
{
|
||||
SuccessOrExit(error = ParseUnsignedLong(aArgs[++argCur], value));
|
||||
config.mSequenceNumber = static_cast<uint8_t>(value);
|
||||
}
|
||||
else if (strcmp(aArgs[argCur], "delay") == 0)
|
||||
{
|
||||
SuccessOrExit(error = ParseUnsignedLong(aArgs[++argCur], value));
|
||||
config.mReregistrationDelay = static_cast<uint16_t>(value);
|
||||
}
|
||||
else if (strcmp(aArgs[argCur], "timeout") == 0)
|
||||
{
|
||||
SuccessOrExit(error = ParseUnsignedLong(aArgs[++argCur], value));
|
||||
config.mMlrTimeout = static_cast<uint32_t>(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
|
||||
otBackboneRouterSetConfig(mInstance, &config);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error = OT_ERROR_INVALID_COMMAND;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
|
||||
#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
|
||||
void Interpreter::ProcessBufferInfo(uint8_t aArgsLength, char *aArgs[])
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aArgsLength);
|
||||
|
||||
@@ -203,6 +203,13 @@ private:
|
||||
void ProcessHelp(uint8_t aArgsLength, char *aArgs[]);
|
||||
void ProcessBufferInfo(uint8_t aArgsLength, char *aArgs[]);
|
||||
void ProcessChannel(uint8_t aArgsLength, char *aArgs[]);
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
void ProcessBackboneRouter(uint8_t aArgsLength, char *aArgs[]);
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
otError ProcessBackboneRouterLocal(uint8_t aArgsLength, char *aArgs[]);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
void ProcessChild(uint8_t aArgsLength, char *aArgs[]);
|
||||
void ProcessChildIp(uint8_t aArgsLength, char *aArgs[]);
|
||||
|
||||
@@ -70,6 +70,8 @@ set(COMMON_INCLUDES
|
||||
)
|
||||
|
||||
set(COMMON_SOURCES
|
||||
api/backbone_router_api.cpp
|
||||
api/backbone_router_ftd_api.cpp
|
||||
api/border_router_api.cpp
|
||||
api/channel_manager_api.cpp
|
||||
api/channel_monitor_api.cpp
|
||||
@@ -103,6 +105,8 @@ set(COMMON_SOURCES
|
||||
api/thread_api.cpp
|
||||
api/thread_ftd_api.cpp
|
||||
api/udp_api.cpp
|
||||
backbone_router/leader.cpp
|
||||
backbone_router/local.cpp
|
||||
coap/coap.cpp
|
||||
coap/coap_message.cpp
|
||||
coap/coap_secure.cpp
|
||||
|
||||
@@ -108,6 +108,8 @@ libopenthread_mtd_a_CPPFLAGS = \
|
||||
#
|
||||
|
||||
SOURCES_COMMON = \
|
||||
api/backbone_router_api.cpp \
|
||||
api/backbone_router_ftd_api.cpp \
|
||||
api/border_router_api.cpp \
|
||||
api/channel_manager_api.cpp \
|
||||
api/channel_monitor_api.cpp \
|
||||
@@ -141,6 +143,8 @@ SOURCES_COMMON = \
|
||||
api/thread_api.cpp \
|
||||
api/thread_ftd_api.cpp \
|
||||
api/udp_api.cpp \
|
||||
backbone_router/leader.cpp \
|
||||
backbone_router/local.cpp \
|
||||
coap/coap.cpp \
|
||||
coap/coap_message.cpp \
|
||||
coap/coap_secure.cpp \
|
||||
@@ -302,6 +306,8 @@ endif # OPENTHREAD_ENABLE_VENDOR_EXTENSION
|
||||
|
||||
HEADERS_COMMON = \
|
||||
openthread-core-config.h \
|
||||
backbone_router/leader.hpp \
|
||||
backbone_router/local.hpp \
|
||||
coap/coap.hpp \
|
||||
coap/coap_message.hpp \
|
||||
coap/coap_secure.hpp \
|
||||
@@ -328,6 +334,7 @@ HEADERS_COMMON = \
|
||||
common/tlvs.hpp \
|
||||
common/trickle_timer.hpp \
|
||||
config/announce_sender.h \
|
||||
config/backbone_router.h \
|
||||
config/border_router.h \
|
||||
config/channel_manager.h \
|
||||
config/channel_monitor.h \
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 defines the OpenThread Backbone Router API (Thread 1.2)
|
||||
*/
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
#include <openthread/backbone_router.h>
|
||||
#include "common/instance.hpp"
|
||||
|
||||
using namespace ot;
|
||||
|
||||
otError otBackboneRouterGetPrimary(otInstance *aInstance, otBackboneRouterConfig *aConfig)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
OT_ASSERT(aConfig != NULL);
|
||||
|
||||
return instance.Get<BackboneRouter::Leader>().GetConfig(*aConfig);
|
||||
}
|
||||
|
||||
#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 defines the OpenThread Backbone Router API (for Thread 1.2 FTD with
|
||||
* `OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE`).
|
||||
*/
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <openthread/backbone_router_ftd.h>
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
#include "common/instance.hpp"
|
||||
|
||||
using namespace ot;
|
||||
|
||||
void otBackboneRouterSetEnabled(otInstance *aInstance, bool aEnabled)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<BackboneRouter::Local>().SetEnabled(aEnabled);
|
||||
}
|
||||
|
||||
otBackboneRouterState otBackboneRouterGetState(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<BackboneRouter::Local>().GetState();
|
||||
}
|
||||
|
||||
void otBackboneRouterGetConfig(otInstance *aInstance, otBackboneRouterConfig *aConfig)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
OT_ASSERT(aConfig != NULL);
|
||||
|
||||
instance.Get<BackboneRouter::Local>().GetConfig(*aConfig);
|
||||
}
|
||||
|
||||
void otBackboneRouterSetConfig(otInstance *aInstance, const otBackboneRouterConfig *aConfig)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
OT_ASSERT(aConfig != NULL);
|
||||
|
||||
instance.Get<BackboneRouter::Local>().SetConfig(*aConfig);
|
||||
}
|
||||
|
||||
otError otBackboneRouterRegister(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<BackboneRouter::Local>().AddService(true /* Force registration */);
|
||||
}
|
||||
|
||||
uint8_t otBackboneRouterGetRegistrationJitter(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<BackboneRouter::Local>().GetRegistrationJitter();
|
||||
}
|
||||
|
||||
void otBackboneRouterSetRegistrationJitter(otInstance *aInstance, uint8_t aJitter)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<BackboneRouter::Local>().SetRegistrationJitter(aJitter);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 Primary Backbone Router service management in the Thread Network.
|
||||
*/
|
||||
|
||||
#include "leader.hpp"
|
||||
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/debug.hpp"
|
||||
#include "common/instance.hpp"
|
||||
#include "common/locator-getters.hpp"
|
||||
#include "common/logging.hpp"
|
||||
#include "common/settings.hpp"
|
||||
|
||||
#include "thread/network_data_leader.hpp"
|
||||
#include "thread/network_data_tlvs.hpp"
|
||||
#include "thread/thread_netif.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace BackboneRouter {
|
||||
|
||||
Leader::Leader(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void Leader::Reset(void)
|
||||
{
|
||||
memset(&mConfig, 0, sizeof(mConfig));
|
||||
mConfig.mServer16 = Mac::kShortAddrInvalid;
|
||||
}
|
||||
|
||||
otError Leader::GetConfig(BackboneRouterConfig &aConfig) const
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
VerifyOrExit(HasPrimary(), error = OT_ERROR_NOT_FOUND);
|
||||
|
||||
aConfig = mConfig;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Leader::GetServiceId(uint8_t &aServiceId) const
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint8_t serviceData = NetworkData::ServiceTlv::kServiceDataBackboneRouter;
|
||||
|
||||
VerifyOrExit(HasPrimary(), error = OT_ERROR_NOT_FOUND);
|
||||
|
||||
error = Get<NetworkData::Leader>().GetServiceId(THREAD_ENTERPRISE_NUMBER, &serviceData, sizeof(serviceData), true,
|
||||
aServiceId);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Leader::LogBackboneRouterPrimary(State aState, const BackboneRouterConfig &aConfig) const
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aConfig);
|
||||
|
||||
otLogInfoNetData("BBR state %s", StateToString(aState));
|
||||
|
||||
if (aState != kStateRemoved && aState != kStateNone)
|
||||
{
|
||||
otLogInfoNetData("Rloc16: 0x%4X, seqno: %d, delay: %d, timeout %d", aConfig.mServer16, aConfig.mSequenceNumber,
|
||||
aConfig.mReregistrationDelay, aConfig.mMlrTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
const char *Leader::StateToString(State aState)
|
||||
{
|
||||
const char *logString = "Unknown";
|
||||
|
||||
switch (aState)
|
||||
{
|
||||
case kStateNone:
|
||||
logString = "PBBR: None";
|
||||
break;
|
||||
|
||||
case kStateAdded:
|
||||
logString = "PBBR: Added";
|
||||
break;
|
||||
|
||||
case kStateRemoved:
|
||||
logString = "PBBR: Removed";
|
||||
break;
|
||||
|
||||
case kStateToTriggerRereg:
|
||||
logString = "PBBR: To trigger re-registration";
|
||||
break;
|
||||
|
||||
case kStateRefreshed:
|
||||
logString = "PBBR: Refreshed";
|
||||
break;
|
||||
|
||||
case kStateUnchanged:
|
||||
logString = "PBBR: Unchanged";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return logString;
|
||||
}
|
||||
|
||||
void Leader::Update(void)
|
||||
{
|
||||
BackboneRouterConfig config;
|
||||
State state;
|
||||
|
||||
Get<NetworkData::Leader>().GetBackboneRouterPrimary(config);
|
||||
|
||||
if (config.mServer16 != mConfig.mServer16)
|
||||
{
|
||||
if (config.mServer16 == Mac::kShortAddrInvalid)
|
||||
{
|
||||
state = kStateRemoved;
|
||||
}
|
||||
else if (mConfig.mServer16 == Mac::kShortAddrInvalid)
|
||||
{
|
||||
state = kStateAdded;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Short Address of PBBR changes
|
||||
state = kStateToTriggerRereg;
|
||||
}
|
||||
}
|
||||
else if (config.mServer16 == Mac::kShortAddrInvalid)
|
||||
{
|
||||
// If no primary all the time
|
||||
state = kStateNone;
|
||||
}
|
||||
else if (config.mSequenceNumber != mConfig.mSequenceNumber)
|
||||
{
|
||||
state = kStateToTriggerRereg;
|
||||
}
|
||||
else if (config.mReregistrationDelay != mConfig.mReregistrationDelay || config.mMlrTimeout != mConfig.mMlrTimeout)
|
||||
{
|
||||
state = kStateRefreshed;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = kStateUnchanged;
|
||||
}
|
||||
|
||||
mConfig = config;
|
||||
LogBackboneRouterPrimary(state, mConfig);
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
Get<BackboneRouter::Local>().UpdateBackboneRouterPrimary(state, mConfig);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace BackboneRouter
|
||||
} // namespace ot
|
||||
|
||||
#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 Primary Backbone Router service management in the Thread Network.
|
||||
*/
|
||||
|
||||
#ifndef BACKBONE_ROUTER_LEADER_HPP_
|
||||
#define BACKBONE_ROUTER_LEADER_HPP_
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
#include <openthread/backbone_router.h>
|
||||
#include <openthread/ip6.h>
|
||||
|
||||
#include "common/locator.hpp"
|
||||
#include "net/ip6_address.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
namespace BackboneRouter {
|
||||
|
||||
typedef otBackboneRouterConfig BackboneRouterConfig;
|
||||
|
||||
/**
|
||||
* This class implements the basic Primary Backbone Router service operations.
|
||||
*
|
||||
*/
|
||||
class Leader : public InstanceLocator
|
||||
{
|
||||
public:
|
||||
// Primary Backbone Router Service State or State change.
|
||||
enum State
|
||||
{
|
||||
kStateNone = 0, // Not exist (trigger Backbone Router register its service).
|
||||
kStateAdded, // Newly added.
|
||||
kStateRemoved, // Newly removed (trigger Backbone Router register its service).
|
||||
kStateToTriggerRereg, // Short address or sequence number changes (trigger re-registration).
|
||||
// May also have ReregistrationDelay or MlrTimeout update.
|
||||
kStateRefreshed, // Only ReregistrationDelay or MlrTimeout changes.
|
||||
kStateUnchanged, // No change on Primary Backbone Router information (only for logging).
|
||||
};
|
||||
|
||||
/**
|
||||
* This constructor initializes the `Leader`.
|
||||
*
|
||||
* @param[in] aInstance A reference to the OpenThread instance.
|
||||
*
|
||||
*/
|
||||
explicit Leader(Instance &aInstance);
|
||||
|
||||
/**
|
||||
* This method resets the cached Primary Backbone Router.
|
||||
*
|
||||
*/
|
||||
void Reset(void);
|
||||
|
||||
/**
|
||||
* This method updates the cached Primary Backbone Router if any when new network data is available.
|
||||
*
|
||||
*/
|
||||
void Update(void);
|
||||
|
||||
/**
|
||||
* This method gets the Primary Backbone Router in the Thread Network.
|
||||
*
|
||||
* @param[out] aConfig The Primary Backbone Router information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully got the Primary Backbone Router information.
|
||||
* @retval OT_ERROR_NOT_FOUND No Backbone Router in the Thread Network.
|
||||
*
|
||||
*/
|
||||
otError GetConfig(BackboneRouterConfig &aConfig) const;
|
||||
|
||||
/**
|
||||
* This method gets the Backbone Router Service ID.
|
||||
*
|
||||
* @param[out] aServiceId The reference whether to put the Backbone Router Service ID.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully got the Backbone Router Service ID.
|
||||
* @retval OT_ERROR_NOT_FOUND Backbone Router service doesn't exist.
|
||||
*
|
||||
*/
|
||||
otError GetServiceId(uint8_t &aServiceId) const;
|
||||
|
||||
/**
|
||||
* This method gets the short address of the Primary Backbone Router.
|
||||
*
|
||||
* @returns short address of Primary Backbone Router, or Mac::kShortAddrInvalid if no Primary Backbone Router.
|
||||
*
|
||||
*/
|
||||
uint16_t GetServer16(void) const { return mConfig.mServer16; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not there is Primary Backbone Router.
|
||||
*
|
||||
* @retval TRUE if there is Primary Backbone Router, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
bool HasPrimary(void) const { return mConfig.mServer16 != Mac::kShortAddrInvalid; }
|
||||
|
||||
private:
|
||||
void LogBackboneRouterPrimary(State aState, const BackboneRouterConfig &aConfig) const;
|
||||
static const char *StateToString(State aState);
|
||||
|
||||
BackboneRouterConfig mConfig; ///< Primary Backbone Router information.
|
||||
};
|
||||
|
||||
} // namespace BackboneRouter
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
} // namespace ot
|
||||
|
||||
#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
|
||||
#endif // BACKBONE_ROUTER_LEADER_HPP_
|
||||
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 local Backbone Router service.
|
||||
*/
|
||||
|
||||
#include "local.hpp"
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/instance.hpp"
|
||||
#include "common/locator-getters.hpp"
|
||||
#include "common/logging.hpp"
|
||||
#include "common/random.hpp"
|
||||
#include "thread/mle.hpp"
|
||||
#include "thread/mle_types.hpp"
|
||||
#include "thread/thread_netif.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
namespace BackboneRouter {
|
||||
|
||||
Local::Local(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mState(OT_BACKBONE_ROUTER_STATE_DISABLED)
|
||||
, mMlrTimeout(Mle::kMlrTimeoutDefault)
|
||||
, mReregistrationDelay(Mle::kRegistrationDelayDefault)
|
||||
, mSequenceNumber(Random::NonCrypto::GetUint8())
|
||||
, mRegistrationJitter(Mle::kBackboneRouterRegistrationJitter)
|
||||
, mIsServiceAdded(false)
|
||||
{
|
||||
}
|
||||
|
||||
void Local::SetEnabled(bool aEnable)
|
||||
{
|
||||
VerifyOrExit(aEnable == (mState == OT_BACKBONE_ROUTER_STATE_DISABLED));
|
||||
|
||||
if (aEnable)
|
||||
{
|
||||
SetState(OT_BACKBONE_ROUTER_STATE_SECONDARY);
|
||||
AddService();
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveService();
|
||||
SetState(OT_BACKBONE_ROUTER_STATE_DISABLED);
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Local::Reset(void)
|
||||
{
|
||||
VerifyOrExit(mState != OT_BACKBONE_ROUTER_STATE_DISABLED);
|
||||
|
||||
RemoveService();
|
||||
|
||||
if (mState == OT_BACKBONE_ROUTER_STATE_PRIMARY)
|
||||
{
|
||||
// Increase sequence number when changing from primary to secondary.
|
||||
mSequenceNumber++;
|
||||
Get<Notifier>().Signal(OT_CHANGED_THREAD_BACKBONE_ROUTER_LOCAL);
|
||||
SetState(OT_BACKBONE_ROUTER_STATE_SECONDARY);
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Local::GetConfig(BackboneRouterConfig &aConfig) const
|
||||
{
|
||||
aConfig.mSequenceNumber = mSequenceNumber;
|
||||
aConfig.mReregistrationDelay = mReregistrationDelay;
|
||||
aConfig.mMlrTimeout = mMlrTimeout;
|
||||
}
|
||||
|
||||
void Local::SetConfig(const BackboneRouterConfig &aConfig)
|
||||
{
|
||||
bool update = false;
|
||||
|
||||
if (aConfig.mReregistrationDelay != mReregistrationDelay)
|
||||
{
|
||||
mReregistrationDelay = aConfig.mReregistrationDelay;
|
||||
update = true;
|
||||
}
|
||||
|
||||
if (aConfig.mMlrTimeout != mMlrTimeout)
|
||||
{
|
||||
mMlrTimeout = aConfig.mMlrTimeout;
|
||||
update = true;
|
||||
}
|
||||
|
||||
if (aConfig.mSequenceNumber != mSequenceNumber)
|
||||
{
|
||||
mSequenceNumber = aConfig.mSequenceNumber;
|
||||
update = true;
|
||||
}
|
||||
|
||||
if (update)
|
||||
{
|
||||
IgnoreReturnValue(AddService());
|
||||
Get<Notifier>().Signal(OT_CHANGED_THREAD_BACKBONE_ROUTER_LOCAL);
|
||||
}
|
||||
|
||||
otLogDebgNetData("BBR local: seqno (%d), delay (%ds), timeout (%ds)", mSequenceNumber, mReregistrationDelay,
|
||||
mMlrTimeout);
|
||||
}
|
||||
|
||||
otError Local::AddService(bool aForce)
|
||||
{
|
||||
otError error = OT_ERROR_INVALID_STATE;
|
||||
uint8_t serviceData = NetworkData::ServiceTlv::kServiceDataBackboneRouter;
|
||||
NetworkData::BackboneRouterServerData serverData;
|
||||
|
||||
VerifyOrExit(mState != OT_BACKBONE_ROUTER_STATE_DISABLED && Get<Mle::Mle>().IsAttached());
|
||||
|
||||
VerifyOrExit(aForce /* if register by force */ ||
|
||||
!Get<BackboneRouter::Leader>().HasPrimary() /* if no available Backbone Router service */ ||
|
||||
Get<BackboneRouter::Leader>().GetServer16() == Get<Mle::MleRouter>().GetRloc16()
|
||||
/* If the device itself should be BBR. */
|
||||
);
|
||||
|
||||
serverData.SetSequenceNumber(mSequenceNumber);
|
||||
serverData.SetReregistrationDelay(mReregistrationDelay);
|
||||
serverData.SetMlrTimeout(mMlrTimeout);
|
||||
|
||||
SuccessOrExit(error = Get<NetworkData::Local>().AddService(
|
||||
THREAD_ENTERPRISE_NUMBER, &serviceData, sizeof(serviceData), true,
|
||||
reinterpret_cast<const uint8_t *>(&serverData), sizeof(serverData)));
|
||||
|
||||
mIsServiceAdded = true;
|
||||
Get<NetworkData::Local>().SendServerDataNotification();
|
||||
|
||||
otLogInfoNetData("BBR Service added: seqno (%d), delay (%ds), timeout (%ds)", mSequenceNumber, mReregistrationDelay,
|
||||
mMlrTimeout);
|
||||
|
||||
exit:
|
||||
otLogInfoNetData("Add BBR Service: %s", otThreadErrorToString(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Local::RemoveService(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint8_t serviceData = NetworkData::ServiceTlv::kServiceDataBackboneRouter;
|
||||
|
||||
SuccessOrExit(
|
||||
error = Get<NetworkData::Local>().RemoveService(THREAD_ENTERPRISE_NUMBER, &serviceData, sizeof(serviceData)));
|
||||
|
||||
mIsServiceAdded = false;
|
||||
|
||||
if (Get<Mle::MleRouter>().IsAttached())
|
||||
{
|
||||
Get<NetworkData::Local>().SendServerDataNotification();
|
||||
}
|
||||
|
||||
exit:
|
||||
otLogInfoNetData("Remove BBR Service %s", otThreadErrorToString(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
void Local::SetState(BackboneRouterState aState)
|
||||
{
|
||||
VerifyOrExit(mState != aState);
|
||||
|
||||
mState = aState;
|
||||
Get<Notifier>().Signal(OT_CHANGED_THREAD_BACKBONE_ROUTER_STATE);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Local::UpdateBackboneRouterPrimary(Leader::State aState, const BackboneRouterConfig &aConfig)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aState);
|
||||
|
||||
VerifyOrExit(mState != OT_BACKBONE_ROUTER_STATE_DISABLED && Get<Mle::MleRouter>().IsAttached());
|
||||
|
||||
// Wait some jitter before trying to Register.
|
||||
if (aConfig.mServer16 == Mac::kShortAddrInvalid)
|
||||
{
|
||||
uint8_t delay = 1;
|
||||
|
||||
if (Get<Mle::MleRouter>().GetRole() != OT_DEVICE_ROLE_LEADER)
|
||||
{
|
||||
delay += Random::NonCrypto::GetUint8InRange(0, mRegistrationJitter < 255 ? mRegistrationJitter + 1
|
||||
: mRegistrationJitter);
|
||||
}
|
||||
|
||||
// Here uses the timer resource in Mle.
|
||||
Get<Mle::MleRouter>().SetBackboneRouterRegistrationDelay(delay);
|
||||
}
|
||||
else if (aConfig.mServer16 != Get<Mle::MleRouter>().GetRloc16())
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
else if (!mIsServiceAdded)
|
||||
{
|
||||
// Here original PBBR restores its Backbone Router Service from Thread Network,
|
||||
// Intentionally skips the state update as PBBR will refresh its service.
|
||||
mSequenceNumber = aConfig.mSequenceNumber + 1;
|
||||
mReregistrationDelay = aConfig.mReregistrationDelay;
|
||||
mMlrTimeout = aConfig.mMlrTimeout;
|
||||
Get<Notifier>().Signal(OT_CHANGED_THREAD_BACKBONE_ROUTER_LOCAL);
|
||||
AddService(true /* Force registration to refresh and restore Primary state */);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetState(OT_BACKBONE_ROUTER_STATE_PRIMARY);
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace BackboneRouter
|
||||
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 local Backbone Router service.
|
||||
*/
|
||||
|
||||
#ifndef BACKBONE_ROUTER_LOCAL_HPP_
|
||||
#define BACKBONE_ROUTER_LOCAL_HPP_
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
#include <openthread/backbone_router.h>
|
||||
#include <openthread/backbone_router_ftd.h>
|
||||
|
||||
#include "backbone_router/leader.hpp"
|
||||
#include "net/netif.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
namespace BackboneRouter {
|
||||
|
||||
/**
|
||||
* This class implements the definitions for local Backbone Router service.
|
||||
*
|
||||
*/
|
||||
class Local : public InstanceLocator
|
||||
{
|
||||
public:
|
||||
typedef otBackboneRouterState BackboneRouterState;
|
||||
|
||||
/**
|
||||
* This constructor initializes the local Backbone Router.
|
||||
*
|
||||
* @param[in] aInstance A reference to the OpenThread instance.
|
||||
*
|
||||
*/
|
||||
explicit Local(Instance &aInstance);
|
||||
|
||||
/**
|
||||
* This methhod enables/disables Backbone function.
|
||||
*
|
||||
* @param[in] aEnable TRUE to enable the backbone function, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
void SetEnabled(bool aEnable);
|
||||
|
||||
/**
|
||||
* This methhod retrieves the Backbone Router state.
|
||||
*
|
||||
*
|
||||
* @retval OT_BACKBONE_ROUTER_STATE_DISABLED Backbone function is disabled.
|
||||
* @retval OT_BACKBONE_ROUTER_STATE_SECONDARY Secondary Backbone Router.
|
||||
* @retval OT_BACKBONE_ROUTER_STATE_PRIMARY Primary Backbone Router.
|
||||
*
|
||||
*/
|
||||
BackboneRouterState GetState(void) const { return mState; }
|
||||
|
||||
/**
|
||||
* This method resets the local Thread Network Data.
|
||||
*
|
||||
*/
|
||||
void Reset(void);
|
||||
|
||||
/**
|
||||
* This method gets local Backbone Router configuration.
|
||||
*
|
||||
* @param[out] aConfig The local Backbone Router configuration.
|
||||
*
|
||||
*/
|
||||
void GetConfig(BackboneRouterConfig &aConfig) const;
|
||||
|
||||
/**
|
||||
* This method sets local Backbone Router configuration.
|
||||
*
|
||||
* @param[in] aConfig The configuration to set.
|
||||
*
|
||||
*/
|
||||
void SetConfig(const BackboneRouterConfig &aConfig);
|
||||
|
||||
/**
|
||||
* This method registers Backbone Router Dataset to Leader.
|
||||
*
|
||||
* @param[in] aForce True to force registration regardless of current BackboneRouterState.
|
||||
* False to decide based on current BackboneRouterState.
|
||||
*
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully added the Service entry.
|
||||
* @retval OT_ERROR_INVALID_STATE Not in the ready state to register.
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient space to add the Service entry.
|
||||
*
|
||||
*/
|
||||
otError AddService(bool aForce = false);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the Backbone Router is primary.
|
||||
*
|
||||
* @retval True if the backbone router is primary.
|
||||
* @retval False if the backbone router is not primary.
|
||||
*
|
||||
*/
|
||||
bool IsPrimary(void) const { return mState == OT_BACKBONE_ROUTER_STATE_PRIMARY; }
|
||||
|
||||
/**
|
||||
* This method sets the Backbone Router registration jitter value.
|
||||
*
|
||||
* @param[in] aRegistrationJitter the Backbone Router registration jitter value to set.
|
||||
*
|
||||
*/
|
||||
void SetRegistrationJitter(uint8_t aRegistrationJitter) { mRegistrationJitter = aRegistrationJitter; }
|
||||
|
||||
/**
|
||||
* This method returns the Backbone Router registration jitter value.
|
||||
*
|
||||
* @returns The Backbone Router registration jitter value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetRegistrationJitter(void) const { return mRegistrationJitter; }
|
||||
|
||||
/**
|
||||
* This method notifies primary backbone router status.
|
||||
*
|
||||
* @param[in] aState The state or state change of primary backbone router.
|
||||
* @param[in] aConfig The primary backbone router service.
|
||||
*
|
||||
*/
|
||||
void UpdateBackboneRouterPrimary(Leader::State aState, const BackboneRouterConfig &aConfig);
|
||||
|
||||
private:
|
||||
void SetState(BackboneRouterState aState);
|
||||
otError RemoveService(void);
|
||||
|
||||
BackboneRouterState mState;
|
||||
uint32_t mMlrTimeout;
|
||||
uint16_t mReregistrationDelay;
|
||||
uint8_t mSequenceNumber;
|
||||
uint8_t mRegistrationJitter;
|
||||
|
||||
// Indicates whether or not already add Backbone Router Service to local server data.
|
||||
// Used to check whether or not in restore stage after reset or whether to remove bbr
|
||||
// service for secondary bbr if it is added by force.
|
||||
bool mIsServiceAdded;
|
||||
};
|
||||
|
||||
} // namespace BackboneRouter
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
|
||||
#endif // BACKBONE_ROUTER_LOCAL_HPP_
|
||||
@@ -73,6 +73,16 @@
|
||||
#if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
|
||||
#include "utils/channel_monitor.hpp"
|
||||
#endif
|
||||
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
#include "backbone_router/leader.hpp"
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
#include "backbone_router/local.hpp"
|
||||
#endif
|
||||
|
||||
#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
|
||||
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||
#if OPENTHREAD_ENABLE_VENDOR_EXTENSION
|
||||
#include "common/extension.hpp"
|
||||
@@ -685,6 +695,20 @@ template <> inline MessagePool &Instance::Get(void)
|
||||
return mMessagePool;
|
||||
}
|
||||
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
template <> inline BackboneRouter::Leader &Instance::Get(void)
|
||||
{
|
||||
return mThreadNetif.mBackboneRouterLeader;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
template <> inline BackboneRouter::Local &Instance::Get(void)
|
||||
{
|
||||
return mThreadNetif.mBackboneRouterLocal;
|
||||
}
|
||||
#endif
|
||||
#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
|
||||
#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
|
||||
#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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 compile-time configurations for Backbone Router services.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_BACKBONE_ROUTER_H_
|
||||
#define CONFIG_BACKBONE_ROUTER_H_
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
*
|
||||
* Define to 1 to enable Backbone Router support.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
#define OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE 0
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_BACKBONE_ROUTER_H_
|
||||
@@ -468,4 +468,15 @@
|
||||
"OPENTHREAD_CONFIG_COAP_ACK_TIMEOUT (in seconds) was replaced by OPENTHREAD_CONFIG_COAP_ACK_TIMEOUT_MILLIS (in milliseconds)"
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION < OT_THREAD_VERSION_1_2)
|
||||
#error "At least Thread Version 1.2 is required for OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE"
|
||||
#endif
|
||||
|
||||
#if !OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
|
||||
#error "OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE is required for OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE"
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
|
||||
#endif // OPENTHREAD_CORE_CONFIG_CHECK_H_
|
||||
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
/**
|
||||
* This method generate the response header according to the saved metadata.
|
||||
*
|
||||
* @param[out] aHeader A refernce to the response header.
|
||||
* @param[out] aHeader A reference to the response header.
|
||||
* @param[in] aCode The response code to fill in the response header.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully generated the response header.
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "config/openthread-core-default-config.h"
|
||||
|
||||
#include "config/announce_sender.h"
|
||||
#include "config/backbone_router.h"
|
||||
#include "config/border_router.h"
|
||||
#include "config/channel_manager.h"
|
||||
#include "config/channel_monitor.h"
|
||||
|
||||
@@ -420,6 +420,14 @@ otError MeshForwarder::UpdateIp6RouteFtd(Ip6::Header &ip6Header)
|
||||
{
|
||||
SuccessOrExit(error = MeshCoP::GetBorderAgentRloc(Get<ThreadNetif>(), mMeshDest));
|
||||
}
|
||||
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
else if (aloc16 == Mle::kAloc16BackboneRouterPrimary)
|
||||
{
|
||||
VerifyOrExit(Get<BackboneRouter::Leader>().HasPrimary(), error = OT_ERROR_DROP);
|
||||
mMeshDest = Get<BackboneRouter::Leader>().GetServer16();
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
// TODO: support for Neighbor Discovery Agent ALOC
|
||||
|
||||
@@ -55,6 +55,10 @@
|
||||
#include "thread/thread_netif.hpp"
|
||||
#include "thread/time_sync_service.hpp"
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
#include "backbone_router/local.hpp"
|
||||
#endif
|
||||
|
||||
using ot::Encoding::BigEndian::HostSwap16;
|
||||
|
||||
namespace ot {
|
||||
@@ -155,6 +159,17 @@ Mle::Mle(Instance &aInstance)
|
||||
mServiceAlocs[i].GetAddress().SetLocator(Mac::kShortAddrInvalid);
|
||||
}
|
||||
|
||||
#endif
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
// Primary Backbone Router Aloc
|
||||
mBackboneRouterPrimaryAloc.Clear();
|
||||
|
||||
mBackboneRouterPrimaryAloc.mPrefixLength = 64;
|
||||
mBackboneRouterPrimaryAloc.mPreferred = true;
|
||||
mBackboneRouterPrimaryAloc.mValid = true;
|
||||
mBackboneRouterPrimaryAloc.mScopeOverride = Ip6::Address::kRealmLocalScope;
|
||||
mBackboneRouterPrimaryAloc.mScopeOverrideValid = true;
|
||||
mBackboneRouterPrimaryAloc.GetAddress().SetLocator(kAloc16BackboneRouterPrimary);
|
||||
#endif
|
||||
|
||||
// initialize Mesh Local Prefix
|
||||
@@ -748,6 +763,13 @@ bool Mle::IsAttached(void) const
|
||||
|
||||
void Mle::SetStateDetached(void)
|
||||
{
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
Get<BackboneRouter::Local>().Reset();
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
||||
Get<BackboneRouter::Leader>().Reset();
|
||||
#endif
|
||||
|
||||
if (mRole == OT_DEVICE_ROLE_LEADER)
|
||||
{
|
||||
Get<ThreadNetif>().RemoveUnicastAddress(mLeaderAloc);
|
||||
@@ -921,12 +943,23 @@ void Mle::SetMeshLocalPrefix(const MeshLocalPrefix &aMeshLocalPrefix)
|
||||
Get<ThreadNetif>().RemoveUnicastAddress(mMeshLocal16);
|
||||
Get<ThreadNetif>().UnsubscribeMulticast(mLinkLocalAllThreadNodes);
|
||||
Get<ThreadNetif>().UnsubscribeMulticast(mRealmLocalAllThreadNodes);
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
if (Get<BackboneRouter::Local>().IsPrimary())
|
||||
{
|
||||
Get<ThreadNetif>().RemoveUnicastAddress(mBackboneRouterPrimaryAloc);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
mMeshLocal64.GetAddress().SetPrefix(aMeshLocalPrefix);
|
||||
mMeshLocal16.GetAddress().SetPrefix(aMeshLocalPrefix);
|
||||
mLeaderAloc.GetAddress().SetPrefix(aMeshLocalPrefix);
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
mBackboneRouterPrimaryAloc.GetAddress().SetPrefix(GetMeshLocalPrefix());
|
||||
#endif
|
||||
|
||||
// Just keep mesh local prefix if network interface is down
|
||||
VerifyOrExit(Get<ThreadNetif>().IsUp());
|
||||
|
||||
@@ -952,6 +985,13 @@ void Mle::ApplyMeshLocalPrefix(void)
|
||||
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
if (Get<BackboneRouter::Local>().IsPrimary())
|
||||
{
|
||||
Get<ThreadNetif>().AddUnicastAddress(mBackboneRouterPrimaryAloc);
|
||||
}
|
||||
#endif
|
||||
|
||||
mLinkLocalAllThreadNodes.GetAddress().mFields.m8[3] = 64;
|
||||
memcpy(mLinkLocalAllThreadNodes.GetAddress().mFields.m8 + 4, mMeshLocal64.GetAddress().mFields.m8, 8);
|
||||
|
||||
@@ -1549,6 +1589,9 @@ void Mle::HandleStateChanged(otChangedFlags aFlags)
|
||||
}
|
||||
}
|
||||
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
Get<BackboneRouter::Leader>().Update();
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
|
||||
Get<NetworkData::Local>().SendServerDataNotification();
|
||||
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
|
||||
@@ -1582,6 +1625,20 @@ void Mle::HandleStateChanged(otChangedFlags aFlags)
|
||||
(Get<KeyManager>().GetSecurityPolicyFlags() & OT_SECURITY_POLICY_NATIVE_COMMISSIONING) != 0);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
if (aFlags & OT_CHANGED_THREAD_BACKBONE_ROUTER_STATE)
|
||||
{
|
||||
if (Get<BackboneRouter::Local>().IsPrimary())
|
||||
{
|
||||
Get<ThreadNetif>().AddUnicastAddress(mBackboneRouterPrimaryAloc);
|
||||
}
|
||||
else
|
||||
{
|
||||
Get<ThreadNetif>().RemoveUnicastAddress(mBackboneRouterPrimaryAloc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -732,7 +732,7 @@ public:
|
||||
/**
|
||||
* This method retrieves the Service ALOC for given Service ID.
|
||||
*
|
||||
* @param[in] aServiceID Service ID to get ALOC for.
|
||||
* @param[in] aServiceId Service ID to get ALOC for.
|
||||
* @param[out] aAddress A reference to the Service ALOC.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully retrieved the Service ALOC.
|
||||
@@ -1767,7 +1767,11 @@ private:
|
||||
Ip6::NetifUnicastAddress mLeaderAloc;
|
||||
|
||||
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
|
||||
Ip6::NetifUnicastAddress mServiceAlocs[OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS];
|
||||
Ip6::NetifUnicastAddress mServiceAlocs[kMaxServiceAlocs];
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
Ip6::NetifUnicastAddress mBackboneRouterPrimaryAloc;
|
||||
#endif
|
||||
|
||||
otMleCounters mCounters;
|
||||
|
||||
@@ -80,6 +80,9 @@ MleRouter::MleRouter(Instance &aInstance)
|
||||
, mRouterSelectionJitter(kRouterSelectionJitter)
|
||||
, mRouterSelectionJitterTimeout(0)
|
||||
, mParentPriority(kParentPriorityUnspecified)
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
, mBackboneRouterRegistrationDelay(0)
|
||||
#endif
|
||||
{
|
||||
mDeviceMode.Set(mDeviceMode.Get() | DeviceMode::kModeFullThreadDevice | DeviceMode::kModeFullNetworkData);
|
||||
|
||||
@@ -1725,6 +1728,23 @@ void MleRouter::HandleStateUpdateTimer(void)
|
||||
routerStateUpdate = true;
|
||||
}
|
||||
}
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
// Delay register only when `mRouterSelectionJitterTimeout` is 0,
|
||||
// that is, when the device has decided to stay as REED or Router.
|
||||
else if (mBackboneRouterRegistrationDelay > 0)
|
||||
{
|
||||
mBackboneRouterRegistrationDelay--;
|
||||
|
||||
if (mBackboneRouterRegistrationDelay == 0)
|
||||
{
|
||||
// If no Backbone Router service after jitter, try to register its own Backbone Router Service.
|
||||
if (!Get<BackboneRouter::Leader>().HasPrimary())
|
||||
{
|
||||
Get<BackboneRouter::Local>().AddService();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (mRole)
|
||||
{
|
||||
|
||||
@@ -659,6 +659,16 @@ public:
|
||||
otError SendTimeSync(void);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
/**
|
||||
* This method sets the delay before registering Backbone Router service.
|
||||
*
|
||||
* @param[in] aDelay The delay before registering Backbone Router service.
|
||||
*
|
||||
*/
|
||||
void SetBackboneRouterRegistrationDelay(uint8_t aDelay) { mBackboneRouterRegistrationDelay = aDelay; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
@@ -803,6 +813,9 @@ private:
|
||||
uint8_t mRouterSelectionJitterTimeout; ///< The Timeout prior to request/release Router ID.
|
||||
|
||||
int8_t mParentPriority; ///< The assigned parent priority value, -2 means not assigned.
|
||||
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
uint8_t mBackboneRouterRegistrationDelay; ///< Delay before registering Backbone Router service.
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
|
||||
MeshCoP::SteeringDataTlv mSteeringData;
|
||||
|
||||
@@ -63,6 +63,12 @@ enum
|
||||
kMaxChildren = OPENTHREAD_CONFIG_MLE_MAX_CHILDREN,
|
||||
kMaxChildKeepAliveAttempts = 4, ///< Maximum keep alive attempts before attempting to reattach to a new Parent
|
||||
kFailedChildTransmissions = OPENTHREAD_CONFIG_FAILED_CHILD_TRANSMISSIONS, ///< FAILED_CHILD_TRANSMISSIONS
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
// Extra one for core Backbone Router Service.
|
||||
kMaxServiceAlocs = OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS + 1,
|
||||
#else
|
||||
kMaxServiceAlocs = OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS,
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -90,12 +96,12 @@ enum
|
||||
kMaxChildUpdateResponseTimeout = 2000, ///< Maximum delay for receiving a Child Update Response
|
||||
kMaxLinkRequestTimeout = 2000, ///< Maximum delay for receiving a Link Accept
|
||||
kMinTimeoutKeepAlive = (((kMaxChildKeepAliveAttempts + 1) * kUnicastRetransmissionDelay) /
|
||||
1000), ///< Minimum timeout(s) for keep alive
|
||||
1000), ///< Minimum timeout(in seconds) for keep alive
|
||||
kMinTimeoutDataPoll = (OPENTHREAD_CONFIG_MAC_MINIMUM_POLL_PERIOD +
|
||||
OPENTHREAD_CONFIG_FAILED_CHILD_TRANSMISSIONS * OPENTHREAD_CONFIG_MAC_RETX_POLL_PERIOD) /
|
||||
1000, ///< Minimum timeout(s) for data poll
|
||||
1000, ///< Minimum timeout(in seconds) for data poll
|
||||
kMinTimeout = (kMinTimeoutKeepAlive >= kMinTimeoutDataPoll ? kMinTimeoutKeepAlive
|
||||
: kMinTimeoutDataPoll), ///< Minimum timeout(s)
|
||||
: kMinTimeoutDataPoll), ///< Minimum timeout(in seconds)
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -210,6 +216,7 @@ enum AlocAllocation
|
||||
kAloc16ServiceEnd = 0xfc2f,
|
||||
kAloc16CommissionerStart = 0xfc30,
|
||||
kAloc16CommissionerEnd = 0xfc37,
|
||||
kAloc16BackboneRouterPrimary = 0xfc38,
|
||||
kAloc16CommissionerMask = 0x0007,
|
||||
kAloc16NeighborDiscoveryAgentStart = 0xfc40,
|
||||
kAloc16NeighborDiscoveryAgentEnd = 0xfc4e,
|
||||
@@ -219,12 +226,27 @@ enum AlocAllocation
|
||||
* Service IDs
|
||||
*
|
||||
*/
|
||||
enum ServiceID
|
||||
enum ServiceId
|
||||
{
|
||||
kServiceMinId = 0x00, ///< Minimal Service ID.
|
||||
kServiceMaxId = 0x0f, ///< Maximal Service ID.
|
||||
};
|
||||
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
|
||||
/**
|
||||
* Backbone Router constants
|
||||
*
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kRegistrationDelayDefault = 1200, //< In seconds.
|
||||
kMlrTimeoutDefault = 3600, //< In seconds.
|
||||
kBackboneRouterRegistrationJitter = 5, //< In seconds.
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This type represents a MLE device mode.
|
||||
*
|
||||
|
||||
@@ -275,7 +275,7 @@ otError NetworkData::GetNextService(Iterator &aIterator, uint16_t aRloc16, Servi
|
||||
{
|
||||
memset(&aConfig, 0, sizeof(aConfig));
|
||||
|
||||
aConfig.mServiceID = service->GetServiceID();
|
||||
aConfig.mServiceId = service->GetServiceId();
|
||||
aConfig.mEnterpriseNumber = service->GetEnterpriseNumber();
|
||||
aConfig.mServiceDataLength = service->GetServiceDataLength();
|
||||
|
||||
@@ -347,7 +347,7 @@ otError NetworkData::GetNextServiceId(Iterator &aIterator, uint16_t aRloc16, uin
|
||||
|
||||
if ((aRloc16 == Mac::kShortAddrBroadcast) || (server->GetServer16() == aRloc16))
|
||||
{
|
||||
aServiceId = service->GetServiceID();
|
||||
aServiceId = service->GetServiceId();
|
||||
|
||||
if (subCur->GetNext() >= cur->GetNext())
|
||||
{
|
||||
@@ -486,7 +486,7 @@ bool NetworkData::ContainsService(uint8_t aServiceId, uint16_t aRloc16)
|
||||
|
||||
service = static_cast<ServiceTlv *>(cur);
|
||||
|
||||
if (service->GetServiceID() == aServiceId)
|
||||
if (service->GetServiceId() == aServiceId)
|
||||
{
|
||||
subCur = service->GetSubTlvs();
|
||||
subEnd = cur->GetNext();
|
||||
@@ -715,7 +715,7 @@ void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, Serv
|
||||
case NetworkDataTlv::kTypeServer:
|
||||
{
|
||||
server = static_cast<ServerTlv *>(cur);
|
||||
server->SetServer16(Mle::Mle::ServiceAlocFromId(aService.GetServiceID()));
|
||||
server->SetServer16(Mle::Mle::ServiceAlocFromId(aService.GetServiceId()));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -240,11 +240,11 @@ public:
|
||||
otError GetNextService(Iterator &aIterator, uint16_t aRloc16, ServiceConfig &aConfig);
|
||||
|
||||
/**
|
||||
* This method provides the next service ID in the Thread Network Data for a given RLOC16.
|
||||
* This method provides the next Service ID in the Thread Network Data for a given RLOC16.
|
||||
*
|
||||
* @param[inout] aIterator A reference to the Network Data iterator.
|
||||
* @param[in] aRloc16 The RLOC16 value.
|
||||
* @param[out] aServiceID A reference to variable where the service ID will be placed.
|
||||
* @param[out] aServiceId A reference to variable where the Service ID will be placed.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully found the next service.
|
||||
* @retval OT_ERROR_NOT_FOUND No subsequent service exists in the Thread Network Data.
|
||||
@@ -295,7 +295,7 @@ public:
|
||||
* This method indicates whether or not the Thread Network Data contains the service with given Service ID
|
||||
* associated with @p aRloc16.
|
||||
*
|
||||
* @param[in] aServiceID The Service ID to search for.
|
||||
* @param[in] aServiceId The Service ID to search for.
|
||||
* @param[in] aRloc16 The RLOC16 to consider.
|
||||
*
|
||||
* @returns TRUE if this object contains the service with given ID associated with @p aRloc16,
|
||||
|
||||
@@ -67,6 +67,91 @@ void LeaderBase::Reset(void)
|
||||
Get<Notifier>().Signal(OT_CHANGED_THREAD_NETDATA);
|
||||
}
|
||||
|
||||
otError LeaderBase::GetServiceId(uint32_t aEnterpriseNumber,
|
||||
const uint8_t *aServiceData,
|
||||
uint8_t aServiceDataLength,
|
||||
bool aServerStable,
|
||||
uint8_t & aServiceId)
|
||||
{
|
||||
otError error = OT_ERROR_NOT_FOUND;
|
||||
Iterator iterator = kIteratorInit;
|
||||
otServiceConfig serviceConfig;
|
||||
|
||||
while (GetNextService(iterator, serviceConfig) == OT_ERROR_NONE)
|
||||
{
|
||||
if (aEnterpriseNumber == serviceConfig.mEnterpriseNumber &&
|
||||
aServiceDataLength == serviceConfig.mServiceDataLength &&
|
||||
memcmp(aServiceData, serviceConfig.mServiceData, aServiceDataLength) == 0 &&
|
||||
aServerStable == serviceConfig.mServerConfig.mStable)
|
||||
{
|
||||
aServiceId = serviceConfig.mServiceId;
|
||||
ExitNow(error = OT_ERROR_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
otError LeaderBase::GetBackboneRouterPrimary(BackboneRouter::BackboneRouterConfig &aConfig)
|
||||
{
|
||||
otError error = OT_ERROR_NOT_FOUND;
|
||||
uint8_t serviceData = ServiceTlv::kServiceDataBackboneRouter;
|
||||
const ServerTlv * rvalServerTlv = NULL;
|
||||
const BackboneRouterServerData *rvalServerData = NULL;
|
||||
ServiceTlv * serviceTlv;
|
||||
NetworkDataTlv * subCur;
|
||||
NetworkDataTlv * subEnd;
|
||||
|
||||
serviceTlv = Get<Leader>().FindService(THREAD_ENTERPRISE_NUMBER, &serviceData, sizeof(serviceData));
|
||||
|
||||
if (serviceTlv == NULL)
|
||||
{
|
||||
aConfig.mServer16 = Mac::kShortAddrInvalid;
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
subCur = serviceTlv->GetSubTlvs();
|
||||
subEnd = serviceTlv->GetNext();
|
||||
|
||||
while (subCur < subEnd)
|
||||
{
|
||||
ServerTlv * serverTlv;
|
||||
const BackboneRouterServerData *serverData;
|
||||
|
||||
VerifyOrExit((subCur + 1) <= subEnd && subCur->GetNext() <= subEnd, error = OT_ERROR_PARSE);
|
||||
|
||||
serverTlv = static_cast<ServerTlv *>(subCur);
|
||||
serverData = reinterpret_cast<const BackboneRouterServerData *>(serverTlv->GetServerData());
|
||||
|
||||
if (rvalServerTlv == NULL ||
|
||||
(serverTlv->GetServer16() == Mle::Mle::Rloc16FromRouterId(Get<Mle::MleRouter>().GetLeaderId())) ||
|
||||
serverData->GetSequenceNumber() > rvalServerData->GetSequenceNumber() ||
|
||||
(serverData->GetSequenceNumber() == rvalServerData->GetSequenceNumber() &&
|
||||
serverTlv->GetServer16() > rvalServerTlv->GetServer16()))
|
||||
{
|
||||
rvalServerTlv = const_cast<ServerTlv *>(serverTlv);
|
||||
rvalServerData = serverData;
|
||||
}
|
||||
|
||||
subCur = subCur->GetNext();
|
||||
}
|
||||
|
||||
VerifyOrExit(rvalServerTlv != NULL);
|
||||
|
||||
aConfig.mServer16 = rvalServerTlv->GetServer16();
|
||||
aConfig.mSequenceNumber = rvalServerData->GetSequenceNumber();
|
||||
aConfig.mReregistrationDelay = rvalServerData->GetReregistrationDelay();
|
||||
aConfig.mMlrTimeout = rvalServerData->GetMlrTimeout();
|
||||
|
||||
error = OT_ERROR_NONE;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
|
||||
otError LeaderBase::GetContext(const Ip6::Address &aAddress, Lowpan::Context &aContext)
|
||||
{
|
||||
PrefixTlv * prefix;
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
#include "backbone_router/leader.hpp"
|
||||
#endif
|
||||
|
||||
#include "coap/coap.hpp"
|
||||
#include "common/timer.hpp"
|
||||
#include "net/ip6_address.hpp"
|
||||
@@ -229,6 +233,38 @@ public:
|
||||
*/
|
||||
otError GetRlocByContextId(uint8_t aContextId, uint16_t &aRloc16);
|
||||
|
||||
/**
|
||||
* This method gets the Service ID for the specified service.
|
||||
*
|
||||
* @param[in] aEnterpriseNumber Enterprise Number (IANA-assigned) for Service TLV
|
||||
* @param[in] aServiceData A pointer to the Service Data
|
||||
* @param[in] aServiceDataLength The length of @p aServiceData in bytes.
|
||||
* @param[in] aServerStable The Stable flag value for Server TLV
|
||||
* @param[out] aServiceId A reference where to put the Service ID.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully got the Service ID.
|
||||
* @retval OT_ERROR_NOT_FOUND The specified service was not found.
|
||||
*
|
||||
*/
|
||||
otError GetServiceId(uint32_t aEnterpriseNumber,
|
||||
const uint8_t *aServiceData,
|
||||
uint8_t aServiceDataLength,
|
||||
bool aServerStable,
|
||||
uint8_t & aServiceId);
|
||||
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
/**
|
||||
* This method gets the Primary Backbone Router (PBBR) in the Thread Network.
|
||||
*
|
||||
* @param[out] aConfig The Primary Backbone Router configuration.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully got the Primary Backbone Router configuration.
|
||||
* @retval OT_ERROR_NOT_FOUND No Backbone Router Service in the Thread Network.
|
||||
*
|
||||
*/
|
||||
otError GetBackboneRouterPrimary(BackboneRouter::BackboneRouterConfig &aConfig);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
uint8_t mStableVersion;
|
||||
uint8_t mVersion;
|
||||
|
||||
@@ -750,7 +750,7 @@ otError Leader::RegisterNetworkData(uint16_t aRloc16, uint8_t *aTlvs, uint8_t aT
|
||||
rlocStable = true;
|
||||
}
|
||||
|
||||
// Store old Service IDs for given rloc16, so updates to server will reuse the same Service ID
|
||||
// Store old Service IDs for given rloc16, so updates to server will reuse the same Service ID.
|
||||
SuccessOrExit(error = GetNetworkData(false, oldTlvs, oldTlvsLength));
|
||||
|
||||
RemoveRloc(aRloc16, kMatchModeRloc16);
|
||||
@@ -946,7 +946,7 @@ otError Leader::AddServer(ServiceTlv &aService, ServerTlv &aServer, uint8_t *aOl
|
||||
ServiceTlv *oldService = NULL;
|
||||
ServerTlv * dstServer = NULL;
|
||||
uint16_t appendLength = 0;
|
||||
uint8_t serviceID = 0;
|
||||
uint8_t serviceId = 0;
|
||||
uint8_t serviceInsertLength = sizeof(ServiceTlv) + sizeof(uint8_t) /*mServiceDataLength*/ +
|
||||
ServiceTlv::GetEnterpriseNumberFieldLength(aService.GetEnterpriseNumber()) +
|
||||
aService.GetServiceDataLength();
|
||||
@@ -972,21 +972,21 @@ otError Leader::AddServer(ServiceTlv &aService, ServerTlv &aServer, uint8_t *aOl
|
||||
if (oldService != NULL)
|
||||
{
|
||||
// The same service is not found in current data, but was in old data. So, it had to be just removed by
|
||||
// RemoveRloc() Lets use the same ServiceID
|
||||
serviceID = oldService->GetServiceID();
|
||||
// RemoveRloc() Lets use the same ServiceId
|
||||
serviceId = oldService->GetServiceId();
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
// This seems like completely new service. Lets try to find new ServiceID for it. If all are taken, error
|
||||
// This seems like completely new service. Lets try to find new ServiceId for it. If all are taken, error
|
||||
// out. Since we call FindServiceById() on mTlv, we need to execute this before Insert() call, otherwise
|
||||
// we'll find uninitialized service as well.
|
||||
for (i = Mle::kServiceMinId; i <= Mle::kServiceMaxId; i++)
|
||||
{
|
||||
if (FindServiceById(i) == NULL)
|
||||
{
|
||||
serviceID = i;
|
||||
serviceId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -999,7 +999,7 @@ otError Leader::AddServer(ServiceTlv &aService, ServerTlv &aServer, uint8_t *aOl
|
||||
dstService = reinterpret_cast<ServiceTlv *>(mTlvs + mLength);
|
||||
Insert(reinterpret_cast<uint8_t *>(dstService), serviceInsertLength);
|
||||
dstService->Init();
|
||||
dstService->SetServiceID(serviceID);
|
||||
dstService->SetServiceId(serviceId);
|
||||
dstService->SetEnterpriseNumber(aService.GetEnterpriseNumber());
|
||||
dstService->SetServiceData(aService.GetServiceData(), aService.GetServiceDataLength());
|
||||
dstService->SetLength(serviceInsertLength - sizeof(NetworkDataTlv));
|
||||
@@ -1038,7 +1038,7 @@ ServiceTlv *Leader::FindServiceById(uint8_t aServiceId)
|
||||
{
|
||||
compare = static_cast<ServiceTlv *>(cur);
|
||||
|
||||
if (compare->GetServiceID() == aServiceId)
|
||||
if (compare->GetServiceId() == aServiceId)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ public:
|
||||
void UpdateContextsAfterReset(void);
|
||||
|
||||
/**
|
||||
* This method scans network data for given service ID and returns pointer to the respective TLV, if present.
|
||||
* This method scans network data for given Service ID and returns pointer to the respective TLV, if present.
|
||||
*
|
||||
* @param aServiceId Service ID to look for.
|
||||
* @return Pointer to the Service TLV for given Service ID, or NULL if not present.
|
||||
|
||||
@@ -248,7 +248,7 @@ otError Local::AddService(uint32_t aEnterpriseNumber,
|
||||
|
||||
serviceTlv->Init();
|
||||
serviceTlv->SetEnterpriseNumber(aEnterpriseNumber);
|
||||
serviceTlv->SetServiceID(0);
|
||||
serviceTlv->SetServiceId(0);
|
||||
serviceTlv->SetServiceData(aServiceData, aServiceDataLength);
|
||||
serviceTlv->SetLength(static_cast<uint8_t>(serviceTlvLength));
|
||||
|
||||
|
||||
@@ -808,6 +808,11 @@ OT_TOOL_PACKED_BEGIN
|
||||
class ServiceTlv : public NetworkDataTlv
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kServiceDataBackboneRouter = 0x01, // const THREAD_SERVICE_DATA_BBR
|
||||
};
|
||||
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
* Initial length is set to 2, to hold S_service_data_length field.
|
||||
@@ -945,16 +950,16 @@ public:
|
||||
*
|
||||
* @returns Service ID
|
||||
*/
|
||||
uint8_t GetServiceID(void) const { return (mTResSId & kSIdMask) >> kSIdOffset; }
|
||||
uint8_t GetServiceId(void) const { return (mTResSId & kSIdMask) >> kSIdOffset; }
|
||||
|
||||
/**
|
||||
* This method sets Service ID.
|
||||
*
|
||||
* @param [in] aServiceID Service ID to be set. Expected range: 0x00-0x0f.
|
||||
* @param [in] aServiceId Service ID to be set. Expected range: 0x00-0x0f.
|
||||
*/
|
||||
void SetServiceID(uint8_t aServiceID)
|
||||
void SetServiceId(uint8_t aServiceId)
|
||||
{
|
||||
mTResSId = static_cast<uint8_t>((mTResSId & ~kSIdMask) | (aServiceID << kSIdOffset));
|
||||
mTResSId = static_cast<uint8_t>((mTResSId & ~kSIdMask) | (aServiceId << kSIdOffset));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1100,6 +1105,67 @@ private:
|
||||
uint16_t mServer16;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class BackboneRouterServerData
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method returns the sequence number of Backbone Router.
|
||||
*
|
||||
* @returns The sequence number of the Backbone Router.
|
||||
*
|
||||
*/
|
||||
uint8_t GetSequenceNumber(void) const { return mSequenceNumber; }
|
||||
|
||||
/**
|
||||
* This method sets the sequence number of Backbone Router.
|
||||
*
|
||||
* @param[in] aSequenceNumber The sequence number of Backbone Router.
|
||||
*
|
||||
*/
|
||||
void SetSequenceNumber(uint8_t aSequenceNumber) { mSequenceNumber = aSequenceNumber; }
|
||||
|
||||
/**
|
||||
* This method returns the Registration Delay (in seconds) of Backbone Router.
|
||||
*
|
||||
* @returns The BBR Registration Delay (in seconds) of Backbone Router.
|
||||
*
|
||||
*/
|
||||
uint16_t GetReregistrationDelay(void) const { return HostSwap16(mReregistrationDelay); }
|
||||
|
||||
/**
|
||||
* This method sets the Registration Delay (in seconds) of Backbone Router.
|
||||
*
|
||||
* @param[in] aReregistrationDelay The Registration Delay (in seconds) of Backbone Router.
|
||||
*
|
||||
*/
|
||||
void SetReregistrationDelay(uint16_t aReregistrationDelay)
|
||||
{
|
||||
mReregistrationDelay = HostSwap16(aReregistrationDelay);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the multicast listener report timeout (in seconds) of Backbone Router.
|
||||
*
|
||||
* @returns The multicast listener report timeout (in seconds) of Backbone Router.
|
||||
*
|
||||
*/
|
||||
uint32_t GetMlrTimeout(void) const { return HostSwap32(mMlrTimeout); }
|
||||
|
||||
/**
|
||||
* This method sets multicast listener report timeout (in seconds) of Backbone Router.
|
||||
*
|
||||
* @param[in] aMlrTimeout The multicast listener report timeout (in seconds) of Backbone Router.
|
||||
*
|
||||
*/
|
||||
void SetMlrTimeout(uint32_t aMlrTimeout) { mMlrTimeout = HostSwap32(aMlrTimeout); }
|
||||
|
||||
private:
|
||||
uint8_t mSequenceNumber;
|
||||
uint16_t mReregistrationDelay;
|
||||
uint32_t mMlrTimeout;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
||||
@@ -100,6 +100,12 @@ ThreadNetif::ThreadNetif(Instance &aInstance)
|
||||
, mLeader(aInstance)
|
||||
, mAddressResolver(aInstance)
|
||||
#endif // OPENTHREAD_FTD
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
, mBackboneRouterLeader(aInstance)
|
||||
#endif
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
, mBackboneRouterLocal(aInstance)
|
||||
#endif
|
||||
, mChildSupervisor(aInstance)
|
||||
, mSupervisionListener(aInstance)
|
||||
, mAnnounceBegin(aInstance)
|
||||
|
||||
@@ -47,6 +47,12 @@
|
||||
#include "meshcop/commissioner.hpp"
|
||||
#endif // OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
|
||||
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
#include "backbone_router/leader.hpp"
|
||||
#endif
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
#include "backbone_router/local.hpp"
|
||||
#endif
|
||||
#include "meshcop/dataset_manager.hpp"
|
||||
|
||||
#if OPENTHREAD_CONFIG_JOINER_ENABLE
|
||||
@@ -221,6 +227,12 @@ private:
|
||||
AddressResolver mAddressResolver;
|
||||
#endif // OPENTHREAD_FTD
|
||||
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
|
||||
BackboneRouter::Leader mBackboneRouterLeader;
|
||||
#endif
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
BackboneRouter::Local mBackboneRouterLocal;
|
||||
#endif
|
||||
Utils::ChildSupervisor mChildSupervisor;
|
||||
Utils::SupervisionListener mSupervisionListener;
|
||||
AnnounceBeginServer mAnnounceBegin;
|
||||
|
||||
@@ -926,7 +926,7 @@ template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SERVER_LEADER_SERVICE
|
||||
{
|
||||
SuccessOrExit(error = mEncoder.OpenStruct());
|
||||
|
||||
SuccessOrExit(error = mEncoder.WriteUint8(cfg.mServiceID));
|
||||
SuccessOrExit(error = mEncoder.WriteUint8(cfg.mServiceId));
|
||||
SuccessOrExit(error = mEncoder.WriteUint32(cfg.mEnterpriseNumber));
|
||||
SuccessOrExit(error = mEncoder.WriteDataWithLen(cfg.mServiceData, cfg.mServiceDataLength));
|
||||
SuccessOrExit(error = mEncoder.WriteBool(cfg.mServerConfig.mStable));
|
||||
|
||||
@@ -43,11 +43,17 @@ import binascii
|
||||
|
||||
class Node:
|
||||
|
||||
def __init__(self, nodeid, is_mtd=False, simulator=None, version=None):
|
||||
def __init__(self,
|
||||
nodeid,
|
||||
is_mtd=False,
|
||||
simulator=None,
|
||||
version=None,
|
||||
is_bbr=False):
|
||||
self.nodeid = nodeid
|
||||
self.verbose = int(float(os.getenv('VERBOSE', 0)))
|
||||
self.node_type = os.getenv('NODE_TYPE', 'sim')
|
||||
self.env_version = os.getenv('THREAD_VERSION', '1.1')
|
||||
self.is_bbr = is_bbr
|
||||
self._initialized = False
|
||||
|
||||
if version is not None:
|
||||
@@ -76,24 +82,45 @@ class Node:
|
||||
|
||||
def __init_sim(self, nodeid, mode):
|
||||
""" Initialize a simulation node. """
|
||||
if 'OT_CLI_PATH' in os.environ:
|
||||
cmd = os.environ['OT_CLI_PATH']
|
||||
elif (self.version == '1.1' and self.version != self.env_version):
|
||||
|
||||
# Default command if no match below, will be overridden if below conditions are met.
|
||||
cmd = './ot-cli-%s' % (mode)
|
||||
|
||||
# If Thread version of node matches the testing environment version.
|
||||
if self.version == self.env_version:
|
||||
# Load Thread 1.2 BBR device when testing Thread 1.2 scenarios
|
||||
# which requires device with Backbone functionality.
|
||||
if self.version == '1.2' and self.is_bbr:
|
||||
if 'OT_CLI_PATH_1_2_BBR' in os.environ:
|
||||
cmd = os.environ['OT_CLI_PATH_1_2_BBR']
|
||||
elif 'top_builddir_1_2_bbr' in os.environ:
|
||||
srcdir = os.environ['top_builddir_1_2_bbr']
|
||||
cmd = '%s/examples/apps/cli/ot-cli-%s' % (srcdir, mode)
|
||||
|
||||
# Load Thread device of the testing environment version (may be 1.1 or 1.2)
|
||||
else:
|
||||
if 'OT_CLI_PATH' in os.environ:
|
||||
cmd = os.environ['OT_CLI_PATH']
|
||||
elif 'top_builddir' in os.environ:
|
||||
srcdir = os.environ['top_builddir']
|
||||
cmd = '%s/examples/apps/cli/ot-cli-%s' % (srcdir, mode)
|
||||
|
||||
if 'RADIO_DEVICE' in os.environ:
|
||||
cmd += ' -v %s' % os.environ['RADIO_DEVICE']
|
||||
os.environ['NODE_ID'] = str(nodeid)
|
||||
|
||||
# Load Thread 1.1 node when testing Thread 1.2 scenarios for interoperability
|
||||
elif self.version == '1.1':
|
||||
# Posix app
|
||||
if 'OT_CLI_PATH_1_1' in os.environ:
|
||||
cmd = os.environ['OT_CLI_PATH_1_1']
|
||||
elif ('top_builddir_1_1') in os.environ:
|
||||
elif 'top_builddir_1_1' in os.environ:
|
||||
srcdir = os.environ['top_builddir_1_1']
|
||||
cmd = '%s/examples/apps/cli/ot-cli-%s' % (srcdir, mode)
|
||||
elif ('top_builddir') in os.environ:
|
||||
srcdir = os.environ['top_builddir']
|
||||
cmd = '%s/examples/apps/cli/ot-cli-%s' % (srcdir, mode)
|
||||
else:
|
||||
cmd = '%s/ot-cli-%s' % (self.version, mode)
|
||||
|
||||
if 'RADIO_DEVICE' in os.environ:
|
||||
cmd += ' -v %s' % os.environ['RADIO_DEVICE']
|
||||
os.environ['NODE_ID'] = str(nodeid)
|
||||
if 'RADIO_DEVICE_1_1' in os.environ:
|
||||
cmd += ' -v %s' % os.environ['RADIO_DEVICE_1_1']
|
||||
os.environ['NODE_ID'] = str(nodeid)
|
||||
|
||||
cmd += ' %d' % nodeid
|
||||
print("%s" % cmd)
|
||||
@@ -112,43 +139,69 @@ class Node:
|
||||
|
||||
def __init_ncp_sim(self, nodeid, mode):
|
||||
""" Initialize an NCP simulation node. """
|
||||
if 'RADIO_DEVICE' in os.environ:
|
||||
args = ' %s' % os.environ['RADIO_DEVICE']
|
||||
os.environ['NODE_ID'] = str(nodeid)
|
||||
else:
|
||||
args = ''
|
||||
|
||||
if 'OT_NCP_PATH' in os.environ:
|
||||
cmd = 'spinel-cli.py -p "%s%s" -n' % (
|
||||
os.environ['OT_NCP_PATH'],
|
||||
args,
|
||||
)
|
||||
elif (self.version == '1.1' and self.version != self.env_version):
|
||||
# Default command if no match below, will be overridden if below conditions are met.
|
||||
cmd = 'spinel-cli.py -p ./ot-ncp-%s -n' % mode
|
||||
|
||||
# If Thread version of node matches the testing environment version.
|
||||
if self.version == self.env_version:
|
||||
if 'RADIO_DEVICE' in os.environ:
|
||||
args = ' %s' % os.environ['RADIO_DEVICE']
|
||||
os.environ['NODE_ID'] = str(nodeid)
|
||||
else:
|
||||
args = ''
|
||||
|
||||
# Load Thread 1.2 BBR device when testing Thread 1.2 scenarios
|
||||
# which requires device with Backbone functionality.
|
||||
if self.version == '1.2' and self.is_bbr:
|
||||
if 'OT_NCP_PATH_1_2_BBR' in os.environ:
|
||||
cmd = 'spinel-cli.py -p "%s%s" -n' % (
|
||||
os.environ['OT_NCP_PATH_1_2_BBR'],
|
||||
args,
|
||||
)
|
||||
elif 'top_builddir_1_2_bbr' in os.environ:
|
||||
srcdir = os.environ['top_builddir_1_2_bbr']
|
||||
cmd = '%s/examples/apps/ncp/ot-ncp-%s' % (srcdir, mode)
|
||||
cmd = 'spinel-cli.py -p "%s%s" -n' % (
|
||||
cmd,
|
||||
args,
|
||||
)
|
||||
|
||||
# Load Thread device of the testing environment version (may be 1.1 or 1.2).
|
||||
else:
|
||||
if 'OT_NCP_PATH' in os.environ:
|
||||
cmd = 'spinel-cli.py -p "%s%s" -n' % (
|
||||
os.environ['OT_NCP_PATH'],
|
||||
args,
|
||||
)
|
||||
elif 'top_builddir' in os.environ:
|
||||
srcdir = os.environ['top_builddir']
|
||||
cmd = '%s/examples/apps/ncp/ot-ncp-%s' % (srcdir, mode)
|
||||
cmd = 'spinel-cli.py -p "%s%s" -n' % (
|
||||
cmd,
|
||||
args,
|
||||
)
|
||||
|
||||
# Load Thread 1.1 node when testing Thread 1.2 scenarios for interoperability.
|
||||
elif self.version == '1.1':
|
||||
if 'RADIO_DEVICE_1_1' in os.environ:
|
||||
args = ' %s' % os.environ['RADIO_DEVICE_1_1']
|
||||
os.environ['NODE_ID'] = str(nodeid)
|
||||
else:
|
||||
args = ''
|
||||
|
||||
if 'OT_NCP_PATH_1_1' in os.environ:
|
||||
cmd = 'spinel-cli.py -p "%s%s" -n' % (
|
||||
os.environ['OT_NCP_PATH_1_1'],
|
||||
args,
|
||||
)
|
||||
elif ('top_builddir_1_1') in os.environ:
|
||||
elif 'top_builddir_1_1' in os.environ:
|
||||
srcdir = os.environ['top_builddir_1_1']
|
||||
cmd = '%s/examples/apps/ncp/ot-ncp-%s' % (srcdir, mode)
|
||||
cmd = 'spinel-cli.py -p "%s%s" -n' % (
|
||||
cmd,
|
||||
args,
|
||||
)
|
||||
elif ('top_builddir') in os.environ:
|
||||
srcdir = os.environ['top_builddir']
|
||||
cmd = '%s/examples/apps/ncp/ot-ncp-%s' % (srcdir, mode)
|
||||
cmd = 'spinel-cli.py -p "%s%s" -n' % (
|
||||
cmd,
|
||||
args,
|
||||
)
|
||||
else:
|
||||
cmd = 'spinel-cli.py -p "%s/ot-ncp-%s%s" -n' % (
|
||||
self.version,
|
||||
mode,
|
||||
args,
|
||||
)
|
||||
|
||||
cmd += ' %d' % nodeid
|
||||
print("%s" % cmd)
|
||||
@@ -388,6 +441,74 @@ class Node:
|
||||
self.send_command(cmd)
|
||||
self._expect('Done')
|
||||
|
||||
def get_bbr_registration_jitter(self):
|
||||
self.send_command('bbr jitter')
|
||||
return int(self._expect_result(r'\d+'))
|
||||
|
||||
def set_bbr_registration_jitter(self, jitter):
|
||||
cmd = 'bbr jitter %d' % jitter
|
||||
self.send_command(cmd)
|
||||
self._expect('Done')
|
||||
|
||||
def enable_backbone_router(self):
|
||||
cmd = 'bbr enable'
|
||||
self.send_command(cmd)
|
||||
self._expect('Done')
|
||||
|
||||
def disable_backbone_router(self):
|
||||
cmd = 'bbr disable'
|
||||
self.send_command(cmd)
|
||||
self._expect('Done')
|
||||
|
||||
def register_backbone_router(self):
|
||||
cmd = 'bbr register'
|
||||
self.send_command(cmd)
|
||||
self._expect('Done')
|
||||
|
||||
def get_backbone_router_state(self):
|
||||
states = [r'Disabled', r'Primary', r'Secondary']
|
||||
self.send_command('bbr state')
|
||||
return self._expect_result(states)
|
||||
|
||||
def get_backbone_router(self):
|
||||
cmd = 'bbr config'
|
||||
self.send_command(cmd)
|
||||
self._expect(r'(.*)Done')
|
||||
g = self.pexpect.match.groups()
|
||||
output = g[0].decode("utf-8")
|
||||
lines = output.strip().split('\n')
|
||||
lines = [l.strip() for l in lines]
|
||||
ret = {}
|
||||
for l in lines:
|
||||
z = re.search(r'seqno:\s+([0-9]+)', l)
|
||||
if z:
|
||||
ret['seqno'] = int(z.groups()[0])
|
||||
|
||||
z = re.search(r'delay:\s+([0-9]+)', l)
|
||||
if z:
|
||||
ret['delay'] = int(z.groups()[0])
|
||||
|
||||
z = re.search(r'timeout:\s+([0-9]+)', l)
|
||||
if z:
|
||||
ret['timeout'] = int(z.groups()[0])
|
||||
|
||||
return ret
|
||||
|
||||
def set_backbone_router(self, seqno=None, reg_delay=None, mlr_timeout=None):
|
||||
cmd = 'bbr config'
|
||||
|
||||
if seqno is not None:
|
||||
cmd += ' seqno %d' % seqno
|
||||
|
||||
if reg_delay is not None:
|
||||
cmd += ' delay %d' % reg_delay
|
||||
|
||||
if mlr_timeout is not None:
|
||||
cmd += ' timeout %d' % mlr_timeout
|
||||
|
||||
self.send_command(cmd)
|
||||
self._expect('Done')
|
||||
|
||||
def set_link_quality(self, addr, lqi):
|
||||
cmd = 'macfilter rss add-lqi %s %s' % (addr, lqi)
|
||||
self.send_command(cmd)
|
||||
|
||||
@@ -35,6 +35,7 @@ from node import Node
|
||||
|
||||
DEFAULT_PARAMS = {
|
||||
'is_mtd': False,
|
||||
'is_bbr': False,
|
||||
'mode': 'rsdn',
|
||||
'panid': 0xface,
|
||||
'whitelist': None,
|
||||
@@ -73,6 +74,7 @@ class TestCase(unittest.TestCase):
|
||||
params['is_mtd'],
|
||||
simulator=self.simulator,
|
||||
version=params['version'],
|
||||
is_bbr=params['is_bbr'],
|
||||
)
|
||||
self.nodes[i].set_panid(params['panid'])
|
||||
self.nodes[i].set_mode(params['mode'])
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2019, 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.
|
||||
#
|
||||
|
||||
import unittest
|
||||
|
||||
import thread_cert
|
||||
|
||||
LEADER_1_1 = 1
|
||||
BBR_1 = 2
|
||||
BBR_2 = 3
|
||||
|
||||
WAIT_ATTACH = 5
|
||||
WAIT_REDUNDANCE = 3
|
||||
ROUTER_SELECTION_JITTER = 1
|
||||
BBR_REGISTRATION_JITTER = 5
|
||||
"""
|
||||
Topology
|
||||
|
||||
LEADER_1_1 --- BBR_1
|
||||
\ |
|
||||
\ |
|
||||
\ |
|
||||
BBR_2
|
||||
|
||||
1) Bring up Leader_1_1 and then BBR_1, BBR_1 becomes Primary Backbone Router.
|
||||
2) Reset BBR_1, if bring back soon, it could restore the Backbone Router Service
|
||||
from the network, after increasing sequence number, it will reregister its
|
||||
Backbone Router Service to the Leader and become Primary.
|
||||
3) Reset BBR_1, if bring back after it is released in the network, BBR_1 will
|
||||
choose a random sequence number, register its Backbone Router Service to
|
||||
Leader and become Primary.
|
||||
4) Configure BBR_2 with highest sequence number and explicitly trigger SRV_DATA.ntf.
|
||||
BBR_2 would become Primary and BBR_1 would change to Secondary with sequence
|
||||
number increased by 1.
|
||||
5) Stop BBR_2, BBR_1 would become Primary after detecting there is no available
|
||||
Backbone Router Service in Thread Network.
|
||||
6) Bring back BBR_2, and it would become Secondary.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class TestBackboneRouterService(thread_cert.TestCase):
|
||||
topology = {
|
||||
LEADER_1_1: {
|
||||
'version': '1.1',
|
||||
'whitelist': [BBR_1, BBR_2],
|
||||
},
|
||||
BBR_1: {
|
||||
'version': '1.2',
|
||||
'whitelist': [LEADER_1_1, BBR_2],
|
||||
'is_bbr': True
|
||||
},
|
||||
BBR_2: {
|
||||
'version': '1.2',
|
||||
'whitelist': [LEADER_1_1, BBR_1],
|
||||
'is_bbr': True
|
||||
},
|
||||
}
|
||||
"""All nodes are created with default configurations"""
|
||||
|
||||
def test(self):
|
||||
|
||||
self.nodes[LEADER_1_1].start()
|
||||
WAIT_TIME = WAIT_ATTACH
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[LEADER_1_1].get_state(), 'leader')
|
||||
|
||||
# 1) First Backbone Router would become the Primary.
|
||||
self.nodes[BBR_1].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
|
||||
self.nodes[BBR_1].set_bbr_registration_jitter(BBR_REGISTRATION_JITTER)
|
||||
self.nodes[BBR_1].set_backbone_router(seqno=1)
|
||||
self.nodes[BBR_1].start()
|
||||
WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[BBR_1].get_state(), 'router')
|
||||
self.nodes[BBR_1].enable_backbone_router()
|
||||
WAIT_TIME = BBR_REGISTRATION_JITTER + WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[BBR_1].get_backbone_router_state(),
|
||||
'Primary')
|
||||
|
||||
# 2) Reset BBR_1 and bring it back soon.
|
||||
# Verify that it restores Primary State with sequence number
|
||||
# increased by 1.
|
||||
self.nodes[BBR_1].reset()
|
||||
self.nodes[BBR_1].set_bbr_registration_jitter(BBR_REGISTRATION_JITTER)
|
||||
self.nodes[BBR_1].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
|
||||
self.nodes[BBR_1].enable_backbone_router()
|
||||
self.nodes[BBR_1].start()
|
||||
WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[BBR_1].get_state(), 'router')
|
||||
WAIT_TIME = BBR_REGISTRATION_JITTER + WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[BBR_1].get_backbone_router_state(),
|
||||
'Primary')
|
||||
assert self.nodes[BBR_1].get_backbone_router()['seqno'] == 2
|
||||
|
||||
# 3) Reset BBR_1 and bring it back after its original router id is released
|
||||
# 200s (100s MaxNeighborAge + 90s InfiniteCost + 10s redundance)
|
||||
# Verify it becomes Primary again.
|
||||
# Note: To ensure test in next step, here Step 3) will repeat until
|
||||
# the random sequence number is not the highest value 255.
|
||||
while True:
|
||||
self.nodes[BBR_1].reset()
|
||||
WAIT_TIME = 200
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.nodes[BBR_1].set_router_selection_jitter(
|
||||
ROUTER_SELECTION_JITTER)
|
||||
self.nodes[BBR_1].set_bbr_registration_jitter(
|
||||
BBR_REGISTRATION_JITTER)
|
||||
self.nodes[BBR_1].enable_backbone_router()
|
||||
self.nodes[BBR_1].start()
|
||||
WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[BBR_1].get_state(), 'router')
|
||||
WAIT_TIME = BBR_REGISTRATION_JITTER + WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[BBR_1].get_backbone_router_state(),
|
||||
'Primary')
|
||||
BBR_1_SEQNO = self.nodes[BBR_1].get_backbone_router()['seqno']
|
||||
if (BBR_1_SEQNO != 255):
|
||||
break
|
||||
|
||||
#4) Configure BBR_2 with highest sequence number (255) and
|
||||
# explicitly trigger SRV_DATA.ntf.
|
||||
# Verify BBR_2 would become Primary and BBR_1 would change to
|
||||
# Secondary with sequence number increased by 1.
|
||||
|
||||
# Bring up BBR_2, it becomes Router with backbone function disabled
|
||||
# by default.
|
||||
self.nodes[BBR_2].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
|
||||
self.nodes[BBR_2].set_bbr_registration_jitter(BBR_REGISTRATION_JITTER)
|
||||
self.nodes[BBR_2].start()
|
||||
WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[BBR_2].get_state(), 'router')
|
||||
WAIT_TIME = BBR_REGISTRATION_JITTER + WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[BBR_2].get_backbone_router_state(),
|
||||
'Disabled')
|
||||
|
||||
# Enable Backbone function, it will stay at Secondary state as
|
||||
# there is Primary Backbone Router already.
|
||||
self.nodes[BBR_2].enable_backbone_router()
|
||||
self.nodes[BBR_2].set_backbone_router(seqno=255)
|
||||
WAIT_TIME = BBR_REGISTRATION_JITTER + WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[BBR_2].get_backbone_router_state(),
|
||||
'Secondary')
|
||||
# Check no SRV_DATA.ntf.
|
||||
messages = self.simulator.get_messages_sent_by(BBR_2)
|
||||
msg = messages.next_coap_message('0.02', '/a/sd', False)
|
||||
assert (
|
||||
msg is None
|
||||
), "Error: %d sent unexpected SRV_DATA.ntf when there is PBbr already"
|
||||
|
||||
# Flush relative message queue.
|
||||
self.flush_nodes([BBR_1])
|
||||
|
||||
# BBR_2 registers SRV_DATA.ntf explicitly.
|
||||
self.nodes[BBR_2].register_backbone_router()
|
||||
WAIT_TIME = WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[BBR_2].get_backbone_router_state(),
|
||||
'Primary')
|
||||
|
||||
# Verify BBR_1 becomes Secondary and sends SRV_DATA.ntf to deregister
|
||||
# its service.
|
||||
messages = self.simulator.get_messages_sent_by(BBR_1)
|
||||
messages.next_coap_message('0.02', '/a/sd', True)
|
||||
self.assertEqual(self.nodes[BBR_1].get_backbone_router_state(),
|
||||
'Secondary')
|
||||
# Verify Sequence number increases when become Secondary from Primary.
|
||||
assert self.nodes[BBR_1].get_backbone_router()['seqno'] == (
|
||||
BBR_1_SEQNO + 1)
|
||||
|
||||
# 5) Stop BBR_2, BBR_1 becomes Primary after detecting there is no
|
||||
# available Backbone Router Service.
|
||||
self.nodes[BBR_2].reset()
|
||||
self.nodes[LEADER_1_1].release_router_id(
|
||||
self.nodes[BBR_2].get_router_id())
|
||||
# Wait for the dissemination of Network Data without backbone router service
|
||||
self.simulator.go(10)
|
||||
|
||||
# BBR_1 becomes Primary.
|
||||
self.assertEqual(self.nodes[BBR_1].get_backbone_router_state(),
|
||||
'Primary')
|
||||
messages = self.simulator.get_messages_sent_by(BBR_1)
|
||||
messages.next_coap_message('0.02', '/a/sd', True)
|
||||
|
||||
# 6) Bring back BBR_2.
|
||||
# Verify that BBR_2 stays at Secondary.
|
||||
self.nodes[BBR_2].set_router_selection_jitter(ROUTER_SELECTION_JITTER)
|
||||
self.nodes[BBR_2].set_bbr_registration_jitter(BBR_REGISTRATION_JITTER)
|
||||
self.nodes[BBR_2].enable_backbone_router()
|
||||
self.nodes[BBR_2].interface_up()
|
||||
self.nodes[BBR_2].thread_start()
|
||||
WAIT_TIME = WAIT_ATTACH + ROUTER_SELECTION_JITTER
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[BBR_2].get_state(), 'router')
|
||||
WAIT_TIME = BBR_REGISTRATION_JITTER + WAIT_REDUNDANCE
|
||||
self.simulator.go(WAIT_TIME)
|
||||
self.assertEqual(self.nodes[BBR_2].get_backbone_router_state(),
|
||||
'Secondary')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user