Merge pull request #66 from lmaciejonczyk/pr/upmerge-20220623
upmerge 20220623
This commit is contained in:
commit
dc5fe8d71b
|
@ -46,7 +46,7 @@ jobs:
|
|||
REFERENCE_DEVICE: 1
|
||||
VIRTUAL_TIME: 0
|
||||
PACKET_VERIFICATION: 1
|
||||
THREAD_VERSION: 1.2
|
||||
THREAD_VERSION: 1.3
|
||||
INTER_OP: 1
|
||||
COVERAGE: 1
|
||||
MULTIPLY: 1
|
||||
|
@ -83,12 +83,12 @@ jobs:
|
|||
sudo -E ./script/test cert_suite ./tests/scripts/thread-cert/backbone/*.py || (sudo chmod a+r *.log *.json *.pcap && false)
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: cov-thread-1-2-backbone-docker
|
||||
name: cov-thread-1-3-backbone-docker
|
||||
path: /tmp/coverage/
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
name: thread-1-2-backbone-results
|
||||
name: thread-1-3-backbone-results
|
||||
path: |
|
||||
*.pcap
|
||||
*.json
|
||||
|
@ -100,7 +100,7 @@ jobs:
|
|||
./script/test generate_coverage gcc
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: cov-thread-1-2-backbone
|
||||
name: cov-thread-1-3-backbone
|
||||
path: tmp/coverage.info
|
||||
|
||||
thread-border-router:
|
||||
|
@ -144,7 +144,7 @@ jobs:
|
|||
REFERENCE_DEVICE: 1
|
||||
VIRTUAL_TIME: 0
|
||||
PACKET_VERIFICATION: ${{ matrix.packet_verification }}
|
||||
THREAD_VERSION: 1.2
|
||||
THREAD_VERSION: 1.3
|
||||
INTER_OP: 1
|
||||
COVERAGE: 1
|
||||
MULTIPLY: 1
|
||||
|
@ -220,7 +220,7 @@ jobs:
|
|||
script/test combine_coverage
|
||||
- name: Upload Coverage
|
||||
continue-on-error: true
|
||||
uses: codecov/codecov-action@v1
|
||||
uses: codecov/codecov-action@v2
|
||||
with:
|
||||
files: final.info
|
||||
fail_ci_if_error: true
|
||||
|
|
|
@ -61,7 +61,7 @@ jobs:
|
|||
- name: Build
|
||||
run: |
|
||||
./bootstrap
|
||||
make -f examples/Makefile-simulation THREAD_VERSION=1.2 DUA=1 MLR=1 BACKBONE_ROUTER=1 CSL_RECEIVER=1
|
||||
make -f examples/Makefile-simulation THREAD_VERSION=1.3 DUA=1 MLR=1 BACKBONE_ROUTER=1 CSL_RECEIVER=1
|
||||
- name: Install OTCI Python Library
|
||||
run: |
|
||||
(cd tools/otci && python3 setup.py install --user)
|
||||
|
|
|
@ -293,7 +293,7 @@ jobs:
|
|||
run: |
|
||||
script/test combine_coverage
|
||||
- name: Upload Coverage
|
||||
uses: codecov/codecov-action@v1
|
||||
uses: codecov/codecov-action@v2
|
||||
with:
|
||||
files: final.info
|
||||
fail_ci_if_error: true
|
||||
|
|
|
@ -372,7 +372,7 @@ jobs:
|
|||
run: |
|
||||
script/test combine_coverage
|
||||
- name: Upload Coverage
|
||||
uses: codecov/codecov-action@v1
|
||||
uses: codecov/codecov-action@v2
|
||||
with:
|
||||
files: final.info
|
||||
fail_ci_if_error: true
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
name: Simulation 1.2
|
||||
name: Simulation 1.3
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
|
@ -40,15 +40,15 @@ jobs:
|
|||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
if: "github.ref != 'refs/heads/main'"
|
||||
|
||||
thread-1-2:
|
||||
name: thread-1-2-${{ matrix.compiler.c }}-${{ matrix.arch }}
|
||||
thread-1-3:
|
||||
name: thread-1-3-${{ matrix.compiler.c }}-${{ matrix.arch }}
|
||||
runs-on: ubuntu-20.04
|
||||
env:
|
||||
CFLAGS: -${{ matrix.arch }}
|
||||
CXXFLAGS: -${{ matrix.arch }}
|
||||
LDFLAGS: -${{ matrix.arch }}
|
||||
COVERAGE: 1
|
||||
THREAD_VERSION: 1.2
|
||||
THREAD_VERSION: 1.3
|
||||
VIRTUAL_TIME: 1
|
||||
INTER_OP: 1
|
||||
CC: ${{ matrix.compiler.c }}
|
||||
|
@ -87,12 +87,12 @@ jobs:
|
|||
- uses: actions/upload-artifact@v2
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
name: thread-1-2-${{ matrix.compiler.c }}-${{ matrix.arch }}-pcaps
|
||||
name: thread-1-3-${{ matrix.compiler.c }}-${{ matrix.arch }}-pcaps
|
||||
path: "*.pcap"
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: ${{ failure() && env.CRASHED == '1' }}
|
||||
with:
|
||||
name: core-packet-verification-thread-1-2
|
||||
name: core-packet-verification-thread-1-3
|
||||
path: |
|
||||
./ot-core-dump/*
|
||||
- name: Generate Coverage
|
||||
|
@ -100,7 +100,7 @@ jobs:
|
|||
./script/test generate_coverage "${{ matrix.compiler.gcov }}"
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: cov-thread-1-2-${{ matrix.compiler.c }}-${{ matrix.arch }}
|
||||
name: cov-thread-1-3-${{ matrix.compiler.c }}-${{ matrix.arch }}
|
||||
path: tmp/coverage.info
|
||||
|
||||
packet-verification-low-power:
|
||||
|
@ -110,7 +110,7 @@ jobs:
|
|||
VIRTUAL_TIME: 1
|
||||
COVERAGE: 1
|
||||
PACKET_VERIFICATION: 1
|
||||
THREAD_VERSION: 1.2
|
||||
THREAD_VERSION: 1.3
|
||||
MAC_FILTER: 1
|
||||
INTER_OP: 1
|
||||
INTER_OP_BBR: 0
|
||||
|
@ -164,13 +164,13 @@ jobs:
|
|||
name: cov-packet-verification-low-power
|
||||
path: tmp/coverage.info
|
||||
|
||||
packet-verification-1-1-on-1-2:
|
||||
packet-verification-1-1-on-1-3:
|
||||
runs-on: ubuntu-20.04
|
||||
env:
|
||||
REFERENCE_DEVICE: 1
|
||||
VIRTUAL_TIME: 1
|
||||
PACKET_VERIFICATION: 1
|
||||
THREAD_VERSION: 1.2
|
||||
THREAD_VERSION: 1.3
|
||||
MULTIPLY: 3
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
@ -193,7 +193,7 @@ jobs:
|
|||
- uses: actions/upload-artifact@v2
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
name: packet-verification-1.1-on-1.2-pcaps
|
||||
name: packet-verification-1.1-on-1.3-pcaps
|
||||
path: |
|
||||
*.pcap
|
||||
*.json
|
||||
|
@ -202,14 +202,14 @@ jobs:
|
|||
./script/test generate_coverage gcc
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: cov-packet-verification-1-1-on-1-2
|
||||
name: cov-packet-verification-1-1-on-1-3
|
||||
path: tmp/coverage.info
|
||||
|
||||
expects:
|
||||
runs-on: ubuntu-20.04
|
||||
env:
|
||||
COVERAGE: 1
|
||||
THREAD_VERSION: 1.2
|
||||
THREAD_VERSION: 1.3
|
||||
VIRTUAL_TIME: 0
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
@ -232,7 +232,7 @@ jobs:
|
|||
- uses: actions/upload-artifact@v2
|
||||
if: ${{ failure() && env.CRASHED == '1' }}
|
||||
with:
|
||||
name: core-expect-1-2
|
||||
name: core-expect-1-3
|
||||
path: |
|
||||
./ot-core-dump/*
|
||||
- name: Generate Coverage
|
||||
|
@ -243,13 +243,13 @@ jobs:
|
|||
name: cov-expects
|
||||
path: tmp/coverage.info
|
||||
|
||||
thread-1-2-posix:
|
||||
thread-1-3-posix:
|
||||
runs-on: ubuntu-20.04
|
||||
env:
|
||||
COVERAGE: 1
|
||||
PYTHONUNBUFFERED: 1
|
||||
READLINE: readline
|
||||
THREAD_VERSION: 1.2
|
||||
THREAD_VERSION: 1.3
|
||||
OT_NODE_TYPE: rcp
|
||||
USE_MTD: 1
|
||||
VIRTUAL_TIME: 1
|
||||
|
@ -285,12 +285,12 @@ jobs:
|
|||
- uses: actions/upload-artifact@v2
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
name: thread-1-2-posix-pcaps
|
||||
name: thread-1-3-posix-pcaps
|
||||
path: "*.pcap"
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: ${{ failure() && env.CRASHED == '1' }}
|
||||
with:
|
||||
name: core-thread-1-2-posix
|
||||
name: core-thread-1-3-posix
|
||||
path: |
|
||||
./ot-core-dump/*
|
||||
- name: Generate Coverage
|
||||
|
@ -298,16 +298,16 @@ jobs:
|
|||
./script/test generate_coverage gcc
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: cov-thread-1-2-posix
|
||||
name: cov-thread-1-3-posix
|
||||
path: tmp/coverage.info
|
||||
|
||||
upload-coverage:
|
||||
needs:
|
||||
- thread-1-2
|
||||
- thread-1-3
|
||||
- packet-verification-low-power
|
||||
- packet-verification-1-1-on-1-2
|
||||
- packet-verification-1-1-on-1-3
|
||||
- expects
|
||||
- thread-1-2-posix
|
||||
- thread-1-3-posix
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
@ -323,7 +323,7 @@ jobs:
|
|||
run: |
|
||||
script/test combine_coverage
|
||||
- name: Upload Coverage
|
||||
uses: codecov/codecov-action@v1
|
||||
uses: codecov/codecov-action@v2
|
||||
with:
|
||||
files: final.info
|
||||
fail_ci_if_error: true
|
||||
|
|
|
@ -139,7 +139,7 @@ jobs:
|
|||
run: |
|
||||
script/test combine_coverage
|
||||
- name: Upload Coverage
|
||||
uses: codecov/codecov-action@v1
|
||||
uses: codecov/codecov-action@v2
|
||||
with:
|
||||
files: final.info
|
||||
fail_ci_if_error: true
|
||||
|
|
|
@ -220,8 +220,7 @@ LOCAL_SRC_FILES := \
|
|||
src/core/backbone_router/bbr_manager.cpp \
|
||||
src/core/backbone_router/multicast_listeners_table.cpp \
|
||||
src/core/backbone_router/ndproxy_table.cpp \
|
||||
src/core/border_router/infra_if_platform.cpp \
|
||||
src/core/border_router/router_advertisement.cpp \
|
||||
src/core/border_router/infra_if.cpp \
|
||||
src/core/border_router/routing_manager.cpp \
|
||||
src/core/coap/coap.cpp \
|
||||
src/core/coap/coap_message.cpp \
|
||||
|
@ -303,6 +302,7 @@ LOCAL_SRC_FILES := \
|
|||
src/core/net/ip6_filter.cpp \
|
||||
src/core/net/ip6_headers.cpp \
|
||||
src/core/net/ip6_mpl.cpp \
|
||||
src/core/net/nd6.cpp \
|
||||
src/core/net/nd_agent.cpp \
|
||||
src/core/net/netif.cpp \
|
||||
src/core/net/sntp_client.cpp \
|
||||
|
|
|
@ -102,12 +102,14 @@ if(OT_PACKAGE_VERSION STREQUAL "")
|
|||
endif()
|
||||
message(STATUS "Package Version: ${OT_PACKAGE_VERSION}")
|
||||
|
||||
set(OT_THREAD_VERSION "1.2" CACHE STRING "Thread version chosen by the user at configure time")
|
||||
set_property(CACHE OT_THREAD_VERSION PROPERTY STRINGS "1.1" "1.2")
|
||||
set(OT_THREAD_VERSION "1.3" CACHE STRING "Thread version chosen by the user at configure time")
|
||||
set_property(CACHE OT_THREAD_VERSION PROPERTY STRINGS "1.1" "1.2" "1.3")
|
||||
if(${OT_THREAD_VERSION} EQUAL "1.1")
|
||||
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_1")
|
||||
elseif(${OT_THREAD_VERSION} EQUAL "1.2")
|
||||
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_2")
|
||||
elseif(${OT_THREAD_VERSION} EQUAL "1.3")
|
||||
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_3")
|
||||
else()
|
||||
message(FATAL_ERROR "Thread version unknown: ${OT_THREAD_VERSION}")
|
||||
endif()
|
||||
|
|
|
@ -59,7 +59,16 @@
|
|||
* @defgroup api-ip6 IPv6
|
||||
* @defgroup api-srp SRP
|
||||
* @defgroup api-ping-sender Ping Sender
|
||||
*
|
||||
* @defgroup api-tcp-group TCP
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @defgroup api-tcp TCP
|
||||
* @defgroup api-tcp-ext TCP Abstractions
|
||||
*
|
||||
* @}
|
||||
*
|
||||
* @defgroup api-udp-group UDP
|
||||
*
|
||||
* @{
|
||||
|
|
|
@ -360,6 +360,11 @@ if (OT_TREL)
|
|||
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE=1")
|
||||
endif()
|
||||
|
||||
option(OT_TX_BEACON_PAYLOAD "enable Thread beacon payload in outgoing beacons")
|
||||
if (OT_TX_BEACON_PAYLOAD)
|
||||
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_MAC_OUTGOING_BEACON_PAYLOAD_ENABLE=1")
|
||||
endif()
|
||||
|
||||
option(OT_UDP_FORWARD "enable UDP forward support")
|
||||
if(OT_UDP_FORWARD)
|
||||
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1")
|
||||
|
|
|
@ -37,13 +37,17 @@ if(NOT DEFINED OT_PLATFORM_LIB_RCP)
|
|||
set(OT_PLATFORM_LIB_RCP ${OT_PLATFORM_LIB})
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED OT_MBEDTLS_RCP)
|
||||
set(OT_MBEDTLS_RCP ${OT_MBEDTLS})
|
||||
endif()
|
||||
|
||||
target_link_libraries(ot-cli-radio PRIVATE
|
||||
openthread-cli-radio
|
||||
${OT_PLATFORM_LIB_RCP}
|
||||
openthread-radio-cli
|
||||
${OT_PLATFORM_LIB_RCP}
|
||||
openthread-cli-radio
|
||||
${OT_MBEDTLS}
|
||||
${OT_MBEDTLS_RCP}
|
||||
ot-config
|
||||
)
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ SLAAC ?= 1
|
|||
SNTP_CLIENT ?= 0
|
||||
SRP_CLIENT ?= 0
|
||||
SRP_SERVER ?= 0
|
||||
THREAD_VERSION ?= 1.2
|
||||
THREAD_VERSION ?= 1.3
|
||||
TIME_SYNC ?= 0
|
||||
TREL ?= 0
|
||||
UDP_FORWARD ?= 0
|
||||
|
@ -333,6 +333,8 @@ ifeq ($(THREAD_VERSION),1.1)
|
|||
COMMONCFLAGS += -DOPENTHREAD_CONFIG_THREAD_VERSION=2
|
||||
else ifeq ($(THREAD_VERSION),1.2)
|
||||
COMMONCFLAGS += -DOPENTHREAD_CONFIG_THREAD_VERSION=3
|
||||
else ifeq ($(THREAD_VERSION),1.3)
|
||||
COMMONCFLAGS += -DOPENTHREAD_CONFIG_THREAD_VERSION=4
|
||||
endif
|
||||
|
||||
ifeq ($(TIME_SYNC),1)
|
||||
|
|
|
@ -163,10 +163,11 @@ void platformRadioReceive(otInstance *aInstance, uint8_t *aBuf, uint16_t aBufLen
|
|||
*
|
||||
* @param[in,out] aReadFdSet A pointer to the read file descriptors.
|
||||
* @param[in,out] aWriteFdSet A pointer to the write file descriptors.
|
||||
* @param[in,out] aTimeout A pointer to the timeout.
|
||||
* @param[in,out] aMaxFd A pointer to the max file descriptor.
|
||||
*
|
||||
*/
|
||||
void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMaxFd);
|
||||
void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, struct timeval *aTimeout, int *aMaxFd);
|
||||
|
||||
/**
|
||||
* This function performs radio driver processing.
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "platform-simulation.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <openthread/dataset.h>
|
||||
#include <openthread/link.h>
|
||||
|
@ -47,6 +48,9 @@
|
|||
// The IPv4 group for receiving packets of radio simulation
|
||||
#define OT_RADIO_GROUP "224.0.0.116"
|
||||
|
||||
#define MS_PER_S 1000
|
||||
#define US_PER_MS 1000
|
||||
|
||||
enum
|
||||
{
|
||||
IEEE802154_ACK_LENGTH = 5,
|
||||
|
@ -75,6 +79,10 @@ static uint16_t sPortOffset = 0;
|
|||
static uint16_t sPort = 0;
|
||||
#endif
|
||||
|
||||
static int8_t sEnergyScanResult = OT_RADIO_RSSI_INVALID;
|
||||
static bool sEnergyScanning = false;
|
||||
static uint32_t sEnergyScanEndTime = 0;
|
||||
|
||||
enum
|
||||
{
|
||||
SIM_RADIO_CHANNEL_MIN = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN,
|
||||
|
@ -156,6 +164,13 @@ static otMacKeyMaterial sCurrKey;
|
|||
static otMacKeyMaterial sNextKey;
|
||||
static otRadioKeyType sKeyType;
|
||||
|
||||
static int8_t GetRssi(uint16_t aChannel);
|
||||
|
||||
static bool IsTimeAfterOrEqual(uint32_t aTimeA, uint32_t aTimeB)
|
||||
{
|
||||
return (aTimeA - aTimeB) < (1U << 31);
|
||||
}
|
||||
|
||||
static void ReverseExtAddress(otExtAddress *aReversed, const otExtAddress *aOrigin)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(*aReversed); i++)
|
||||
|
@ -493,20 +508,23 @@ otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
|
|||
int8_t otPlatRadioGetRssi(otInstance *aInstance)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
assert(aInstance != NULL);
|
||||
|
||||
int8_t rssi = SIM_LOW_RSSI_SAMPLE;
|
||||
uint8_t channel = sReceiveFrame.mChannel;
|
||||
return GetRssi(sReceiveFrame.mChannel);
|
||||
}
|
||||
|
||||
static int8_t GetRssi(uint16_t aChannel)
|
||||
{
|
||||
int8_t rssi = SIM_LOW_RSSI_SAMPLE;
|
||||
uint32_t probabilityThreshold;
|
||||
|
||||
otEXPECT((SIM_RADIO_CHANNEL_MIN <= channel) && channel <= (SIM_RADIO_CHANNEL_MAX));
|
||||
otEXPECT((SIM_RADIO_CHANNEL_MIN <= aChannel) && aChannel <= (SIM_RADIO_CHANNEL_MAX));
|
||||
|
||||
// To emulate a simple interference model, we return either a high or
|
||||
// a low RSSI value with a fixed probability per each channel. The
|
||||
// probability is increased per channel by a constant.
|
||||
|
||||
probabilityThreshold = (channel - SIM_RADIO_CHANNEL_MIN) * SIM_HIGH_RSSI_PROB_INC_PER_CHANNEL;
|
||||
probabilityThreshold = (aChannel - SIM_RADIO_CHANNEL_MIN) * SIM_HIGH_RSSI_PROB_INC_PER_CHANNEL;
|
||||
|
||||
if (otRandomNonCryptoGetUint16() < (probabilityThreshold * 0xffff / 100))
|
||||
{
|
||||
|
@ -736,7 +754,7 @@ void platformRadioReceive(otInstance *aInstance, uint8_t *aBuf, uint16_t aBufLen
|
|||
radioReceive(aInstance);
|
||||
}
|
||||
#else
|
||||
void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMaxFd)
|
||||
void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, struct timeval *aTimeout, int *aMaxFd)
|
||||
{
|
||||
if (aReadFdSet != NULL && (sState != OT_RADIO_STATE_TRANSMIT || sTxWait))
|
||||
{
|
||||
|
@ -757,6 +775,25 @@ void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMax
|
|||
*aMaxFd = sTxFd;
|
||||
}
|
||||
}
|
||||
|
||||
if (sEnergyScanning)
|
||||
{
|
||||
struct timeval tv = {0, 0};
|
||||
uint32_t now = otPlatAlarmMilliGetNow();
|
||||
|
||||
if (IsTimeAfterOrEqual(sEnergyScanEndTime, now))
|
||||
{
|
||||
uint32_t remaining = sEnergyScanEndTime - now;
|
||||
|
||||
tv.tv_sec = remaining / MS_PER_S;
|
||||
tv.tv_usec = (remaining % MS_PER_S) * US_PER_MS;
|
||||
}
|
||||
|
||||
if (timercmp(&tv, aTimeout, <))
|
||||
{
|
||||
*aTimeout = tv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// no need to close in virtual time mode.
|
||||
|
@ -811,11 +848,16 @@ void platformRadioProcess(otInstance *aInstance, const fd_set *aReadFdSet, const
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (platformRadioIsTransmitPending())
|
||||
{
|
||||
radioSendMessage(aInstance);
|
||||
}
|
||||
|
||||
if (sEnergyScanning && IsTimeAfterOrEqual(otPlatAlarmMilliGetNow(), sEnergyScanEndTime))
|
||||
{
|
||||
sEnergyScanning = false;
|
||||
otPlatRadioEnergyScanDone(aInstance, sEnergyScanResult);
|
||||
}
|
||||
}
|
||||
|
||||
void radioTransmit(struct RadioMessage *aMessage, const struct otRadioFrame *aFrame)
|
||||
|
@ -982,13 +1024,22 @@ otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint1
|
|||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aScanChannel);
|
||||
OT_UNUSED_VARIABLE(aScanDuration);
|
||||
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
assert(aInstance != NULL);
|
||||
assert(aScanChannel >= SIM_RADIO_CHANNEL_MIN && aScanChannel <= SIM_RADIO_CHANNEL_MAX);
|
||||
assert(aScanDuration > 0);
|
||||
|
||||
return OT_ERROR_NOT_IMPLEMENTED;
|
||||
otEXPECT_ACTION((gRadioCaps & OT_RADIO_CAPS_ENERGY_SCAN), error = OT_ERROR_NOT_IMPLEMENTED);
|
||||
otEXPECT_ACTION(!sEnergyScanning, error = OT_ERROR_BUSY);
|
||||
|
||||
sEnergyScanResult = GetRssi(aScanChannel);
|
||||
sEnergyScanning = true;
|
||||
sEnergyScanEndTime = otPlatAlarmMilliGetNow() + aScanDuration;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
|
||||
|
|
|
@ -70,10 +70,11 @@ static void handleSignal(int aSignal)
|
|||
*/
|
||||
enum
|
||||
{
|
||||
OT_SIM_OPT_HELP = 'h',
|
||||
OT_SIM_OPT_SLEEP_TO_TX = 't',
|
||||
OT_SIM_OPT_TIME_SPEED = 's',
|
||||
OT_SIM_OPT_UNKNOWN = '?',
|
||||
OT_SIM_OPT_HELP = 'h',
|
||||
OT_SIM_OPT_ENABLE_ENERGY_SCAN = 'E',
|
||||
OT_SIM_OPT_SLEEP_TO_TX = 't',
|
||||
OT_SIM_OPT_TIME_SPEED = 's',
|
||||
OT_SIM_OPT_UNKNOWN = '?',
|
||||
};
|
||||
|
||||
static void PrintUsage(const char *aProgramName, int aExitCode)
|
||||
|
@ -82,9 +83,10 @@ static void PrintUsage(const char *aProgramName, int aExitCode)
|
|||
"Syntax:\n"
|
||||
" %s [Options] NodeId\n"
|
||||
"Options:\n"
|
||||
" -h --help Display this usage information.\n"
|
||||
" -t --sleep-to-tx Let radio support direct transition from sleep to TX with CSMA.\n"
|
||||
" -s --time-speed=val Speed up the time in simulation.\n",
|
||||
" -h --help Display this usage information.\n"
|
||||
" -E --enable-energy-scan Enable energy scan capability.\n"
|
||||
" -t --sleep-to-tx Let radio support direct transition from sleep to TX with CSMA.\n"
|
||||
" -s --time-speed=val Speed up the time in simulation.\n",
|
||||
aProgramName);
|
||||
|
||||
exit(aExitCode);
|
||||
|
@ -97,6 +99,7 @@ void otSysInit(int aArgCount, char *aArgVector[])
|
|||
|
||||
static const struct option long_options[] = {
|
||||
{"help", no_argument, 0, OT_SIM_OPT_HELP},
|
||||
{"enable-energy-scan", no_argument, 0, OT_SIM_OPT_SLEEP_TO_TX},
|
||||
{"sleep-to-tx", no_argument, 0, OT_SIM_OPT_SLEEP_TO_TX},
|
||||
{"time-speed", required_argument, 0, OT_SIM_OPT_TIME_SPEED},
|
||||
{0, 0, 0, 0},
|
||||
|
@ -112,7 +115,7 @@ void otSysInit(int aArgCount, char *aArgVector[])
|
|||
|
||||
while (true)
|
||||
{
|
||||
int c = getopt_long(aArgCount, aArgVector, "hts:", long_options, NULL);
|
||||
int c = getopt_long(aArgCount, aArgVector, "Ehts:", long_options, NULL);
|
||||
|
||||
if (c == -1)
|
||||
{
|
||||
|
@ -127,6 +130,9 @@ void otSysInit(int aArgCount, char *aArgVector[])
|
|||
case OT_SIM_OPT_HELP:
|
||||
PrintUsage(aArgVector[0], EXIT_SUCCESS);
|
||||
break;
|
||||
case OT_SIM_OPT_ENABLE_ENERGY_SCAN:
|
||||
gRadioCaps |= OT_RADIO_CAPS_ENERGY_SCAN;
|
||||
break;
|
||||
case OT_SIM_OPT_SLEEP_TO_TX:
|
||||
gRadioCaps |= OT_RADIO_CAPS_SLEEP_TO_TX;
|
||||
break;
|
||||
|
@ -197,8 +203,8 @@ void otSysProcessDrivers(otInstance *aInstance)
|
|||
FD_ZERO(&error_fds);
|
||||
|
||||
platformUartUpdateFdSet(&read_fds, &write_fds, &error_fds, &max_fd);
|
||||
platformRadioUpdateFdSet(&read_fds, &write_fds, &max_fd);
|
||||
platformAlarmUpdateTimeout(&timeout);
|
||||
platformRadioUpdateFdSet(&read_fds, &write_fds, &timeout, &max_fd);
|
||||
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
|
||||
platformTrelUpdateFdSet(&read_fds, &write_fds, &timeout, &max_fd);
|
||||
#endif
|
||||
|
|
|
@ -213,6 +213,17 @@ typedef struct otOperationalDatasetComponents
|
|||
bool mIsChannelMaskPresent : 1; ///< TRUE if Channel Mask is present, FALSE otherwise.
|
||||
} otOperationalDatasetComponents;
|
||||
|
||||
/**
|
||||
* This structure represents a Thread Dataset timestamp component.
|
||||
*
|
||||
*/
|
||||
typedef struct otTimestamp
|
||||
{
|
||||
uint64_t mSeconds;
|
||||
uint16_t mTicks;
|
||||
bool mAuthoritative;
|
||||
} otTimestamp;
|
||||
|
||||
/**
|
||||
* This structure represents an Active or Pending Operational Dataset.
|
||||
*
|
||||
|
@ -221,8 +232,8 @@ typedef struct otOperationalDatasetComponents
|
|||
*/
|
||||
typedef struct otOperationalDataset
|
||||
{
|
||||
uint64_t mActiveTimestamp; ///< Active Timestamp
|
||||
uint64_t mPendingTimestamp; ///< Pending Timestamp
|
||||
otTimestamp mActiveTimestamp; ///< Active Timestamp
|
||||
otTimestamp mPendingTimestamp; ///< Pending Timestamp
|
||||
otNetworkKey mNetworkKey; ///< Network Key
|
||||
otNetworkName mNetworkName; ///< Network Name
|
||||
otExtendedPanId mExtendedPanId; ///< Extended PAN ID
|
||||
|
|
|
@ -147,6 +147,22 @@ typedef enum
|
|||
OT_DNSSD_QUERY_TYPE_RESOLVE_HOST = 3, ///< Service type resolve hostname.
|
||||
} otDnssdQueryType;
|
||||
|
||||
/**
|
||||
* This structure contains the counters of DNS-SD server.
|
||||
*
|
||||
*/
|
||||
typedef struct otDnssdCounters
|
||||
{
|
||||
uint32_t mSuccessResponse; ///< The number of successful responses
|
||||
uint32_t mServerFailureResponse; ///< The number of server failure responses
|
||||
uint32_t mFormatErrorResponse; ///< The number of format error responses
|
||||
uint32_t mNameErrorResponse; ///< The number of name error responses
|
||||
uint32_t mNotImplementedResponse; ///< The number of 'not implemented' responses
|
||||
uint32_t mOtherResponse; ///< The number of other responses
|
||||
|
||||
uint32_t mResolvedBySrp; ///< The number of queries completely resolved by the local SRP server
|
||||
} otDnssdCounters;
|
||||
|
||||
/**
|
||||
* This function sets DNS-SD server query callbacks.
|
||||
*
|
||||
|
@ -219,6 +235,16 @@ const otDnssdQuery *otDnssdGetNextQuery(otInstance *aInstance, const otDnssdQuer
|
|||
*/
|
||||
otDnssdQueryType otDnssdGetQueryTypeAndName(const otDnssdQuery *aQuery, char (*aNameOutput)[OT_DNS_MAX_NAME_SIZE]);
|
||||
|
||||
/**
|
||||
* This function returns the counters of the DNS-SD server.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance structure.
|
||||
*
|
||||
* @returns A pointer to the counters of the DNS-SD server.
|
||||
*
|
||||
*/
|
||||
const otDnssdCounters *otDnssdGetCounters(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
|
|
@ -53,7 +53,7 @@ extern "C" {
|
|||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (207)
|
||||
#define OPENTHREAD_API_VERSION (220)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
|
|
@ -391,6 +391,10 @@ typedef struct otActiveScanResult
|
|||
unsigned int mVersion : 4; ///< Version
|
||||
bool mIsNative : 1; ///< Native Commissioner flag
|
||||
bool mDiscover : 1; ///< Result from MLE Discovery
|
||||
|
||||
// Applicable/Required only when beacon payload parsing feature
|
||||
// (`OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE`) is enabled.
|
||||
bool mIsJoinable : 1; ///< Joining Permitted flag
|
||||
} otActiveScanResult;
|
||||
|
||||
/**
|
||||
|
@ -486,7 +490,6 @@ bool otLinkIsEnergyScanInProgress(otInstance *aInstance);
|
|||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully enqueued an IEEE 802.15.4 Data Request message.
|
||||
* @retval OT_ERROR_ALREADY An IEEE 802.15.4 Data Request message is already enqueued.
|
||||
* @retval OT_ERROR_INVALID_STATE Device is not in rx-off-when-idle mode.
|
||||
* @retval OT_ERROR_NO_BUFS Insufficient message buffers available.
|
||||
*
|
||||
|
|
|
@ -236,6 +236,7 @@ typedef void (*otLinkRawEnergyScanDone)(otInstance *aInstance, int8_t aEnergySca
|
|||
* @param[in] aCallback A pointer to a function called on completion of a scanned channel.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully started scanning the channel.
|
||||
* @retval OT_ERROR_BUSY The radio is performing enery scanning.
|
||||
* @retval OT_ERROR_NOT_IMPLEMENTED The radio doesn't support energy scanning.
|
||||
* @retval OT_ERROR_INVALID_STATE If the raw link-layer isn't enabled.
|
||||
*
|
||||
|
|
|
@ -192,12 +192,18 @@ void otNetDataUnpublishDnsSrpService(otInstance *aInstance);
|
|||
*
|
||||
* Only stable entries can be published (i.e.,`aConfig.mStable` MUST be TRUE).
|
||||
*
|
||||
* A subsequent call to this method will replace a previous request for the same prefix. In particular, if the new call
|
||||
* only changes the flags (e.g., preference level) and the prefix is already added in the Network Data, the change to
|
||||
* flags is immediately reflected in the Network Data. This ensures that existing entries in the Network Data are not
|
||||
* abruptly removed. Note that a change in the preference level can potentially later cause the entry to be removed
|
||||
* from the Network Data after determining there are other nodes that are publishing the same prefix with the same or
|
||||
* higher preference.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aConfig The on-mesh prefix config to publish (MUST NOT be NULL).
|
||||
*
|
||||
* @retval OT_ERROR_NONE The on-mesh prefix is published successfully.
|
||||
* @retval OT_ERROR_INVALID_ARGS The @p aConfig is not valid (bad prefix, invalid flag combinations, or not stable).
|
||||
* @retval OT_ERROR_ALREADY An entry with the same prefix is already in the published list.
|
||||
* @retval OT_ERROR_NO_BUFS Could not allocate an entry for the new request. Publisher supports a limited number
|
||||
* of entries (shared between on-mesh prefix and external route) determined by config
|
||||
* `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES`.
|
||||
|
@ -213,12 +219,18 @@ otError otNetDataPublishOnMeshPrefix(otInstance *aInstance, const otBorderRouter
|
|||
*
|
||||
* Only stable entries can be published (i.e.,`aConfig.mStable` MUST be TRUE).
|
||||
*
|
||||
* A subsequent call to this method will replace a previous request for the same prefix. In particular, if the new call
|
||||
* only changes the flags (e.g., preference level) and the prefix is already added in the Network Data, the change to
|
||||
* flags is immediately reflected in the Network Data. This ensures that existing entries in the Network Data are not
|
||||
* abruptly removed. Note that a change in the preference level can potentially later cause the entry to be removed
|
||||
* from the Network Data after determining there are other nodes that are publishing the same prefix with the same or
|
||||
* higher preference.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aConfig The external route config to publish (MUST NOT be NULL).
|
||||
*
|
||||
* @retval OT_ERROR_NONE The external route is published successfully.
|
||||
* @retval OT_ERROR_INVALID_ARGS The @p aConfig is not valid (bad prefix, invalid flag combinations, or not stable).
|
||||
* @retval OT_ERROR_ALREADY An entry with the same prefix is already in the published list.
|
||||
* @retval OT_ERROR_NO_BUFS Could not allocate an entry for the new request. Publisher supports a limited number
|
||||
* of entries (shared between on-mesh prefix and external route) determined by config
|
||||
* `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES`.
|
||||
|
|
|
@ -857,6 +857,7 @@ int8_t otPlatRadioGetRssi(otInstance *aInstance);
|
|||
* @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully started scanning the channel.
|
||||
* @retval OT_ERROR_BUSY The radio is performing enery scanning.
|
||||
* @retval OT_ERROR_NOT_IMPLEMENTED The radio doesn't support energy scanning.
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -55,7 +55,8 @@ extern "C" {
|
|||
* This enumeration defines the keys of settings.
|
||||
*
|
||||
* Note: When adding a new settings key, if the settings corresponding to the key contains security sensitive
|
||||
* information, the developer MUST add the key to the array `kSensitiveKeys`.
|
||||
* information, the developer MUST add the key to the array `aSensitiveKeys` which is passed in
|
||||
* `otPlatSettingsInit()`.
|
||||
*
|
||||
*/
|
||||
enum
|
||||
|
@ -65,17 +66,20 @@ enum
|
|||
OT_SETTINGS_KEY_NETWORK_INFO = 0x0003, ///< Thread network information.
|
||||
OT_SETTINGS_KEY_PARENT_INFO = 0x0004, ///< Parent information.
|
||||
OT_SETTINGS_KEY_CHILD_INFO = 0x0005, ///< Child information.
|
||||
OT_SETTINGS_KEY_RESERVED = 0x0006, ///< Reserved (previously auto-start).
|
||||
OT_SETTINGS_KEY_SLAAC_IID_SECRET_KEY = 0x0007, ///< SLAAC key to generate semantically opaque IID.
|
||||
OT_SETTINGS_KEY_DAD_INFO = 0x0008, ///< Duplicate Address Detection (DAD) information.
|
||||
OT_SETTINGS_KEY_LEGACY_OMR_PREFIX = 0x0009, ///< Reserved. Legacy Off-mesh routable (OMR) prefix.
|
||||
OT_SETTINGS_KEY_ON_LINK_PREFIX = 0x000a, ///< On-link prefix for infrastructure link.
|
||||
OT_SETTINGS_KEY_SRP_ECDSA_KEY = 0x000b, ///< SRP client ECDSA public/private key pair.
|
||||
OT_SETTINGS_KEY_SRP_CLIENT_INFO = 0x000c, ///< The SRP client info (selected SRP server address).
|
||||
OT_SETTINGS_KEY_SRP_SERVER_INFO = 0x000d, ///< The SRP server info (UDP port).
|
||||
OT_SETTINGS_KEY_LEGACY_NAT64_PREFIX = 0x000e, ///< Reserved. Legacy NAT64 prefix.
|
||||
OT_SETTINGS_KEY_BR_ULA_PREFIX = 0x000f, ///< BR ULA prefix.
|
||||
|
||||
// Deprecated and reserved key values:
|
||||
//
|
||||
// 0x0006 previously auto-start.
|
||||
// 0x0009 previously OMR prefix.
|
||||
// 0x000a previously on-link prefix.
|
||||
// 0x000e previously NAT64 prefix.
|
||||
|
||||
// Keys in range 0x8000-0xffff are reserved for vendor-specific use.
|
||||
OT_SETTINGS_KEY_VENDOR_RESERVED_MIN = 0x8000,
|
||||
OT_SETTINGS_KEY_VENDOR_RESERVED_MAX = 0xffff,
|
||||
|
@ -104,80 +108,100 @@ void otPlatSettingsInit(otInstance *aInstance, const uint16_t *aSensitiveKeys, u
|
|||
*/
|
||||
void otPlatSettingsDeinit(otInstance *aInstance);
|
||||
|
||||
/// Fetches the value of a setting
|
||||
/** This function fetches the value of the setting identified
|
||||
* by aKey and write it to the memory pointed to by aValue.
|
||||
* It then writes the length to the integer pointed to by
|
||||
* aValueLength. The initial value of aValueLength is the
|
||||
* maximum number of bytes to be written to aValue.
|
||||
/**
|
||||
* Fetches the value of a setting.
|
||||
*
|
||||
* This function can be used to check for the existence of
|
||||
* a key without fetching the value by setting aValue and
|
||||
* aValueLength to NULL. You can also check the length of
|
||||
* the setting without fetching it by setting only aValue
|
||||
* to NULL.
|
||||
* This function fetches the value of the setting identified
|
||||
* by @p aKey and write it to the memory pointed to by aValue.
|
||||
* It then writes the length to the integer pointed to by
|
||||
* @p aValueLength. The initial value of @p aValueLength is the
|
||||
* maximum number of bytes to be written to @p aValue.
|
||||
*
|
||||
* Note that the underlying storage implementation is not
|
||||
* required to maintain the order of settings with multiple
|
||||
* values. The order of such values MAY change after ANY
|
||||
* write operation to the store.
|
||||
* This function can be used to check for the existence of
|
||||
* a key without fetching the value by setting @p aValue and
|
||||
* @p aValueLength to NULL. You can also check the length of
|
||||
* the setting without fetching it by setting only aValue
|
||||
* to NULL.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance structure.
|
||||
* @param[in] aKey The key associated with the requested setting.
|
||||
* @param[in] aIndex The index of the specific item to get.
|
||||
* @param[out] aValue A pointer to where the value of the setting should be written. May be set to NULL if
|
||||
* just testing for the presence or length of a setting.
|
||||
* @param[in,out] aValueLength A pointer to the length of the value. When called, this pointer should point to an
|
||||
* integer containing the maximum value size that can be written to aValue. At return,
|
||||
* the actual length of the setting is written. This may be set to NULL if performing
|
||||
* a presence check.
|
||||
* Note that the underlying storage implementation is not
|
||||
* required to maintain the order of settings with multiple
|
||||
* values. The order of such values MAY change after ANY
|
||||
* write operation to the store.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The given setting was found and fetched successfully.
|
||||
* @retval OT_ERROR_NOT_FOUND The given setting was not found in the setting store.
|
||||
* @retval OT_ERROR_NOT_IMPLEMENTED This function is not implemented on this platform.
|
||||
* @param[in] aInstance The OpenThread instance structure.
|
||||
* @param[in] aKey The key associated with the requested setting.
|
||||
* @param[in] aIndex The index of the specific item to get.
|
||||
* @param[out] aValue A pointer to where the value of the setting should be written. May be set to NULL if
|
||||
* just testing for the presence or length of a setting.
|
||||
* @param[in,out] aValueLength A pointer to the length of the value. When called, this pointer should point to an
|
||||
* integer containing the maximum value size that can be written to @p aValue. At return,
|
||||
* the actual length of the setting is written. This may be set to NULL if performing
|
||||
* a presence check.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The given setting was found and fetched successfully.
|
||||
* @retval OT_ERROR_NOT_FOUND The given setting was not found in the setting store.
|
||||
* @retval OT_ERROR_NOT_IMPLEMENTED This function is not implemented on this platform.
|
||||
*/
|
||||
otError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength);
|
||||
|
||||
/// Sets or replaces the value of a setting
|
||||
/** This function sets or replaces the value of a setting
|
||||
* identified by aKey. If there was more than one
|
||||
* value previously associated with aKey, then they are
|
||||
* all deleted and replaced with this single entry.
|
||||
/**
|
||||
* Sets or replaces the value of a setting.
|
||||
*
|
||||
* Calling this function successfully may cause unrelated
|
||||
* settings with multiple values to be reordered.
|
||||
* This function sets or replaces the value of a setting
|
||||
* identified by @p aKey.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance structure.
|
||||
* @param[in] aKey The key associated with the setting to change.
|
||||
* @param[in] aValue A pointer to where the new value of the setting should be read from. MUST NOT be NULL if
|
||||
* aValueLength is non-zero.
|
||||
* @param[in] aValueLength The length of the data pointed to by aValue. May be zero.
|
||||
* Calling this function successfully may cause unrelated
|
||||
* settings with multiple values to be reordered.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The given setting was changed or staged.
|
||||
* @retval OT_ERROR_NOT_IMPLEMENTED This function is not implemented on this platform.
|
||||
* @retval OT_ERROR_NO_BUFS No space remaining to store the given setting.
|
||||
* OpenThread stack guarantees to use `otPlatSettingsSet()`
|
||||
* method for a @p aKey that was either previously set using
|
||||
* `otPlatSettingsSet()` (i.e., contains a single value) or
|
||||
* is empty and/or fully deleted (contains no value).
|
||||
*
|
||||
* Platform layer can rely and use this fact for optimizing
|
||||
* its implementation.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance structure.
|
||||
* @param[in] aKey The key associated with the setting to change.
|
||||
* @param[in] aValue A pointer to where the new value of the setting should be read from. MUST NOT be NULL if
|
||||
* @p aValueLength is non-zero.
|
||||
* @param[in] aValueLength The length of the data pointed to by aValue. May be zero.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The given setting was changed or staged.
|
||||
* @retval OT_ERROR_NOT_IMPLEMENTED This function is not implemented on this platform.
|
||||
* @retval OT_ERROR_NO_BUFS No space remaining to store the given setting.
|
||||
*/
|
||||
otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
|
||||
|
||||
/// Adds a value to a setting
|
||||
/** This function adds the value to a setting
|
||||
* identified by aKey, without replacing any existing
|
||||
* values.
|
||||
/**
|
||||
* Adds a value to a setting.
|
||||
*
|
||||
* Note that the underlying implementation is not required
|
||||
* to maintain the order of the items associated with a
|
||||
* specific key. The added value may be added to the end,
|
||||
* the beginning, or even somewhere in the middle. The order
|
||||
* of any pre-existing values may also change.
|
||||
* This function adds the value to a setting
|
||||
* identified by @p aKey, without replacing any existing
|
||||
* values.
|
||||
*
|
||||
* Calling this function successfully may cause unrelated
|
||||
* settings with multiple values to be reordered.
|
||||
* Note that the underlying implementation is not required
|
||||
* to maintain the order of the items associated with a
|
||||
* specific key. The added value may be added to the end,
|
||||
* the beginning, or even somewhere in the middle. The order
|
||||
* of any pre-existing values may also change.
|
||||
*
|
||||
* Calling this function successfully may cause unrelated
|
||||
* settings with multiple values to be reordered.
|
||||
*
|
||||
* OpenThread stack guarantees to use `otPlatSettingsAdd()`
|
||||
* method for a @p aKey that was either previously managed by
|
||||
* `otPlatSettingsAdd()` (i.e., contains one or more items) or
|
||||
* is empty and/or fully deleted (contains no value).
|
||||
*
|
||||
* Platform layer can rely and use this fact for optimizing
|
||||
* its implementation.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance structure.
|
||||
* @param[in] aKey The key associated with the setting to change.
|
||||
* @param[in] aValue A pointer to where the new value of the setting should be read from. MUST NOT be NULL
|
||||
* if aValueLength is non-zero.
|
||||
* @param[in] aValueLength The length of the data pointed to by aValue. May be zero.
|
||||
* if @p aValueLength is non-zero.
|
||||
* @param[in] aValueLength The length of the data pointed to by @p aValue. May be zero.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The given setting was added or staged to be added.
|
||||
* @retval OT_ERROR_NOT_IMPLEMENTED This function is not implemented on this platform.
|
||||
|
@ -185,29 +209,34 @@ otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *a
|
|||
*/
|
||||
otError otPlatSettingsAdd(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
|
||||
|
||||
/// Removes a setting from the setting store
|
||||
/** This function deletes a specific value from the
|
||||
* setting identified by aKey from the settings store.
|
||||
/**
|
||||
* Removes a setting from the setting store.
|
||||
*
|
||||
* Note that the underlying implementation is not required
|
||||
* to maintain the order of the items associated with a
|
||||
* specific key.
|
||||
* This function deletes a specific value from the
|
||||
* setting identified by aKey from the settings store.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance structure.
|
||||
* @param[in] aKey The key associated with the requested setting.
|
||||
* @param[in] aIndex The index of the value to be removed. If set to -1, all values for this aKey will be removed.
|
||||
* Note that the underlying implementation is not required
|
||||
* to maintain the order of the items associated with a
|
||||
* specific key.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The given key and index was found and removed successfully.
|
||||
* @retval OT_ERROR_NOT_FOUND The given key or index was not found in the setting store.
|
||||
* @retval OT_ERROR_NOT_IMPLEMENTED This function is not implemented on this platform.
|
||||
* @param[in] aInstance The OpenThread instance structure.
|
||||
* @param[in] aKey The key associated with the requested setting.
|
||||
* @param[in] aIndex The index of the value to be removed. If set to -1, all values for this @p aKey will be
|
||||
* removed.
|
||||
*
|
||||
* @retval OT_ERROR_NONE The given key and index was found and removed successfully.
|
||||
* @retval OT_ERROR_NOT_FOUND The given key or index was not found in the setting store.
|
||||
* @retval OT_ERROR_NOT_IMPLEMENTED This function is not implemented on this platform.
|
||||
*/
|
||||
otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex);
|
||||
|
||||
/// Removes all settings from the setting store
|
||||
/** This function deletes all settings from the settings
|
||||
* store, resetting it to its initial factory state.
|
||||
/**
|
||||
* Removes all settings from the setting store.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance structure.
|
||||
* This function deletes all settings from the settings
|
||||
* store, resetting it to its initial factory state.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance structure.
|
||||
*/
|
||||
void otPlatSettingsWipe(otInstance *aInstance);
|
||||
|
||||
|
|
|
@ -75,8 +75,9 @@ typedef enum
|
|||
typedef struct otSrpClientHostInfo
|
||||
{
|
||||
const char * mName; ///< Host name (label) string (NULL if not yet set).
|
||||
const otIp6Address * mAddresses; ///< Pointer to an array of host IPv6 addresses (NULL if not yet set).
|
||||
const otIp6Address * mAddresses; ///< Array of host IPv6 addresses (NULL if not set or auto address is enabled).
|
||||
uint8_t mNumAddresses; ///< Number of IPv6 addresses in `mAddresses` array.
|
||||
bool mAutoAddress; ///< Indicates whether auto address mode is enabled or not.
|
||||
otSrpClientItemState mState; ///< Host info state.
|
||||
} otSrpClientHostInfo;
|
||||
|
||||
|
@ -315,6 +316,34 @@ void otSrpClientDisableAutoStartMode(otInstance *aInstance);
|
|||
*/
|
||||
bool otSrpClientIsAutoStartModeEnabled(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function gets the TTL value in every record included in SRP update requests.
|
||||
*
|
||||
* Note that this is the TTL requested by the SRP client. The server may choose to accept a different TTL.
|
||||
*
|
||||
* By default, the TTL will equal the lease interval. Passing 0 or a value larger than the lease interval via
|
||||
* `otSrpClientSetTtl()` will also cause the TTL to equal the lease interval.
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
*
|
||||
* @returns The TTL (in seconds).
|
||||
*
|
||||
*/
|
||||
uint32_t otSrpClientGetTtl(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function sets the TTL value in every record included in SRP update requests.
|
||||
*
|
||||
* Changing the TTL does not impact the TTL of already registered services/host-info.
|
||||
* It only affects future SRP update messages (i.e., adding new services and/or refreshes of the existing services).
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
* @param[in] aTtl The TTL (in seconds). If value is zero or greater than lease interval, the TTL is set to the
|
||||
* lease interval.
|
||||
*
|
||||
*/
|
||||
void otSrpClientSetTtl(otInstance *aInstance, uint32_t aTtl);
|
||||
|
||||
/**
|
||||
* This function gets the lease interval used in SRP update requests.
|
||||
*
|
||||
|
@ -400,6 +429,27 @@ const otSrpClientHostInfo *otSrpClientGetHostInfo(otInstance *aInstance);
|
|||
*/
|
||||
otError otSrpClientSetHostName(otInstance *aInstance, const char *aName);
|
||||
|
||||
/**
|
||||
* This function enables auto host address mode.
|
||||
*
|
||||
* When enabled host IPv6 addresses are automatically set by SRP client using all the unicast addresses on Thread netif
|
||||
* excluding all link-local and mesh-local addresses. If there is no valid address, then Mesh Local EID address is
|
||||
* added. The SRP client will automatically re-register when/if addresses on Thread netif are updated (new addresses
|
||||
* are added or existing addresses are removed).
|
||||
*
|
||||
* The auto host address mode can be enabled before start or during operation of SRP client except when the host info
|
||||
* is being removed (client is busy handling a remove request from an call to `otSrpClientRemoveHostAndServices()` and
|
||||
* host info still being in either `STATE_TO_REMOVE` or `STATE_REMOVING` states).
|
||||
*
|
||||
* After auto host address mode is enabled, it can be disabled by a call to `otSrpClientSetHostAddresses()` which
|
||||
* then explicitly sets the host addresses.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully enabled auto host address mode.
|
||||
* @retval OT_ERROR_INVALID_STATE Host is being removed and therefore cannot enable auto host address mode.
|
||||
*
|
||||
*/
|
||||
otError otSrpClientEnableAutoHostAddress(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function sets/updates the list of host IPv6 address.
|
||||
*
|
||||
|
@ -414,6 +464,9 @@ otError otSrpClientSetHostName(otInstance *aInstance, const char *aName);
|
|||
* After a successful call to this function, `otSrpClientCallback` will be called to report the status of the address
|
||||
* registration with SRP server.
|
||||
*
|
||||
* Calling this function disables auto host address mode if it was previously enabled from a successful call to
|
||||
* `otSrpClientEnableAutoHostAddress()`.
|
||||
*
|
||||
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||
* @param[in] aIp6Addresses A pointer to the an array containing the host IPv6 addresses.
|
||||
* @param[in] aNumAddresses The number of addresses in the @p aIp6Addresses array.
|
||||
|
|
|
@ -155,6 +155,16 @@ typedef enum otSrpServerAddressMode
|
|||
OT_SRP_SERVER_ADDRESS_MODE_ANYCAST = 1, ///< Anycast address mode.
|
||||
} otSrpServerAddressMode;
|
||||
|
||||
/**
|
||||
* This structure includes SRP server TTL configurations.
|
||||
*
|
||||
*/
|
||||
typedef struct otSrpServerTtlConfig
|
||||
{
|
||||
uint32_t mMinTtl; ///< The minimum TTL in seconds.
|
||||
uint32_t mMaxTtl; ///< The maximum TTL in seconds.
|
||||
} otSrpServerTtlConfig;
|
||||
|
||||
/**
|
||||
* This structure includes SRP server LEASE and KEY-LEASE configurations.
|
||||
*
|
||||
|
@ -167,6 +177,32 @@ typedef struct otSrpServerLeaseConfig
|
|||
uint32_t mMaxKeyLease; ///< The maximum KEY-LEASE interval in seconds.
|
||||
} otSrpServerLeaseConfig;
|
||||
|
||||
/**
|
||||
* This structure includes SRP server lease information of a host/service.
|
||||
*
|
||||
*/
|
||||
typedef struct otSrpServerLeaseInfo
|
||||
{
|
||||
uint32_t mLease; ///< The lease time of a host/service in milliseconds.
|
||||
uint32_t mKeyLease; ///< The key lease time of a host/service in milliseconds.
|
||||
uint32_t mRemainingLease; ///< The remaining lease time of the host/service in milliseconds.
|
||||
uint32_t mRemainingKeyLease; ///< The remaining key lease time of a host/service in milliseconds.
|
||||
} otSrpServerLeaseInfo;
|
||||
|
||||
/**
|
||||
* This structure includes the statistics of SRP server responses.
|
||||
*
|
||||
*/
|
||||
typedef struct otSrpServerResponseCounters
|
||||
{
|
||||
uint32_t mSuccess; ///< The number of successful responses.
|
||||
uint32_t mServerFailure; ///< The number of server failure responses.
|
||||
uint32_t mFormatError; ///< The number of format error responses.
|
||||
uint32_t mNameExists; ///< The number of 'name exists' responses.
|
||||
uint32_t mRefused; ///< The number of refused responses.
|
||||
uint32_t mOther; ///< The number of other responses.
|
||||
} otSrpServerResponseCounters;
|
||||
|
||||
/**
|
||||
* This function returns the domain authorized to the SRP server.
|
||||
*
|
||||
|
@ -207,6 +243,16 @@ otError otSrpServerSetDomain(otInstance *aInstance, const char *aDomain);
|
|||
*/
|
||||
otSrpServerState otSrpServerGetState(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function returns the port the SRP server is listening to.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @returns The port of the SRP server. It returns 0 if the server is not running.
|
||||
*
|
||||
*/
|
||||
uint16_t otSrpServerGetPort(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function returns the address mode being used by the SRP server.
|
||||
*
|
||||
|
@ -262,6 +308,30 @@ otError otSrpServerSetAnycastModeSequenceNumber(otInstance *aInstance, uint8_t a
|
|||
*/
|
||||
void otSrpServerSetEnabled(otInstance *aInstance, bool aEnabled);
|
||||
|
||||
/**
|
||||
* This function returns SRP server TTL configuration.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[out] aTtlConfig A pointer to an `otSrpServerTtlConfig` instance.
|
||||
*
|
||||
*/
|
||||
void otSrpServerGetTtlConfig(otInstance *aInstance, otSrpServerTtlConfig *aTtlConfig);
|
||||
|
||||
/**
|
||||
* This function sets SRP server TTL configuration.
|
||||
*
|
||||
* The granted TTL will always be no greater than the max lease interval configured via `otSrpServerSetLeaseConfig()`,
|
||||
* regardless of the minimum and maximum TTL configuration.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aTtlConfig A pointer to an `otSrpServerTtlConfig` instance.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully set the TTL configuration.
|
||||
* @retval OT_ERROR_INVALID_ARGS The TTL configuration is not valid.
|
||||
*
|
||||
*/
|
||||
otError otSrpServerSetTtlConfig(otInstance *aInstance, const otSrpServerTtlConfig *aTtlConfig);
|
||||
|
||||
/**
|
||||
* This function returns SRP server LEASE and KEY-LEASE configurations.
|
||||
*
|
||||
|
@ -365,6 +435,16 @@ void otSrpServerHandleServiceUpdateResult(otInstance *aInstance, otSrpServerServ
|
|||
*/
|
||||
const otSrpServerHost *otSrpServerGetNextHost(otInstance *aInstance, const otSrpServerHost *aHost);
|
||||
|
||||
/**
|
||||
* This function returns the response counters of the SRP server.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @returns A pointer to the response counters of the SRP server.
|
||||
*
|
||||
*/
|
||||
const otSrpServerResponseCounters *otSrpServerGetResponseCounters(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This function tells if the SRP service host has been deleted.
|
||||
*
|
||||
|
@ -399,6 +479,15 @@ const char *otSrpServerHostGetFullName(const otSrpServerHost *aHost);
|
|||
*/
|
||||
const otIp6Address *otSrpServerHostGetAddresses(const otSrpServerHost *aHost, uint8_t *aAddressesNum);
|
||||
|
||||
/**
|
||||
* This function returns the LEASE and KEY-LEASE information of a given host.
|
||||
*
|
||||
* @param[in] aHost A pointer to the SRP server host.
|
||||
* @param[out] aLeaseInfo A pointer to where to output the LEASE and KEY-LEASE information.
|
||||
*
|
||||
*/
|
||||
void otSrpServerHostGetLeaseInfo(const otSrpServerHost *aHost, otSrpServerLeaseInfo *aLeaseInfo);
|
||||
|
||||
/**
|
||||
* This function returns the next service (excluding any sub-type services) of given host.
|
||||
*
|
||||
|
@ -562,6 +651,16 @@ uint16_t otSrpServerServiceGetWeight(const otSrpServerService *aService);
|
|||
*/
|
||||
uint16_t otSrpServerServiceGetPriority(const otSrpServerService *aService);
|
||||
|
||||
/**
|
||||
* This function returns the TTL of the service instance.
|
||||
*
|
||||
* @param[in] aService A pointer to the SRP service.
|
||||
*
|
||||
* @returns The TTL of the service instance..
|
||||
*
|
||||
*/
|
||||
uint32_t otSrpServerServiceGetTtl(const otSrpServerService *aService);
|
||||
|
||||
/**
|
||||
* This function returns the TXT record data of the service instance.
|
||||
*
|
||||
|
@ -583,6 +682,14 @@ const uint8_t *otSrpServerServiceGetTxtData(const otSrpServerService *aService,
|
|||
*/
|
||||
const otSrpServerHost *otSrpServerServiceGetHost(const otSrpServerService *aService);
|
||||
|
||||
/**
|
||||
* This function returns the LEASE and KEY-LEASE information of a given service.
|
||||
*
|
||||
* @param[in] aService A pointer to the SRP server service.
|
||||
* @param[out] aLeaseInfo A pointer to where to output the LEASE and KEY-LEASE information.
|
||||
*
|
||||
*/
|
||||
void otSrpServerServiceGetLeaseInfo(const otSrpServerService *aService, otSrpServerLeaseInfo *aLeaseInfo);
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
|
|
@ -194,11 +194,22 @@ typedef struct otThreadParentResponseInfo
|
|||
bool mIsAttached; ///< Is the node receiving parent response attached
|
||||
} otThreadParentResponseInfo;
|
||||
|
||||
/**
|
||||
* This callback informs the application that the detaching process has finished.
|
||||
*
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*
|
||||
*/
|
||||
typedef void (*otDetachGracefullyCallback)(void *aContext);
|
||||
|
||||
/**
|
||||
* This function starts Thread protocol operation.
|
||||
*
|
||||
* The interface must be up when calling this function.
|
||||
*
|
||||
* Calling this function with @p aEnabled set to FALSE stops any ongoing processes of detaching started by
|
||||
* otThreadDetachGracefully(). Its callback will be called.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aEnabled TRUE if Thread is enabled, FALSE otherwise.
|
||||
*
|
||||
|
@ -1009,6 +1020,21 @@ otError otThreadSendProactiveBackboneNotification(otInstance * aIns
|
|||
otIp6InterfaceIdentifier *aMlIid,
|
||||
uint32_t aTimeSinceLastTransaction);
|
||||
|
||||
/**
|
||||
* This function notifies other nodes in the network (if any) and then stops Thread protocol operation.
|
||||
*
|
||||
* It sends an Address Release if it's a router, or sets its child timeout to 0 if it's a child.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aCallback A pointer to a function that is called upon finishing detaching.
|
||||
* @param[in] aContext A pointer to callback application-specific context.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully started detaching.
|
||||
* @retval OT_ERROR_BUSY Detaching is already in progress.
|
||||
*
|
||||
*/
|
||||
otError otThreadDetachGracefully(otInstance *aInstance, otDetachGracefullyCallback aCallback, void *aContext);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
|
|
@ -43,7 +43,7 @@ build_cc2538()
|
|||
"DNS_CLIENT=1"
|
||||
"JOINER=1"
|
||||
"SLAAC=1"
|
||||
# cc2538 does not have enough resources to support Thread 1.2
|
||||
# cc2538 does not have enough resources to support Thread 1.3
|
||||
"THREAD_VERSION=1.1"
|
||||
)
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ reset_source()
|
|||
build_cc2538()
|
||||
{
|
||||
local options=(
|
||||
# cc2538 does not have enough resources to support Thread 1.2
|
||||
# cc2538 does not have enough resources to support Thread 1.3
|
||||
"-DOT_THREAD_VERSION=1.1"
|
||||
)
|
||||
|
||||
|
|
|
@ -43,10 +43,10 @@ main()
|
|||
ninja -C gn-out
|
||||
test -f gn-out/obj/src/core/libopenthread-ftd.a
|
||||
|
||||
# Check GN build for OT1.2
|
||||
# Check GN build for OT1.3
|
||||
rm gn-out -r || true
|
||||
mkdir gn-out
|
||||
echo 'openthread_config_thread_version = "1.2"' >gn-out/args.gn
|
||||
echo 'openthread_config_thread_version = "1.3"' >gn-out/args.gn
|
||||
gn gen --check gn-out
|
||||
gn args gn-out --list
|
||||
ninja -C gn-out
|
||||
|
|
|
@ -89,9 +89,11 @@ build_all_features()
|
|||
"-DOPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_MAC_OUTGOING_BEACON_PAYLOAD_ENABLE=1"
|
||||
)
|
||||
|
||||
local options_1_2=(
|
||||
local options_1_3=(
|
||||
"-DOPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE=1"
|
||||
"-DOPENTHREAD_CONFIG_DUA_ENABLE=1"
|
||||
|
@ -108,15 +110,15 @@ build_all_features()
|
|||
reset_source
|
||||
make -f examples/Makefile-simulation THREAD_VERSION=1.1 FULL_LOGS=1
|
||||
|
||||
# Build Thread 1.2 with full features and logs
|
||||
export CPPFLAGS="${options[*]} ${options_1_2[*]} -DOPENTHREAD_CONFIG_LOG_OUTPUT=OT_LOG_OUTPUT_NONE"
|
||||
# Build Thread 1.3 with full features and logs
|
||||
export CPPFLAGS="${options[*]} ${options_1_3[*]} -DOPENTHREAD_CONFIG_LOG_OUTPUT=OT_LOG_OUTPUT_NONE"
|
||||
reset_source
|
||||
make -f examples/Makefile-simulation THREAD_VERSION=1.2
|
||||
make -f examples/Makefile-simulation THREAD_VERSION=1.3
|
||||
|
||||
# Build Thread 1.2 with full features and full logs
|
||||
export CPPFLAGS="${options[*]} ${options_1_2[*]}"
|
||||
# Build Thread 1.3 with full features and full logs
|
||||
export CPPFLAGS="${options[*]} ${options_1_3[*]}"
|
||||
reset_source
|
||||
make -f examples/Makefile-simulation THREAD_VERSION=1.2 FULL_LOGS=1
|
||||
make -f examples/Makefile-simulation THREAD_VERSION=1.3 FULL_LOGS=1
|
||||
|
||||
# Build Thread 1.1 with ASSERT disabled
|
||||
export CPPFLAGS="${options[*]} -DOPENTHREAD_CONFIG_ASSERT_ENABLE=0"
|
||||
|
|
|
@ -53,7 +53,7 @@ build_all_features()
|
|||
-DOT_FTD=OFF \
|
||||
-DOT_MTD=OFF
|
||||
|
||||
# Thread 1.2 options
|
||||
# Thread 1.3 options
|
||||
local options=(
|
||||
"-DOT_BACKBONE_ROUTER=ON"
|
||||
"-DOT_BORDER_ROUTING=ON"
|
||||
|
@ -61,18 +61,18 @@ build_all_features()
|
|||
"-DOT_MLR=ON"
|
||||
"-DOT_OTNS=ON"
|
||||
"-DOT_SIMULATION_VIRTUAL_TIME=ON"
|
||||
"-DOT_THREAD_VERSION=1.2"
|
||||
"-DOT_THREAD_VERSION=1.3"
|
||||
)
|
||||
|
||||
# Build Thread 1.2 with full features
|
||||
# Build Thread 1.3 with full features
|
||||
reset_source
|
||||
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_DUA=ON
|
||||
|
||||
# Build Thread 1.2 Backbone Router without DUA ND Proxying
|
||||
# Build Thread 1.3 Backbone Router without DUA ND Proxying
|
||||
reset_source
|
||||
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_BACKBONE_ROUTER_DUA_NDPROXYING=OFF
|
||||
|
||||
# Build Thread 1.2 Backbone Router without Multicast Routing
|
||||
# Build Thread 1.3 Backbone Router without Multicast Routing
|
||||
reset_source
|
||||
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_BACKBONE_ROUTER_MULTICAST_ROUTING=OFF
|
||||
|
||||
|
@ -82,11 +82,11 @@ build_all_features()
|
|||
-DOT_THREAD_VERSION=1.1 \
|
||||
-DOT_VENDOR_EXTENSION=../../src/core/common/extension_example.cpp
|
||||
|
||||
# Build Thread 1.2 with no additional features
|
||||
# Build Thread 1.3 with no additional features
|
||||
reset_source
|
||||
"$(dirname "$0")"/cmake-build simulation -DOT_THREAD_VERSION=1.2
|
||||
"$(dirname "$0")"/cmake-build simulation -DOT_THREAD_VERSION=1.3
|
||||
|
||||
# Build Thread 1.2 with full features and OT_ASSERT=OFF
|
||||
# Build Thread 1.3 with full features and OT_ASSERT=OFF
|
||||
reset_source
|
||||
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_DUA=ON -DOT_ASSERT=OFF
|
||||
|
||||
|
|
|
@ -151,9 +151,9 @@ size_nrf52840_version()
|
|||
|
||||
local thread_version=$1
|
||||
|
||||
if [[ ${thread_version} == "1.2" ]]; then
|
||||
if [[ ${thread_version} != "1.1" ]]; then
|
||||
options+=(
|
||||
"-DOT_THREAD_VERSION=1.2"
|
||||
"-DOT_THREAD_VERSION=1.3"
|
||||
"-DOT_BACKBONE_ROUTER=ON"
|
||||
"-DOT_DUA=ON"
|
||||
"-DOT_MLR=ON"
|
||||
|
@ -243,7 +243,7 @@ size_nrf52840()
|
|||
"${reporter}" init OpenThread
|
||||
|
||||
size_nrf52840_version 1.1
|
||||
size_nrf52840_version 1.2
|
||||
size_nrf52840_version 1.3
|
||||
|
||||
"${reporter}" post
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ readonly OT_CLANG_TIDY_BUILD_OPTS=(
|
|||
'-DOT_SNTP_CLIENT=ON'
|
||||
'-DOT_SRP_CLIENT=ON'
|
||||
'-DOT_SRP_SERVER=ON'
|
||||
'-DOT_THREAD_VERSION=1.2'
|
||||
'-DOT_THREAD_VERSION=1.3'
|
||||
'-DOT_TREL=ON'
|
||||
'-DOT_COVERAGE=ON'
|
||||
'-DOT_LOG_LEVEL_DYNAMIC=ON'
|
||||
|
@ -177,7 +177,7 @@ do_clang_tidy_fix()
|
|||
|
||||
(mkdir -p ./build/cmake-tidy \
|
||||
&& cd ./build/cmake-tidy \
|
||||
&& THREAD_VERSION=1.2 cmake "${OT_CLANG_TIDY_BUILD_OPTS[@]}" ../.. \
|
||||
&& THREAD_VERSION=1.3 cmake "${OT_CLANG_TIDY_BUILD_OPTS[@]}" ../.. \
|
||||
&& ../../script/clang-tidy -header-filter='.*' -checks="${OT_CLANG_TIDY_CHECKS}" -j"$OT_BUILD_JOBS" "${OT_CLANG_TIDY_FIX_DIRS[@]}" -fix)
|
||||
}
|
||||
|
||||
|
@ -190,7 +190,7 @@ do_clang_tidy_check()
|
|||
(
|
||||
mkdir -p ./build/cmake-tidy \
|
||||
&& cd ./build/cmake-tidy \
|
||||
&& THREAD_VERSION=1.2 cmake "${OT_CLANG_TIDY_BUILD_OPTS[@]}" ../.. \
|
||||
&& THREAD_VERSION=1.3 cmake "${OT_CLANG_TIDY_BUILD_OPTS[@]}" ../.. \
|
||||
&& ../../script/clang-tidy -header-filter='.*' -checks="${OT_CLANG_TIDY_CHECKS}" -j"$OT_BUILD_JOBS" "${OT_CLANG_TIDY_FIX_DIRS[@]}" \
|
||||
| grep -v -E "third_party" >output.txt
|
||||
if grep -q "warning: \|error: " output.txt; then
|
||||
|
|
42
script/test
42
script/test
|
@ -42,7 +42,7 @@ readonly OT_COLOR_NONE='\033[0m'
|
|||
|
||||
readonly OT_NODE_TYPE="${OT_NODE_TYPE:-cli}"
|
||||
readonly OT_NATIVE_IP="${OT_NATIVE_IP:-0}"
|
||||
readonly THREAD_VERSION="${THREAD_VERSION:-1.2}"
|
||||
readonly THREAD_VERSION="${THREAD_VERSION:-1.3}"
|
||||
readonly INTER_OP="${INTER_OP:-0}"
|
||||
readonly VERBOSE="${VERBOSE:-0}"
|
||||
readonly BORDER_ROUTING="${BORDER_ROUTING:-1}"
|
||||
|
@ -81,7 +81,7 @@ build_simulation()
|
|||
options+=("-DOT_FULL_LOGS=ON")
|
||||
fi
|
||||
|
||||
if [[ ${version} == "1.2" ]]; then
|
||||
if [[ ${version} != "1.1" ]]; then
|
||||
options+=("-DOT_DUA=ON")
|
||||
options+=("-DOT_MLR=ON")
|
||||
fi
|
||||
|
@ -90,7 +90,7 @@ build_simulation()
|
|||
options+=("-DOT_SIMULATION_VIRTUAL_TIME=ON")
|
||||
fi
|
||||
|
||||
if [[ ${version} == "1.2" ]]; then
|
||||
if [[ ${version} != "1.1" ]]; then
|
||||
options+=("-DOT_CSL_RECEIVER=ON")
|
||||
options+=("-DOT_LINK_METRICS_INITIATOR=ON")
|
||||
options+=("-DOT_LINK_METRICS_SUBJECT=ON")
|
||||
|
@ -106,7 +106,7 @@ build_simulation()
|
|||
OT_CMAKE_NINJA_TARGET=ot-rcp OT_CMAKE_BUILD_DIR="${OT_BUILDDIR}/openthread-simulation-${version}" "${OT_SRCDIR}"/script/cmake-build simulation "${options[@]}" "-DOT_SIMULATION_VIRTUAL_TIME_UART=ON"
|
||||
fi
|
||||
|
||||
if [[ ${version} == "1.2" && ${INTER_OP_BBR} == 1 ]]; then
|
||||
if [[ ${version} != "1.1" && ${INTER_OP_BBR} == 1 ]]; then
|
||||
|
||||
options+=("-DOT_BACKBONE_ROUTER=ON")
|
||||
|
||||
|
@ -124,7 +124,7 @@ build_posix()
|
|||
local version="$1"
|
||||
local options=("-DOT_MESSAGE_USE_HEAP=ON" "-DOT_THREAD_VERSION=${version}" "-DBUILD_TESTING=ON")
|
||||
|
||||
if [[ ${version} == "1.2" ]]; then
|
||||
if [[ ${version} != "1.1" ]]; then
|
||||
options+=("-DOT_DUA=ON")
|
||||
options+=("-DOT_MLR=ON")
|
||||
fi
|
||||
|
@ -147,7 +147,7 @@ build_posix()
|
|||
|
||||
OT_CMAKE_BUILD_DIR="${OT_BUILDDIR}/openthread-posix-${version}" "${OT_SRCDIR}"/script/cmake-build posix "${options[@]}"
|
||||
|
||||
if [[ ${version} == "1.2" && ${INTER_OP_BBR} == 1 ]]; then
|
||||
if [[ ${version} != "1.1" && ${INTER_OP_BBR} == 1 ]]; then
|
||||
|
||||
options+=("-DOT_BACKBONE_ROUTER=ON")
|
||||
|
||||
|
@ -170,7 +170,7 @@ do_build()
|
|||
{
|
||||
build_for_one_version "${THREAD_VERSION}"
|
||||
|
||||
if [[ ${THREAD_VERSION} == "1.2" && ${INTER_OP} == "1" ]]; then
|
||||
if [[ ${THREAD_VERSION} != "1.1" && ${INTER_OP} == "1" ]]; then
|
||||
build_for_one_version 1.1
|
||||
fi
|
||||
}
|
||||
|
@ -201,8 +201,8 @@ do_unit()
|
|||
{
|
||||
do_unit_version "${THREAD_VERSION}"
|
||||
|
||||
if [[ ${THREAD_VERSION} == "1.2" && ${INTER_OP_BBR} == 1 ]]; then
|
||||
do_unit_version "1.2-bbr"
|
||||
if [[ ${THREAD_VERSION} != "1.1" && ${INTER_OP_BBR} == 1 ]]; then
|
||||
do_unit_version "1.3-bbr"
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -220,8 +220,8 @@ do_cert()
|
|||
;;
|
||||
esac
|
||||
|
||||
if [[ ${THREAD_VERSION} == "1.2" ]]; then
|
||||
export top_builddir_1_2_bbr="${OT_BUILDDIR}/openthread-simulation-1.2-bbr"
|
||||
if [[ ${THREAD_VERSION} != "1.1" ]]; then
|
||||
export top_builddir_1_3_bbr="${OT_BUILDDIR}/openthread-simulation-1.3-bbr"
|
||||
if [[ ${INTER_OP} == "1" ]]; then
|
||||
export top_builddir_1_1="${OT_BUILDDIR}/openthread-simulation-1.1"
|
||||
fi
|
||||
|
@ -238,8 +238,8 @@ do_cert_suite()
|
|||
{
|
||||
export top_builddir="${OT_BUILDDIR}/openthread-simulation-${THREAD_VERSION}"
|
||||
|
||||
if [[ ${THREAD_VERSION} == "1.2" ]]; then
|
||||
export top_builddir_1_2_bbr="${OT_BUILDDIR}/openthread-simulation-1.2-bbr"
|
||||
if [[ ${THREAD_VERSION} != "1.1" ]]; then
|
||||
export top_builddir_1_3_bbr="${OT_BUILDDIR}/openthread-simulation-1.3-bbr"
|
||||
if [[ ${INTER_OP} == "1" ]]; then
|
||||
export top_builddir_1_1="${OT_BUILDDIR}/openthread-simulation-1.1"
|
||||
fi
|
||||
|
@ -386,7 +386,7 @@ do_expect()
|
|||
test_patterns=(-name 'tun-*.exp')
|
||||
else
|
||||
test_patterns=(-name 'posix-*.exp' -o -name 'cli-*.exp')
|
||||
if [[ ${THREAD_VERSION} == "1.2" ]]; then
|
||||
if [[ ${THREAD_VERSION} != "1.1" ]]; then
|
||||
test_patterns+=(-o -name 'v1_2-*.exp')
|
||||
fi
|
||||
fi
|
||||
|
@ -421,9 +421,9 @@ ENVIRONMENTS:
|
|||
VERBOSE 1 to build or test verbosely. The default is 0.
|
||||
VIRTUAL_TIME 1 for virtual time, otherwise real time. The default value is 0 when running expect tests,
|
||||
otherwise default value is 1.
|
||||
THREAD_VERSION 1.1 for Thread 1.1 stack, 1.2 for Thread 1.2 stack. The default is 1.2.
|
||||
INTER_OP 1 to build 1.1 together. Only works when THREAD_VERSION is 1.2. The default is 0.
|
||||
INTER_OP_BBR 1 to build bbr version together. Only works when THREAD_VERSION is 1.2. The default is 1.
|
||||
THREAD_VERSION 1.1 for Thread 1.1 stack, 1.3 for Thread 1.3 stack. The default is 1.3.
|
||||
INTER_OP 1 to build 1.1 together. Only works when THREAD_VERSION is 1.3. The default is 0.
|
||||
INTER_OP_BBR 1 to build bbr version together. Only works when THREAD_VERSION is 1.3. The default is 1.
|
||||
|
||||
COMMANDS:
|
||||
clean Clean built files to prepare for new build.
|
||||
|
@ -455,7 +455,7 @@ EXAMPLES:
|
|||
THREAD_VERSION=1.1 VIRTUAL_TIME=0 $0 clean build cert tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py
|
||||
THREAD_VERSION=1.1 VIRTUAL_TIME=0 $0 cert tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py
|
||||
|
||||
# Test Thread 1.2 with real time, use 'INTER_OP=1' when the case needs both versions.
|
||||
# Test Thread 1.3 with real time, use 'INTER_OP=1' when the case needs both versions.
|
||||
VIRTUAL_TIME=0 $0 clean build cert tests/scripts/thread-cert/v1_2_test_enhanced_keep_alive.py
|
||||
INTER_OP=1 VIRTUAL_TIME=0 $0 clean build cert tests/scripts/thread-cert/v1_2_router_5_1_1.py
|
||||
INTER_OP=1 VIRTUAL_TIME=0 $0 clean build cert_suite tests/scripts/thread-cert/v1_2_*
|
||||
|
@ -559,10 +559,10 @@ envsetup()
|
|||
export RADIO_DEVICE="${OT_BUILDDIR}/openthread-simulation-${THREAD_VERSION}/examples/apps/ncp/ot-rcp"
|
||||
export OT_CLI_PATH="${OT_BUILDDIR}/openthread-posix-${THREAD_VERSION}/src/posix/ot-cli"
|
||||
|
||||
if [[ ${THREAD_VERSION} == "1.2" ]]; then
|
||||
if [[ ${THREAD_VERSION} != "1.1" ]]; then
|
||||
export RADIO_DEVICE_1_1="${OT_BUILDDIR}/openthread-simulation-1.1/examples/apps/ncp/ot-rcp"
|
||||
export OT_CLI_PATH_1_1="${OT_BUILDDIR}/openthread-posix-1.1/src/posix/ot-cli"
|
||||
export OT_CLI_PATH_1_2_BBR="${OT_BUILDDIR}/openthread-posix-1.2-bbr/src/posix/ot-cli"
|
||||
export OT_CLI_PATH_BBR="${OT_BUILDDIR}/openthread-posix-1.3-bbr/src/posix/ot-cli"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -606,7 +606,7 @@ main()
|
|||
fi
|
||||
|
||||
[[ ${VIRTUAL_TIME} == 1 ]] && echo "Using virtual time" || echo "Using real time"
|
||||
[[ ${THREAD_VERSION} == "1.2" ]] && echo "Using Thread 1.2 stack" || echo "Using Thread 1.1 stack"
|
||||
[[ ${THREAD_VERSION} != "1.1" ]] && echo "Using Thread 1.3 stack" || echo "Using Thread 1.1 stack"
|
||||
|
||||
while [[ $# != 0 ]]; do
|
||||
case "$1" in
|
||||
|
|
|
@ -62,7 +62,6 @@ Done
|
|||
- [leaderdata](#leaderdata)
|
||||
- [leaderweight](#leaderweight)
|
||||
- [linkmetrics](#linkmetrics-mgmt-ipaddr-enhanced-ack-clear)
|
||||
- [linkquality](#linkquality-extaddr)
|
||||
- [locate](#locate)
|
||||
- [log](#log-filename-filename)
|
||||
- [mac](#mac-retries-direct)
|
||||
|
@ -1627,25 +1626,6 @@ Done
|
|||
- RSSI: -18 (dBm) (Exponential Moving Average)
|
||||
```
|
||||
|
||||
### linkquality \<extaddr\>
|
||||
|
||||
Get the link quality on the link to a given extended address.
|
||||
|
||||
```bash
|
||||
> linkquality 36c1dd7a4f5201ff
|
||||
3
|
||||
Done
|
||||
```
|
||||
|
||||
### linkquality \<extaddr\> \<linkquality\>
|
||||
|
||||
Set the link quality on the link to a given extended address.
|
||||
|
||||
```bash
|
||||
> linkquality 36c1dd7a4f5201ff 3
|
||||
Done
|
||||
```
|
||||
|
||||
### locate
|
||||
|
||||
Gets the current state (`In Progress` or `Idle`) of anycast locator.
|
||||
|
|
|
@ -196,7 +196,7 @@ Done
|
|||
|
||||
Usage: `dataset activetimestamp [timestamp]`
|
||||
|
||||
Get active timestamp.
|
||||
Get active timestamp seconds.
|
||||
|
||||
```bash
|
||||
> dataset activetimestamp
|
||||
|
@ -204,7 +204,7 @@ Get active timestamp.
|
|||
Done
|
||||
```
|
||||
|
||||
Set active timestamp.
|
||||
Set active timestamp seconds.
|
||||
|
||||
```bash
|
||||
> dataset activetimestamp 123456789
|
||||
|
@ -457,7 +457,7 @@ Done
|
|||
|
||||
Usage: `dataset pendingtimestamp [timestamp]`
|
||||
|
||||
Get pending timestamp.
|
||||
Get pending timestamp seconds.
|
||||
|
||||
```bash
|
||||
> dataset pendingtimestamp
|
||||
|
@ -465,7 +465,7 @@ Get pending timestamp.
|
|||
Done
|
||||
```
|
||||
|
||||
Set pending timestamp.
|
||||
Set pending timestamp seconds.
|
||||
|
||||
```bash
|
||||
> dataset pendingtimestamp 123456789
|
||||
|
|
|
@ -15,6 +15,7 @@ Usage : `srp client [command] ...`
|
|||
- [start](#start)
|
||||
- [state](#state)
|
||||
- [stop](#stop)
|
||||
- [ttl](#ttl)
|
||||
|
||||
## Command Details
|
||||
|
||||
|
@ -36,6 +37,7 @@ service
|
|||
start
|
||||
state
|
||||
stop
|
||||
ttl
|
||||
Done
|
||||
```
|
||||
|
||||
|
@ -137,6 +139,14 @@ name:"dev4312", state:Registered, addrs:[fd00:0:0:0:0:0:0:1234, fd00:0:0:0:0:0:0
|
|||
Done
|
||||
```
|
||||
|
||||
When auto host address mode is enabled.
|
||||
|
||||
```bash
|
||||
srp client host
|
||||
name:"dev1234", state:Registered, addrs:auto
|
||||
Done
|
||||
```
|
||||
|
||||
### host name
|
||||
|
||||
Usage: `srp client host name [name]`
|
||||
|
@ -158,9 +168,17 @@ Done
|
|||
|
||||
### host address
|
||||
|
||||
Usage : `srp client host address [<address> ...]`
|
||||
Usage : `srp client host address [auto | <address> ...]`
|
||||
|
||||
Get the list of host addresses.
|
||||
Indicate auto address mode is enabled.
|
||||
|
||||
```bash
|
||||
> srp client host address
|
||||
auto
|
||||
Done
|
||||
```
|
||||
|
||||
Get the list of host addresses (when auto host address is not enabled).
|
||||
|
||||
```bash
|
||||
> srp client host address
|
||||
|
@ -169,7 +187,14 @@ fd00:0:0:0:0:0:0:beef
|
|||
Done
|
||||
```
|
||||
|
||||
Set the list of host addresses (can be set while client is running to update the host addresses)
|
||||
Enable auto host address mode. When enabled client will automatically use all Thread netif unicast addresses excluding all link-local and mesh-local addresses. If there is no valid address, then Mesh Local EID address is added. SRP client will automatically re-register if/when addresses on Thread netif get changed (e.g., new address is added or existing address is removed).
|
||||
|
||||
```bash
|
||||
> srp client host address auto
|
||||
Done
|
||||
```
|
||||
|
||||
Explicitly set the list of host addresses (can be set while client is running to update the host addresses), also disabled auto host address mode.
|
||||
|
||||
```bash
|
||||
> srp client host address fd00::cafe
|
||||
|
@ -409,3 +434,23 @@ Stop the SRP client.
|
|||
> srp client stop
|
||||
Done
|
||||
```
|
||||
|
||||
### ttl
|
||||
|
||||
Usage: `srp client ttl [value]`
|
||||
|
||||
Get the TTL (in seconds).
|
||||
|
||||
```bash
|
||||
> srp client ttl
|
||||
7200
|
||||
Done
|
||||
>
|
||||
```
|
||||
|
||||
Set the TTL.
|
||||
|
||||
```bash
|
||||
> srp client ttl 3600
|
||||
Done
|
||||
```
|
||||
|
|
|
@ -1453,6 +1453,25 @@ exit:
|
|||
}
|
||||
#endif
|
||||
|
||||
template <> otError Interpreter::Process<Cmd("detach")>(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
if (aArgs[0] == "async")
|
||||
{
|
||||
SuccessOrExit(error = otThreadDetachGracefully(GetInstancePtr(), nullptr, nullptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error =
|
||||
otThreadDetachGracefully(GetInstancePtr(), &Interpreter::HandleDetachGracefullyResult, this));
|
||||
error = OT_ERROR_PENDING;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <> otError Interpreter::Process<Cmd("discover")>(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
@ -4903,6 +4922,17 @@ void Interpreter::OutputChildTableEntry(uint8_t aIndentSize, const otNetworkDiag
|
|||
}
|
||||
#endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
|
||||
|
||||
void Interpreter::HandleDetachGracefullyResult(void *aContext)
|
||||
{
|
||||
static_cast<Interpreter *>(aContext)->HandleDetachGracefullyResult();
|
||||
}
|
||||
|
||||
void Interpreter::HandleDetachGracefullyResult(void)
|
||||
{
|
||||
OutputLine("Finished detaching");
|
||||
OutputResult(OT_ERROR_NONE);
|
||||
}
|
||||
|
||||
void Interpreter::HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo &aInfo)
|
||||
{
|
||||
OutputFormat("~ Discovery Request from ");
|
||||
|
@ -5017,6 +5047,7 @@ otError Interpreter::ProcessCommand(Arg aArgs[])
|
|||
#if OPENTHREAD_FTD
|
||||
CmdEntry("delaytimermin"),
|
||||
#endif
|
||||
CmdEntry("detach"),
|
||||
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||
#if OPENTHREAD_CONFIG_DIAG_ENABLE
|
||||
CmdEntry("diag"),
|
||||
|
|
|
@ -452,6 +452,9 @@ private:
|
|||
const char *LinkMetricsStatusToStr(uint8_t aStatus);
|
||||
#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
|
||||
|
||||
static void HandleDetachGracefullyResult(void *aContext);
|
||||
void HandleDetachGracefullyResult(void);
|
||||
|
||||
static void HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo *aInfo, void *aContext)
|
||||
{
|
||||
static_cast<Interpreter *>(aContext)->HandleDiscoveryRequest(*aInfo);
|
||||
|
|
|
@ -51,12 +51,12 @@ otError Dataset::Print(otOperationalDataset &aDataset)
|
|||
{
|
||||
if (aDataset.mComponents.mIsPendingTimestampPresent)
|
||||
{
|
||||
OutputLine("Pending Timestamp: %lu", aDataset.mPendingTimestamp);
|
||||
OutputLine("Pending Timestamp: %lu", aDataset.mPendingTimestamp.mSeconds);
|
||||
}
|
||||
|
||||
if (aDataset.mComponents.mIsActiveTimestampPresent)
|
||||
{
|
||||
OutputLine("Active Timestamp: %lu", aDataset.mActiveTimestamp);
|
||||
OutputLine("Active Timestamp: %lu", aDataset.mActiveTimestamp.mSeconds);
|
||||
}
|
||||
|
||||
if (aDataset.mComponents.mIsChannelPresent)
|
||||
|
@ -205,12 +205,14 @@ template <> otError Dataset::Process<Cmd("activetimestamp")>(Arg aArgs[])
|
|||
{
|
||||
if (sDataset.mComponents.mIsActiveTimestampPresent)
|
||||
{
|
||||
OutputLine("%lu", sDataset.mActiveTimestamp);
|
||||
OutputLine("%lu", sDataset.mActiveTimestamp.mSeconds);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = aArgs[0].ParseAsUint64(sDataset.mActiveTimestamp));
|
||||
SuccessOrExit(error = aArgs[0].ParseAsUint64(sDataset.mActiveTimestamp.mSeconds));
|
||||
sDataset.mActiveTimestamp.mTicks = 0;
|
||||
sDataset.mActiveTimestamp.mAuthoritative = false;
|
||||
sDataset.mComponents.mIsActiveTimestampPresent = true;
|
||||
}
|
||||
|
||||
|
@ -423,12 +425,14 @@ template <> otError Dataset::Process<Cmd("pendingtimestamp")>(Arg aArgs[])
|
|||
{
|
||||
if (sDataset.mComponents.mIsPendingTimestampPresent)
|
||||
{
|
||||
OutputLine("%lu", sDataset.mPendingTimestamp);
|
||||
OutputLine("%lu", sDataset.mPendingTimestamp.mSeconds);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = aArgs[0].ParseAsUint64(sDataset.mPendingTimestamp));
|
||||
SuccessOrExit(error = aArgs[0].ParseAsUint64(sDataset.mPendingTimestamp.mSeconds));
|
||||
sDataset.mPendingTimestamp.mTicks = 0;
|
||||
sDataset.mPendingTimestamp.mAuthoritative = false;
|
||||
sDataset.mComponents.mIsPendingTimestampPresent = true;
|
||||
}
|
||||
|
||||
|
@ -450,14 +454,18 @@ template <> otError Dataset::Process<Cmd("mgmtsetcommand")>(Arg aArgs[])
|
|||
if (*arg == "activetimestamp")
|
||||
{
|
||||
arg++;
|
||||
SuccessOrExit(error = arg->ParseAsUint64(dataset.mActiveTimestamp.mSeconds));
|
||||
dataset.mActiveTimestamp.mTicks = 0;
|
||||
dataset.mActiveTimestamp.mAuthoritative = false;
|
||||
dataset.mComponents.mIsActiveTimestampPresent = true;
|
||||
SuccessOrExit(error = arg->ParseAsUint64(dataset.mActiveTimestamp));
|
||||
}
|
||||
else if (*arg == "pendingtimestamp")
|
||||
{
|
||||
arg++;
|
||||
SuccessOrExit(error = arg->ParseAsUint64(dataset.mPendingTimestamp.mSeconds));
|
||||
dataset.mPendingTimestamp.mTicks = 0;
|
||||
dataset.mPendingTimestamp.mAuthoritative = false;
|
||||
dataset.mComponents.mIsPendingTimestampPresent = true;
|
||||
SuccessOrExit(error = arg->ParseAsUint64(dataset.mPendingTimestamp));
|
||||
}
|
||||
else if (*arg == "networkkey")
|
||||
{
|
||||
|
|
|
@ -160,10 +160,21 @@ template <> otError SrpClient::Process<Cmd("host")>(Arg aArgs[])
|
|||
{
|
||||
const otSrpClientHostInfo *hostInfo = otSrpClientGetHostInfo(GetInstancePtr());
|
||||
|
||||
for (uint8_t index = 0; index < hostInfo->mNumAddresses; index++)
|
||||
if (hostInfo->mAutoAddress)
|
||||
{
|
||||
OutputIp6AddressLine(hostInfo->mAddresses[index]);
|
||||
OutputLine("auto");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint8_t index = 0; index < hostInfo->mNumAddresses; index++)
|
||||
{
|
||||
OutputIp6AddressLine(hostInfo->mAddresses[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (aArgs[1] == "auto")
|
||||
{
|
||||
error = otSrpClientEnableAutoHostAddress(GetInstancePtr());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -447,19 +458,28 @@ void SrpClient::OutputHostInfo(uint8_t aIndentSize, const otSrpClientHostInfo &a
|
|||
OutputFormat("(null)");
|
||||
}
|
||||
|
||||
OutputFormat(", state:%s, addrs:[", otSrpClientItemStateToString(aHostInfo.mState));
|
||||
OutputFormat(", state:%s, addrs:", otSrpClientItemStateToString(aHostInfo.mState));
|
||||
|
||||
for (uint8_t index = 0; index < aHostInfo.mNumAddresses; index++)
|
||||
if (aHostInfo.mAutoAddress)
|
||||
{
|
||||
if (index > 0)
|
||||
OutputLine("auto");
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputFormat("[");
|
||||
|
||||
for (uint8_t index = 0; index < aHostInfo.mNumAddresses; index++)
|
||||
{
|
||||
OutputFormat(", ");
|
||||
if (index > 0)
|
||||
{
|
||||
OutputFormat(", ");
|
||||
}
|
||||
|
||||
OutputIp6Address(aHostInfo.mAddresses[index]);
|
||||
}
|
||||
|
||||
OutputIp6Address(aHostInfo.mAddresses[index]);
|
||||
OutputLine("]");
|
||||
}
|
||||
|
||||
OutputLine("]");
|
||||
}
|
||||
|
||||
void SrpClient::OutputServiceList(uint8_t aIndentSize, const otSrpClientService *aServices)
|
||||
|
@ -525,6 +545,11 @@ exit:
|
|||
return error;
|
||||
}
|
||||
|
||||
template <> otError SrpClient::Process<Cmd("ttl")>(Arg aArgs[])
|
||||
{
|
||||
return Interpreter::GetInterpreter().ProcessGetSet(aArgs, otSrpClientGetTtl, otSrpClientSetTtl);
|
||||
}
|
||||
|
||||
void SrpClient::HandleCallback(otError aError,
|
||||
const otSrpClientHostInfo *aHostInfo,
|
||||
const otSrpClientService * aServices,
|
||||
|
@ -578,7 +603,7 @@ otError SrpClient::Process(Arg aArgs[])
|
|||
static constexpr Command kCommands[] = {
|
||||
CmdEntry("autostart"), CmdEntry("callback"), CmdEntry("host"), CmdEntry("keyleaseinterval"),
|
||||
CmdEntry("leaseinterval"), CmdEntry("server"), CmdEntry("service"), CmdEntry("start"),
|
||||
CmdEntry("state"), CmdEntry("stop"),
|
||||
CmdEntry("state"), CmdEntry("stop"), CmdEntry("ttl"),
|
||||
};
|
||||
|
||||
static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted");
|
||||
|
|
|
@ -149,6 +149,30 @@ otError SrpServer::ProcessDisable(Arg aArgs[])
|
|||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError SrpServer::ProcessTtl(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otSrpServerTtlConfig ttlConfig;
|
||||
|
||||
if (aArgs[0].IsEmpty())
|
||||
{
|
||||
otSrpServerGetTtlConfig(GetInstancePtr(), &ttlConfig);
|
||||
OutputLine("min ttl: %u", ttlConfig.mMinTtl);
|
||||
OutputLine("max ttl: %u", ttlConfig.mMaxTtl);
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = aArgs[0].ParseAsUint32(ttlConfig.mMinTtl));
|
||||
SuccessOrExit(error = aArgs[1].ParseAsUint32(ttlConfig.mMaxTtl));
|
||||
VerifyOrExit(aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
error = otSrpServerSetTtlConfig(GetInstancePtr(), &ttlConfig);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError SrpServer::ProcessLease(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
@ -289,6 +313,7 @@ otError SrpServer::ProcessService(Arg aArgs[])
|
|||
OutputLine(kIndentSize, "port: %hu", otSrpServerServiceGetPort(service));
|
||||
OutputLine(kIndentSize, "priority: %hu", otSrpServerServiceGetPriority(service));
|
||||
OutputLine(kIndentSize, "weight: %hu", otSrpServerServiceGetWeight(service));
|
||||
OutputLine(kIndentSize, "ttl: %hu", otSrpServerServiceGetTtl(service));
|
||||
|
||||
txtData = otSrpServerServiceGetTxtData(service, &txtDataLength);
|
||||
OutputFormat(kIndentSize, "TXT: ");
|
||||
|
|
|
@ -90,6 +90,7 @@ private:
|
|||
otError ProcessHost(Arg aArgs[]);
|
||||
otError ProcessService(Arg aArgs[]);
|
||||
otError ProcessSeqNum(Arg aArgs[]);
|
||||
otError ProcessTtl(Arg aArgs[]);
|
||||
otError ProcessHelp(Arg aArgs[]);
|
||||
|
||||
void OutputHostAddresses(const otSrpServerHost *aHost);
|
||||
|
@ -100,6 +101,7 @@ private:
|
|||
{"help", &SrpServer::ProcessHelp}, {"host", &SrpServer::ProcessHost},
|
||||
{"lease", &SrpServer::ProcessLease}, {"seqnum", &SrpServer::ProcessSeqNum},
|
||||
{"service", &SrpServer::ProcessService}, {"state", &SrpServer::ProcessState},
|
||||
{"ttl", &SrpServer::ProcessTtl},
|
||||
};
|
||||
|
||||
static_assert(BinarySearch::IsSorted(sCommands), "Command Table is not sorted");
|
||||
|
|
|
@ -46,10 +46,14 @@ target_sources(openthread-cli-radio
|
|||
cli_output.cpp
|
||||
)
|
||||
|
||||
if(NOT DEFINED OT_MBEDTLS_RCP)
|
||||
set(OT_MBEDTLS_RCP ${OT_MBEDTLS})
|
||||
endif()
|
||||
|
||||
target_link_libraries(openthread-cli-radio
|
||||
PUBLIC
|
||||
openthread-radio
|
||||
PRIVATE
|
||||
${OT_MBEDTLS}
|
||||
${OT_MBEDTLS_RCP}
|
||||
ot-config
|
||||
)
|
||||
|
|
|
@ -37,6 +37,8 @@ if (openthread_enable_core_config_args) {
|
|||
defines += [ "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_1" ]
|
||||
} else if (openthread_config_thread_version == "1.2") {
|
||||
defines += [ "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_2" ]
|
||||
} else if (openthread_config_thread_version == "1.3") {
|
||||
defines += [ "OPENTHREAD_CONFIG_THREAD_VERSION=OT_THREAD_VERSION_1_3" ]
|
||||
} else if (openthread_config_thread_version != "") {
|
||||
assert(false,
|
||||
"Unrecognized Thread version: ${openthread_config_thread_version}")
|
||||
|
@ -363,9 +365,8 @@ openthread_core_files = [
|
|||
"backbone_router/multicast_listeners_table.hpp",
|
||||
"backbone_router/ndproxy_table.cpp",
|
||||
"backbone_router/ndproxy_table.hpp",
|
||||
"border_router/infra_if_platform.cpp",
|
||||
"border_router/router_advertisement.cpp",
|
||||
"border_router/router_advertisement.hpp",
|
||||
"border_router/infra_if.cpp",
|
||||
"border_router/infra_if.hpp",
|
||||
"border_router/routing_manager.cpp",
|
||||
"border_router/routing_manager.hpp",
|
||||
"coap/coap.cpp",
|
||||
|
@ -557,6 +558,8 @@ openthread_core_files = [
|
|||
"net/ip6_mpl.cpp",
|
||||
"net/ip6_mpl.hpp",
|
||||
"net/ip6_types.hpp",
|
||||
"net/nd6.cpp",
|
||||
"net/nd6.hpp",
|
||||
"net/nd_agent.cpp",
|
||||
"net/nd_agent.hpp",
|
||||
"net/netif.cpp",
|
||||
|
|
|
@ -86,8 +86,7 @@ set(COMMON_SOURCES
|
|||
backbone_router/bbr_manager.cpp
|
||||
backbone_router/multicast_listeners_table.cpp
|
||||
backbone_router/ndproxy_table.cpp
|
||||
border_router/infra_if_platform.cpp
|
||||
border_router/router_advertisement.cpp
|
||||
border_router/infra_if.cpp
|
||||
border_router/routing_manager.cpp
|
||||
coap/coap.cpp
|
||||
coap/coap_message.cpp
|
||||
|
@ -169,6 +168,7 @@ set(COMMON_SOURCES
|
|||
net/ip6_filter.cpp
|
||||
net/ip6_headers.cpp
|
||||
net/ip6_mpl.cpp
|
||||
net/nd6.cpp
|
||||
net/nd_agent.cpp
|
||||
net/netif.cpp
|
||||
net/sntp_client.cpp
|
||||
|
|
|
@ -176,8 +176,7 @@ SOURCES_COMMON = \
|
|||
backbone_router/bbr_manager.cpp \
|
||||
backbone_router/multicast_listeners_table.cpp \
|
||||
backbone_router/ndproxy_table.cpp \
|
||||
border_router/infra_if_platform.cpp \
|
||||
border_router/router_advertisement.cpp \
|
||||
border_router/infra_if.cpp \
|
||||
border_router/routing_manager.cpp \
|
||||
coap/coap.cpp \
|
||||
coap/coap_message.cpp \
|
||||
|
@ -259,6 +258,7 @@ SOURCES_COMMON = \
|
|||
net/ip6_filter.cpp \
|
||||
net/ip6_headers.cpp \
|
||||
net/ip6_mpl.cpp \
|
||||
net/nd6.cpp \
|
||||
net/nd_agent.cpp \
|
||||
net/netif.cpp \
|
||||
net/sntp_client.cpp \
|
||||
|
@ -415,7 +415,7 @@ HEADERS_COMMON = \
|
|||
backbone_router/bbr_manager.hpp \
|
||||
backbone_router/multicast_listeners_table.hpp \
|
||||
backbone_router/ndproxy_table.hpp \
|
||||
border_router/router_advertisement.hpp \
|
||||
border_router/infra_if.hpp \
|
||||
border_router/routing_manager.hpp \
|
||||
coap/coap.hpp \
|
||||
coap/coap_message.hpp \
|
||||
|
@ -563,6 +563,7 @@ HEADERS_COMMON = \
|
|||
net/ip6_headers.hpp \
|
||||
net/ip6_mpl.hpp \
|
||||
net/ip6_types.hpp \
|
||||
net/nd6.hpp \
|
||||
net/nd_agent.hpp \
|
||||
net/netif.hpp \
|
||||
net/sntp_client.hpp \
|
||||
|
|
|
@ -81,4 +81,9 @@ otDnssdQueryType otDnssdGetQueryTypeAndName(const otDnssdQuery *aQuery, char (*a
|
|||
return MapEnum(Dns::ServiceDiscovery::Server::GetQueryTypeAndName(aQuery, *aNameOutput));
|
||||
}
|
||||
|
||||
const otDnssdCounters *otDnssdGetCounters(otInstance *aInstance)
|
||||
{
|
||||
return &AsCoreType(aInstance).Get<Dns::ServiceDiscovery::Server>().GetCounters();
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE
|
||||
|
|
|
@ -84,6 +84,16 @@ bool otSrpClientIsAutoStartModeEnabled(otInstance *aInstance)
|
|||
}
|
||||
#endif // OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
|
||||
|
||||
uint32_t otSrpClientGetTtl(otInstance *aInstance)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<Srp::Client>().GetTtl();
|
||||
}
|
||||
|
||||
void otSrpClientSetTtl(otInstance *aInstance, uint32_t aTtl)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<Srp::Client>().SetTtl(aTtl);
|
||||
}
|
||||
|
||||
uint32_t otSrpClientGetLeaseInterval(otInstance *aInstance)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<Srp::Client>().GetLeaseInterval();
|
||||
|
@ -114,6 +124,11 @@ otError otSrpClientSetHostName(otInstance *aInstance, const char *aName)
|
|||
return AsCoreType(aInstance).Get<Srp::Client>().SetHostName(aName);
|
||||
}
|
||||
|
||||
otError otSrpClientEnableAutoHostAddress(otInstance *aInstance)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<Srp::Client>().EnableAutoHostAddress();
|
||||
}
|
||||
|
||||
otError otSrpClientSetHostAddresses(otInstance *aInstance, const otIp6Address *aIp6Addresses, uint8_t aNumAddresses)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<Srp::Client>().SetHostAddresses(AsCoreTypePtr(aIp6Addresses), aNumAddresses);
|
||||
|
|
|
@ -57,6 +57,11 @@ otSrpServerState otSrpServerGetState(otInstance *aInstance)
|
|||
return MapEnum(AsCoreType(aInstance).Get<Srp::Server>().GetState());
|
||||
}
|
||||
|
||||
uint16_t otSrpServerGetPort(otInstance *aInstance)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<Srp::Server>().GetPort();
|
||||
}
|
||||
|
||||
otSrpServerAddressMode otSrpServerGetAddressMode(otInstance *aInstance)
|
||||
{
|
||||
return MapEnum(AsCoreType(aInstance).Get<Srp::Server>().GetAddressMode());
|
||||
|
@ -82,6 +87,16 @@ void otSrpServerSetEnabled(otInstance *aInstance, bool aEnabled)
|
|||
AsCoreType(aInstance).Get<Srp::Server>().SetEnabled(aEnabled);
|
||||
}
|
||||
|
||||
void otSrpServerGetTtlConfig(otInstance *aInstance, otSrpServerTtlConfig *aTtlConfig)
|
||||
{
|
||||
AsCoreType(aInstance).Get<Srp::Server>().GetTtlConfig(AsCoreType(aTtlConfig));
|
||||
}
|
||||
|
||||
otError otSrpServerSetTtlConfig(otInstance *aInstance, const otSrpServerTtlConfig *aTtlConfig)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<Srp::Server>().SetTtlConfig(AsCoreType(aTtlConfig));
|
||||
}
|
||||
|
||||
void otSrpServerGetLeaseConfig(otInstance *aInstance, otSrpServerLeaseConfig *aLeaseConfig)
|
||||
{
|
||||
AsCoreType(aInstance).Get<Srp::Server>().GetLeaseConfig(AsCoreType(aLeaseConfig));
|
||||
|
@ -109,6 +124,11 @@ const otSrpServerHost *otSrpServerGetNextHost(otInstance *aInstance, const otSrp
|
|||
return AsCoreType(aInstance).Get<Srp::Server>().GetNextHost(AsCoreTypePtr(aHost));
|
||||
}
|
||||
|
||||
const otSrpServerResponseCounters *otSrpServerGetResponseCounters(otInstance *aInstance)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<Srp::Server>().GetResponseCounters();
|
||||
}
|
||||
|
||||
bool otSrpServerHostIsDeleted(const otSrpServerHost *aHost)
|
||||
{
|
||||
return AsCoreType(aHost).IsDeleted();
|
||||
|
@ -124,6 +144,16 @@ const otIp6Address *otSrpServerHostGetAddresses(const otSrpServerHost *aHost, ui
|
|||
return AsCoreType(aHost).GetAddresses(*aAddressesNum);
|
||||
}
|
||||
|
||||
void otSrpServerHostGetLeaseInfo(const otSrpServerHost *aHost, otSrpServerLeaseInfo *aLeaseInfo)
|
||||
{
|
||||
AsCoreType(aHost).GetLeaseInfo(*aLeaseInfo);
|
||||
}
|
||||
|
||||
uint32_t otSrpServerHostGetKeyLease(const otSrpServerHost *aHost)
|
||||
{
|
||||
return AsCoreType(aHost).GetKeyLease();
|
||||
}
|
||||
|
||||
const otSrpServerService *otSrpServerHostGetNextService(const otSrpServerHost * aHost,
|
||||
const otSrpServerService *aService)
|
||||
{
|
||||
|
@ -184,6 +214,11 @@ uint16_t otSrpServerServiceGetPriority(const otSrpServerService *aService)
|
|||
return AsCoreType(aService).GetPriority();
|
||||
}
|
||||
|
||||
uint32_t otSrpServerServiceGetTtl(const otSrpServerService *aService)
|
||||
{
|
||||
return AsCoreType(aService).GetTtl();
|
||||
}
|
||||
|
||||
const uint8_t *otSrpServerServiceGetTxtData(const otSrpServerService *aService, uint16_t *aDataLength)
|
||||
{
|
||||
*aDataLength = AsCoreType(aService).GetTxtDataLength();
|
||||
|
@ -196,4 +231,9 @@ const otSrpServerHost *otSrpServerServiceGetHost(const otSrpServerService *aServ
|
|||
return &AsCoreType(aService).GetHost();
|
||||
}
|
||||
|
||||
void otSrpServerServiceGetLeaseInfo(const otSrpServerService *aService, otSrpServerLeaseInfo *aLeaseInfo)
|
||||
{
|
||||
AsCoreType(aService).GetLeaseInfo(*aLeaseInfo);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
||||
|
|
|
@ -497,4 +497,9 @@ bool otThreadIsAnycastLocateInProgress(otInstance *aInstance)
|
|||
}
|
||||
#endif
|
||||
|
||||
otError otThreadDetachGracefully(otInstance *aInstance, otDetachGracefullyCallback aCallback, void *aContext)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<Mle::MleRouter>().DetachGracefully(aCallback, aContext);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||
|
|
|
@ -251,7 +251,7 @@ void NdProxyTable::HandleTimer(void)
|
|||
|
||||
for (NdProxy &proxy : Iterate(kFilterDadInProcess))
|
||||
{
|
||||
if (proxy.IsDadAttamptsComplete())
|
||||
if (proxy.IsDadAttemptsComplete())
|
||||
{
|
||||
proxy.mDadFlag = false;
|
||||
NotifyDuaRegistrationOnBackboneLink(proxy, /* aIsRenew */ false);
|
||||
|
@ -262,7 +262,7 @@ void NdProxyTable::HandleTimer(void)
|
|||
|
||||
if (Get<BackboneRouter::Manager>().SendBackboneQuery(GetDua(proxy)) == kErrorNone)
|
||||
{
|
||||
proxy.IncreaseDadAttampts();
|
||||
proxy.IncreaseDadAttempts();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,8 +111,8 @@ public:
|
|||
uint32_t aTimeSinceLastTransaction);
|
||||
|
||||
void Update(uint16_t aRloc16, uint32_t aTimeSinceLastTransaction);
|
||||
void IncreaseDadAttampts(void) { mDadAttempts++; }
|
||||
bool IsDadAttamptsComplete() const { return mDadAttempts == Mle::kDuaDadRepeats; }
|
||||
void IncreaseDadAttempts(void) { mDadAttempts++; }
|
||||
bool IsDadAttemptsComplete() const { return mDadAttempts == Mle::kDuaDadRepeats; }
|
||||
|
||||
Ip6::InterfaceIdentifier mAddressIid;
|
||||
Ip6::InterfaceIdentifier mMeshLocalIid;
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Copyright (c) 2022, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements infrastructure network interface.
|
||||
*/
|
||||
|
||||
#include "infra_if.hpp"
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
#include "border_router/routing_manager.hpp"
|
||||
#include "common/as_core_type.hpp"
|
||||
#include "common/instance.hpp"
|
||||
#include "common/locator_getters.hpp"
|
||||
#include "common/logging.hpp"
|
||||
#include "net/icmp6.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace BorderRouter {
|
||||
|
||||
RegisterLogModule("InfraIf");
|
||||
|
||||
InfraIf::InfraIf(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mInitialized(false)
|
||||
, mIsRunning(false)
|
||||
, mIfIndex(0)
|
||||
{
|
||||
}
|
||||
|
||||
Error InfraIf::Init(uint32_t aIfIndex)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(!mInitialized, error = kErrorInvalidState);
|
||||
VerifyOrExit(aIfIndex > 0, error = kErrorInvalidArgs);
|
||||
|
||||
mIfIndex = aIfIndex;
|
||||
mInitialized = true;
|
||||
|
||||
LogInfo("Init %s", ToString().AsCString());
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void InfraIf::Deinit(void)
|
||||
{
|
||||
mInitialized = false;
|
||||
mIsRunning = false;
|
||||
mIfIndex = 0;
|
||||
|
||||
LogInfo("Deinit");
|
||||
}
|
||||
|
||||
bool InfraIf::HasAddress(const Ip6::Address &aAddress)
|
||||
{
|
||||
OT_ASSERT(mInitialized);
|
||||
|
||||
return otPlatInfraIfHasAddress(mIfIndex, &aAddress);
|
||||
}
|
||||
|
||||
Error InfraIf::Send(const Icmp6Packet &aPacket, const Ip6::Address &aDestination)
|
||||
{
|
||||
OT_ASSERT(mInitialized);
|
||||
|
||||
return otPlatInfraIfSendIcmp6Nd(mIfIndex, &aDestination, aPacket.GetBytes(), aPacket.GetLength());
|
||||
}
|
||||
|
||||
void InfraIf::HandledReceived(uint32_t aIfIndex, const Ip6::Address &aSource, const Icmp6Packet &aPacket)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(mInitialized && mIsRunning, error = kErrorInvalidState);
|
||||
VerifyOrExit(aIfIndex == mIfIndex, error = kErrorDrop);
|
||||
VerifyOrExit(aPacket.GetBytes() != nullptr, error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aPacket.GetLength() >= sizeof(Ip6::Icmp::Header), error = kErrorParse);
|
||||
|
||||
Get<RoutingManager>().HandleReceived(aPacket, aSource);
|
||||
|
||||
exit:
|
||||
if (error != kErrorNone)
|
||||
{
|
||||
LogDebg("Dropped ICMPv6 message: %s", ErrorToString(error));
|
||||
}
|
||||
}
|
||||
|
||||
Error InfraIf::HandleStateChanged(uint32_t aIfIndex, bool aIsRunning)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(mInitialized, error = kErrorInvalidState);
|
||||
VerifyOrExit(aIfIndex == mIfIndex, error = kErrorInvalidArgs);
|
||||
|
||||
VerifyOrExit(aIsRunning != mIsRunning);
|
||||
LogInfo("State changed: %sRUNNING -> %sRUNNING", mIsRunning ? "" : "NOT ", aIsRunning ? "" : "NOT ");
|
||||
|
||||
mIsRunning = aIsRunning;
|
||||
|
||||
Get<RoutingManager>().HandleInfraIfStateChanged();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
InfraIf::InfoString InfraIf::ToString(void) const
|
||||
{
|
||||
InfoString string;
|
||||
|
||||
string.Append("infra netif %u", mIfIndex);
|
||||
return string;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern "C" void otPlatInfraIfRecvIcmp6Nd(otInstance * aInstance,
|
||||
uint32_t aInfraIfIndex,
|
||||
const otIp6Address *aSrcAddress,
|
||||
const uint8_t * aBuffer,
|
||||
uint16_t aBufferLength)
|
||||
{
|
||||
InfraIf::Icmp6Packet packet;
|
||||
|
||||
packet.Init(aBuffer, aBufferLength);
|
||||
AsCoreType(aInstance).Get<InfraIf>().HandledReceived(aInfraIfIndex, AsCoreType(aSrcAddress), packet);
|
||||
}
|
||||
|
||||
extern "C" otError otPlatInfraIfStateChanged(otInstance *aInstance, uint32_t aInfraIfIndex, bool aIsRunning)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<InfraIf>().HandleStateChanged(aInfraIfIndex, aIsRunning);
|
||||
}
|
||||
|
||||
} // namespace BorderRouter
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* Copyright (c) 2022, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes definitions for infrastructure network interface.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef INFRA_IF_HPP_
|
||||
#define INFRA_IF_HPP_
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
#include <openthread/platform/infra_if.h>
|
||||
|
||||
#include "common/data.hpp"
|
||||
#include "common/error.hpp"
|
||||
#include "common/locator.hpp"
|
||||
#include "common/string.hpp"
|
||||
#include "net/ip6.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace BorderRouter {
|
||||
|
||||
/**
|
||||
* This class represents the infrastructure network interface on a border router.
|
||||
*
|
||||
*/
|
||||
class InfraIf : public InstanceLocator
|
||||
{
|
||||
public:
|
||||
static constexpr uint16_t kInfoStringSize = 20; ///< Max chars for the info string (`ToString()`).
|
||||
|
||||
typedef String<kInfoStringSize> InfoString; ///< String type returned from `ToString()`.
|
||||
typedef Data<kWithUint16Length> Icmp6Packet; ///< An IMCPv6 packet (data containing the IP payload)
|
||||
|
||||
/**
|
||||
* This constructor initializes the `InfraIf`.
|
||||
*
|
||||
* @param[in] aInstance A OpenThread instance.
|
||||
*
|
||||
*/
|
||||
explicit InfraIf(Instance &aInstance);
|
||||
|
||||
/**
|
||||
* This method initializes the `InfraIf`.
|
||||
*
|
||||
* @param[in] aIfIndex The infrastructure interface index.
|
||||
*
|
||||
* @retval kErrorNone Successfully initialized the `InfraIf`.
|
||||
* @retval kErrorInvalidArgs The index of the infra interface is not valid.
|
||||
* @retval kErrorInvalidState The `InfraIf` is already initialized.
|
||||
*
|
||||
*/
|
||||
Error Init(uint32_t aIfIndex);
|
||||
|
||||
/**
|
||||
* This method deinitilaizes the `InfraIf`.
|
||||
*
|
||||
*/
|
||||
void Deinit(void);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the `InfraIf` is initialized.
|
||||
*
|
||||
* @retval TRUE The `InfraIf` is initialized.
|
||||
* @retval FALSE The `InfraIf` is not initialized.
|
||||
*
|
||||
*/
|
||||
bool IsInitialized(void) const { return mInitialized; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the infra interface is running.
|
||||
*
|
||||
* @retval TRUE The infrastructure interface is running.
|
||||
* @retval FALSE The infrastructure interface is not running.
|
||||
*
|
||||
*/
|
||||
bool IsRunning(void) const { return mIsRunning; }
|
||||
|
||||
/**
|
||||
* This method returns the infrastructure interface index.
|
||||
*
|
||||
* @returns The interface index or zero if not initialized.
|
||||
*
|
||||
*/
|
||||
uint32_t GetIfIndex(void) const { return mIfIndex; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the infra interface has the given IPv6 address assigned.
|
||||
*
|
||||
* This method MUST be used when interface is initialized.
|
||||
*
|
||||
* @param[in] aAddress The IPv6 address.
|
||||
*
|
||||
* @retval TRUE The infrastructure interface has @p aAddress.
|
||||
* @retval FALSE The infrastructure interface does not have @p aAddress.
|
||||
*
|
||||
*/
|
||||
bool HasAddress(const Ip6::Address &aAddress);
|
||||
|
||||
/**
|
||||
* This method sends an ICMPv6 Neighbor Discovery packet on the infrastructure interface.
|
||||
*
|
||||
* This method MUST be used when interface is initialized.
|
||||
*
|
||||
* @param[in] aPacket The ICMPv6 packet to send.
|
||||
* @param[in] aDestination The destination address.
|
||||
*
|
||||
* @retval kErrorNone Successfully sent the ICMPv6 message.
|
||||
* @retval kErrorFailed Failed to send the ICMPv6 message.
|
||||
*
|
||||
*/
|
||||
Error Send(const Icmp6Packet &aPacket, const Ip6::Address &aDestination);
|
||||
|
||||
/**
|
||||
* This method processes a received ICMPv6 Neighbor Discovery packet from an infrastructure interface.
|
||||
*
|
||||
* @param[in] aIfIndex The infrastructure interface index on which the ICMPv6 message is received.
|
||||
* @param[in] aSource The IPv6 source address.
|
||||
* @param[in] aPacket The ICMPv6 packet.
|
||||
*
|
||||
*/
|
||||
void HandledReceived(uint32_t aIfIndex, const Ip6::Address &aSource, const Icmp6Packet &aPacket);
|
||||
|
||||
/**
|
||||
* This method handles infrastructure interface state changes.
|
||||
*
|
||||
* @param[in] aIfIndex The infrastructure interface index.
|
||||
* @param[in] aIsRunning A boolean that indicates whether the infrastructure interface is running.
|
||||
*
|
||||
* @retval kErrorNone Successfully updated the infra interface status.
|
||||
* @retval kErrorInvalidState The `InfraIf` is not initialized.
|
||||
* @retval kErrorInvalidArgs The @p IfIndex does not match the interface index of `InfraIf`.
|
||||
*
|
||||
*/
|
||||
Error HandleStateChanged(uint32_t aIfIndex, bool aIsRunning);
|
||||
|
||||
/**
|
||||
* This method converts the `InfraIf` to a human-readable string.
|
||||
*
|
||||
* @returns The string representation of `InfraIf`.
|
||||
*
|
||||
*/
|
||||
InfoString ToString(void) const;
|
||||
|
||||
private:
|
||||
bool mInitialized : 1;
|
||||
bool mIsRunning : 1;
|
||||
uint32_t mIfIndex;
|
||||
};
|
||||
|
||||
} // namespace BorderRouter
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
#endif // INFRA_IF_HPP_
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2020, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements infrastructure interface platform APIs.
|
||||
*/
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
#include <openthread/platform/infra_if.h>
|
||||
|
||||
#include "border_router/routing_manager.hpp"
|
||||
#include "common/as_core_type.hpp"
|
||||
#include "common/instance.hpp"
|
||||
|
||||
using namespace ot;
|
||||
|
||||
extern "C" void otPlatInfraIfRecvIcmp6Nd(otInstance * aInstance,
|
||||
uint32_t aInfraIfIndex,
|
||||
const otIp6Address *aSrcAddress,
|
||||
const uint8_t * aBuffer,
|
||||
uint16_t aBufferLength)
|
||||
{
|
||||
AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().RecvIcmp6Message(aInfraIfIndex, AsCoreType(aSrcAddress),
|
||||
aBuffer, aBufferLength);
|
||||
}
|
||||
|
||||
extern "C" otError otPlatInfraIfStateChanged(otInstance *aInstance, uint32_t aInfraIfIndex, bool aIsRunning)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<BorderRouter::RoutingManager>().HandleInfraIfStateChanged(aInfraIfIndex,
|
||||
aIsRunning);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
|
@ -1,211 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2020, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes implementations for ICMPv6 Router Advertisement.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "border_router/router_advertisement.hpp"
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
#include "common/as_core_type.hpp"
|
||||
#include "common/code_utils.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
namespace BorderRouter {
|
||||
|
||||
namespace RouterAdv {
|
||||
|
||||
const Option *Option::GetNextOption(const Option *aCurOption, const uint8_t *aBuffer, uint16_t aBufferLength)
|
||||
{
|
||||
const uint8_t *nextOption = nullptr;
|
||||
const uint8_t *bufferEnd = aBuffer + aBufferLength;
|
||||
|
||||
VerifyOrExit(aBuffer != nullptr, nextOption = nullptr);
|
||||
|
||||
if (aCurOption == nullptr)
|
||||
{
|
||||
nextOption = aBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextOption = reinterpret_cast<const uint8_t *>(aCurOption) + aCurOption->GetSize();
|
||||
}
|
||||
|
||||
VerifyOrExit(nextOption + sizeof(Option) <= bufferEnd, nextOption = nullptr);
|
||||
VerifyOrExit(reinterpret_cast<const Option *>(nextOption)->GetSize() > 0, nextOption = nullptr);
|
||||
VerifyOrExit(nextOption + reinterpret_cast<const Option *>(nextOption)->GetSize() <= bufferEnd,
|
||||
nextOption = nullptr);
|
||||
|
||||
exit:
|
||||
return reinterpret_cast<const Option *>(nextOption);
|
||||
}
|
||||
|
||||
PrefixInfoOption::PrefixInfoOption(void)
|
||||
: Option(Type::kPrefixInfo, sizeof(*this) / kLengthUnit)
|
||||
, mPrefixLength(0)
|
||||
, mReserved1(0)
|
||||
, mValidLifetime(0)
|
||||
, mPreferredLifetime(0)
|
||||
, mReserved2(0)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(mReserved2);
|
||||
|
||||
mPrefix.Clear();
|
||||
}
|
||||
|
||||
void PrefixInfoOption::SetOnLink(bool aOnLink)
|
||||
{
|
||||
if (aOnLink)
|
||||
{
|
||||
mReserved1 |= kOnLinkFlagMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
mReserved1 &= ~kOnLinkFlagMask;
|
||||
}
|
||||
}
|
||||
|
||||
void PrefixInfoOption::SetAutoAddrConfig(bool aAutoAddrConfig)
|
||||
{
|
||||
if (aAutoAddrConfig)
|
||||
{
|
||||
mReserved1 |= kAutoConfigFlagMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
mReserved1 &= ~kAutoConfigFlagMask;
|
||||
}
|
||||
}
|
||||
|
||||
void PrefixInfoOption::SetPrefix(const Ip6::Prefix &aPrefix)
|
||||
{
|
||||
mPrefixLength = aPrefix.mLength;
|
||||
mPrefix = AsCoreType(&aPrefix.mPrefix);
|
||||
}
|
||||
|
||||
Ip6::Prefix PrefixInfoOption::GetPrefix(void) const
|
||||
{
|
||||
Ip6::Prefix prefix;
|
||||
|
||||
prefix.Set(mPrefix.GetBytes(), mPrefixLength);
|
||||
return prefix;
|
||||
}
|
||||
|
||||
RouteInfoOption::RouteInfoOption(void)
|
||||
: Option(Type::kRouteInfo, 0)
|
||||
, mPrefixLength(0)
|
||||
, mReserved(0)
|
||||
, mRouteLifetime(0)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(mReserved);
|
||||
|
||||
mPrefix.Clear();
|
||||
}
|
||||
|
||||
void RouteInfoOption::SetPreference(RoutePreference aPreference)
|
||||
{
|
||||
mReserved &= ~kPreferenceMask;
|
||||
mReserved |= (NetworkData::RoutePreferenceToValue(aPreference) << kPreferenceOffset) & kPreferenceMask;
|
||||
}
|
||||
|
||||
RouteInfoOption::RoutePreference RouteInfoOption::GetPreference(void) const
|
||||
{
|
||||
return NetworkData::RoutePreferenceFromValue((mReserved & kPreferenceMask) >> kPreferenceOffset);
|
||||
}
|
||||
|
||||
void RouteInfoOption::SetPrefix(const Ip6::Prefix &aPrefix)
|
||||
{
|
||||
// The total length (in bytes) of a Router Information Option
|
||||
// is: (8 bytes fixed option header) + (0, 8, or 16 bytes prefix).
|
||||
// Because the length of the option must be padded with 8 bytes,
|
||||
// the length of the prefix (in bits) must be padded with 64 bits.
|
||||
SetLength((aPrefix.mLength + kLengthUnit * CHAR_BIT - 1) / (kLengthUnit * CHAR_BIT) + 1);
|
||||
|
||||
mPrefixLength = aPrefix.mLength;
|
||||
mPrefix = AsCoreType(&aPrefix.mPrefix);
|
||||
}
|
||||
|
||||
Ip6::Prefix RouteInfoOption::GetPrefix(void) const
|
||||
{
|
||||
Ip6::Prefix prefix;
|
||||
|
||||
prefix.Set(mPrefix.GetBytes(), mPrefixLength);
|
||||
return prefix;
|
||||
}
|
||||
|
||||
bool RouteInfoOption::IsValid(void) const
|
||||
{
|
||||
return (GetLength() == 1 || GetLength() == 2 || GetLength() == 3) &&
|
||||
(mPrefixLength <= OT_IP6_ADDRESS_SIZE * CHAR_BIT) && NetworkData::IsRoutePreferenceValid(GetPreference());
|
||||
}
|
||||
|
||||
void RouterAdvMessage::SetToDefault(void)
|
||||
{
|
||||
mHeader.Clear();
|
||||
mHeader.SetType(Ip6::Icmp::Header::kTypeRouterAdvert);
|
||||
mReachableTime = 0;
|
||||
mRetransTimer = 0;
|
||||
}
|
||||
|
||||
const RouterAdvMessage &RouterAdvMessage::operator=(const RouterAdvMessage &aOther)
|
||||
{
|
||||
mHeader = aOther.mHeader;
|
||||
|
||||
// Set zero value and let platform do the calculation.
|
||||
mHeader.SetChecksum(0);
|
||||
|
||||
mReachableTime = aOther.mReachableTime;
|
||||
mRetransTimer = aOther.mRetransTimer;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool RouterAdvMessage::operator==(const RouterAdvMessage &aOther) const
|
||||
{
|
||||
return memcmp(&mHeader.mData, &aOther.mHeader.mData, sizeof(mHeader.mData)) == 0 &&
|
||||
mReachableTime == aOther.mReachableTime && mRetransTimer == aOther.mRetransTimer;
|
||||
}
|
||||
|
||||
RouterSolicitMessage::RouterSolicitMessage(void)
|
||||
{
|
||||
mHeader.Clear();
|
||||
mHeader.SetType(Ip6::Icmp::Header::kTypeRouterSolicit);
|
||||
}
|
||||
|
||||
} // namespace RouterAdv
|
||||
|
||||
} // namespace BorderRouter
|
||||
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
|
@ -1,511 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2020, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes definitions for IPv6 Router Advertisement.
|
||||
*
|
||||
* See RFC 4861: Neighbor Discovery for IP version 6 (https://tools.ietf.org/html/rfc4861).
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ROUTER_ADVERTISEMENT_HPP_
|
||||
#define ROUTER_ADVERTISEMENT_HPP_
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <openthread/netdata.h>
|
||||
#include <openthread/platform/toolchain.h>
|
||||
|
||||
#include "common/encoding.hpp"
|
||||
#include "common/equatable.hpp"
|
||||
#include "net/icmp6.hpp"
|
||||
#include "net/ip6.hpp"
|
||||
#include "thread/network_data_types.hpp"
|
||||
|
||||
using ot::Encoding::BigEndian::HostSwap16;
|
||||
using ot::Encoding::BigEndian::HostSwap32;
|
||||
|
||||
namespace ot {
|
||||
|
||||
namespace BorderRouter {
|
||||
|
||||
namespace RouterAdv {
|
||||
|
||||
/**
|
||||
* This class represents the variable length options in Neighbor
|
||||
* Discovery messages.
|
||||
*
|
||||
* @sa PrefixInfoOption
|
||||
* @sa RouteInfoOption
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class Option
|
||||
{
|
||||
public:
|
||||
enum class Type : uint8_t
|
||||
{
|
||||
kPrefixInfo = 3, ///< Prefix Information Option.
|
||||
kRouteInfo = 24, ///< Route Information Option.
|
||||
};
|
||||
|
||||
static constexpr uint8_t kLengthUnit = 8; ///< The unit of length in octets.
|
||||
|
||||
/**
|
||||
* This constructor initializes the option with given type and length.
|
||||
*
|
||||
* @param[in] aType The type of this option.
|
||||
* @param[in] aLength The length of this option in unit of 8 octets.
|
||||
*
|
||||
*/
|
||||
explicit Option(Type aType, uint8_t aLength = 0)
|
||||
: mType(aType)
|
||||
, mLength(aLength)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the type of this option.
|
||||
*
|
||||
* @returns The option type.
|
||||
*
|
||||
*/
|
||||
Type GetType(void) const { return mType; }
|
||||
|
||||
/**
|
||||
* This method sets the size of the option (in bytes).
|
||||
*
|
||||
* Since the option must end on their natural 64-bits boundaries,
|
||||
* the actual length set to the option is padded to (aSize + 7) / 8 * 8.
|
||||
*
|
||||
* @param[in] aSize The size of the option in unit of 1 byte.
|
||||
*
|
||||
*/
|
||||
void SetSize(uint16_t aSize) { mLength = static_cast<uint8_t>((aSize + kLengthUnit - 1) / kLengthUnit); }
|
||||
|
||||
/**
|
||||
* This method returns the size of the option (in bytes).
|
||||
*
|
||||
* @returns The size of the option in unit of 1 byte.
|
||||
*
|
||||
*/
|
||||
uint16_t GetSize(void) const { return mLength * kLengthUnit; }
|
||||
|
||||
/**
|
||||
* This method sets the length of the option (in unit of 8 bytes).
|
||||
*
|
||||
* @param[in] aLength The length of the option in unit of 8 bytes.
|
||||
*
|
||||
*/
|
||||
void SetLength(uint8_t aLength) { mLength = aLength; }
|
||||
|
||||
/**
|
||||
* This method returns the length of the option (in unit of 8 bytes).
|
||||
*
|
||||
* @returns The length of the option in unit of 8 bytes.
|
||||
*
|
||||
*/
|
||||
uint16_t GetLength(void) const { return mLength; }
|
||||
|
||||
/**
|
||||
* This helper method returns a pointer to the next valid option in the buffer.
|
||||
*
|
||||
* @param[in] aCurOption The current option. Use `nullptr` to get the first option.
|
||||
* @param[in] aBuffer The buffer within which the options are held.
|
||||
* @param[in] aBufferLength The length of the buffer.
|
||||
*
|
||||
* @returns A pointer to the next option if there are a valid one. Otherwise, `nullptr`.
|
||||
*
|
||||
*/
|
||||
static const Option *GetNextOption(const Option *aCurOption, const uint8_t *aBuffer, uint16_t aBufferLength);
|
||||
|
||||
/**
|
||||
* This method tells whether this option is valid.
|
||||
*
|
||||
* @return A boolean that indicates whether this option is valid.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const { return mLength > 0; }
|
||||
|
||||
private:
|
||||
Type mType; // Type of the option.
|
||||
uint8_t mLength; // Length of the option in unit of 8 octets,
|
||||
// including the `type` and `length` fields.
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class represents the Prefix Information Option.
|
||||
*
|
||||
* See section 4.6.2 of RFC 4861 for definition of this option.
|
||||
* https://tools.ietf.org/html/rfc4861#section-4.6.2
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class PrefixInfoOption : public Option
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes this option with zero prefix
|
||||
* length, valid lifetime and preferred lifetime.
|
||||
*
|
||||
*/
|
||||
PrefixInfoOption(void);
|
||||
|
||||
/**
|
||||
* This method returns the on-link flag.
|
||||
*
|
||||
* @returns A boolean which indicates whether the on-link flag is set.
|
||||
*
|
||||
*/
|
||||
bool GetOnLink(void) const { return (mReserved1 & kOnLinkFlagMask) != 0; }
|
||||
|
||||
/**
|
||||
* This method sets the on-link (L) flag.
|
||||
*
|
||||
* @param[in] aOnLink A boolean indicates whether the prefix is on-link or off-link.
|
||||
*
|
||||
*/
|
||||
void SetOnLink(bool aOnLink);
|
||||
|
||||
/**
|
||||
* This method returns the autonomous address-configuration (A) flag.
|
||||
*
|
||||
* @returns A boolean which indicates whether the A flag is set.
|
||||
*
|
||||
*/
|
||||
bool GetAutoAddrConfig(void) const { return (mReserved1 & kAutoConfigFlagMask) != 0; }
|
||||
|
||||
/**
|
||||
* This method sets the autonomous address-configuration (A) flag.
|
||||
*
|
||||
* @param[in] aAutoAddrConfig A boolean indicates whether this prefix can be used
|
||||
* for SLAAC.
|
||||
*
|
||||
*/
|
||||
void SetAutoAddrConfig(bool aAutoAddrConfig);
|
||||
|
||||
/**
|
||||
* This method set the valid lifetime of the prefix in seconds.
|
||||
*
|
||||
* @param[in] aValidLifetime The valid lifetime in seconds.
|
||||
*
|
||||
*/
|
||||
void SetValidLifetime(uint32_t aValidLifetime) { mValidLifetime = HostSwap32(aValidLifetime); }
|
||||
|
||||
/**
|
||||
* THis method returns the valid lifetime of the prefix in seconds.
|
||||
*
|
||||
* @returns The valid lifetime in seconds.
|
||||
*
|
||||
*/
|
||||
uint32_t GetValidLifetime(void) const { return HostSwap32(mValidLifetime); }
|
||||
|
||||
/**
|
||||
* This method sets the preferred lifetime of the prefix in seconds.
|
||||
*
|
||||
* @param[in] aPreferredLifetime The preferred lifetime in seconds.
|
||||
*
|
||||
*/
|
||||
void SetPreferredLifetime(uint32_t aPreferredLifetime) { mPreferredLifetime = HostSwap32(aPreferredLifetime); }
|
||||
|
||||
/**
|
||||
* THis method returns the preferred lifetime of the prefix in seconds.
|
||||
*
|
||||
* @returns The preferred lifetime in seconds.
|
||||
*
|
||||
*/
|
||||
uint32_t GetPreferredLifetime(void) const { return HostSwap32(mPreferredLifetime); }
|
||||
|
||||
/**
|
||||
* This method sets the prefix.
|
||||
*
|
||||
* @param[in] aPrefix The prefix contained in this option.
|
||||
*
|
||||
*/
|
||||
void SetPrefix(const Ip6::Prefix &aPrefix);
|
||||
|
||||
/**
|
||||
* This method returns the prefix in this option.
|
||||
*
|
||||
* @returns The IPv6 prefix in this option.
|
||||
*
|
||||
*/
|
||||
Ip6::Prefix GetPrefix(void) const;
|
||||
|
||||
/**
|
||||
* This method tells whether this option is valid.
|
||||
*
|
||||
* @returns A boolean indicates whether this option is valid.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const
|
||||
{
|
||||
return (GetSize() == sizeof(*this)) && (mPrefixLength <= OT_IP6_ADDRESS_SIZE * CHAR_BIT) &&
|
||||
(GetPreferredLifetime() <= GetValidLifetime());
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr uint8_t kAutoConfigFlagMask = 0x40; // Bit mask of the Automatic Address Configure flag.
|
||||
static constexpr uint8_t kOnLinkFlagMask = 0x80; // Bit mask of the On-link flag.
|
||||
|
||||
uint8_t mPrefixLength; // The prefix length in bits.
|
||||
uint8_t mReserved1; // The reserved field.
|
||||
uint32_t mValidLifetime; // The valid lifetime of the prefix.
|
||||
uint32_t mPreferredLifetime; // The preferred lifetime of the prefix.
|
||||
uint32_t mReserved2; // The reserved field.
|
||||
Ip6::Address mPrefix; // The prefix.
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
static_assert(sizeof(PrefixInfoOption) == 32, "invalid PrefixInfoOption structure");
|
||||
|
||||
/**
|
||||
* This class represents the Route Information Option.
|
||||
*
|
||||
* See section 2.3 of RFC 4191 for definition of this option.
|
||||
* https://tools.ietf.org/html/rfc4191#section-2.3
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class RouteInfoOption : public Option
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This type represents a route preference.
|
||||
*
|
||||
*/
|
||||
typedef NetworkData::RoutePreference RoutePreference;
|
||||
|
||||
/**
|
||||
* This constructor initializes this option with zero prefix length.
|
||||
*
|
||||
*/
|
||||
RouteInfoOption(void);
|
||||
|
||||
/**
|
||||
* This method sets the route preference.
|
||||
*
|
||||
* @param[in] aPreference The route preference.
|
||||
*
|
||||
*/
|
||||
void SetPreference(RoutePreference aPreference);
|
||||
|
||||
/**
|
||||
* This method returns the route preference.
|
||||
*
|
||||
* @returns The route preference.
|
||||
*
|
||||
*/
|
||||
RoutePreference GetPreference(void) const;
|
||||
|
||||
/**
|
||||
* This method sets the lifetime of the route in seconds.
|
||||
*
|
||||
* @param[in] aLifetime The lifetime of the route in seconds.
|
||||
*
|
||||
*/
|
||||
void SetRouteLifetime(uint32_t aLifetime) { mRouteLifetime = HostSwap32(aLifetime); }
|
||||
|
||||
/**
|
||||
* This method returns Route Lifetime in seconds.
|
||||
*
|
||||
* @returns The Route Lifetime in seconds.
|
||||
*
|
||||
*/
|
||||
uint32_t GetRouteLifetime(void) const { return HostSwap32(mRouteLifetime); }
|
||||
|
||||
/**
|
||||
* This method sets the prefix.
|
||||
*
|
||||
* @param[in] aPrefix The prefix contained in this option.
|
||||
*
|
||||
*/
|
||||
void SetPrefix(const Ip6::Prefix &aPrefix);
|
||||
|
||||
/**
|
||||
* This method returns the prefix in this option.
|
||||
*
|
||||
* @returns The IPv6 prefix in this option.
|
||||
*
|
||||
*/
|
||||
Ip6::Prefix GetPrefix(void) const;
|
||||
|
||||
/**
|
||||
* This method tells whether this option is valid.
|
||||
*
|
||||
* @returns A boolean indicates whether this option is valid.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const;
|
||||
|
||||
private:
|
||||
static constexpr uint8_t kPreferenceOffset = 3;
|
||||
static constexpr uint8_t kPreferenceMask = 3 << kPreferenceOffset;
|
||||
|
||||
uint8_t mPrefixLength; // The prefix length in bits.
|
||||
uint8_t mReserved; // The reserved field.
|
||||
uint32_t mRouteLifetime; // The lifetime in seconds.
|
||||
Ip6::Address mPrefix; // The prefix.
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
static_assert(sizeof(RouteInfoOption) == 24, "invalid RouteInfoOption structure");
|
||||
|
||||
/**
|
||||
* This class implements the Router Advertisement message.
|
||||
*
|
||||
* See section 4.2 of RFC 4861 for definition of this message.
|
||||
* https://tools.ietf.org/html/rfc4861#section-4.2
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class RouterAdvMessage : public Unequatable<RouterAdvMessage>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the Router Advertisement message with
|
||||
* zero router lifetime, reachable time and retransmission timer.
|
||||
*
|
||||
*/
|
||||
RouterAdvMessage(void) { SetToDefault(); }
|
||||
|
||||
/**
|
||||
* This method sets the RA message to default values.
|
||||
*
|
||||
*/
|
||||
void SetToDefault(void);
|
||||
|
||||
/**
|
||||
* This method sets the checksum value.
|
||||
*
|
||||
* @param[in] aChecksum The checksum value.
|
||||
*
|
||||
*/
|
||||
void SetChecksum(uint16_t aChecksum) { mHeader.SetChecksum(aChecksum); }
|
||||
|
||||
/**
|
||||
* This method sets the Router Lifetime in seconds.
|
||||
*
|
||||
* Zero Router Lifetime means we are not a default router.
|
||||
*
|
||||
* @param[in] aRouterLifetime The router lifetime in seconds.
|
||||
*
|
||||
*/
|
||||
void SetRouterLifetime(uint16_t aRouterLifetime)
|
||||
{
|
||||
mHeader.mData.m16[kRouteLifetimeIdx] = HostSwap16(aRouterLifetime);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the Router Lifetime.
|
||||
*
|
||||
* Zero Router Lifetime means we are not a default router.
|
||||
*
|
||||
* @returns The router lifetime in seconds.
|
||||
*
|
||||
*/
|
||||
uint16_t GetRouterLifetime(void) const { return HostSwap16(mHeader.mData.m16[kRouteLifetimeIdx]); }
|
||||
|
||||
/**
|
||||
* This method returns the Managed Address Configuration ('m') flag.
|
||||
*
|
||||
* @returns A boolean which indicates whether the 'm' flag is set.
|
||||
*
|
||||
*/
|
||||
bool GetManagedAddrConfig(void) const { return (mHeader.mData.m8[kReservedIdx] & kManagedAddressConfigMask) != 0; }
|
||||
|
||||
/**
|
||||
* This method overloads the assignment operator.
|
||||
*
|
||||
*/
|
||||
const RouterAdvMessage &operator=(const RouterAdvMessage &aOther);
|
||||
|
||||
/**
|
||||
* This method overloads operator `==` to evaluate whether or not
|
||||
* two instances of `RouterAdvMessage` are equal.
|
||||
*
|
||||
* @param[in] aOther The other `RouterAdvMessage` instance to compare with.
|
||||
*
|
||||
* @retval TRUE If the two `RouterAdvMessage` instances are equal.
|
||||
* @retval FALSE If the two `RouterAdvMessage` instances are not equal.
|
||||
*
|
||||
*/
|
||||
bool operator==(const RouterAdvMessage &aOther) const;
|
||||
|
||||
private:
|
||||
// The index of Route Lifetime in ICMPv6 Header Data. In unit of 2 octets.
|
||||
static constexpr uint8_t kRouteLifetimeIdx = 1;
|
||||
|
||||
// The index of Reserved byte in ICMPv6 Header Data. In unit of 1 octet.
|
||||
static constexpr uint8_t kReservedIdx = 1;
|
||||
|
||||
// The bitmask of the Managed Address Configuration ('m') flag.
|
||||
static constexpr uint8_t kManagedAddressConfigMask = 0x80;
|
||||
|
||||
Ip6::Icmp::Header mHeader; // The common ICMPv6 header.
|
||||
uint32_t mReachableTime; // The reachable time. In milliseconds.
|
||||
uint32_t mRetransTimer; // The retransmission timer. In milliseconds.
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
static_assert(sizeof(RouterAdvMessage) == 16, "invalid RouterAdvMessage structure");
|
||||
|
||||
/**
|
||||
* This class implements the Router Solicitation message.
|
||||
*
|
||||
* See section 4.1 of RFC 4861 for definition of this message.
|
||||
* https://tools.ietf.org/html/rfc4861#section-4.1
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class RouterSolicitMessage
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the Router Solicitation message.
|
||||
*
|
||||
*/
|
||||
RouterSolicitMessage(void);
|
||||
|
||||
private:
|
||||
Ip6::Icmp::Header mHeader; // The common ICMPv6 header.
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
static_assert(sizeof(RouterSolicitMessage) == 8, "invalid RouterSolicitMessage structure");
|
||||
|
||||
} // namespace RouterAdv
|
||||
|
||||
} // namespace BorderRouter
|
||||
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
#endif // ROUTER_ADVERTISEMENT_HPP_
|
File diff suppressed because it is too large
Load Diff
|
@ -48,15 +48,16 @@
|
|||
#endif
|
||||
|
||||
#include <openthread/netdata.h>
|
||||
#include <openthread/platform/infra_if.h>
|
||||
|
||||
#include "border_router/router_advertisement.hpp"
|
||||
#include "border_router/infra_if.hpp"
|
||||
#include "common/array.hpp"
|
||||
#include "common/error.hpp"
|
||||
#include "common/locator.hpp"
|
||||
#include "common/notifier.hpp"
|
||||
#include "common/string.hpp"
|
||||
#include "common/timer.hpp"
|
||||
#include "net/ip6.hpp"
|
||||
#include "net/nd6.hpp"
|
||||
#include "thread/network_data.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
@ -73,6 +74,7 @@ namespace BorderRouter {
|
|||
class RoutingManager : public InstanceLocator
|
||||
{
|
||||
friend class ot::Notifier;
|
||||
friend class ot::Instance;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -155,35 +157,21 @@ public:
|
|||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE
|
||||
|
||||
/**
|
||||
* This method receives an ICMPv6 message on the infrastructure interface.
|
||||
* This method processes a received ICMPv6 message from the infrastructure interface.
|
||||
*
|
||||
* Malformed or undesired messages are dropped silently.
|
||||
*
|
||||
* @param[in] aInfraIfIndex The infrastructure interface index.
|
||||
* @param[in] aPacket The received ICMPv6 packet.
|
||||
* @param[in] aSrcAddress The source address this message is sent from.
|
||||
* @param[in] aBuffer THe ICMPv6 message buffer.
|
||||
* @param[in] aLength The length of the ICMPv6 message buffer.
|
||||
*
|
||||
*/
|
||||
void RecvIcmp6Message(uint32_t aInfraIfIndex,
|
||||
const Ip6::Address &aSrcAddress,
|
||||
const uint8_t * aBuffer,
|
||||
uint16_t aBufferLength);
|
||||
void HandleReceived(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress);
|
||||
|
||||
/**
|
||||
* This method handles infrastructure interface state changes.
|
||||
*
|
||||
* @param[in] aInfraIfIndex The index of the infrastructure interface.
|
||||
* @param[in] aIsRunning A boolean that indicates whether the infrastructure
|
||||
* interface is running.
|
||||
*
|
||||
* @retval kErrorNone Successfully updated the infra interface status.
|
||||
* @retval kErrorInvalidState The Routing Manager is not initialized.
|
||||
* @retval kErrorInvalidArgs The @p aInfraIfIndex doesn't match the infra interface
|
||||
* the Routing Manager is initialized with.
|
||||
*
|
||||
*/
|
||||
Error HandleInfraIfStateChanged(uint32_t aInfraIfIndex, bool aIsRunning);
|
||||
void HandleInfraIfStateChanged(void) { EvaluateState(); }
|
||||
|
||||
/**
|
||||
* This method checks if the on-mesh prefix configuration is a valid OMR prefix.
|
||||
|
@ -250,76 +238,162 @@ private:
|
|||
// The value is chosen in range of [`kMaxRtrAdvInterval` upper bound (1800s), `kDefaultOnLinkPrefixLifetime`].
|
||||
static constexpr uint32_t kRtrAdvStaleTime = 1800;
|
||||
|
||||
// The VICARIOUS_SOLICIT_TIME in seconds. The Routing Manager will consider
|
||||
// the discovered prefixes invalid if they are not refreshed after receiving
|
||||
// a Router Solicitation message.
|
||||
// The value is equal to Router Solicitation timeout.
|
||||
static constexpr uint32_t kVicariousSolicitationTime =
|
||||
kRtrSolicitationInterval * (kMaxRtrSolicitations - 1) + kMaxRtrSolicitationDelay;
|
||||
|
||||
static_assert(kMinRtrAdvInterval <= 3 * kMaxRtrAdvInterval / 4, "invalid RA intervals");
|
||||
static_assert(kDefaultOmrPrefixLifetime >= kMaxRtrAdvInterval, "invalid default OMR prefix lifetime");
|
||||
static_assert(kDefaultOnLinkPrefixLifetime >= kMaxRtrAdvInterval, "invalid default on-link prefix lifetime");
|
||||
static_assert(kRtrAdvStaleTime >= 1800 && kRtrAdvStaleTime <= kDefaultOnLinkPrefixLifetime,
|
||||
"invalid RA STALE time");
|
||||
|
||||
// This struct represents an external prefix which is
|
||||
// discovered on the infrastructure interface.
|
||||
struct ExternalPrefix : public Clearable<ExternalPrefix>, public Unequatable<ExternalPrefix>
|
||||
class DiscoveredPrefixTable : public InstanceLocator
|
||||
{
|
||||
Ip6::Prefix mPrefix;
|
||||
uint32_t mValidLifetime;
|
||||
// This class maintains the discovered on-link and route prefixes
|
||||
// from the received RA messages by processing PIO and RIO options
|
||||
// from the message. It takes care of processing the RA message but
|
||||
// delegates the decision whether to include or exclude a prefix to
|
||||
// `RoutingManager` by calling its `ShouldProcessPrefixInfoOption()`
|
||||
// and `ShouldProcessRouteInfoOption()` methods.
|
||||
//
|
||||
// It manages the lifetime of the discovered entries and publishes
|
||||
// and unpublishes the prefixes in the Network Data (as external
|
||||
// route) as they are added or removed.
|
||||
//
|
||||
// When there is any change in the table (an entry is added, removed,
|
||||
// or modified), it signals the change to `RoutingManager` by calling
|
||||
// `HandleDiscoveredPrefixTableChanged()` callback. A `Tasklet` is
|
||||
// used for signalling which ensures that if there are multiple
|
||||
// changes within the same flow of execution, the callback is
|
||||
// invoked after all the changes are processed.
|
||||
|
||||
union
|
||||
public:
|
||||
enum NetDataMode : uint8_t // Used in `Remove{}` methods
|
||||
{
|
||||
// Preferred Lifetime of on-link prefix, available
|
||||
// only when `mIsOnLinkPrefix` is TRUE.
|
||||
uint32_t mPreferredLifetime;
|
||||
|
||||
// The preference of this route, available
|
||||
// only when `mIsOnLinkPrefix` is FALSE.
|
||||
RoutePreference mRoutePreference;
|
||||
kUnpublishFromNetData, // Unpublish the entry from Network Data if previously published.
|
||||
kKeepInNetData, // Keep entry in Network Data if previously published.
|
||||
};
|
||||
TimeMilli mTimeLastUpdate;
|
||||
bool mIsOnLinkPrefix;
|
||||
|
||||
bool operator==(const ExternalPrefix &aPrefix) const
|
||||
explicit DiscoveredPrefixTable(Instance &aInstance);
|
||||
|
||||
void ProcessRouterAdvertMessage(const Ip6::Nd::RouterAdvertMessage &aRaMessage,
|
||||
const Ip6::Address & aSrcAddress);
|
||||
|
||||
void FindFavoredOnLinkPrefix(Ip6::Prefix &aPrefix) const;
|
||||
bool ContainsOnLinkPrefix(const Ip6::Prefix &aPrefix) const;
|
||||
void RemoveOnLinkPrefix(const Ip6::Prefix &aPrefix, NetDataMode aNetDataMode);
|
||||
|
||||
bool ContainsRoutePrefix(const Ip6::Prefix &aPrefix) const;
|
||||
void RemoveRoutePrefix(const Ip6::Prefix &aPrefix, NetDataMode aNetDataMode);
|
||||
|
||||
void RemoveAllEntries(void);
|
||||
void RemoveOrDeprecateOldEntries(TimeMilli aTimeThreshold);
|
||||
|
||||
TimeMilli CalculateNextStaleTime(TimeMilli aNow) const;
|
||||
|
||||
private:
|
||||
static constexpr uint8_t kMaxEntries = OPENTHREAD_CONFIG_BORDER_ROUTING_MAX_DISCOVERED_PREFIXES;
|
||||
|
||||
struct Entry : private Clearable<Entry>, public Unequatable<Entry>
|
||||
{
|
||||
return mPrefix == aPrefix.mPrefix && mIsOnLinkPrefix == aPrefix.mIsOnLinkPrefix;
|
||||
}
|
||||
public:
|
||||
enum Type : uint8_t
|
||||
{
|
||||
kTypeOnLink,
|
||||
kTypeRoute,
|
||||
};
|
||||
|
||||
bool IsDeprecated(void) const
|
||||
{
|
||||
OT_ASSERT(mIsOnLinkPrefix);
|
||||
struct Matcher
|
||||
{
|
||||
Matcher(const Ip6::Prefix &aPrefix, Type aType)
|
||||
: mPrefix(aPrefix)
|
||||
, mType(aType)
|
||||
{
|
||||
}
|
||||
|
||||
return mTimeLastUpdate + TimeMilli::SecToMsec(mPreferredLifetime) <= TimerMilli::GetNow();
|
||||
}
|
||||
const Ip6::Prefix &mPrefix;
|
||||
bool mType;
|
||||
};
|
||||
|
||||
TimeMilli GetExpireTime(void) const { return mTimeLastUpdate + GetPrefixExpireDelay(mValidLifetime); }
|
||||
TimeMilli GetStaleTime(void) const
|
||||
{
|
||||
uint32_t delay = OT_MIN(kRtrAdvStaleTime, mIsOnLinkPrefix ? mPreferredLifetime : mValidLifetime);
|
||||
void InitFrom(const Ip6::Nd::PrefixInfoOption &aPio);
|
||||
void InitFrom(const Ip6::Nd::RouteInfoOption &aRio);
|
||||
bool IsOnLinkPrefix(void) const { return (mType == kTypeOnLink); }
|
||||
const Ip6::Prefix &GetPrefix(void) const { return mPrefix; }
|
||||
const TimeMilli & GetLastUpdateTime(void) const { return mLastUpdateTime; }
|
||||
uint32_t GetValidLifetime(void) const { return mValidLifetime; }
|
||||
void ClearValidLifetime(void) { mValidLifetime = 0; }
|
||||
TimeMilli GetExpireTime(void) const;
|
||||
TimeMilli GetStaleTime(void) const;
|
||||
bool operator==(const Entry &aOther) const;
|
||||
bool Matches(const Matcher &aMatcher) const;
|
||||
|
||||
return mTimeLastUpdate + TimeMilli::SecToMsec(delay);
|
||||
}
|
||||
// Methods to use when `IsOnLinkPrefix()`
|
||||
uint32_t GetPreferredLifetime(void) const { return mPreferredLifetime; }
|
||||
void ClearPreferredLifetime(void) { mPreferredLifetime = 0; }
|
||||
bool IsDeprecated(void) const;
|
||||
void AdoptValidAndPreferredLiftimesFrom(const Entry &aEntry);
|
||||
|
||||
static uint32_t GetPrefixExpireDelay(uint32_t aValidLifetime);
|
||||
// Method to use when `!IsOnlinkPrefix()`
|
||||
RoutePreference GetRoutePreference(void) const { return mRoutePreference; }
|
||||
|
||||
private:
|
||||
static uint32_t CalculateExpireDelay(uint32_t aValidLifetime);
|
||||
|
||||
Ip6::Prefix mPrefix;
|
||||
TimeMilli mLastUpdateTime;
|
||||
uint32_t mValidLifetime;
|
||||
uint32_t mPreferredLifetime; // Applicable when prefix is on-link.
|
||||
RoutePreference mRoutePreference; // Applicable when prefix is not on-link
|
||||
Type mType;
|
||||
};
|
||||
|
||||
typedef Array<Entry, kMaxEntries> EntryArray;
|
||||
|
||||
void RemovePrefix(const Ip6::Prefix &aPrefix, Entry::Type aType, NetDataMode aNetDataMode);
|
||||
|
||||
void ProcessPrefixInfoOption(const Ip6::Nd::PrefixInfoOption &aPio);
|
||||
void ProcessRouteInfoOption(const Ip6::Nd::RouteInfoOption &aRio);
|
||||
static void HandleTimer(Timer &aTimer);
|
||||
void HandleTimer(void);
|
||||
void RemoveExpiredEntries(void);
|
||||
void SignalTableChanged(void);
|
||||
static void HandleSignalTask(Tasklet &aTasklet);
|
||||
|
||||
EntryArray mEntries;
|
||||
TimerMilli mTimer;
|
||||
Tasklet mSignalTask;
|
||||
};
|
||||
|
||||
typedef Array<Ip6::Prefix, kMaxOmrPrefixNum> OmrPrefixArray;
|
||||
typedef Array<ExternalPrefix, kMaxDiscoveredPrefixNum> ExternalPrefixArray;
|
||||
class OmrPrefix // An OMR Prefix
|
||||
{
|
||||
public:
|
||||
static constexpr uint16_t kInfoStringSize = 60;
|
||||
typedef String<kInfoStringSize> InfoString;
|
||||
|
||||
void Init(const Ip6::Prefix &aPrefix, RoutePreference aPreference);
|
||||
void InitFrom(NetworkData::OnMeshPrefixConfig &aOnMeshPrefixConfig);
|
||||
const Ip6::Prefix &GetPrefix(void) const { return mPrefix; }
|
||||
RoutePreference GetPreference(void) const { return mPreference; }
|
||||
void SetPreference(RoutePreference aPreference) { mPreference = aPreference; }
|
||||
bool Matches(const Ip6::Prefix &aPrefix) const { return mPrefix == aPrefix; }
|
||||
bool IsFavoredOver(const OmrPrefix &aOther) const;
|
||||
InfoString ToString(void) const;
|
||||
|
||||
private:
|
||||
Ip6::Prefix mPrefix;
|
||||
RoutePreference mPreference;
|
||||
};
|
||||
|
||||
typedef Array<OmrPrefix, kMaxOmrPrefixNum> OmrPrefixArray;
|
||||
|
||||
void EvaluateState(void);
|
||||
void Start(void);
|
||||
void Stop(void);
|
||||
void HandleNotifierEvents(Events aEvents);
|
||||
bool IsInitialized(void) const { return mInfraIfIndex != 0; }
|
||||
bool IsInitialized(void) const { return mInfraIf.IsInitialized(); }
|
||||
bool IsEnabled(void) const { return mIsEnabled; }
|
||||
Error LoadOrGenerateRandomBrUlaPrefix(void);
|
||||
void GenerateOmrPrefix(void);
|
||||
Error LoadOrGenerateRandomOnLinkPrefix(void);
|
||||
void GenerateOnLinkPrefix(void);
|
||||
|
||||
const Ip6::Prefix *EvaluateOnLinkPrefix(void);
|
||||
void EvaluateOnLinkPrefix(void);
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE
|
||||
void GenerateNat64Prefix(void);
|
||||
|
@ -333,17 +407,13 @@ private:
|
|||
Error PublishLocalOmrPrefix(void);
|
||||
void UnpublishLocalOmrPrefix(void);
|
||||
bool IsOmrPrefixAddedToLocalNetworkData(void) const;
|
||||
Error AddExternalRoute(const Ip6::Prefix &aPrefix, RoutePreference aRoutePreference, bool aNat64 = false);
|
||||
void RemoveExternalRoute(const Ip6::Prefix &aPrefix);
|
||||
Error PublishExternalRoute(const Ip6::Prefix &aPrefix, RoutePreference aRoutePreference, bool aNat64 = false);
|
||||
void UnpublishExternalRoute(const Ip6::Prefix &aPrefix);
|
||||
void StartRouterSolicitationDelay(void);
|
||||
Error SendRouterSolicitation(void);
|
||||
void SendRouterAdvertisement(const OmrPrefixArray &aNewOmrPrefixes, const Ip6::Prefix *aNewOnLinkPrefix);
|
||||
void SendRouterAdvertisement(const OmrPrefixArray &aNewOmrPrefixes);
|
||||
bool IsRouterSolicitationInProgress(void) const;
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_VICARIOUS_RS_ENABLE
|
||||
static void HandleVicariousRouterSolicitTimer(Timer &aTimer);
|
||||
void HandleVicariousRouterSolicitTimer(void);
|
||||
#endif
|
||||
static void HandleRouterSolicitTimer(Timer &aTimer);
|
||||
void HandleRouterSolicitTimer(void);
|
||||
static void HandleDiscoveredPrefixInvalidTimer(Timer &aTimer);
|
||||
|
@ -355,18 +425,17 @@ private:
|
|||
static void HandleOnLinkPrefixDeprecateTimer(Timer &aTimer);
|
||||
|
||||
void DeprecateOnLinkPrefix(void);
|
||||
void HandleRouterSolicit(const Ip6::Address &aSrcAddress, const uint8_t *aBuffer, uint16_t aBufferLength);
|
||||
void HandleRouterAdvertisement(const Ip6::Address &aSrcAddress, const uint8_t *aBuffer, uint16_t aBufferLength);
|
||||
bool UpdateDiscoveredOnLinkPrefix(const RouterAdv::PrefixInfoOption &aPio);
|
||||
void UpdateDiscoveredOmrPrefix(const RouterAdv::RouteInfoOption &aRio);
|
||||
void InvalidateDiscoveredPrefixes(const Ip6::Prefix *aPrefix = nullptr, bool aIsOnLinkPrefix = true);
|
||||
void InvalidateAllDiscoveredPrefixes(void);
|
||||
void HandleRouterSolicit(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress);
|
||||
void HandleRouterAdvertisement(const InfraIf::Icmp6Packet &aPacket, const Ip6::Address &aSrcAddress);
|
||||
bool ShouldProcessPrefixInfoOption(const Ip6::Nd::PrefixInfoOption &aPio, const Ip6::Prefix &aPrefix);
|
||||
bool ShouldProcessRouteInfoOption(const Ip6::Nd::RouteInfoOption &aRio, const Ip6::Prefix &aPrefix);
|
||||
void HandleDiscoveredPrefixTableChanged(void);
|
||||
bool NetworkDataContainsOmrPrefix(const Ip6::Prefix &aPrefix) const;
|
||||
bool UpdateRouterAdvMessage(const RouterAdv::RouterAdvMessage *aRouterAdvMessage);
|
||||
void UpdateRouterAdvertHeader(const Ip6::Nd::RouterAdvertMessage *aRouterAdvertMessage);
|
||||
void ResetDiscoveredPrefixStaleTimer(void);
|
||||
|
||||
static bool IsValidBrUlaPrefix(const Ip6::Prefix &aBrUlaPrefix);
|
||||
static bool IsValidOnLinkPrefix(const RouterAdv::PrefixInfoOption &aPio);
|
||||
static bool IsValidOnLinkPrefix(const Ip6::Nd::PrefixInfoOption &aPio);
|
||||
static bool IsValidOnLinkPrefix(const Ip6::Prefix &aOnLinkPrefix);
|
||||
|
||||
// Indicates whether the Routing Manager is running (started).
|
||||
|
@ -376,13 +445,7 @@ private:
|
|||
// Manager will be stopped if we are disabled.
|
||||
bool mIsEnabled;
|
||||
|
||||
// Indicates whether the infra interface is running. The Routing
|
||||
// Manager will be stopped when the Infra interface is not running.
|
||||
bool mInfraIfIsRunning;
|
||||
|
||||
// The index of the infra interface on which Router Advertisement
|
||||
// messages will be sent.
|
||||
uint32_t mInfraIfIndex;
|
||||
InfraIf mInfraIf;
|
||||
|
||||
// The /48 BR ULA prefix loaded from local persistent storage or
|
||||
// randomly generated if none is found in persistent storage.
|
||||
|
@ -399,6 +462,10 @@ private:
|
|||
// advertised on infra link.
|
||||
OmrPrefixArray mAdvertisedOmrPrefixes;
|
||||
|
||||
// The currently favored (smallest) discovered on-link prefix.
|
||||
// Prefix length of zero indicates there is none.
|
||||
Ip6::Prefix mFavoredDiscoveredOnLinkPrefix;
|
||||
|
||||
// The on-link prefix loaded from local persistent storage or
|
||||
// randomly generated if non is found in persistent storage.
|
||||
Ip6::Prefix mLocalOnLinkPrefix;
|
||||
|
@ -416,29 +483,20 @@ private:
|
|||
// True if the local NAT64 prefix is advertised in Thread network.
|
||||
bool mIsAdvertisingLocalNat64Prefix;
|
||||
|
||||
// The array of prefixes discovered on the infra link. Those
|
||||
// prefixes consist of on-link prefix(es) and OMR prefixes
|
||||
// advertised by BRs in another Thread Network which is connected to
|
||||
// the same infra link.
|
||||
ExternalPrefixArray mDiscoveredPrefixes;
|
||||
DiscoveredPrefixTable mDiscoveredPrefixTable;
|
||||
|
||||
// The RA header and parameters for the infra interface.
|
||||
// This value is initialized with `RouterAdvMessage::SetToDefault`
|
||||
// and updated with RA messages initiated from infra interface.
|
||||
RouterAdv::RouterAdvMessage mRouterAdvMessage;
|
||||
TimeMilli mTimeRouterAdvMessageLastUpdate;
|
||||
bool mLearntRouterAdvMessageFromHost;
|
||||
Ip6::Nd::RouterAdvertMessage::Header mRouterAdvertHeader;
|
||||
TimeMilli mTimeRouterAdvMessageLastUpdate;
|
||||
bool mLearntRouterAdvMessageFromHost;
|
||||
|
||||
TimerMilli mDiscoveredPrefixInvalidTimer;
|
||||
TimerMilli mDiscoveredPrefixStaleTimer;
|
||||
|
||||
uint32_t mRouterAdvertisementCount;
|
||||
TimeMilli mLastRouterAdvertisementSendTime;
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_VICARIOUS_RS_ENABLE
|
||||
TimerMilli mVicariousRouterSolicitTimer;
|
||||
TimeMilli mTimeVicariousRouterSolicitStart;
|
||||
#endif
|
||||
TimerMilli mRouterSolicitTimer;
|
||||
TimeMilli mTimeRouterSolicitStart;
|
||||
uint8_t mRouterSolicitCount;
|
||||
|
|
|
@ -310,6 +310,27 @@ public:
|
|||
*/
|
||||
IndexType IndexOf(const Type &aElement) const { return static_cast<IndexType>(&aElement - &mElements[0]); }
|
||||
|
||||
/**
|
||||
* This method removes an element from the array.
|
||||
*
|
||||
* The @p aElement MUST be from the array, otherwise the behavior of this method is undefined.
|
||||
*
|
||||
* To remove @p aElement, it is replaced by the last element in array, so the order of items in the array can
|
||||
* change after a call to this method.
|
||||
*
|
||||
* The method uses assignment `=` operator on `Type` to copy the last element in place of @p aElement.
|
||||
*
|
||||
*/
|
||||
void Remove(Type &aElement)
|
||||
{
|
||||
Type *lastElement = PopBack();
|
||||
|
||||
if (lastElement != &aElement)
|
||||
{
|
||||
aElement = *lastElement;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method finds the first match of a given entry in the array.
|
||||
*
|
||||
|
@ -430,6 +451,32 @@ public:
|
|||
return FindMatching(aIndicator) != nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* This template method removes the first element in the array matching a given indicator.
|
||||
*
|
||||
* This method behaves similar to `Remove()`, i.e., the matched element (if found) is replaced with the last element
|
||||
* in the array (using `=` operator on `Type`). So the order of items in the array can change after a call to this
|
||||
* method.
|
||||
*
|
||||
* The template type `Indicator` specifies the type of @p aIndicator object which is used to match against elements
|
||||
* in the array. To check that an element matches the given indicator, the `Matches()` method is invoked on each
|
||||
* `Type` element in the array. The `Matches()` method should be provided by `Type` class accordingly:
|
||||
*
|
||||
* bool Type::Matches(const Indicator &aIndicator) const
|
||||
*
|
||||
* @param[in] aIndicator An indicator to match with elements in the array.
|
||||
*
|
||||
*/
|
||||
template <typename Indicator> void RemoveMatching(const Indicator &aIndicator)
|
||||
{
|
||||
Type *entry = FindMatching(aIndicator);
|
||||
|
||||
if (entry != nullptr)
|
||||
{
|
||||
Remove(*entry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method overloads assignment `=` operator to copy elements from another array into the array.
|
||||
*
|
||||
|
|
|
@ -972,6 +972,11 @@ template <> inline BorderRouter::RoutingManager &Instance::Get(void)
|
|||
{
|
||||
return mRoutingManager;
|
||||
}
|
||||
|
||||
template <> inline BorderRouter::InfraIf &Instance::Get(void)
|
||||
{
|
||||
return mRoutingManager.mInfraIf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
||||
|
|
|
@ -146,15 +146,15 @@ const char *SettingsBase::KeyToString(Key aKey)
|
|||
"NetworkInfo", // (3) kKeyNetworkInfo
|
||||
"ParentInfo", // (4) kKeyParentInfo
|
||||
"ChildInfo", // (5) kKeyChildInfo
|
||||
"", // (6) kKeyReserved
|
||||
"", // (6) Removed (previously auto-start).
|
||||
"SlaacIidSecretKey", // (7) kKeySlaacIidSecretKey
|
||||
"DadInfo", // (8) kKeyDadInfo
|
||||
"LegacyOmrPrefix", // (9) kKeyLegacyOmrPrefix
|
||||
"OnLinkPrefix", // (10) kKeyOnLinkPrefix
|
||||
"", // (9) Removed (previously OMR prefix).
|
||||
"", // (10) Removed (previously on-link prefix).
|
||||
"SrpEcdsaKey", // (11) kKeySrpEcdsaKey
|
||||
"SrpClientInfo", // (12) kKeySrpClientInfo
|
||||
"SrpServerInfo", // (13) kKeySrpServerInfo
|
||||
"LegacyNat64Prefix", // (14) kKeyLegacyNat64Prefix
|
||||
"", // (14) Removed (previously NAT64 prefix)
|
||||
"BrUlaPrefix", // (15) kKeyBrUlaPrefix
|
||||
};
|
||||
|
||||
|
@ -163,15 +163,11 @@ const char *SettingsBase::KeyToString(Key aKey)
|
|||
static_assert(3 == kKeyNetworkInfo, "kKeyNetworkInfo value is incorrect");
|
||||
static_assert(4 == kKeyParentInfo, "kKeyParentInfo value is incorrect");
|
||||
static_assert(5 == kKeyChildInfo, "kKeyChildInfo value is incorrect");
|
||||
static_assert(6 == kKeyReserved, "kKeyReserved value is incorrect");
|
||||
static_assert(7 == kKeySlaacIidSecretKey, "kKeySlaacIidSecretKey value is incorrect");
|
||||
static_assert(8 == kKeyDadInfo, "kKeyDadInfo value is incorrect");
|
||||
static_assert(9 == kKeyLegacyOmrPrefix, "kKeyLegacyOmrPrefix value is incorrect");
|
||||
static_assert(10 == kKeyOnLinkPrefix, "kKeyOnLinkPrefix value is incorrect");
|
||||
static_assert(11 == kKeySrpEcdsaKey, "kKeySrpEcdsaKey value is incorrect");
|
||||
static_assert(12 == kKeySrpClientInfo, "kKeySrpClientInfo value is incorrect");
|
||||
static_assert(13 == kKeySrpServerInfo, "kKeySrpServerInfo value is incorrect");
|
||||
static_assert(14 == kKeyLegacyNat64Prefix, "kKeyLegacyNat64Prefix value is incorrect");
|
||||
static_assert(15 == kKeyBrUlaPrefix, "kKeyBrUlaPrefix value is incorrect");
|
||||
|
||||
static_assert(kLastKey == kKeyBrUlaPrefix, "kLastKey is not valid");
|
||||
|
@ -435,9 +431,6 @@ void Settings::Log(Action aAction, Error aError, Key aKey, const void *aValue)
|
|||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
case kKeyBrUlaPrefix:
|
||||
case kKeyLegacyOmrPrefix:
|
||||
case kKeyOnLinkPrefix:
|
||||
case kKeyLegacyNat64Prefix:
|
||||
LogPrefix(aAction, aKey, *reinterpret_cast<const Ip6::Prefix *>(aValue));
|
||||
break;
|
||||
#endif
|
||||
|
|
|
@ -112,15 +112,11 @@ public:
|
|||
kKeyNetworkInfo = OT_SETTINGS_KEY_NETWORK_INFO,
|
||||
kKeyParentInfo = OT_SETTINGS_KEY_PARENT_INFO,
|
||||
kKeyChildInfo = OT_SETTINGS_KEY_CHILD_INFO,
|
||||
kKeyReserved = OT_SETTINGS_KEY_RESERVED,
|
||||
kKeySlaacIidSecretKey = OT_SETTINGS_KEY_SLAAC_IID_SECRET_KEY,
|
||||
kKeyDadInfo = OT_SETTINGS_KEY_DAD_INFO,
|
||||
kKeyLegacyOmrPrefix = OT_SETTINGS_KEY_LEGACY_OMR_PREFIX,
|
||||
kKeyOnLinkPrefix = OT_SETTINGS_KEY_ON_LINK_PREFIX,
|
||||
kKeySrpEcdsaKey = OT_SETTINGS_KEY_SRP_ECDSA_KEY,
|
||||
kKeySrpClientInfo = OT_SETTINGS_KEY_SRP_CLIENT_INFO,
|
||||
kKeySrpServerInfo = OT_SETTINGS_KEY_SRP_SERVER_INFO,
|
||||
kKeyLegacyNat64Prefix = OT_SETTINGS_KEY_LEGACY_NAT64_PREFIX,
|
||||
kKeyBrUlaPrefix = OT_SETTINGS_KEY_BR_ULA_PREFIX,
|
||||
};
|
||||
|
||||
|
@ -583,37 +579,7 @@ public:
|
|||
private:
|
||||
BrUlaPrefix(void) = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class defines constants and types for legacy OMR prefix settings.
|
||||
*
|
||||
*/
|
||||
class LegacyOmrPrefix
|
||||
{
|
||||
public:
|
||||
static constexpr Key kKey = kKeyLegacyOmrPrefix; ///< The associated key.
|
||||
|
||||
typedef Ip6::Prefix ValueType; ///< The associated value type.
|
||||
|
||||
private:
|
||||
LegacyOmrPrefix(void) = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class defines constants and types for on-link prefix settings.
|
||||
*
|
||||
*/
|
||||
class OnLinkPrefix
|
||||
{
|
||||
public:
|
||||
static constexpr Key kKey = kKeyOnLinkPrefix; ///< The associated key.
|
||||
|
||||
typedef Ip6::Prefix ValueType; ///< The associated value type.
|
||||
|
||||
private:
|
||||
OnLinkPrefix(void) = default;
|
||||
};
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
|
||||
/**
|
||||
|
|
|
@ -94,6 +94,13 @@ void TimeTicker::HandleTimer(void)
|
|||
Get<AddressResolver>().HandleTimeTick();
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE && OPENTHREAD_CONFIG_BORDER_ROUTER_REQUEST_ROUTER_ROLE
|
||||
if (mReceivers & Mask(kNetworkDataNotifier))
|
||||
{
|
||||
Get<NetworkData::Notifier>().HandleTimeTick();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE
|
||||
if (mReceivers & Mask(kChildSupervisor))
|
||||
{
|
||||
|
|
|
@ -71,6 +71,7 @@ public:
|
|||
kIp6FragmentReassembler, ///< `Ip6::Ip6` (handling of fragmented messages)
|
||||
kDuaManager, ///< `DuaManager`
|
||||
kMlrManager, ///< `MlrManager`
|
||||
kNetworkDataNotifier, ///< `NetworkData::Notifier`
|
||||
|
||||
kNumReceivers, ///< Number of receivers.
|
||||
};
|
||||
|
|
|
@ -55,6 +55,32 @@
|
|||
#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_BORDER_ROUTER_REQUEST_ROUTER_ROLE
|
||||
*
|
||||
* Define to 1 to enable mechanism on a Border Router which provides IP connectivity to request router role upgrade.
|
||||
*
|
||||
* This config is applicable on an `OPENTHREAD_FTD` build and when `OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE` is also
|
||||
* enabled.
|
||||
*
|
||||
* A Border Router is considered to provide external IP connectivity if at least one of the below conditions hold:
|
||||
*
|
||||
* - It has added at least one external route entry.
|
||||
* - It has added at least one prefix entry with default-route and on-mesh flags set.
|
||||
* - It has added at least one domain prefix (domain and on-mesh flags set).
|
||||
*
|
||||
* A Border Router which provides IP connectivity and is acting as a REED is eligible to request a router role upgrade
|
||||
* by sending an "Address Solicit" request to leader with status reason `BorderRouterRequest`. This reason is used when
|
||||
* the number of active routers in the Thread mesh is above the threshold, and only if the number of existing eligible
|
||||
* BRs (determined from the Thread Network Data) that are acting as router is less than two. This mechanism allows up
|
||||
* to two eligible Border Routers to request router role upgrade when the number of routers is already above the
|
||||
* threshold.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_BORDER_ROUTER_REQUEST_ROUTER_ROLE
|
||||
#define OPENTHREAD_CONFIG_BORDER_ROUTER_REQUEST_ROUTER_ROLE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
*
|
||||
|
@ -75,16 +101,6 @@
|
|||
#define OPENTHREAD_CONFIG_BORDER_ROUTING_MAX_DISCOVERED_PREFIXES 8
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_BORDER_ROUTING_VICARIOUS_RS_ENABLE
|
||||
*
|
||||
* Define to 1 to enable Border Routing Vicarious Router Solicitation.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_BORDER_ROUTING_VICARIOUS_RS_ENABLE
|
||||
#define OPENTHREAD_CONFIG_BORDER_ROUTING_VICARIOUS_RS_ENABLE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_BORDER_ROUTING_NAT64_ENABLE
|
||||
*
|
||||
|
|
|
@ -499,4 +499,26 @@
|
|||
#define OPENTHREAD_CONFIG_MAC_SCAN_DURATION 300
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE
|
||||
*
|
||||
* This setting configures if the beacon payload parsing needs to be enabled in MAC. This is optional and is disabled by
|
||||
* default because Thread 1.2.1 has removed support for beacon payloads.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE
|
||||
#define OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_MAC_OUTGOING_BEACON_PAYLOAD_ENABLE
|
||||
*
|
||||
* This setting configures if the beacon payload needs to be enabled in outgoing beacon frames. This is optional and is
|
||||
* disabled by default because Thread 1.2.1 has removed support for beacon payloads.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_MAC_OUTGOING_BEACON_PAYLOAD_ENABLE
|
||||
#define OPENTHREAD_CONFIG_MAC_OUTGOING_BEACON_PAYLOAD_ENABLE 0
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_MAC_H_
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#ifndef CONFIG_NETDATA_PUBLISHER_H_
|
||||
#define CONFIG_NETDATA_PUBLISHER_H_
|
||||
|
||||
#include "config/border_router.h"
|
||||
#include "config/srp_server.h"
|
||||
|
||||
/**
|
||||
|
@ -48,7 +49,8 @@
|
|||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE
|
||||
#define OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
||||
#define OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE \
|
||||
(OPENTHREAD_CONFIG_SRP_SERVER_ENABLE || OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE)
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -149,7 +151,13 @@
|
|||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES
|
||||
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
#define OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES \
|
||||
(OPENTHREAD_CONFIG_BORDER_ROUTING_MAX_DISCOVERED_PREFIXES + 5)
|
||||
#else
|
||||
#define OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES 3
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_NETDATA_PUBLISHER_H_
|
||||
|
|
|
@ -623,4 +623,8 @@
|
|||
#error "OPENTHREAD_CONFIG_PLATFORM_CSL_UNCERT was removed and no longer supported"
|
||||
#endif
|
||||
|
||||
#ifdef OPENTHREAD_CONFIG_BORDER_ROUTING_VICARIOUS_RS_ENABLE
|
||||
#error "OPENTHREAD_CONFIG_BORDER_ROUTING_VICARIOUS_RS_ENABLE was removed and no longer supported"
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_CORE_CONFIG_CHECK_H_
|
||||
|
|
|
@ -123,11 +123,6 @@ exit:
|
|||
StopPolling();
|
||||
break;
|
||||
|
||||
case kErrorAlready:
|
||||
LogDebg("Data poll tx requested when a previous data request still in send queue.");
|
||||
ScheduleNextPoll(kUsePreviousPollPeriod);
|
||||
break;
|
||||
|
||||
default:
|
||||
LogWarn("Unexpected error %s requesting data poll", ErrorToString(error));
|
||||
ScheduleNextPoll(kRecalculatePollPeriod);
|
||||
|
|
|
@ -164,6 +164,7 @@ public:
|
|||
* @param[in] aCallback A pointer to a function called on completion of a scanned channel.
|
||||
*
|
||||
* @retval kErrorNone Successfully started scanning the channel.
|
||||
* @retval kErrorBusy The radio is performing energy scanning.
|
||||
* @retval kErrorNotImplemented The radio doesn't support energy scanning.
|
||||
* @retval kErrorInvalidState If the raw link-layer isn't enabled.
|
||||
*
|
||||
|
|
|
@ -210,6 +210,11 @@ Error Mac::ConvertBeaconToActiveScanResult(const RxFrame *aBeaconFrame, ActiveSc
|
|||
{
|
||||
Error error = kErrorNone;
|
||||
Address address;
|
||||
#if OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE
|
||||
const BeaconPayload *beaconPayload = nullptr;
|
||||
const Beacon * beacon = nullptr;
|
||||
uint16_t payloadLength;
|
||||
#endif
|
||||
|
||||
memset(&aResult, 0, sizeof(ActiveScanResult));
|
||||
|
||||
|
@ -229,6 +234,23 @@ Error Mac::ConvertBeaconToActiveScanResult(const RxFrame *aBeaconFrame, ActiveSc
|
|||
aResult.mRssi = aBeaconFrame->GetRssi();
|
||||
aResult.mLqi = aBeaconFrame->GetLqi();
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE
|
||||
payloadLength = aBeaconFrame->GetPayloadLength();
|
||||
|
||||
beacon = reinterpret_cast<const Beacon *>(aBeaconFrame->GetPayload());
|
||||
beaconPayload = reinterpret_cast<const BeaconPayload *>(beacon->GetPayload());
|
||||
|
||||
if ((payloadLength >= (sizeof(*beacon) + sizeof(*beaconPayload))) && beacon->IsValid() && beaconPayload->IsValid())
|
||||
{
|
||||
aResult.mVersion = beaconPayload->GetProtocolVersion();
|
||||
aResult.mIsJoinable = beaconPayload->IsJoiningPermitted();
|
||||
aResult.mIsNative = beaconPayload->IsNative();
|
||||
IgnoreError(AsCoreType(&aResult.mNetworkName).Set(beaconPayload->GetNetworkName()));
|
||||
VerifyOrExit(IsValidUtf8String(aResult.mNetworkName.m8), error = kErrorParse);
|
||||
aResult.mExtendedPanId = beaconPayload->GetExtendedPanId();
|
||||
}
|
||||
#endif
|
||||
|
||||
LogBeacon("Received");
|
||||
|
||||
exit:
|
||||
|
@ -482,7 +504,7 @@ Error Mac::RequestDataPollTransmission(void)
|
|||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(IsEnabled(), error = kErrorInvalidState);
|
||||
VerifyOrExit(!IsActiveOrPending(kOperationTransmitPoll), error = kErrorAlready);
|
||||
VerifyOrExit(!IsActiveOrPending(kOperationTransmitPoll));
|
||||
|
||||
// We ensure data frame and data poll tx requests are handled in the
|
||||
// order they are requested. So if we have a pending direct data frame
|
||||
|
@ -715,6 +737,10 @@ TxFrame *Mac::PrepareBeacon(void)
|
|||
TxFrame *frame;
|
||||
uint16_t fcf;
|
||||
Beacon * beacon = nullptr;
|
||||
#if OPENTHREAD_CONFIG_MAC_OUTGOING_BEACON_PAYLOAD_ENABLE
|
||||
uint8_t beaconLength;
|
||||
BeaconPayload *beaconPayload = nullptr;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_MULTI_RADIO
|
||||
OT_ASSERT(!mTxBeaconRadioLinks.IsEmpty());
|
||||
|
@ -732,6 +758,30 @@ TxFrame *Mac::PrepareBeacon(void)
|
|||
beacon = reinterpret_cast<Beacon *>(frame->GetPayload());
|
||||
beacon->Init();
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_OUTGOING_BEACON_PAYLOAD_ENABLE
|
||||
beaconLength = sizeof(*beacon);
|
||||
|
||||
beaconPayload = reinterpret_cast<BeaconPayload *>(beacon->GetPayload());
|
||||
|
||||
beaconPayload->Init();
|
||||
|
||||
if (IsJoinable())
|
||||
{
|
||||
beaconPayload->SetJoiningPermitted();
|
||||
}
|
||||
else
|
||||
{
|
||||
beaconPayload->ClearJoiningPermitted();
|
||||
}
|
||||
|
||||
beaconPayload->SetNetworkName(Get<MeshCoP::NetworkNameManager>().GetNetworkName().GetAsData());
|
||||
beaconPayload->SetExtendedPanId(Get<MeshCoP::ExtendedPanIdManager>().GetExtPanId());
|
||||
|
||||
beaconLength += sizeof(*beaconPayload);
|
||||
|
||||
frame->SetPayloadLength(beaconLength);
|
||||
#endif
|
||||
|
||||
LogBeacon("Sending");
|
||||
|
||||
return frame;
|
||||
|
|
|
@ -228,7 +228,6 @@ public:
|
|||
* This method requests transmission of a data poll (MAC Data Request) frame.
|
||||
*
|
||||
* @retval kErrorNone Data poll transmission request is scheduled successfully.
|
||||
* @retval kErrorAlready MAC is busy sending earlier poll transmission request.
|
||||
* @retval kErrorInvalidState The MAC layer is not enabled.
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "common/const_cast.hpp"
|
||||
#include "common/encoding.hpp"
|
||||
#include "mac/mac_types.hpp"
|
||||
#include "meshcop/network_name.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Mac {
|
||||
|
@ -1482,6 +1483,145 @@ private:
|
|||
uint8_t mPendingAddressSpec;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements IEEE 802.15.4 Beacon Payload generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class BeaconPayload
|
||||
{
|
||||
public:
|
||||
static constexpr uint8_t kProtocolId = 3; ///< Thread Protocol ID.
|
||||
static constexpr uint8_t kProtocolVersion = 2; ///< Thread Protocol version.
|
||||
static constexpr uint8_t kVersionOffset = 4; ///< Version field bit offset.
|
||||
static constexpr uint8_t kVersionMask = 0xf << kVersionOffset; ///< Version field mask.
|
||||
static constexpr uint8_t kNativeFlag = 1 << 3; ///< Native Commissioner flag.
|
||||
static constexpr uint8_t kJoiningFlag = 1 << 0; ///< Joining Permitted flag.
|
||||
|
||||
/**
|
||||
* This method initializes the Beacon Payload.
|
||||
*
|
||||
*/
|
||||
void Init(void)
|
||||
{
|
||||
mProtocolId = kProtocolId;
|
||||
mFlags = kProtocolVersion << kVersionOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the beacon appears to be a valid Thread Beacon Payload.
|
||||
*
|
||||
* @retval TRUE If the beacon appears to be a valid Thread Beacon Payload.
|
||||
* @retval FALSE If the beacon does not appear to be a valid Thread Beacon Payload.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const { return (mProtocolId == kProtocolId); }
|
||||
|
||||
/**
|
||||
* This method returns the Protocol ID value.
|
||||
*
|
||||
* @returns the Protocol ID value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetProtocolId(void) const { return mProtocolId; }
|
||||
|
||||
/**
|
||||
* This method returns the Protocol Version value.
|
||||
*
|
||||
* @returns The Protocol Version value.
|
||||
*
|
||||
*/
|
||||
uint8_t GetProtocolVersion(void) const { return mFlags >> kVersionOffset; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the Native Commissioner flag is set.
|
||||
*
|
||||
* @retval TRUE If the Native Commissioner flag is set.
|
||||
* @retval FALSE If the Native Commissioner flag is not set.
|
||||
*
|
||||
*/
|
||||
bool IsNative(void) const { return (mFlags & kNativeFlag) != 0; }
|
||||
|
||||
/**
|
||||
* This method clears the Native Commissioner flag.
|
||||
*
|
||||
*/
|
||||
void ClearNative(void) { mFlags &= ~kNativeFlag; }
|
||||
|
||||
/**
|
||||
* This method sets the Native Commissioner flag.
|
||||
*
|
||||
*/
|
||||
void SetNative(void) { mFlags |= kNativeFlag; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the Joining Permitted flag is set.
|
||||
*
|
||||
* @retval TRUE If the Joining Permitted flag is set.
|
||||
* @retval FALSE If the Joining Permitted flag is not set.
|
||||
*
|
||||
*/
|
||||
bool IsJoiningPermitted(void) const { return (mFlags & kJoiningFlag) != 0; }
|
||||
|
||||
/**
|
||||
* This method clears the Joining Permitted flag.
|
||||
*
|
||||
*/
|
||||
void ClearJoiningPermitted(void) { mFlags &= ~kJoiningFlag; }
|
||||
|
||||
/**
|
||||
* This method sets the Joining Permitted flag.
|
||||
*
|
||||
*/
|
||||
void SetJoiningPermitted(void)
|
||||
{
|
||||
mFlags |= kJoiningFlag;
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_JOIN_BEACON_VERSION != 2 // check against kProtocolVersion
|
||||
mFlags &= ~kVersionMask;
|
||||
mFlags |= OPENTHREAD_CONFIG_MAC_JOIN_BEACON_VERSION << kVersionOffset;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets the Network Name field.
|
||||
*
|
||||
* @returns The Network Name field as `NameData`.
|
||||
*
|
||||
*/
|
||||
MeshCoP::NameData GetNetworkName(void) const { return MeshCoP::NameData(mNetworkName, sizeof(mNetworkName)); }
|
||||
|
||||
/**
|
||||
* This method sets the Network Name field.
|
||||
*
|
||||
* @param[in] aNameData The Network Name (as a `NameData`).
|
||||
*
|
||||
*/
|
||||
void SetNetworkName(const MeshCoP::NameData &aNameData) { aNameData.CopyTo(mNetworkName, sizeof(mNetworkName)); }
|
||||
|
||||
/**
|
||||
* This method returns the Extended PAN ID field.
|
||||
*
|
||||
* @returns The Extended PAN ID field.
|
||||
*
|
||||
*/
|
||||
const otExtendedPanId &GetExtendedPanId(void) const { return mExtendedPanId; }
|
||||
|
||||
/**
|
||||
* This method sets the Extended PAN ID field.
|
||||
*
|
||||
* @param[in] aExtPanId An Extended PAN ID.
|
||||
*
|
||||
*/
|
||||
void SetExtendedPanId(const otExtendedPanId &aExtPanId) { mExtendedPanId = aExtPanId; }
|
||||
|
||||
private:
|
||||
uint8_t mProtocolId;
|
||||
uint8_t mFlags;
|
||||
char mNetworkName[MeshCoP::NetworkName::kMaxSize];
|
||||
otExtendedPanId mExtendedPanId;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements CSL IE data structure.
|
||||
*
|
||||
|
|
|
@ -572,6 +572,7 @@ public:
|
|||
* @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned.
|
||||
*
|
||||
* @retval kErrorNone Successfully started scanning the channel.
|
||||
* @retval kErrorBusy The radio is performing energy scanning.
|
||||
* @retval kErrorInvalidState The radio was disabled or transmitting.
|
||||
* @retval kErrorNotImplemented Energy scan is not supported by radio link.
|
||||
*
|
||||
|
|
|
@ -379,6 +379,7 @@ public:
|
|||
* @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned.
|
||||
*
|
||||
* @retval kErrorNone Successfully started scanning the channel.
|
||||
* @retval kErrorBusy The radio is performing energy scanning.
|
||||
* @retval kErrorInvalidState The radio was disabled or transmitting.
|
||||
* @retval kErrorNotImplemented Energy scan is not supported (applicable in link-raw/radio mode only).
|
||||
*
|
||||
|
|
|
@ -588,7 +588,7 @@ void BorderAgent::Start(void)
|
|||
mState = kStateStarted;
|
||||
mUdpProxyPort = 0;
|
||||
|
||||
LogInfo("Border Agent start listening on port %d", kBorderAgentUdpPort);
|
||||
LogInfo("Border Agent start listening on port %u", GetUdpPort());
|
||||
|
||||
exit:
|
||||
if (error != kErrorNone)
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "common/log.hpp"
|
||||
#include "mac/mac_types.hpp"
|
||||
#include "meshcop/meshcop_tlvs.hpp"
|
||||
#include "meshcop/timestamp.hpp"
|
||||
#include "thread/mle_tlvs.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
@ -69,10 +70,12 @@ Error Dataset::Info::GenerateRandom(Instance &aInstance)
|
|||
|
||||
Clear();
|
||||
|
||||
mActiveTimestamp = 1;
|
||||
mChannel = preferredChannels.ChooseRandomChannel();
|
||||
mChannelMask = supportedChannels.GetMask();
|
||||
mPanId = Mac::GenerateRandomPanId();
|
||||
mActiveTimestamp.mSeconds = 1;
|
||||
mActiveTimestamp.mTicks = 0;
|
||||
mActiveTimestamp.mAuthoritative = false;
|
||||
mChannel = preferredChannels.ChooseRandomChannel();
|
||||
mChannelMask = supportedChannels.GetMask();
|
||||
mPanId = Mac::GenerateRandomPanId();
|
||||
AsCoreType(&mSecurityPolicy).SetToDefault();
|
||||
|
||||
SuccessOrExit(error = AsCoreType(&mNetworkKey).GenerateRandom());
|
||||
|
@ -193,7 +196,7 @@ void Dataset::ConvertTo(Info &aDatasetInfo) const
|
|||
switch (cur->GetType())
|
||||
{
|
||||
case Tlv::kActiveTimestamp:
|
||||
aDatasetInfo.SetActiveTimestamp(As<ActiveTimestampTlv>(cur)->GetTimestamp().GetSeconds());
|
||||
aDatasetInfo.SetActiveTimestamp(As<ActiveTimestampTlv>(cur)->GetTimestamp());
|
||||
break;
|
||||
|
||||
case Tlv::kChannel:
|
||||
|
@ -237,7 +240,7 @@ void Dataset::ConvertTo(Info &aDatasetInfo) const
|
|||
break;
|
||||
|
||||
case Tlv::kPendingTimestamp:
|
||||
aDatasetInfo.SetPendingTimestamp(As<PendingTimestampTlv>(cur)->GetTimestamp().GetSeconds());
|
||||
aDatasetInfo.SetPendingTimestamp(As<PendingTimestampTlv>(cur)->GetTimestamp());
|
||||
break;
|
||||
|
||||
case Tlv::kPskc:
|
||||
|
@ -286,20 +289,18 @@ Error Dataset::SetFrom(const Info &aDatasetInfo)
|
|||
|
||||
if (aDatasetInfo.IsActiveTimestampPresent())
|
||||
{
|
||||
Timestamp timestamp;
|
||||
Timestamp activeTimestamp;
|
||||
|
||||
timestamp.Clear();
|
||||
timestamp.SetSeconds(aDatasetInfo.GetActiveTimestamp());
|
||||
IgnoreError(SetTlv(Tlv::kActiveTimestamp, timestamp));
|
||||
aDatasetInfo.GetActiveTimestamp(activeTimestamp);
|
||||
IgnoreError(SetTlv(Tlv::kActiveTimestamp, activeTimestamp));
|
||||
}
|
||||
|
||||
if (aDatasetInfo.IsPendingTimestampPresent())
|
||||
{
|
||||
Timestamp timestamp;
|
||||
Timestamp pendingTimestamp;
|
||||
|
||||
timestamp.Clear();
|
||||
timestamp.SetSeconds(aDatasetInfo.GetPendingTimestamp());
|
||||
IgnoreError(SetTlv(Tlv::kPendingTimestamp, timestamp));
|
||||
aDatasetInfo.GetPendingTimestamp(pendingTimestamp);
|
||||
IgnoreError(SetTlv(Tlv::kPendingTimestamp, pendingTimestamp));
|
||||
}
|
||||
|
||||
if (aDatasetInfo.IsDelayPresent())
|
||||
|
|
|
@ -203,7 +203,7 @@ public:
|
|||
* @returns The Active Timestamp in the Dataset.
|
||||
*
|
||||
*/
|
||||
uint64_t GetActiveTimestamp(void) const { return mActiveTimestamp; }
|
||||
void GetActiveTimestamp(Timestamp &aTimestamp) const { aTimestamp.SetFromTimestamp(mActiveTimestamp); }
|
||||
|
||||
/**
|
||||
* This method sets the Active Timestamp in the Dataset.
|
||||
|
@ -211,9 +211,9 @@ public:
|
|||
* @param[in] aTimestamp A Timestamp value.
|
||||
*
|
||||
*/
|
||||
void SetActiveTimestamp(uint64_t aTimestamp)
|
||||
void SetActiveTimestamp(const Timestamp &aTimestamp)
|
||||
{
|
||||
mActiveTimestamp = aTimestamp;
|
||||
aTimestamp.ConvertTo(mActiveTimestamp);
|
||||
mComponents.mIsActiveTimestampPresent = true;
|
||||
}
|
||||
|
||||
|
@ -234,7 +234,7 @@ public:
|
|||
* @returns The Pending Timestamp in the Dataset.
|
||||
*
|
||||
*/
|
||||
uint64_t GetPendingTimestamp(void) const { return mPendingTimestamp; }
|
||||
void GetPendingTimestamp(Timestamp &aTimestamp) const { aTimestamp.SetFromTimestamp(mPendingTimestamp); }
|
||||
|
||||
/**
|
||||
* This method sets the Pending Timestamp in the Dataset.
|
||||
|
@ -242,9 +242,9 @@ public:
|
|||
* @param[in] aTimestamp A Timestamp value.
|
||||
*
|
||||
*/
|
||||
void SetPendingTimestamp(uint64_t aTimestamp)
|
||||
void SetPendingTimestamp(const Timestamp &aTimestamp)
|
||||
{
|
||||
mPendingTimestamp = aTimestamp;
|
||||
aTimestamp.ConvertTo(mPendingTimestamp);
|
||||
mComponents.mIsPendingTimestampPresent = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "common/locator_getters.hpp"
|
||||
#include "common/log.hpp"
|
||||
#include "common/random.hpp"
|
||||
#include "meshcop/timestamp.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace MeshCoP {
|
||||
|
@ -193,9 +194,17 @@ void DatasetUpdater::HandleNotifierEvents(Events aEvents)
|
|||
{
|
||||
Finish(kErrorNone);
|
||||
}
|
||||
else if (requestedDataset.GetActiveTimestamp() <= dataset.GetActiveTimestamp())
|
||||
else
|
||||
{
|
||||
Finish(kErrorAlready);
|
||||
Timestamp requestedDatasetTimestamp;
|
||||
Timestamp activeDatasetTimestamp;
|
||||
|
||||
requestedDataset.GetActiveTimestamp(requestedDatasetTimestamp);
|
||||
dataset.GetActiveTimestamp(activeDatasetTimestamp);
|
||||
if (Timestamp::Compare(requestedDatasetTimestamp, activeDatasetTimestamp) <= 0)
|
||||
{
|
||||
Finish(kErrorAlready);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,13 +38,23 @@
|
|||
namespace ot {
|
||||
namespace MeshCoP {
|
||||
|
||||
void Timestamp::ConvertTo(otTimestamp &aTimestamp) const
|
||||
{
|
||||
aTimestamp.mSeconds = GetSeconds();
|
||||
aTimestamp.mTicks = GetTicks();
|
||||
aTimestamp.mAuthoritative = GetAuthoritative();
|
||||
}
|
||||
|
||||
void Timestamp::SetFromTimestamp(const otTimestamp &aTimestamp)
|
||||
{
|
||||
SetSeconds(aTimestamp.mSeconds);
|
||||
SetTicks(aTimestamp.mTicks);
|
||||
SetAuthoritative(aTimestamp.mAuthoritative);
|
||||
}
|
||||
|
||||
int Timestamp::Compare(const Timestamp *aFirst, const Timestamp *aSecond)
|
||||
{
|
||||
int rval;
|
||||
uint64_t firstSeconds;
|
||||
uint64_t secondSeconds;
|
||||
uint16_t firstTicks;
|
||||
uint16_t secondTicks;
|
||||
int rval;
|
||||
|
||||
if (aFirst == nullptr)
|
||||
{
|
||||
|
@ -62,22 +72,46 @@ int Timestamp::Compare(const Timestamp *aFirst, const Timestamp *aSecond)
|
|||
|
||||
// Both are non-null.
|
||||
|
||||
firstSeconds = aFirst->GetSeconds();
|
||||
secondSeconds = aSecond->GetSeconds();
|
||||
rval = Compare(*aFirst, *aSecond);
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
int Timestamp::Compare(const Timestamp &aFirst, const Timestamp &aSecond)
|
||||
{
|
||||
int rval;
|
||||
uint64_t firstSeconds;
|
||||
uint64_t secondSeconds;
|
||||
uint16_t firstTicks;
|
||||
uint16_t secondTicks;
|
||||
bool firstAuthoritative;
|
||||
bool secondAuthoritative;
|
||||
|
||||
firstSeconds = aFirst.GetSeconds();
|
||||
secondSeconds = aSecond.GetSeconds();
|
||||
|
||||
if (firstSeconds != secondSeconds)
|
||||
{
|
||||
ExitNow(rval = (firstSeconds > secondSeconds) ? 1 : -1);
|
||||
}
|
||||
|
||||
firstTicks = aFirst->GetTicks();
|
||||
secondTicks = aSecond->GetTicks();
|
||||
firstTicks = aFirst.GetTicks();
|
||||
secondTicks = aSecond.GetTicks();
|
||||
|
||||
if (firstTicks != secondTicks)
|
||||
{
|
||||
ExitNow(rval = (firstTicks > secondTicks) ? 1 : -1);
|
||||
}
|
||||
|
||||
firstAuthoritative = aFirst.GetAuthoritative();
|
||||
secondAuthoritative = aSecond.GetAuthoritative();
|
||||
|
||||
if (firstAuthoritative != secondAuthoritative)
|
||||
{
|
||||
ExitNow(rval = firstAuthoritative ? 1 : -1);
|
||||
}
|
||||
|
||||
rval = 0;
|
||||
|
||||
exit:
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include <openthread/dataset.h>
|
||||
#include <openthread/platform/toolchain.h>
|
||||
|
||||
#include "common/clearable.hpp"
|
||||
|
@ -59,6 +60,18 @@ OT_TOOL_PACKED_BEGIN
|
|||
class Timestamp : public Clearable<Timestamp>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method converts the timestamp to `otTimestamp`.
|
||||
*
|
||||
*/
|
||||
void ConvertTo(otTimestamp &aTimestamp) const;
|
||||
|
||||
/**
|
||||
* This method sets the timestamp from `otTimestamp`.
|
||||
*
|
||||
*/
|
||||
void SetFromTimestamp(const otTimestamp &aTimestamp);
|
||||
|
||||
/**
|
||||
* This method returns the Seconds value.
|
||||
*
|
||||
|
@ -127,6 +140,15 @@ public:
|
|||
*/
|
||||
void AdvanceRandomTicks(void);
|
||||
|
||||
/**
|
||||
* This method indicates whether the timestamp indicates an MLE Orphan Announce message.
|
||||
*
|
||||
* @retval TRUE The timestamp indicates an Orphan Announce message.
|
||||
* @retval FALSE If the timestamp does not indicate an Orphan Announce message.
|
||||
*
|
||||
*/
|
||||
bool IsOrphanTimestamp(void) const { return GetSeconds() == 0 && GetTicks() == 0 && GetAuthoritative(); }
|
||||
|
||||
/**
|
||||
* This static method compares two timestamps.
|
||||
*
|
||||
|
@ -143,6 +165,19 @@ public:
|
|||
*/
|
||||
static int Compare(const Timestamp *aFirst, const Timestamp *aSecond);
|
||||
|
||||
/**
|
||||
* This static method compares two timestamps.
|
||||
*
|
||||
* @param[in] aFirst A reference to the first timestamp to compare.
|
||||
* @param[in] aSecond A reference to the second timestamp to compare.
|
||||
*
|
||||
* @retval -1 if @p aFirst is less than @p aSecond (`aFirst < aSecond`).
|
||||
* @retval 0 if @p aFirst is equal to @p aSecond (`aFirst == aSecond`).
|
||||
* @retval 1 if @p aFirst is greater than @p aSecond (`aFirst > aSecond`).
|
||||
*
|
||||
*/
|
||||
static int Compare(const Timestamp &aFirst, const Timestamp &aSecond);
|
||||
|
||||
private:
|
||||
static constexpr uint8_t kTicksOffset = 1;
|
||||
static constexpr uint16_t kTicksMask = 0x7fff << kTicksOffset;
|
||||
|
|
|
@ -1409,20 +1409,7 @@ exit:
|
|||
|
||||
void Dso::Connection::PendingRequests::Remove(MessageId aMessageId)
|
||||
{
|
||||
Entry *entry = mRequests.FindMatching(aMessageId);
|
||||
Entry *lastEntry;
|
||||
|
||||
VerifyOrExit(entry != nullptr);
|
||||
|
||||
// Remove last entry from the `mRequests` array, if it is not the
|
||||
// `entry` we want to remove, replace `entry` with `lastEntry.
|
||||
|
||||
lastEntry = mRequests.PopBack();
|
||||
VerifyOrExit(lastEntry != entry);
|
||||
*entry = *lastEntry;
|
||||
|
||||
exit:
|
||||
return;
|
||||
mRequests.RemoveMatching(aMessageId);
|
||||
}
|
||||
|
||||
bool Dso::Connection::PendingRequests::HasAnyTimedOut(TimeMilli aNow) const
|
||||
|
|
|
@ -65,6 +65,7 @@ Server::Server(Instance &aInstance)
|
|||
, mQueryUnsubscribe(nullptr)
|
||||
, mTimer(aInstance, Server::HandleTimer)
|
||||
{
|
||||
mCounters.Clear();
|
||||
}
|
||||
|
||||
Error Server::Start(void)
|
||||
|
@ -173,11 +174,19 @@ void Server::ProcessQuery(const Header &aRequestHeader, Message &aRequestMessage
|
|||
#endif
|
||||
|
||||
// Resolve the question using query callbacks if SRP server failed to resolve the questions.
|
||||
if (responseHeader.GetAnswerCount() == 0 &&
|
||||
kErrorNone == ResolveByQueryCallbacks(responseHeader, *responseMessage, compressInfo, aMessageInfo))
|
||||
if (responseHeader.GetAnswerCount() == 0)
|
||||
{
|
||||
resolveByQueryCallbacks = true;
|
||||
if (kErrorNone == ResolveByQueryCallbacks(responseHeader, *responseMessage, compressInfo, aMessageInfo))
|
||||
{
|
||||
resolveByQueryCallbacks = true;
|
||||
}
|
||||
}
|
||||
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
||||
else
|
||||
{
|
||||
++mCounters.mResolvedBySrp;
|
||||
}
|
||||
#endif
|
||||
|
||||
exit:
|
||||
if (error == kErrorNone && !resolveByQueryCallbacks)
|
||||
|
@ -220,6 +229,8 @@ void Server::SendResponse(Header aHeader,
|
|||
{
|
||||
LogInfo("send DNS-SD reply: %s, RCODE=%d", ErrorToString(error), aResponseCode);
|
||||
}
|
||||
|
||||
UpdateResponseCounters(aResponseCode);
|
||||
}
|
||||
|
||||
Header::Response Server::AddQuestions(const Header & aRequestHeader,
|
||||
|
@ -842,7 +853,7 @@ Server::QueryTransaction *Server::NewQuery(const Header & aResponseHead
|
|||
continue;
|
||||
}
|
||||
|
||||
query.Init(aResponseHeader, aResponseMessage, aCompressInfo, aMessageInfo);
|
||||
query.Init(aResponseHeader, aResponseMessage, aCompressInfo, aMessageInfo, GetInstance());
|
||||
ExitNow(newQuery = &query);
|
||||
}
|
||||
|
||||
|
@ -1194,10 +1205,12 @@ void Server::FinalizeQuery(QueryTransaction &aQuery, Header::Response aResponseC
|
|||
void Server::QueryTransaction::Init(const Header & aResponseHeader,
|
||||
Message & aResponseMessage,
|
||||
const NameCompressInfo &aCompressInfo,
|
||||
const Ip6::MessageInfo &aMessageInfo)
|
||||
const Ip6::MessageInfo &aMessageInfo,
|
||||
Instance & aInstance)
|
||||
{
|
||||
OT_ASSERT(mResponseMessage == nullptr);
|
||||
|
||||
InstanceLocatorInit::Init(aInstance);
|
||||
mResponseHeader = aResponseHeader;
|
||||
mResponseMessage = &aResponseMessage;
|
||||
mCompressInfo = aCompressInfo;
|
||||
|
@ -1209,10 +1222,35 @@ void Server::QueryTransaction::Finalize(Header::Response aResponseMessage, Ip6::
|
|||
{
|
||||
OT_ASSERT(mResponseMessage != nullptr);
|
||||
|
||||
SendResponse(mResponseHeader, aResponseMessage, *mResponseMessage, mMessageInfo, aSocket);
|
||||
Get<Server>().SendResponse(mResponseHeader, aResponseMessage, *mResponseMessage, mMessageInfo, aSocket);
|
||||
mResponseMessage = nullptr;
|
||||
}
|
||||
|
||||
void Server::UpdateResponseCounters(Header::Response aResponseCode)
|
||||
{
|
||||
switch (aResponseCode)
|
||||
{
|
||||
case UpdateHeader::kResponseSuccess:
|
||||
++mCounters.mSuccessResponse;
|
||||
break;
|
||||
case UpdateHeader::kResponseServerFailure:
|
||||
++mCounters.mServerFailureResponse;
|
||||
break;
|
||||
case UpdateHeader::kResponseFormatError:
|
||||
++mCounters.mFormatErrorResponse;
|
||||
break;
|
||||
case UpdateHeader::kResponseNameError:
|
||||
++mCounters.mNameErrorResponse;
|
||||
break;
|
||||
case UpdateHeader::kResponseNotImplemented:
|
||||
++mCounters.mNotImplementedResponse;
|
||||
break;
|
||||
default:
|
||||
++mCounters.mOtherResponse;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ServiceDiscovery
|
||||
} // namespace Dns
|
||||
} // namespace ot
|
||||
|
|
|
@ -67,6 +67,14 @@ class Server : public InstanceLocator, private NonCopyable
|
|||
friend class Srp::Server;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This class contains the counters of the DNS-SD server.
|
||||
*
|
||||
*/
|
||||
class Counters : public otDnssdCounters, public Clearable<Counters>
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* This enumeration specifies a DNS-SD query type.
|
||||
*
|
||||
|
@ -155,6 +163,14 @@ public:
|
|||
*/
|
||||
static DnsQueryType GetQueryTypeAndName(const otDnssdQuery *aQuery, char (&aName)[Name::kMaxNameSize]);
|
||||
|
||||
/**
|
||||
* This method returns the counters of the DNS-SD server.
|
||||
*
|
||||
* @returns A reference to the `Counters` instance.
|
||||
*
|
||||
*/
|
||||
const Counters &GetCounters(void) const { return mCounters; };
|
||||
|
||||
private:
|
||||
class NameCompressInfo : public Clearable<NameCompressInfo>
|
||||
{
|
||||
|
@ -273,7 +289,7 @@ private:
|
|||
* This class contains the compress information for a dns packet.
|
||||
*
|
||||
*/
|
||||
class QueryTransaction
|
||||
class QueryTransaction : public InstanceLocatorInit
|
||||
{
|
||||
public:
|
||||
explicit QueryTransaction(void)
|
||||
|
@ -284,7 +300,8 @@ private:
|
|||
void Init(const Header & aResponseHeader,
|
||||
Message & aResponseMessage,
|
||||
const NameCompressInfo &aCompressInfo,
|
||||
const Ip6::MessageInfo &aMessageInfo);
|
||||
const Ip6::MessageInfo &aMessageInfo,
|
||||
Instance & aInstance);
|
||||
bool IsValid(void) const { return mResponseMessage != nullptr; }
|
||||
const Ip6::MessageInfo &GetMessageInfo(void) const { return mMessageInfo; }
|
||||
const Header & GetResponseHeader(void) const { return mResponseHeader; }
|
||||
|
@ -347,7 +364,7 @@ private:
|
|||
static void IncResourceRecordCount(Header &aHeader, bool aAdditional);
|
||||
static Error FindNameComponents(const char *aName, const char *aDomain, NameComponentsOffsetInfo &aInfo);
|
||||
static Error FindPreviousLabel(const char *aName, uint8_t &aStart, uint8_t &aStop);
|
||||
static void SendResponse(Header aHeader,
|
||||
void SendResponse(Header aHeader,
|
||||
Header::Response aResponseCode,
|
||||
Message & aMessage,
|
||||
const Ip6::MessageInfo &aMessageInfo,
|
||||
|
@ -392,6 +409,8 @@ private:
|
|||
void HandleTimer(void);
|
||||
void ResetTimer(void);
|
||||
|
||||
void UpdateResponseCounters(Header::Response aResponseCode);
|
||||
|
||||
static const char kDnssdProtocolUdp[];
|
||||
static const char kDnssdProtocolTcp[];
|
||||
static const char kDnssdSubTypeLabel[];
|
||||
|
@ -403,6 +422,8 @@ private:
|
|||
otDnssdQuerySubscribeCallback mQuerySubscribe;
|
||||
otDnssdQueryUnsubscribeCallback mQueryUnsubscribe;
|
||||
TimerMilli mTimer;
|
||||
|
||||
Counters mCounters;
|
||||
};
|
||||
|
||||
} // namespace ServiceDiscovery
|
||||
|
|
|
@ -1309,43 +1309,29 @@ exit:
|
|||
|
||||
bool Ip6::ShouldForwardToThread(const MessageInfo &aMessageInfo, bool aFromHost) const
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aFromHost);
|
||||
bool shouldForward = false;
|
||||
|
||||
bool rval = false;
|
||||
|
||||
if (aMessageInfo.GetSockAddr().IsMulticast())
|
||||
if (aMessageInfo.GetSockAddr().IsMulticast() || aMessageInfo.GetSockAddr().IsLinkLocal())
|
||||
{
|
||||
// multicast
|
||||
ExitNow(rval = true);
|
||||
}
|
||||
else if (aMessageInfo.GetSockAddr().IsLinkLocal())
|
||||
{
|
||||
// on-link link-local address
|
||||
ExitNow(rval = true);
|
||||
shouldForward = true;
|
||||
}
|
||||
else if (IsOnLink(aMessageInfo.GetSockAddr()))
|
||||
{
|
||||
// on-link global address
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
|
||||
ExitNow(rval = (aFromHost ||
|
||||
!Get<BackboneRouter::Manager>().ShouldForwardDuaToBackbone(aMessageInfo.GetSockAddr())));
|
||||
shouldForward =
|
||||
(aFromHost || !Get<BackboneRouter::Manager>().ShouldForwardDuaToBackbone(aMessageInfo.GetSockAddr()));
|
||||
#else
|
||||
ExitNow(rval = true);
|
||||
OT_UNUSED_VARIABLE(aFromHost);
|
||||
shouldForward = true;
|
||||
#endif
|
||||
}
|
||||
else if (Get<ThreadNetif>().RouteLookup(aMessageInfo.GetPeerAddr(), aMessageInfo.GetSockAddr(), nullptr) ==
|
||||
kErrorNone)
|
||||
{
|
||||
// route
|
||||
ExitNow(rval = true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(rval = false);
|
||||
shouldForward = true;
|
||||
}
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
return shouldForward;
|
||||
}
|
||||
|
||||
const Netif::UnicastAddress *Ip6::SelectSourceAddress(MessageInfo &aMessageInfo)
|
||||
|
|
|
@ -77,13 +77,17 @@ bool Prefix::IsEqual(const uint8_t *aPrefixBytes, uint8_t aPrefixLength) const
|
|||
bool Prefix::operator<(const Prefix &aOther) const
|
||||
{
|
||||
bool isSmaller;
|
||||
uint8_t minLength;
|
||||
uint8_t matchedLength;
|
||||
|
||||
VerifyOrExit(GetLength() == aOther.GetLength(), isSmaller = GetLength() < aOther.GetLength());
|
||||
minLength = OT_MIN(GetLength(), aOther.GetLength());
|
||||
matchedLength = MatchLength(GetBytes(), aOther.GetBytes(), SizeForLength(minLength));
|
||||
|
||||
matchedLength = MatchLength(GetBytes(), aOther.GetBytes(), GetBytesSize());
|
||||
|
||||
VerifyOrExit(matchedLength < GetLength(), isSmaller = false);
|
||||
if (matchedLength >= minLength)
|
||||
{
|
||||
isSmaller = (GetLength() < aOther.GetLength());
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
isSmaller = GetBytes()[matchedLength / CHAR_BIT] < aOther.GetBytes()[matchedLength / CHAR_BIT];
|
||||
|
||||
|
|
|
@ -266,8 +266,10 @@ public:
|
|||
/**
|
||||
* This method overloads operator `<` to compare two prefixes.
|
||||
*
|
||||
* A prefix with shorter length is considered smaller than the one with longer length. If the prefix lengths are
|
||||
* equal, then the prefix bytes are compared directly.
|
||||
* If the two prefixes have the same length N, then the bytes are compared directly (as two big-endian N-bit
|
||||
* numbers). If the two prefix have different lengths, the shorter prefix is padded by `0` bit up to the longer
|
||||
* prefix length N before the bytes are compared (as big-endian N-bit numbers). If all bytes are equal, the prefix
|
||||
* with shorter length is considered smaller.
|
||||
*
|
||||
* @param[in] aOther The other prefix to compare against.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,282 @@
|
|||
/*
|
||||
* Copyright (c) 2020, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes implementations for IPv6 Neighbor Discovery (ND6).
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nd6.hpp"
|
||||
|
||||
#include "common/as_core_type.hpp"
|
||||
#include "common/code_utils.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Ip6 {
|
||||
namespace Nd {
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Option::Iterator
|
||||
|
||||
Option::Iterator::Iterator(void)
|
||||
: mOption(nullptr)
|
||||
, mEnd(nullptr)
|
||||
{
|
||||
// An empty iterator (used to indicate `end()` of list).
|
||||
}
|
||||
|
||||
Option::Iterator::Iterator(const void *aStart, const void *aEnd)
|
||||
: mOption(nullptr)
|
||||
, mEnd(reinterpret_cast<const Option *>(aEnd))
|
||||
{
|
||||
// Note that `Validate()` uses `mEnd` so can only be called after
|
||||
// `mEnd` is set.
|
||||
|
||||
mOption = Validate(reinterpret_cast<const Option *>(aStart));
|
||||
}
|
||||
|
||||
const Option *Option::Iterator::Next(const Option *aOption)
|
||||
{
|
||||
return reinterpret_cast<const Option *>(reinterpret_cast<const uint8_t *>(aOption) + aOption->GetSize());
|
||||
}
|
||||
|
||||
void Option::Iterator::Advance(void)
|
||||
{
|
||||
mOption = (mOption != nullptr) ? Validate(Next(mOption)) : nullptr;
|
||||
}
|
||||
|
||||
const Option *Option::Iterator::Validate(const Option *aOption) const
|
||||
{
|
||||
// Check if `aOption` is well-formed and fits in the range
|
||||
// up to `mEnd`. Returns `aOption` if it is valid, `nullptr`
|
||||
// otherwise.
|
||||
|
||||
return ((aOption != nullptr) && ((aOption + 1) <= mEnd) && aOption->IsValid() && (Next(aOption) <= mEnd)) ? aOption
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// PrefixInfoOption
|
||||
|
||||
void PrefixInfoOption::Init(void)
|
||||
{
|
||||
Clear();
|
||||
SetType(kTypePrefixInfo);
|
||||
SetSize(sizeof(PrefixInfoOption));
|
||||
|
||||
OT_UNUSED_VARIABLE(mReserved2);
|
||||
}
|
||||
|
||||
void PrefixInfoOption::SetPrefix(const Prefix &aPrefix)
|
||||
{
|
||||
mPrefixLength = aPrefix.mLength;
|
||||
mPrefix = AsCoreType(&aPrefix.mPrefix);
|
||||
}
|
||||
|
||||
void PrefixInfoOption::GetPrefix(Prefix &aPrefix) const
|
||||
{
|
||||
aPrefix.Set(mPrefix.GetBytes(), mPrefixLength);
|
||||
}
|
||||
|
||||
bool PrefixInfoOption::IsValid(void) const
|
||||
{
|
||||
return (GetSize() >= sizeof(*this)) && (mPrefixLength <= Prefix::kMaxLength) &&
|
||||
(GetPreferredLifetime() <= GetValidLifetime());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// RouteInfoOption
|
||||
|
||||
void RouteInfoOption::Init(void)
|
||||
{
|
||||
Clear();
|
||||
SetType(kTypeRouteInfo);
|
||||
}
|
||||
|
||||
void RouteInfoOption::SetPreference(RoutePreference aPreference)
|
||||
{
|
||||
mResvdPrf &= ~kPreferenceMask;
|
||||
mResvdPrf |= (NetworkData::RoutePreferenceToValue(aPreference) << kPreferenceOffset) & kPreferenceMask;
|
||||
}
|
||||
|
||||
RoutePreference RouteInfoOption::GetPreference(void) const
|
||||
{
|
||||
return NetworkData::RoutePreferenceFromValue((mResvdPrf & kPreferenceMask) >> kPreferenceOffset);
|
||||
}
|
||||
|
||||
void RouteInfoOption::SetPrefix(const Prefix &aPrefix)
|
||||
{
|
||||
SetLength(OptionLengthForPrefix(aPrefix.mLength));
|
||||
mPrefixLength = aPrefix.mLength;
|
||||
memcpy(GetPrefixBytes(), aPrefix.GetBytes(), aPrefix.GetBytesSize());
|
||||
}
|
||||
|
||||
void RouteInfoOption::GetPrefix(Prefix &aPrefix) const
|
||||
{
|
||||
aPrefix.Set(GetPrefixBytes(), mPrefixLength);
|
||||
}
|
||||
|
||||
bool RouteInfoOption::IsValid(void) const
|
||||
{
|
||||
return (GetSize() >= kMinSize) && (mPrefixLength <= Prefix::kMaxLength) &&
|
||||
(GetLength() >= OptionLengthForPrefix(mPrefixLength)) &&
|
||||
NetworkData::IsRoutePreferenceValid(GetPreference());
|
||||
}
|
||||
|
||||
uint8_t RouteInfoOption::OptionLengthForPrefix(uint8_t aPrefixLength)
|
||||
{
|
||||
static constexpr uint8_t kMaxPrefixLenForOptionLen1 = 0;
|
||||
static constexpr uint8_t kMaxPrefixLenForOptionLen2 = 64;
|
||||
|
||||
uint8_t length;
|
||||
|
||||
// The Option Length can be 1, 2, or 3 depending on the prefix
|
||||
// length
|
||||
//
|
||||
// - 1 when prefix len is zero.
|
||||
// - 2 when prefix len is less then or equal to 64.
|
||||
// - 3 otherwise.
|
||||
|
||||
if (aPrefixLength == kMaxPrefixLenForOptionLen1)
|
||||
{
|
||||
length = 1;
|
||||
}
|
||||
else if (aPrefixLength <= kMaxPrefixLenForOptionLen2)
|
||||
{
|
||||
length = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
length = 3;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// RouterAdverMessage::Header
|
||||
|
||||
void RouterAdvertMessage::Header::SetToDefault(void)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(mCode);
|
||||
OT_UNUSED_VARIABLE(mCurHopLimit);
|
||||
OT_UNUSED_VARIABLE(mReachableTime);
|
||||
OT_UNUSED_VARIABLE(mRetransTimer);
|
||||
|
||||
Clear();
|
||||
mType = Icmp::Header::kTypeRouterAdvert;
|
||||
}
|
||||
|
||||
RoutePreference RouterAdvertMessage::Header::GetDefaultRouterPreference(void) const
|
||||
{
|
||||
return NetworkData::RoutePreferenceFromValue((mFlags & kPreferenceMask) >> kPreferenceOffset);
|
||||
}
|
||||
|
||||
void RouterAdvertMessage::Header::SetDefaultRouterPreference(RoutePreference aPreference)
|
||||
{
|
||||
mFlags &= ~kPreferenceMask;
|
||||
mFlags |= (NetworkData::RoutePreferenceToValue(aPreference) << kPreferenceOffset) & kPreferenceMask;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// RouterAdverMessage
|
||||
|
||||
Option *RouterAdvertMessage::AppendOption(uint16_t aOptionSize)
|
||||
{
|
||||
// This method appends an option with a given size to the RA
|
||||
// message by reserving space in the data buffer if there is
|
||||
// room. On success returns pointer to the option, on failure
|
||||
// returns `nullptr`. The returned option needs to be
|
||||
// initialized and populated by the caller.
|
||||
|
||||
Option * option = nullptr;
|
||||
uint32_t newLength = mData.GetLength();
|
||||
|
||||
newLength += aOptionSize;
|
||||
VerifyOrExit(newLength <= mMaxLength);
|
||||
|
||||
option = reinterpret_cast<Option *>(AsNonConst(GetDataEnd()));
|
||||
mData.SetLength(static_cast<uint16_t>(newLength));
|
||||
|
||||
exit:
|
||||
return option;
|
||||
}
|
||||
|
||||
Error RouterAdvertMessage::AppendPrefixInfoOption(const Prefix &aPrefix,
|
||||
uint32_t aValidLifetime,
|
||||
uint32_t aPreferredLifetime)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
PrefixInfoOption *pio;
|
||||
|
||||
pio = static_cast<PrefixInfoOption *>(AppendOption(sizeof(PrefixInfoOption)));
|
||||
VerifyOrExit(pio != nullptr, error = kErrorNoBufs);
|
||||
|
||||
pio->Init();
|
||||
pio->SetOnLinkFlag();
|
||||
pio->SetAutoAddrConfigFlag();
|
||||
pio->SetValidLifetime(aValidLifetime);
|
||||
pio->SetPreferredLifetime(aPreferredLifetime);
|
||||
pio->SetPrefix(aPrefix);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error RouterAdvertMessage::AppendRouteInfoOption(const Prefix & aPrefix,
|
||||
uint32_t aRouteLifetime,
|
||||
RoutePreference aPreference)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
RouteInfoOption *rio;
|
||||
|
||||
rio = static_cast<RouteInfoOption *>(AppendOption(RouteInfoOption::OptionSizeForPrefix(aPrefix.GetLength())));
|
||||
VerifyOrExit(rio != nullptr, error = kErrorNoBufs);
|
||||
|
||||
rio->Init();
|
||||
rio->SetRouteLifetime(aRouteLifetime);
|
||||
rio->SetPreference(aPreference);
|
||||
rio->SetPrefix(aPrefix);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// RouterAdvMessage
|
||||
|
||||
RouterSolicitMessage::RouterSolicitMessage(void)
|
||||
{
|
||||
mHeader.Clear();
|
||||
mHeader.SetType(Icmp::Header::kTypeRouterSolicit);
|
||||
}
|
||||
|
||||
} // namespace Nd
|
||||
} // namespace Ip6
|
||||
} // namespace ot
|
|
@ -0,0 +1,699 @@
|
|||
/*
|
||||
* Copyright (c) 2020, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes definitions for IPv6 Neighbor Discovery (ND).
|
||||
*
|
||||
* See RFC 4861 (https://tools.ietf.org/html/rfc4861) and RFC 4191 (https://tools.ietf.org/html/rfc4191).
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ND6_HPP_
|
||||
#define ND6_HPP_
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <openthread/netdata.h>
|
||||
#include <openthread/platform/toolchain.h>
|
||||
|
||||
#include "common/const_cast.hpp"
|
||||
#include "common/encoding.hpp"
|
||||
#include "common/equatable.hpp"
|
||||
#include "net/icmp6.hpp"
|
||||
#include "net/ip6.hpp"
|
||||
#include "thread/network_data_types.hpp"
|
||||
|
||||
using ot::Encoding::BigEndian::HostSwap16;
|
||||
using ot::Encoding::BigEndian::HostSwap32;
|
||||
|
||||
namespace ot {
|
||||
namespace Ip6 {
|
||||
namespace Nd {
|
||||
|
||||
typedef NetworkData::RoutePreference RoutePreference; ///< Route Preference
|
||||
|
||||
/**
|
||||
* This class represents the variable length options in Neighbor Discovery messages.
|
||||
*
|
||||
* @sa PrefixInfoOption
|
||||
* @sa RouteInfoOption
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class Option
|
||||
{
|
||||
friend class RouterAdvertMessage;
|
||||
|
||||
public:
|
||||
enum Type : uint8_t
|
||||
{
|
||||
kTypePrefixInfo = 3, ///< Prefix Information Option.
|
||||
kTypeRouteInfo = 24, ///< Route Information Option.
|
||||
};
|
||||
|
||||
static constexpr uint16_t kLengthUnit = 8; ///< The unit of length in octets.
|
||||
|
||||
/**
|
||||
* This method gets the option type.
|
||||
*
|
||||
* @returns The option type.
|
||||
*
|
||||
*/
|
||||
uint8_t GetType(void) const { return mType; }
|
||||
|
||||
/**
|
||||
* This method sets the option type.
|
||||
*
|
||||
* @param[in] aType The option type.
|
||||
*
|
||||
*
|
||||
*/
|
||||
void SetType(Type aType) { mType = aType; }
|
||||
|
||||
/**
|
||||
* This method sets the length based on a given total option size in bytes.
|
||||
*
|
||||
* Th option must end on a 64-bit boundary, so the length is derived as `(aSize + 7) / 8 * 8`.
|
||||
*
|
||||
* @param[in] aSize The size of option in bytes.
|
||||
*
|
||||
*/
|
||||
void SetSize(uint16_t aSize) { mLength = static_cast<uint8_t>((aSize + kLengthUnit - 1) / kLengthUnit); }
|
||||
|
||||
/**
|
||||
* This method returns the size of the option in bytes.
|
||||
*
|
||||
* @returns The size of the option in bytes.
|
||||
*
|
||||
*/
|
||||
uint16_t GetSize(void) const { return mLength * kLengthUnit; }
|
||||
|
||||
/**
|
||||
* This method sets the length of the option (in unit of 8 bytes).
|
||||
*
|
||||
* @param[in] aLength The length of the option in unit of 8 bytes.
|
||||
*
|
||||
*/
|
||||
void SetLength(uint8_t aLength) { mLength = aLength; }
|
||||
|
||||
/**
|
||||
* This method returns the length of the option (in unit of 8 bytes).
|
||||
*
|
||||
* @returns The length of the option in unit of 8 bytes.
|
||||
*
|
||||
*/
|
||||
uint16_t GetLength(void) const { return mLength; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not this option is valid.
|
||||
*
|
||||
* @retval TRUE The option is valid.
|
||||
* @retval FALSE The option is not valid.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const { return mLength > 0; }
|
||||
|
||||
private:
|
||||
class Iterator : public Unequatable<Iterator>
|
||||
{
|
||||
public:
|
||||
Iterator(void);
|
||||
Iterator(const void *aStart, const void *aEnd);
|
||||
|
||||
const Option &operator*(void) { return *mOption; }
|
||||
void operator++(void) { Advance(); }
|
||||
void operator++(int) { Advance(); }
|
||||
bool operator==(const Iterator &aOther) const { return mOption == aOther.mOption; }
|
||||
|
||||
private:
|
||||
static const Option *Next(const Option *aOption);
|
||||
void Advance(void);
|
||||
const Option * Validate(const Option *aOption) const;
|
||||
|
||||
const Option *mOption;
|
||||
const Option *mEnd;
|
||||
};
|
||||
|
||||
uint8_t mType; // Type of the option.
|
||||
uint8_t mLength; // Length of the option in unit of 8 octets, including the `mType` and `mLength` fields.
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class represents the Prefix Information Option.
|
||||
*
|
||||
* See section 4.6.2 of RFC 4861 for definition of this option [https://tools.ietf.org/html/rfc4861#section-4.6.2]
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class PrefixInfoOption : public Option, private Clearable<PrefixInfoOption>
|
||||
{
|
||||
public:
|
||||
static constexpr Type kType = kTypePrefixInfo; ///< Prefix Information Option Type.
|
||||
|
||||
/**
|
||||
* This method initializes the Prefix Info option with proper type and length and sets all other fields to zero.
|
||||
*
|
||||
*/
|
||||
void Init(void);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the on-link flag is set.
|
||||
*
|
||||
* @retval TRUE The on-link flag is set.
|
||||
* @retval FALSE The on-link flag is not set.
|
||||
*
|
||||
*/
|
||||
bool IsOnLinkFlagSet(void) const { return (mFlags & kOnLinkFlagMask) != 0; }
|
||||
|
||||
/**
|
||||
* This method sets the on-link (L) flag.
|
||||
*
|
||||
*/
|
||||
void SetOnLinkFlag(void) { mFlags |= kOnLinkFlagMask; }
|
||||
|
||||
/**
|
||||
* This method clears the on-link (L) flag.
|
||||
*
|
||||
*/
|
||||
void ClearOnLinkFlag(void) { mFlags &= ~kOnLinkFlagMask; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the autonomous address-configuration (A) flag is set.
|
||||
*
|
||||
* @retval TRUE The auto address-config flag is set.
|
||||
* @retval FALSE The auto address-config flag is not set.
|
||||
*
|
||||
*/
|
||||
bool IsAutoAddrConfigFlagSet(void) const { return (mFlags & kAutoConfigFlagMask) != 0; }
|
||||
|
||||
/**
|
||||
* This method sets the autonomous address-configuration (A) flag.
|
||||
*
|
||||
*/
|
||||
void SetAutoAddrConfigFlag(void) { mFlags |= kAutoConfigFlagMask; }
|
||||
|
||||
/**
|
||||
* This method clears the autonomous address-configuration (A) flag.
|
||||
*
|
||||
*/
|
||||
void ClearAutoAddrConfigFlag(void) { mFlags &= ~kAutoConfigFlagMask; }
|
||||
|
||||
/**
|
||||
* This method sets the valid lifetime of the prefix in seconds.
|
||||
*
|
||||
* @param[in] aValidLifetime The valid lifetime in seconds.
|
||||
*
|
||||
*/
|
||||
void SetValidLifetime(uint32_t aValidLifetime) { mValidLifetime = HostSwap32(aValidLifetime); }
|
||||
|
||||
/**
|
||||
* THis method gets the valid lifetime of the prefix in seconds.
|
||||
*
|
||||
* @returns The valid lifetime in seconds.
|
||||
*
|
||||
*/
|
||||
uint32_t GetValidLifetime(void) const { return HostSwap32(mValidLifetime); }
|
||||
|
||||
/**
|
||||
* This method sets the preferred lifetime of the prefix in seconds.
|
||||
*
|
||||
* @param[in] aPreferredLifetime The preferred lifetime in seconds.
|
||||
*
|
||||
*/
|
||||
void SetPreferredLifetime(uint32_t aPreferredLifetime) { mPreferredLifetime = HostSwap32(aPreferredLifetime); }
|
||||
|
||||
/**
|
||||
* THis method returns the preferred lifetime of the prefix in seconds.
|
||||
*
|
||||
* @returns The preferred lifetime in seconds.
|
||||
*
|
||||
*/
|
||||
uint32_t GetPreferredLifetime(void) const { return HostSwap32(mPreferredLifetime); }
|
||||
|
||||
/**
|
||||
* This method sets the prefix.
|
||||
*
|
||||
* @param[in] aPrefix The prefix contained in this option.
|
||||
*
|
||||
*/
|
||||
void SetPrefix(const Prefix &aPrefix);
|
||||
|
||||
/**
|
||||
* This method gets the prefix in this option.
|
||||
*
|
||||
* @param[out] aPrefix Reference to a `Prefix` to return the prefix.
|
||||
*
|
||||
*/
|
||||
void GetPrefix(Prefix &aPrefix) const;
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the option is valid.
|
||||
*
|
||||
* @retval TRUE The option is valid
|
||||
* @retval FALSE The option is not valid.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const;
|
||||
|
||||
PrefixInfoOption(void) = delete;
|
||||
|
||||
private:
|
||||
// Prefix Information Option
|
||||
//
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type | Length | Prefix Length |L|A| Reserved1 |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Valid Lifetime |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Preferred Lifetime |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Reserved2 |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | |
|
||||
// + +
|
||||
// | |
|
||||
// + Prefix +
|
||||
// | |
|
||||
// + +
|
||||
// | |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
static constexpr uint8_t kAutoConfigFlagMask = 0x40; // Autonomous address-configuration flag.
|
||||
static constexpr uint8_t kOnLinkFlagMask = 0x80; // On-link flag.
|
||||
|
||||
uint8_t mPrefixLength; // The prefix length in bits.
|
||||
uint8_t mFlags; // The flags field.
|
||||
uint32_t mValidLifetime; // The valid lifetime of the prefix.
|
||||
uint32_t mPreferredLifetime; // The preferred lifetime of the prefix.
|
||||
uint32_t mReserved2; // The reserved field.
|
||||
Address mPrefix; // The prefix.
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
static_assert(sizeof(PrefixInfoOption) == 32, "invalid PrefixInfoOption structure");
|
||||
|
||||
/**
|
||||
* This class represents the Route Information Option.
|
||||
*
|
||||
* See section 2.3 of RFC 4191 for definition of this option. [https://tools.ietf.org/html/rfc4191#section-2.3]
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class RouteInfoOption : public Option, private Clearable<RouteInfoOption>
|
||||
{
|
||||
public:
|
||||
static constexpr uint16_t kMinSize = kLengthUnit; ///< Minimum size (in bytes) of a Route Info Option
|
||||
static constexpr Type kType = kTypeRouteInfo; ///< Route Information Option Type.
|
||||
|
||||
/**
|
||||
* This method initializes the option setting the type and clearing (setting to zero) all other fields.
|
||||
*
|
||||
*/
|
||||
void Init(void);
|
||||
|
||||
/**
|
||||
* This method sets the route preference.
|
||||
*
|
||||
* @param[in] aPreference The route preference.
|
||||
*
|
||||
*/
|
||||
void SetPreference(RoutePreference aPreference);
|
||||
|
||||
/**
|
||||
* This method gets the route preference.
|
||||
*
|
||||
* @returns The route preference.
|
||||
*
|
||||
*/
|
||||
RoutePreference GetPreference(void) const;
|
||||
|
||||
/**
|
||||
* This method sets the lifetime of the route in seconds.
|
||||
*
|
||||
* @param[in] aLifetime The lifetime of the route in seconds.
|
||||
*
|
||||
*/
|
||||
void SetRouteLifetime(uint32_t aLifetime) { mRouteLifetime = HostSwap32(aLifetime); }
|
||||
|
||||
/**
|
||||
* This method gets Route Lifetime in seconds.
|
||||
*
|
||||
* @returns The Route Lifetime in seconds.
|
||||
*
|
||||
*/
|
||||
uint32_t GetRouteLifetime(void) const { return HostSwap32(mRouteLifetime); }
|
||||
|
||||
/**
|
||||
* This method sets the prefix and adjusts the option length based on the prefix length.
|
||||
*
|
||||
* @param[in] aPrefix The prefix contained in this option.
|
||||
*
|
||||
*/
|
||||
void SetPrefix(const Prefix &aPrefix);
|
||||
|
||||
/**
|
||||
* This method gets the prefix in this option.
|
||||
*
|
||||
* @param[out] aPrefix Reference to a `Prefix` to return the prefix.
|
||||
*
|
||||
*/
|
||||
void GetPrefix(Prefix &aPrefix) const;
|
||||
|
||||
/**
|
||||
* This method tells whether this option is valid.
|
||||
*
|
||||
* @returns A boolean indicates whether this option is valid.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const;
|
||||
|
||||
/**
|
||||
* This static method calculates the minimum option length for a given prefix length.
|
||||
*
|
||||
* The option length (which is in unit of 8 octets) can be 1, 2, or 3 depending on the prefix length. It can be 1
|
||||
* for a zero prefix length, 2 if the prefix length is not greater than 64, and 3 otherwise.
|
||||
*
|
||||
* @param[in] aPrefixLength The prefix length (in bits).
|
||||
*
|
||||
* @returns The option length (in unit of 8 octet) for @p aPrefixLength.
|
||||
*
|
||||
*/
|
||||
static uint8_t OptionLengthForPrefix(uint8_t aPrefixLength);
|
||||
|
||||
/**
|
||||
* This static method calculates the minimum option size (in bytes) for a given prefix length.
|
||||
*
|
||||
* @param[in] aPrefixLength The prefix length (in bits).
|
||||
*
|
||||
* @returns The option size (in bytes) for @p aPrefixLength.
|
||||
*
|
||||
*/
|
||||
static uint16_t OptionSizeForPrefix(uint8_t aPrefixLength)
|
||||
{
|
||||
return kLengthUnit * OptionLengthForPrefix(aPrefixLength);
|
||||
}
|
||||
|
||||
RouteInfoOption(void) = delete;
|
||||
|
||||
private:
|
||||
// Route Information Option
|
||||
//
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type | Length | Prefix Length |Resvd|Prf|Resvd|
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Route Lifetime |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Prefix (Variable Length) |
|
||||
// . .
|
||||
// . .
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
static constexpr uint8_t kPreferenceOffset = 3;
|
||||
static constexpr uint8_t kPreferenceMask = 3 << kPreferenceOffset;
|
||||
|
||||
uint8_t * GetPrefixBytes(void) { return AsNonConst(AsConst(this)->GetPrefixBytes()); }
|
||||
const uint8_t *GetPrefixBytes(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); }
|
||||
|
||||
uint8_t mPrefixLength; // The prefix length in bits.
|
||||
uint8_t mResvdPrf; // The preference.
|
||||
uint32_t mRouteLifetime; // The lifetime in seconds.
|
||||
// Followed by prefix bytes (variable length).
|
||||
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
static_assert(sizeof(RouteInfoOption) == 8, "invalid RouteInfoOption structure");
|
||||
|
||||
/**
|
||||
* This class represents a Router Advertisement message.
|
||||
*
|
||||
*/
|
||||
class RouterAdvertMessage
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This class implements the RA message header.
|
||||
*
|
||||
* See section 2.2 of RFC 4191 [https://datatracker.ietf.org/doc/html/rfc4191]
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class Header : public Equatable<Header>, private Clearable<Header>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the Router Advertisement message with
|
||||
* zero router lifetime, reachable time and retransmission timer.
|
||||
*
|
||||
*/
|
||||
Header(void) { SetToDefault(); }
|
||||
|
||||
/**
|
||||
* This method sets the RA message to default values.
|
||||
*
|
||||
*/
|
||||
void SetToDefault(void);
|
||||
|
||||
/**
|
||||
* This method sets the checksum value.
|
||||
*
|
||||
* @param[in] aChecksum The checksum value.
|
||||
*
|
||||
*/
|
||||
void SetChecksum(uint16_t aChecksum) { mChecksum = HostSwap16(aChecksum); }
|
||||
|
||||
/**
|
||||
* This method sets the Router Lifetime in seconds.
|
||||
*
|
||||
* @param[in] aRouterLifetime The router lifetime in seconds.
|
||||
*
|
||||
*/
|
||||
void SetRouterLifetime(uint16_t aRouterLifetime) { mRouterLifetime = HostSwap16(aRouterLifetime); }
|
||||
|
||||
/**
|
||||
* This method gets the Router Lifetime (in seconds).
|
||||
*
|
||||
* Router Lifetime set to zero indicates that the sender is not a default router.
|
||||
*
|
||||
* @returns The router lifetime in seconds.
|
||||
*
|
||||
*/
|
||||
uint16_t GetRouterLifetime(void) const { return HostSwap16(mRouterLifetime); }
|
||||
|
||||
/**
|
||||
* This method sets the default router preference.
|
||||
*
|
||||
* @param[in] aPreference The router preference.
|
||||
*
|
||||
*/
|
||||
void SetDefaultRouterPreference(RoutePreference aPreference);
|
||||
|
||||
/**
|
||||
* This method gets the default router preference.
|
||||
*
|
||||
* @returns The router preference.
|
||||
*
|
||||
*/
|
||||
RoutePreference GetDefaultRouterPreference(void) const;
|
||||
|
||||
private:
|
||||
// Router Advertisement Message
|
||||
//
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Type | Code | Checksum |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Cur Hop Limit |M|O|H|Prf|Resvd| Router Lifetime |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Reachable Time |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Retrans Timer |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Options ...
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-
|
||||
|
||||
static constexpr uint8_t kPreferenceOffset = 3;
|
||||
static constexpr uint8_t kPreferenceMask = 3 << kPreferenceOffset;
|
||||
|
||||
uint8_t mType;
|
||||
uint8_t mCode;
|
||||
uint16_t mChecksum;
|
||||
uint8_t mCurHopLimit;
|
||||
uint8_t mFlags;
|
||||
uint16_t mRouterLifetime;
|
||||
uint32_t mReachableTime;
|
||||
uint32_t mRetransTimer;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
static_assert(sizeof(Header) == 16, "Invalid RA `Header`");
|
||||
|
||||
typedef Data<kWithUint16Length> Icmp6Packet; ///< A data buffer containing an ICMPv6 packet.
|
||||
|
||||
/**
|
||||
* This constructor initializes the RA message from a received packet data buffer.
|
||||
*
|
||||
* @param[in] aPacket A received packet data.
|
||||
*
|
||||
*/
|
||||
explicit RouterAdvertMessage(const Icmp6Packet &aPacket)
|
||||
: mData(aPacket)
|
||||
, mMaxLength(0)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This template constructor initializes the RA message with a given header using a given buffer to store the RA
|
||||
* message.
|
||||
*
|
||||
* @tparam kBufferSize The size of the buffer used to store the RA message.
|
||||
*
|
||||
* @param[in] aHeader The RA message header.
|
||||
* @param[in] aBuffer The data buffer to store the RA message in.
|
||||
*
|
||||
*/
|
||||
template <uint16_t kBufferSize>
|
||||
RouterAdvertMessage(const Header &aHeader, uint8_t (&aBuffer)[kBufferSize])
|
||||
: mMaxLength(kBufferSize)
|
||||
{
|
||||
static_assert(kBufferSize >= sizeof(Header), "Buffer for RA msg is too small");
|
||||
|
||||
memcpy(aBuffer, &aHeader, sizeof(Header));
|
||||
mData.Init(aBuffer, sizeof(Header));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets the RA message as an `Icmp6Packet`.
|
||||
*
|
||||
* @returns The RA message as an `Icmp6Packet`.
|
||||
*
|
||||
*/
|
||||
const Icmp6Packet &GetAsPacket(void) const { return mData; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the RA message is valid.
|
||||
*
|
||||
* @retval TRUE If the RA message is valid.
|
||||
* @retval FALSE If the RA message is not valid.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const { return (mData.GetBytes() != nullptr) && (mData.GetLength() >= sizeof(Header)); }
|
||||
|
||||
/**
|
||||
* This method gets the RA message's header.
|
||||
*
|
||||
* @returns The RA message's header.
|
||||
*
|
||||
*/
|
||||
const Header &GetHeader(void) const { return *reinterpret_cast<const Header *>(mData.GetBytes()); }
|
||||
|
||||
/**
|
||||
* This method appends a Prefix Info Option to the RA message.
|
||||
*
|
||||
* The appended Prefix Info Option will have both on-link (L) and autonomous address-configuration (A) flags set.
|
||||
*
|
||||
* @param[in] aPrefix The prefix.
|
||||
* @param[in] aValidLifetime The valid lifetime in seconds.
|
||||
* @param[in] aPreferredLifetime The preferred lifetime in seconds.
|
||||
*
|
||||
* @retval kErrorNone Option is appended successfully.
|
||||
* @retval kErrorNoBufs No more space in the buffer to append the option.
|
||||
*
|
||||
*/
|
||||
Error AppendPrefixInfoOption(const Prefix &aPrefix, uint32_t aValidLifetime, uint32_t aPreferredLifetime);
|
||||
|
||||
/**
|
||||
* This method appends a Route Info Option to the RA message.
|
||||
*
|
||||
* @param[in] aPrefix The prefix.
|
||||
* @param[in] aRouteLifetime The route lifetime in seconds.
|
||||
* @param[in] aPreference The route preference.
|
||||
*
|
||||
* @retval kErrorNone Option is appended successfully.
|
||||
* @retval kErrorNoBufs No more space in the buffer to append the option.
|
||||
*
|
||||
*/
|
||||
Error AppendRouteInfoOption(const Prefix &aPrefix, uint32_t aRouteLifetime, RoutePreference aPreference);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the RA message contains any options.
|
||||
*
|
||||
* @retval TRUE If the RA message contains at least one option.
|
||||
* @retval FALSE If the RA message contains no options.
|
||||
*
|
||||
*/
|
||||
bool ContainsAnyOptions(void) const { return (mData.GetLength() > sizeof(Header)); }
|
||||
|
||||
// The following methods are intended to support range-based `for`
|
||||
// loop iteration over `Option`s in the RA message.
|
||||
|
||||
Option::Iterator begin(void) const { return Option::Iterator(GetOptionStart(), GetDataEnd()); }
|
||||
Option::Iterator end(void) const { return Option::Iterator(); }
|
||||
|
||||
private:
|
||||
const uint8_t *GetOptionStart(void) const { return (mData.GetBytes() + sizeof(Header)); }
|
||||
const uint8_t *GetDataEnd(void) const { return mData.GetBytes() + mData.GetLength(); }
|
||||
Option * AppendOption(uint16_t aOptionSize);
|
||||
|
||||
Data<kWithUint16Length> mData;
|
||||
uint16_t mMaxLength;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class implements the Router Solicitation message.
|
||||
*
|
||||
* See section 4.1 of RFC 4861 for definition of this message.
|
||||
* https://tools.ietf.org/html/rfc4861#section-4.1
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class RouterSolicitMessage
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the Router Solicitation message.
|
||||
*
|
||||
*/
|
||||
RouterSolicitMessage(void);
|
||||
|
||||
private:
|
||||
Icmp::Header mHeader; // The common ICMPv6 header.
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
static_assert(sizeof(RouterSolicitMessage) == 8, "invalid RouterSolicitMessage structure");
|
||||
|
||||
} // namespace Nd
|
||||
} // namespace Ip6
|
||||
} // namespace ot
|
||||
|
||||
#endif // ND6_HPP_
|
|
@ -76,10 +76,20 @@ void Client::HostInfo::SetState(ItemState aState)
|
|||
}
|
||||
}
|
||||
|
||||
void Client::HostInfo::EnableAutoAddress(void)
|
||||
{
|
||||
mAddresses = nullptr;
|
||||
mNumAddresses = 0;
|
||||
mAutoAddress = true;
|
||||
|
||||
LogInfo("HostInfo enabled auto address", GetNumAddresses());
|
||||
}
|
||||
|
||||
void Client::HostInfo::SetAddresses(const Ip6::Address *aAddresses, uint8_t aNumAddresses)
|
||||
{
|
||||
mAddresses = aAddresses;
|
||||
mNumAddresses = aNumAddresses;
|
||||
mAutoAddress = false;
|
||||
|
||||
LogInfo("HostInfo set %d addrs", GetNumAddresses());
|
||||
|
||||
|
@ -239,12 +249,14 @@ Client::Client(Instance &aInstance)
|
|||
, mState(kStateStopped)
|
||||
, mTxFailureRetryCount(0)
|
||||
, mShouldRemoveKeyLease(false)
|
||||
, mAutoHostAddressAddedMeshLocal(false)
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
, mServiceKeyRecordEnabled(false)
|
||||
#endif
|
||||
, mUpdateMessageId(0)
|
||||
, mRetryWaitInterval(kMinRetryWaitInterval)
|
||||
, mAcceptedLeaseInterval(0)
|
||||
, mTtl(0)
|
||||
, mLeaseInterval(kDefaultLease)
|
||||
, mKeyLeaseInterval(kDefaultKeyLease)
|
||||
, mSocket(aInstance)
|
||||
|
@ -323,6 +335,8 @@ void Client::Stop(Requester aRequester, StopMode aMode)
|
|||
|
||||
VerifyOrExit(GetState() != kStateStopped);
|
||||
|
||||
mSingleServiceMode.Disable();
|
||||
|
||||
// State changes:
|
||||
// kAdding -> kToRefresh
|
||||
// kRefreshing -> kToRefresh
|
||||
|
@ -391,6 +405,8 @@ void Client::Pause(void)
|
|||
/* (7) kRemoved -> */ kRemoved,
|
||||
};
|
||||
|
||||
mSingleServiceMode.Disable();
|
||||
|
||||
// State changes:
|
||||
// kAdding -> kToRefresh
|
||||
// kRefreshing -> kToRefresh
|
||||
|
@ -414,6 +430,22 @@ void Client::HandleNotifierEvents(Events aEvents)
|
|||
ProcessAutoStart();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mHostInfo.IsAutoAddressEnabled())
|
||||
{
|
||||
Events::Flags eventFlags = (kEventIp6AddressAdded | kEventIp6AddressRemoved);
|
||||
|
||||
if (mAutoHostAddressAddedMeshLocal)
|
||||
{
|
||||
eventFlags |= kEventThreadMeshLocalAddrChanged;
|
||||
}
|
||||
|
||||
if (aEvents.ContainsAny(eventFlags))
|
||||
{
|
||||
IgnoreError(UpdateHostInfoStateOnAddressChange());
|
||||
UpdateState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client::HandleRoleChanged(void)
|
||||
|
@ -465,11 +497,37 @@ exit:
|
|||
return error;
|
||||
}
|
||||
|
||||
Error Client::EnableAutoHostAddress(void)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(!mHostInfo.IsAutoAddressEnabled());
|
||||
SuccessOrExit(error = UpdateHostInfoStateOnAddressChange());
|
||||
|
||||
mHostInfo.EnableAutoAddress();
|
||||
UpdateState();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error Client::SetHostAddresses(const Ip6::Address *aAddresses, uint8_t aNumAddresses)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit((aAddresses != nullptr) && (aNumAddresses > 0), error = kErrorInvalidArgs);
|
||||
SuccessOrExit(error = UpdateHostInfoStateOnAddressChange());
|
||||
|
||||
mHostInfo.SetAddresses(aAddresses, aNumAddresses);
|
||||
UpdateState();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error Client::UpdateHostInfoStateOnAddressChange(void)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit((mHostInfo.GetState() != kToRemove) && (mHostInfo.GetState() != kRemoving),
|
||||
error = kErrorInvalidState);
|
||||
|
@ -483,9 +541,6 @@ Error Client::SetHostAddresses(const Ip6::Address *aAddresses, uint8_t aNumAddre
|
|||
mHostInfo.SetState(kToRefresh);
|
||||
}
|
||||
|
||||
mHostInfo.SetAddresses(aAddresses, aNumAddresses);
|
||||
UpdateState();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
@ -659,6 +714,11 @@ void Client::ChangeHostAndServiceStates(const ItemState *aNewStates)
|
|||
|
||||
for (Service &service : mServices)
|
||||
{
|
||||
if (mSingleServiceMode.IsEnabled() && mSingleServiceMode.GetService() != &service)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
service.SetState(aNewStates[service.GetState()]);
|
||||
}
|
||||
|
||||
|
@ -717,9 +777,21 @@ void Client::SendUpdate(void)
|
|||
|
||||
Error error = kErrorNone;
|
||||
Message *message = mSocket.NewMessage(0);
|
||||
uint32_t length;
|
||||
|
||||
VerifyOrExit(message != nullptr, error = kErrorNoBufs);
|
||||
SuccessOrExit(error = PrepareUpdateMessage(*message));
|
||||
|
||||
length = message->GetLength() + sizeof(Ip6::Udp::Header) + sizeof(Ip6::Header);
|
||||
|
||||
if (length >= Ip6::kMaxDatagramLength)
|
||||
{
|
||||
LogInfo("Msg len %u is larger than MTU, enabling single service mode", length);
|
||||
mSingleServiceMode.Enable();
|
||||
IgnoreError(message->SetLength(0));
|
||||
SuccessOrExit(error = PrepareUpdateMessage(*message));
|
||||
}
|
||||
|
||||
SuccessOrExit(error = mSocket.SendTo(*message, Ip6::MessageInfo()));
|
||||
|
||||
LogInfo("Send update");
|
||||
|
@ -757,6 +829,7 @@ exit:
|
|||
|
||||
LogInfo("Failed to send update: %s", ErrorToString(error));
|
||||
|
||||
mSingleServiceMode.Disable();
|
||||
FreeMessage(message);
|
||||
|
||||
SetState(kStateToRetry);
|
||||
|
@ -831,6 +904,11 @@ Error Client::PrepareUpdateMessage(Message &aMessage)
|
|||
for (Service &service : mServices)
|
||||
{
|
||||
SuccessOrExit(error = AppendServiceInstructions(service, aMessage, info));
|
||||
|
||||
if (mSingleServiceMode.IsEnabled() && (mSingleServiceMode.GetService() != nullptr))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -911,7 +989,7 @@ Error Client::AppendServiceInstructions(Service &aService, Message &aMessage, In
|
|||
// to NONE and TTL to zero (RFC 2136 - section 2.5.4).
|
||||
|
||||
rr.Init(Dns::ResourceRecord::kTypePtr, removing ? Dns::PtrRecord::kClassNone : Dns::PtrRecord::kClassInternet);
|
||||
rr.SetTtl(removing ? 0 : mLeaseInterval);
|
||||
rr.SetTtl(removing ? 0 : GetTtl());
|
||||
offset = aMessage.GetLength();
|
||||
SuccessOrExit(error = aMessage.Append(rr));
|
||||
|
||||
|
@ -970,7 +1048,7 @@ Error Client::AppendServiceInstructions(Service &aService, Message &aMessage, In
|
|||
|
||||
SuccessOrExit(error = Dns::Name::AppendPointerLabel(instanceNameOffset, aMessage));
|
||||
srv.Init();
|
||||
srv.SetTtl(mLeaseInterval);
|
||||
srv.SetTtl(GetTtl());
|
||||
srv.SetPriority(aService.GetPriority());
|
||||
srv.SetWeight(aService.GetWeight());
|
||||
srv.SetPort(aService.GetPort());
|
||||
|
@ -1003,14 +1081,18 @@ Error Client::AppendServiceInstructions(Service &aService, Message &aMessage, In
|
|||
}
|
||||
#endif
|
||||
|
||||
if (mSingleServiceMode.IsEnabled())
|
||||
{
|
||||
mSingleServiceMode.SetService(aService);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error Client::AppendHostDescriptionInstruction(Message &aMessage, Info &aInfo) const
|
||||
Error Client::AppendHostDescriptionInstruction(Message &aMessage, Info &aInfo)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Dns::ResourceRecord rr;
|
||||
Error error = kErrorNone;
|
||||
|
||||
//----------------------------------
|
||||
// Host Description Instruction
|
||||
|
@ -1023,16 +1105,37 @@ Error Client::AppendHostDescriptionInstruction(Message &aMessage, Info &aInfo) c
|
|||
|
||||
// AAAA RRs
|
||||
|
||||
rr.Init(Dns::ResourceRecord::kTypeAaaa);
|
||||
rr.SetTtl(mLeaseInterval);
|
||||
rr.SetLength(sizeof(Ip6::Address));
|
||||
|
||||
for (uint8_t index = 0; index < mHostInfo.GetNumAddresses(); index++)
|
||||
if (mHostInfo.IsAutoAddressEnabled())
|
||||
{
|
||||
SuccessOrExit(error = AppendHostName(aMessage, aInfo));
|
||||
SuccessOrExit(error = aMessage.Append(rr));
|
||||
SuccessOrExit(error = aMessage.Append(mHostInfo.GetAddress(index)));
|
||||
aInfo.mRecordCount++;
|
||||
// Append all addresses on Thread netif excluding link-local and
|
||||
// mesh-local addresses. If no address is appended, we include
|
||||
// the mesh local address.
|
||||
|
||||
mAutoHostAddressAddedMeshLocal = true;
|
||||
|
||||
for (const Ip6::Netif::UnicastAddress &unicastAddress : Get<ThreadNetif>().GetUnicastAddresses())
|
||||
{
|
||||
if (unicastAddress.GetAddress().IsLinkLocal() ||
|
||||
Get<Mle::Mle>().IsMeshLocalAddress(unicastAddress.GetAddress()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
SuccessOrExit(error = AppendAaaaRecord(unicastAddress.GetAddress(), aMessage, aInfo));
|
||||
mAutoHostAddressAddedMeshLocal = false;
|
||||
}
|
||||
|
||||
if (mAutoHostAddressAddedMeshLocal)
|
||||
{
|
||||
SuccessOrExit(error = AppendAaaaRecord(Get<Mle::Mle>().GetMeshLocal64(), aMessage, aInfo));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint8_t index = 0; index < mHostInfo.GetNumAddresses(); index++)
|
||||
{
|
||||
SuccessOrExit(error = AppendAaaaRecord(mHostInfo.GetAddress(index), aMessage, aInfo));
|
||||
}
|
||||
}
|
||||
|
||||
// KEY RR
|
||||
|
@ -1044,6 +1147,24 @@ exit:
|
|||
return error;
|
||||
}
|
||||
|
||||
Error Client::AppendAaaaRecord(const Ip6::Address &aAddress, Message &aMessage, Info &aInfo) const
|
||||
{
|
||||
Error error;
|
||||
Dns::ResourceRecord rr;
|
||||
|
||||
rr.Init(Dns::ResourceRecord::kTypeAaaa);
|
||||
rr.SetTtl(GetTtl());
|
||||
rr.SetLength(sizeof(Ip6::Address));
|
||||
|
||||
SuccessOrExit(error = AppendHostName(aMessage, aInfo));
|
||||
SuccessOrExit(error = aMessage.Append(rr));
|
||||
SuccessOrExit(error = aMessage.Append(aAddress));
|
||||
aInfo.mRecordCount++;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error Client::AppendKeyRecord(Message &aMessage, Info &aInfo) const
|
||||
{
|
||||
Error error;
|
||||
|
@ -1051,7 +1172,7 @@ Error Client::AppendKeyRecord(Message &aMessage, Info &aInfo) const
|
|||
Crypto::Ecdsa::P256::PublicKey publicKey;
|
||||
|
||||
key.Init();
|
||||
key.SetTtl(mLeaseInterval);
|
||||
key.SetTtl(GetTtl());
|
||||
key.SetFlags(Dns::KeyRecord::kAuthConfidPermitted, Dns::KeyRecord::kOwnerNonZone,
|
||||
Dns::KeyRecord::kSignatoryFlagGeneral);
|
||||
key.SetProtocol(Dns::KeyRecord::kProtocolDnsSec);
|
||||
|
@ -1384,6 +1505,7 @@ void Client::ProcessResponse(Message &aMessage)
|
|||
// kRemoving -> kRemoved
|
||||
|
||||
ChangeHostAndServiceStates(kNewStateOnUpdateDone);
|
||||
mSingleServiceMode.Disable();
|
||||
|
||||
HandleUpdateDone();
|
||||
UpdateState();
|
||||
|
@ -1518,7 +1640,7 @@ void Client::UpdateState(void)
|
|||
// host address, otherwise no need to send SRP update message.
|
||||
// The exception is when removing host info where we allow
|
||||
// for empty service list.
|
||||
VerifyOrExit(!mServices.IsEmpty() && (mHostInfo.GetNumAddresses() > 0));
|
||||
VerifyOrExit(!mServices.IsEmpty() && (mHostInfo.IsAutoAddressEnabled() || (mHostInfo.GetNumAddresses() > 0)));
|
||||
|
||||
// Fall through
|
||||
|
||||
|
@ -1653,6 +1775,7 @@ void Client::HandleTimer(void)
|
|||
break;
|
||||
|
||||
case kStateUpdating:
|
||||
mSingleServiceMode.Disable();
|
||||
LogRetryWaitInterval();
|
||||
LogInfo("Timed out, no response");
|
||||
GrowRetryWaitInterval();
|
||||
|
@ -1782,7 +1905,6 @@ Error Client::SelectUnicastEntry(DnsSrpUnicast::Origin aOrigin, DnsSrpUnicast::I
|
|||
Error error = kErrorNotFound;
|
||||
DnsSrpUnicast::Info unicastInfo;
|
||||
NetworkData::Service::Manager::Iterator iterator;
|
||||
uint16_t numServers = 0;
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_SAVE_SELECTED_SERVER_ENABLE
|
||||
Settings::SrpClientInfo savedInfo;
|
||||
bool hasSavedServerInfo = false;
|
||||
|
@ -1819,16 +1941,10 @@ Error Client::SelectUnicastEntry(DnsSrpUnicast::Origin aOrigin, DnsSrpUnicast::I
|
|||
ExitNow();
|
||||
}
|
||||
#endif
|
||||
numServers++;
|
||||
|
||||
// Choose a server randomly (with uniform distribution) from
|
||||
// the list of servers. As we iterate through server entries,
|
||||
// with probability `1/numServers`, we choose to switch the
|
||||
// current selected server with the new entry. This approach
|
||||
// results in a uniform/same probability of selection among
|
||||
// all server entries.
|
||||
// Prefer the numerically lowest server address
|
||||
|
||||
if ((numServers == 1) || (Random::NonCrypto::GetUint16InRange(0, numServers) == 0))
|
||||
if ((error == kErrorNotFound) || (unicastInfo.mSockAddr.GetAddress() < aInfo.mSockAddr.GetAddress()))
|
||||
{
|
||||
aInfo = unicastInfo;
|
||||
error = kErrorNone;
|
||||
|
|
|
@ -103,7 +103,7 @@ public:
|
|||
* This type represents an SRP client host info.
|
||||
*
|
||||
*/
|
||||
class HostInfo : public otSrpClientHostInfo, public Clearable<HostInfo>
|
||||
class HostInfo : public otSrpClientHostInfo, private Clearable<HostInfo>
|
||||
{
|
||||
friend class Client;
|
||||
|
||||
|
@ -128,6 +128,15 @@ public:
|
|||
*/
|
||||
const char *GetName(void) const { return mName; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the host auto address mode is enabled.
|
||||
*
|
||||
* @retval TRUE If the auto address mode is enabled.
|
||||
* @retval FALSE If the auto address mode is disabled.
|
||||
*
|
||||
*/
|
||||
bool IsAutoAddressEnabled(void) const { return mAutoAddress; }
|
||||
|
||||
/**
|
||||
* This method gets the number of host IPv6 addresses.
|
||||
*
|
||||
|
@ -158,6 +167,7 @@ public:
|
|||
void SetName(const char *aName) { mName = aName; }
|
||||
void SetState(ItemState aState);
|
||||
void SetAddresses(const Ip6::Address *aAddresses, uint8_t aNumAddresses);
|
||||
void EnableAutoAddress(void);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -410,6 +420,31 @@ public:
|
|||
*/
|
||||
void SetCallback(Callback aCallback, void *aContext);
|
||||
|
||||
/**
|
||||
* This method gets the TTL used in SRP update requests.
|
||||
*
|
||||
* Note that this is the TTL requested by the SRP client. The server may choose to accept a different TTL.
|
||||
*
|
||||
* By default, the TTL will equal the lease interval. Passing 0 or a value larger than the lease interval via
|
||||
* `otSrpClientSetTtl()` will also cause the TTL to equal the lease interval.
|
||||
*
|
||||
* @returns The TTL (in seconds).
|
||||
*
|
||||
*/
|
||||
uint32_t GetTtl(void) const { return (0 < mTtl && mTtl < mLeaseInterval) ? mTtl : mLeaseInterval; }
|
||||
|
||||
/**
|
||||
* This method sets the TTL used in SRP update requests.
|
||||
*
|
||||
* Changing the TTL does not impact the TTL of already registered services/host-info.
|
||||
* It only changes any future SRP update messages (i.e adding new services and/or refreshes of existing services).
|
||||
*
|
||||
* @param[in] aTtl The TTL (in seconds). If value is zero or greater than lease interval, the TTL is set to the
|
||||
* lease interval.
|
||||
*
|
||||
*/
|
||||
void SetTtl(uint32_t aTtl) { mTtl = aTtl; }
|
||||
|
||||
/**
|
||||
* This method gets the lease interval used in SRP update requests.
|
||||
*
|
||||
|
@ -464,16 +499,16 @@ public:
|
|||
const HostInfo &GetHostInfo(void) const { return mHostInfo; }
|
||||
|
||||
/**
|
||||
* This function sets the host name label.
|
||||
* This method sets the host name label.
|
||||
*
|
||||
* After a successful call to this function, `Callback` will be called to report the status of host info
|
||||
* After a successful call to this method, `Callback` will be called to report the status of host info
|
||||
* registration with SRP server.
|
||||
*
|
||||
* The host name can be set before client is started or after start but before host info is registered with server
|
||||
* (host info should be in either `kToAdd` or `kRemoved`).
|
||||
*
|
||||
* @param[in] aName A pointer to host name label string (MUST NOT be NULL). Pointer the string buffer MUST
|
||||
* persist and remain valid and constant after return from this function.
|
||||
* persist and remain valid and constant after return from this method.
|
||||
*
|
||||
* @retval kErrorNone The host name label was set successfully.
|
||||
* @retval kErrorInvalidArgs The @p aName is NULL.
|
||||
|
@ -482,6 +517,27 @@ public:
|
|||
*/
|
||||
Error SetHostName(const char *aName);
|
||||
|
||||
/**
|
||||
* This method enables auto host address mode.
|
||||
*
|
||||
* When enabled host IPv6 addresses are automatically set by SRP client using all the unicast addresses on Thread
|
||||
* netif excluding the link-local and mesh-local addresses. If there is no valid address, then Mesh Local EID
|
||||
* address is added. The SRP client will automatically re-register when/if addresses on Thread netif are updated
|
||||
* (new addresses are added or existing addresses are removed).
|
||||
*
|
||||
* The auto host address mode can be enabled before start or during operation of SRP client except when the host
|
||||
* info is being removed (client is busy handling a remove request from an call to `RemoveHostAndServices()` and
|
||||
* host info still being in either `kStateToRemove` or `kStateRemoving` states).
|
||||
*
|
||||
* After auto host address mode is enabled, it can be disabled by a call to `SetHostAddresses()` which then
|
||||
* explicitly sets the host addresses.
|
||||
*
|
||||
* @retval kErrorNone Successfully enabled auto host address mode.
|
||||
* @retval kErrorInvalidState Host is being removed and therefore cannot enable auto host address mode.
|
||||
*
|
||||
*/
|
||||
Error EnableAutoHostAddress(void);
|
||||
|
||||
/**
|
||||
* This method sets/updates the list of host IPv6 address.
|
||||
*
|
||||
|
@ -493,6 +549,9 @@ public:
|
|||
* After a successful call to this method, `Callback` will be called to report the status of the address
|
||||
* registration with SRP server.
|
||||
*
|
||||
* Calling this method disables auto host address mode if it was previously enabled from a successful call to
|
||||
* `EnableAutoHostAddress()`.
|
||||
*
|
||||
* @param[in] aAddresses A pointer to the an array containing the host IPv6 addresses.
|
||||
* @param[in] aNumAddresses The number of addresses in the @p aAddresses array.
|
||||
*
|
||||
|
@ -795,6 +854,26 @@ private:
|
|||
kKeepRetryInterval,
|
||||
};
|
||||
|
||||
class SingleServiceMode
|
||||
{
|
||||
public:
|
||||
SingleServiceMode(void)
|
||||
: mEnabled(false)
|
||||
, mService(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void Enable(void) { mEnabled = true, mService = nullptr; }
|
||||
void Disable(void) { mEnabled = false; }
|
||||
bool IsEnabled(void) const { return mEnabled; }
|
||||
Service *GetService(void) { return mService; }
|
||||
void SetService(Service &aService) { mService = &aService; }
|
||||
|
||||
private:
|
||||
bool mEnabled;
|
||||
Service *mService;
|
||||
};
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
|
||||
class AutoStart : Clearable<AutoStart>
|
||||
{
|
||||
|
@ -859,6 +938,7 @@ private:
|
|||
void Pause(void);
|
||||
void HandleNotifierEvents(Events aEvents);
|
||||
void HandleRoleChanged(void);
|
||||
Error UpdateHostInfoStateOnAddressChange(void);
|
||||
void UpdateServiceStateToRemove(Service &aService);
|
||||
State GetState(void) const { return mState; }
|
||||
void SetState(State aState);
|
||||
|
@ -870,10 +950,11 @@ private:
|
|||
Error PrepareUpdateMessage(Message &aMessage);
|
||||
Error ReadOrGenerateKey(Crypto::Ecdsa::P256::KeyPair &aKeyPair);
|
||||
Error AppendServiceInstructions(Service &aService, Message &aMessage, Info &aInfo);
|
||||
Error AppendHostDescriptionInstruction(Message &aMessage, Info &aInfo) const;
|
||||
Error AppendHostDescriptionInstruction(Message &aMessage, Info &aInfo);
|
||||
Error AppendKeyRecord(Message &aMessage, Info &aInfo) const;
|
||||
Error AppendDeleteAllRrsets(Message &aMessage) const;
|
||||
Error AppendHostName(Message &aMessage, Info &aInfo, bool aDoNotCompress = false) const;
|
||||
Error AppendAaaaRecord(const Ip6::Address &aAddress, Message &aMessage, Info &aInfo) const;
|
||||
Error AppendUpdateLeaseOptRecord(Message &aMessage) const;
|
||||
Error AppendSignature(Message &aMessage, Info &aInfo);
|
||||
void UpdateRecordLengthInMessage(Dns::ResourceRecord &aRecord, uint16_t aOffset, Message &aMessage) const;
|
||||
|
@ -913,6 +994,7 @@ private:
|
|||
State mState;
|
||||
uint8_t mTxFailureRetryCount : 4;
|
||||
bool mShouldRemoveKeyLease : 1;
|
||||
bool mAutoHostAddressAddedMeshLocal : 1;
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
bool mServiceKeyRecordEnabled : 1;
|
||||
#endif
|
||||
|
@ -922,6 +1004,7 @@ private:
|
|||
|
||||
TimeMilli mLeaseRenewTime;
|
||||
uint32_t mAcceptedLeaseInterval;
|
||||
uint32_t mTtl;
|
||||
uint32_t mLeaseInterval;
|
||||
uint32_t mKeyLeaseInterval;
|
||||
|
||||
|
@ -932,6 +1015,7 @@ private:
|
|||
const char * mDomainName;
|
||||
HostInfo mHostInfo;
|
||||
LinkedList<Service> mServices;
|
||||
SingleServiceMode mSingleServiceMode;
|
||||
TimerMilli mTimer;
|
||||
#if OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_API_ENABLE
|
||||
AutoStart mAutoStart;
|
||||
|
|
|
@ -168,6 +168,30 @@ exit:
|
|||
return;
|
||||
}
|
||||
|
||||
Server::TtlConfig::TtlConfig(void)
|
||||
{
|
||||
mMinTtl = kDefaultMinTtl;
|
||||
mMaxTtl = kDefaultMaxTtl;
|
||||
}
|
||||
|
||||
Error Server::SetTtlConfig(const TtlConfig &aTtlConfig)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(aTtlConfig.IsValid(), error = kErrorInvalidArgs);
|
||||
mTtlConfig = aTtlConfig;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
uint32_t Server::TtlConfig::GrantTtl(uint32_t aLease, uint32_t aTtl) const
|
||||
{
|
||||
OT_ASSERT(mMinTtl <= mMaxTtl);
|
||||
|
||||
return OT_MAX(mMinTtl, OT_MIN(OT_MIN(mMaxTtl, aLease), aTtl));
|
||||
}
|
||||
|
||||
Server::LeaseConfig::LeaseConfig(void)
|
||||
{
|
||||
mMinLease = kDefaultMinLease;
|
||||
|
@ -266,7 +290,6 @@ void Server::AddHost(Host &aHost)
|
|||
OT_ASSERT(mHosts.FindMatching(aHost.GetFullName()) == nullptr);
|
||||
IgnoreError(mHosts.Add(aHost));
|
||||
}
|
||||
|
||||
void Server::RemoveHost(Host *aHost, RetainName aRetainName, NotifyMode aNotifyServiceHandler)
|
||||
{
|
||||
VerifyOrExit(aHost != nullptr);
|
||||
|
@ -374,20 +397,21 @@ void Server::HandleServiceUpdateResult(UpdateMetadata *aUpdate, Error aError)
|
|||
void Server::CommitSrpUpdate(Error aError, Host &aHost, const MessageMetadata &aMessageMetadata)
|
||||
{
|
||||
CommitSrpUpdate(aError, aHost, aMessageMetadata.mDnsHeader, aMessageMetadata.mMessageInfo,
|
||||
aMessageMetadata.mLeaseConfig);
|
||||
aMessageMetadata.mTtlConfig, aMessageMetadata.mLeaseConfig);
|
||||
}
|
||||
|
||||
void Server::CommitSrpUpdate(Error aError, UpdateMetadata &aUpdateMetadata)
|
||||
{
|
||||
CommitSrpUpdate(aError, aUpdateMetadata.GetHost(), aUpdateMetadata.GetDnsHeader(),
|
||||
aUpdateMetadata.IsDirectRxFromClient() ? &aUpdateMetadata.GetMessageInfo() : nullptr,
|
||||
aUpdateMetadata.GetLeaseConfig());
|
||||
aUpdateMetadata.GetTtlConfig(), aUpdateMetadata.GetLeaseConfig());
|
||||
}
|
||||
|
||||
void Server::CommitSrpUpdate(Error aError,
|
||||
Host & aHost,
|
||||
const Dns::UpdateHeader &aDnsHeader,
|
||||
const Ip6::MessageInfo * aMessageInfo,
|
||||
const TtlConfig & aTtlConfig,
|
||||
const LeaseConfig & aLeaseConfig)
|
||||
{
|
||||
Host * existingHost;
|
||||
|
@ -395,6 +419,7 @@ void Server::CommitSrpUpdate(Error aError,
|
|||
uint32_t hostKeyLease;
|
||||
uint32_t grantedLease;
|
||||
uint32_t grantedKeyLease;
|
||||
uint32_t grantedTtl;
|
||||
bool shouldFreeHost = true;
|
||||
|
||||
SuccessOrExit(aError);
|
||||
|
@ -403,14 +428,17 @@ void Server::CommitSrpUpdate(Error aError,
|
|||
hostKeyLease = aHost.GetKeyLease();
|
||||
grantedLease = aLeaseConfig.GrantLease(hostLease);
|
||||
grantedKeyLease = aLeaseConfig.GrantKeyLease(hostKeyLease);
|
||||
grantedTtl = aTtlConfig.GrantTtl(grantedLease, aHost.GetTtl());
|
||||
|
||||
aHost.SetLease(grantedLease);
|
||||
aHost.SetKeyLease(grantedKeyLease);
|
||||
aHost.SetTtl(grantedTtl);
|
||||
|
||||
for (Service &service : aHost.mServices)
|
||||
{
|
||||
service.mDescription->mLease = grantedLease;
|
||||
service.mDescription->mKeyLease = grantedKeyLease;
|
||||
service.mDescription->mTtl = grantedTtl;
|
||||
}
|
||||
|
||||
existingHost = mHosts.FindMatching(aHost.GetFullName());
|
||||
|
@ -690,6 +718,8 @@ void Server::ProcessDnsUpdate(Message &aMessage, MessageMetadata &aMetadata)
|
|||
// Parse lease time and validate signature.
|
||||
SuccessOrExit(error = ProcessAdditionalSection(host, aMessage, aMetadata));
|
||||
|
||||
SuccessOrExit(error = ValidateServiceSubTypes(*host, aMetadata));
|
||||
|
||||
HandleUpdate(*host, aMetadata);
|
||||
|
||||
exit:
|
||||
|
@ -802,6 +832,8 @@ Error Server::ProcessHostDescriptionInstruction(Host & aHost,
|
|||
|
||||
VerifyOrExit(record.GetClass() == aMetadata.mDnsZone.GetClass(), error = kErrorFailed);
|
||||
|
||||
SuccessOrExit(error = aHost.ProcessTtl(record.GetTtl()));
|
||||
|
||||
SuccessOrExit(error = aHost.SetFullName(name));
|
||||
|
||||
SuccessOrExit(error = aMessage.Read(offset, aaaaRecord));
|
||||
|
@ -816,6 +848,9 @@ Error Server::ProcessHostDescriptionInstruction(Host & aHost,
|
|||
Dns::Ecdsa256KeyRecord keyRecord;
|
||||
|
||||
VerifyOrExit(record.GetClass() == aMetadata.mDnsZone.GetClass(), error = kErrorFailed);
|
||||
|
||||
SuccessOrExit(error = aHost.ProcessTtl(record.GetTtl()));
|
||||
|
||||
SuccessOrExit(error = aMessage.Read(offset, keyRecord));
|
||||
VerifyOrExit(keyRecord.IsValid(), error = kErrorParse);
|
||||
|
||||
|
@ -908,6 +943,11 @@ Error Server::ProcessServiceDiscoveryInstructions(Host & aHost,
|
|||
|
||||
// This RR is a "Delete an RR from an RRset" update when the CLASS is NONE.
|
||||
service->mIsDeleted = (ptrRecord.GetClass() == Dns::ResourceRecord::kClassNone);
|
||||
|
||||
if (!service->mIsDeleted)
|
||||
{
|
||||
SuccessOrExit(error = aHost.ProcessTtl(ptrRecord.GetTtl()));
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
|
@ -959,6 +999,9 @@ Error Server::ProcessServiceDescriptionInstructions(Host & aHost,
|
|||
uint16_t hostNameLength = sizeof(hostName);
|
||||
|
||||
VerifyOrExit(record.GetClass() == aMetadata.mDnsZone.GetClass(), error = kErrorFailed);
|
||||
|
||||
SuccessOrExit(error = aHost.ProcessTtl(record.GetTtl()));
|
||||
|
||||
SuccessOrExit(error = aMessage.Read(offset, srvRecord));
|
||||
offset += sizeof(srvRecord);
|
||||
|
||||
|
@ -971,6 +1014,7 @@ Error Server::ProcessServiceDescriptionInstructions(Host & aHost,
|
|||
|
||||
// Make sure that this is the first SRV RR for this service description
|
||||
VerifyOrExit(desc->mPort == 0, error = kErrorFailed);
|
||||
desc->mTtl = srvRecord.GetTtl();
|
||||
desc->mPriority = srvRecord.GetPriority();
|
||||
desc->mWeight = srvRecord.GetWeight();
|
||||
desc->mPort = srvRecord.GetPort();
|
||||
|
@ -980,6 +1024,8 @@ Error Server::ProcessServiceDescriptionInstructions(Host & aHost,
|
|||
{
|
||||
VerifyOrExit(record.GetClass() == aMetadata.mDnsZone.GetClass(), error = kErrorFailed);
|
||||
|
||||
SuccessOrExit(error = aHost.ProcessTtl(record.GetTtl()));
|
||||
|
||||
desc = aHost.FindServiceDescription(name);
|
||||
VerifyOrExit(desc != nullptr, error = kErrorFailed);
|
||||
|
||||
|
@ -1155,6 +1201,68 @@ exit:
|
|||
return error;
|
||||
}
|
||||
|
||||
Error Server::ValidateServiceSubTypes(Host &aHost, const MessageMetadata &aMetadata)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Host *existingHost;
|
||||
|
||||
// Verify that there is a matching base type service for all
|
||||
// sub-type services in `aHost` (which is from the received
|
||||
// and parsed SRP Update message).
|
||||
|
||||
for (const Service &service : aHost.GetServices())
|
||||
{
|
||||
if (service.IsSubType() && (aHost.FindBaseService(service.GetInstanceName()) == nullptr))
|
||||
{
|
||||
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)
|
||||
char subLabel[Dns::Name::kMaxLabelSize];
|
||||
|
||||
IgnoreError(service.GetServiceSubTypeLabel(subLabel, sizeof(subLabel)));
|
||||
LogWarn("Message contains instance %s with subtype %s without base type", service.GetInstanceName(),
|
||||
subLabel);
|
||||
#endif
|
||||
|
||||
ExitNow(error = kErrorParse);
|
||||
}
|
||||
}
|
||||
|
||||
// SRP server must treat the update instructions for a service type
|
||||
// and all its sub-types as atomic, i.e., when a service and its
|
||||
// sub-types are being updated, whatever information appears in the
|
||||
// SRP Update is the entirety of information about that service and
|
||||
// its sub-types. Any previously registered sub-type that does not
|
||||
// appear in a new SRP Update, must be removed.
|
||||
//
|
||||
// We go though the list of registered services for the same host
|
||||
// and if the base service is included in the new SRP Update
|
||||
// message, we add any previously registered service sub-type that
|
||||
// does not appear in new Update message as "deleted".
|
||||
|
||||
existingHost = mHosts.FindMatching(aHost.GetFullName());
|
||||
VerifyOrExit(existingHost != nullptr);
|
||||
|
||||
for (const Service &baseService : existingHost->GetServices())
|
||||
{
|
||||
if (baseService.IsSubType() || (aHost.FindBaseService(baseService.GetInstanceName()) == nullptr))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const Service &subService : existingHost->GetServices())
|
||||
{
|
||||
if (!subService.IsSubType() || !subService.MatchesInstanceName(baseService.GetInstanceName()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
SuccessOrExit(error = aHost.AddCopyOfServiceAsDeletedIfNotPresent(subService, aMetadata.mRxTime));
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Server::HandleUpdate(Host &aHost, const MessageMetadata &aMetadata)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
@ -1180,32 +1288,36 @@ void Server::HandleUpdate(Host &aHost, const MessageMetadata &aMetadata)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (aHost.FindService(service.GetServiceName(), service.GetInstanceName()) == nullptr)
|
||||
{
|
||||
Service *newService = aHost.AddNewService(service.GetServiceName(), service.GetInstanceName(),
|
||||
service.IsSubType(), aMetadata.mRxTime);
|
||||
|
||||
VerifyOrExit(newService != nullptr, error = kErrorNoBufs);
|
||||
newService->mDescription->mUpdateTime = aMetadata.mRxTime;
|
||||
newService->mIsDeleted = true;
|
||||
}
|
||||
SuccessOrExit(error = aHost.AddCopyOfServiceAsDeletedIfNotPresent(service, aMetadata.mRxTime));
|
||||
}
|
||||
|
||||
exit:
|
||||
if ((error == kErrorNone) && (mServiceUpdateHandler != nullptr))
|
||||
InformUpdateHandlerOrCommit(error, aHost, aMetadata);
|
||||
}
|
||||
|
||||
void Server::InformUpdateHandlerOrCommit(Error aError, Host &aHost, const MessageMetadata &aMetadata)
|
||||
{
|
||||
if ((aError == kErrorNone) && (mServiceUpdateHandler != nullptr))
|
||||
{
|
||||
UpdateMetadata *update = UpdateMetadata::Allocate(GetInstance(), aHost, aMetadata);
|
||||
|
||||
mOutstandingUpdates.Push(*update);
|
||||
mOutstandingUpdatesTimer.FireAtIfEarlier(update->GetExpireTime());
|
||||
if (update != nullptr)
|
||||
{
|
||||
mOutstandingUpdates.Push(*update);
|
||||
mOutstandingUpdatesTimer.FireAtIfEarlier(update->GetExpireTime());
|
||||
|
||||
LogInfo("SRP update handler is notified (updatedId = %u)", update->GetId());
|
||||
mServiceUpdateHandler(update->GetId(), &aHost, kDefaultEventsHandlerTimeout, mServiceUpdateHandlerContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
CommitSrpUpdate(error, aHost, aMetadata);
|
||||
LogInfo("SRP update handler is notified (updatedId = %u)", update->GetId());
|
||||
mServiceUpdateHandler(update->GetId(), &aHost, kDefaultEventsHandlerTimeout, mServiceUpdateHandlerContext);
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
aError = kErrorNoBufs;
|
||||
}
|
||||
|
||||
CommitSrpUpdate(aError, aHost, aMetadata);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Server::SendResponse(const Dns::UpdateHeader & aHeader,
|
||||
|
@ -1236,6 +1348,8 @@ void Server::SendResponse(const Dns::UpdateHeader & aHeader,
|
|||
LogInfo("Send success response");
|
||||
}
|
||||
|
||||
UpdateResponseCounters(aResponseCode);
|
||||
|
||||
exit:
|
||||
if (error != kErrorNone)
|
||||
{
|
||||
|
@ -1283,6 +1397,8 @@ void Server::SendResponse(const Dns::UpdateHeader &aHeader,
|
|||
|
||||
LogInfo("Send success response with granted lease: %u and key lease: %u", aLease, aKeyLease);
|
||||
|
||||
UpdateResponseCounters(Dns::UpdateHeader::kResponseSuccess);
|
||||
|
||||
exit:
|
||||
if (error != kErrorNone)
|
||||
{
|
||||
|
@ -1308,11 +1424,12 @@ void Server::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessag
|
|||
|
||||
Error Server::ProcessMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
return ProcessMessage(aMessage, TimerMilli::GetNow(), mLeaseConfig, &aMessageInfo);
|
||||
return ProcessMessage(aMessage, TimerMilli::GetNow(), mTtlConfig, mLeaseConfig, &aMessageInfo);
|
||||
}
|
||||
|
||||
Error Server::ProcessMessage(Message & aMessage,
|
||||
TimeMilli aRxTime,
|
||||
const TtlConfig & aTtlConfig,
|
||||
const LeaseConfig & aLeaseConfig,
|
||||
const Ip6::MessageInfo *aMessageInfo)
|
||||
{
|
||||
|
@ -1321,6 +1438,7 @@ Error Server::ProcessMessage(Message & aMessage,
|
|||
|
||||
metadata.mOffset = aMessage.GetOffset();
|
||||
metadata.mRxTime = aRxTime;
|
||||
metadata.mTtlConfig = aTtlConfig;
|
||||
metadata.mLeaseConfig = aLeaseConfig;
|
||||
metadata.mMessageInfo = aMessageInfo;
|
||||
|
||||
|
@ -1482,6 +1600,31 @@ const char *Server::AddressModeToString(AddressMode aMode)
|
|||
return kAddressModeStrings[aMode];
|
||||
}
|
||||
|
||||
void Server::UpdateResponseCounters(Dns::UpdateHeader::Response aResponseCode)
|
||||
{
|
||||
switch (aResponseCode)
|
||||
{
|
||||
case Dns::UpdateHeader::kResponseSuccess:
|
||||
++mResponseCounters.mSuccess;
|
||||
break;
|
||||
case Dns::UpdateHeader::kResponseServerFailure:
|
||||
++mResponseCounters.mServerFailure;
|
||||
break;
|
||||
case Dns::UpdateHeader::kResponseFormatError:
|
||||
++mResponseCounters.mFormatError;
|
||||
break;
|
||||
case Dns::UpdateHeader::kResponseNameExists:
|
||||
++mResponseCounters.mNameExists;
|
||||
break;
|
||||
case Dns::UpdateHeader::kResponseRefused:
|
||||
++mResponseCounters.mRefused;
|
||||
break;
|
||||
default:
|
||||
++mResponseCounters.mOther;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// Server::Service
|
||||
|
||||
|
@ -1540,6 +1683,18 @@ TimeMilli Server::Service::GetKeyExpireTime(void) const
|
|||
return mUpdateTime + Time::SecToMsec(mDescription->mKeyLease);
|
||||
}
|
||||
|
||||
void Server::Service::GetLeaseInfo(LeaseInfo &aLeaseInfo) const
|
||||
{
|
||||
TimeMilli now = TimerMilli::GetNow();
|
||||
TimeMilli expireTime = GetExpireTime();
|
||||
TimeMilli keyExpireTime = GetKeyExpireTime();
|
||||
|
||||
aLeaseInfo.mLease = Time::SecToMsec(GetLease());
|
||||
aLeaseInfo.mKeyLease = Time::SecToMsec(GetKeyLease());
|
||||
aLeaseInfo.mRemainingLease = (now <= expireTime) ? (expireTime - now) : 0;
|
||||
aLeaseInfo.mRemainingKeyLease = (now <= keyExpireTime) ? (keyExpireTime - now) : 0;
|
||||
}
|
||||
|
||||
bool Server::Service::MatchesInstanceName(const char *aInstanceName) const
|
||||
{
|
||||
return StringMatch(mDescription->mInstanceName.AsCString(), aInstanceName, kStringCaseInsensitiveMatch);
|
||||
|
@ -1627,6 +1782,7 @@ Error Server::Service::Description::Init(const char *aInstanceName, Host &aHost)
|
|||
mHost = &aHost;
|
||||
mPriority = 0;
|
||||
mWeight = 0;
|
||||
mTtl = 0;
|
||||
mPort = 0;
|
||||
mLease = 0;
|
||||
mKeyLease = 0;
|
||||
|
@ -1655,6 +1811,7 @@ void Server::Service::Description::TakeResourcesFrom(Description &aDescription)
|
|||
mWeight = aDescription.mWeight;
|
||||
mPort = aDescription.mPort;
|
||||
|
||||
mTtl = aDescription.mTtl;
|
||||
mLease = aDescription.mLease;
|
||||
mKeyLease = aDescription.mKeyLease;
|
||||
mUpdateTime = TimerMilli::GetNow();
|
||||
|
@ -1683,6 +1840,7 @@ exit:
|
|||
Server::Host::Host(Instance &aInstance, TimeMilli aUpdateTime)
|
||||
: InstanceLocator(aInstance)
|
||||
, mNext(nullptr)
|
||||
, mTtl(0)
|
||||
, mLease(0)
|
||||
, mKeyLease(0)
|
||||
, mUpdateTime(aUpdateTime)
|
||||
|
@ -1739,6 +1897,38 @@ TimeMilli Server::Host::GetKeyExpireTime(void) const
|
|||
return mUpdateTime + Time::SecToMsec(mKeyLease);
|
||||
}
|
||||
|
||||
void Server::Host::GetLeaseInfo(LeaseInfo &aLeaseInfo) const
|
||||
{
|
||||
TimeMilli now = TimerMilli::GetNow();
|
||||
TimeMilli expireTime = GetExpireTime();
|
||||
TimeMilli keyExpireTime = GetKeyExpireTime();
|
||||
|
||||
aLeaseInfo.mLease = Time::SecToMsec(GetLease());
|
||||
aLeaseInfo.mKeyLease = Time::SecToMsec(GetKeyLease());
|
||||
aLeaseInfo.mRemainingLease = (now <= expireTime) ? (expireTime - now) : 0;
|
||||
aLeaseInfo.mRemainingKeyLease = (now <= keyExpireTime) ? (keyExpireTime - now) : 0;
|
||||
}
|
||||
|
||||
Error Server::Host::ProcessTtl(uint32_t aTtl)
|
||||
{
|
||||
// This method processes the TTL value received in a resource record.
|
||||
//
|
||||
// If no TTL value is stored, this method wil set the stored value to @p aTtl and return `kErrorNone`.
|
||||
// If a TTL value is stored and @p aTtl equals the stored value, this method returns `kErrorNone`.
|
||||
// Otherwise, this method returns `kErrorRejected`.
|
||||
|
||||
Error error = kErrorRejected;
|
||||
|
||||
VerifyOrExit(aTtl && (mTtl == 0 || mTtl == aTtl));
|
||||
|
||||
mTtl = aTtl;
|
||||
|
||||
error = kErrorNone;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
const Server::Service *Server::Host::FindNextService(const Service *aPrevService,
|
||||
Service::Flags aFlags,
|
||||
const char * aServiceName,
|
||||
|
@ -1825,6 +2015,25 @@ exit:
|
|||
return;
|
||||
}
|
||||
|
||||
Error Server::Host::AddCopyOfServiceAsDeletedIfNotPresent(const Service &aService, TimeMilli aUpdateTime)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Service *newService;
|
||||
|
||||
VerifyOrExit(FindService(aService.GetServiceName(), aService.GetInstanceName()) == nullptr);
|
||||
|
||||
newService =
|
||||
AddNewService(aService.GetServiceName(), aService.GetInstanceName(), aService.IsSubType(), aUpdateTime);
|
||||
|
||||
VerifyOrExit(newService != nullptr, error = kErrorNoBufs);
|
||||
|
||||
newService->mDescription->mUpdateTime = aUpdateTime;
|
||||
newService->mIsDeleted = true;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Server::Host::FreeAllServices(void)
|
||||
{
|
||||
while (!mServices.IsEmpty())
|
||||
|
@ -1850,6 +2059,7 @@ Error Server::Host::MergeServicesAndResourcesFrom(Host &aHost)
|
|||
|
||||
mAddresses.TakeFrom(static_cast<Heap::Array<Ip6::Address> &&>(aHost.mAddresses));
|
||||
mKeyRecord = aHost.mKeyRecord;
|
||||
mTtl = aHost.mTtl;
|
||||
mLease = aHost.mLease;
|
||||
mKeyLease = aHost.mKeyLease;
|
||||
mUpdateTime = TimerMilli::GetNow();
|
||||
|
@ -1929,6 +2139,17 @@ Server::Service *Server::Host::FindService(const char *aServiceName, const char
|
|||
return AsNonConst(AsConst(this)->FindService(aServiceName, aInstanceName));
|
||||
}
|
||||
|
||||
const Server::Service *Server::Host::FindBaseService(const char *aInstanceName) const
|
||||
{
|
||||
return FindNextService(/*a PrevService */ nullptr, kFlagsBaseTypeServiceOnly, /* aServiceName */ nullptr,
|
||||
aInstanceName);
|
||||
}
|
||||
|
||||
Server::Service *Server::Host::FindBaseService(const char *aInstanceName)
|
||||
{
|
||||
return AsNonConst(AsConst(this)->FindBaseService(aInstanceName));
|
||||
}
|
||||
|
||||
Error Server::Host::AddIp6Address(const Ip6::Address &aIp6Address)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
@ -1963,6 +2184,7 @@ Server::UpdateMetadata::UpdateMetadata(Instance &aInstance, Host &aHost, const M
|
|||
, mExpireTime(TimerMilli::GetNow() + kDefaultEventsHandlerTimeout)
|
||||
, mDnsHeader(aMessageMetadata.mDnsHeader)
|
||||
, mId(Get<Server>().AllocateId())
|
||||
, mTtlConfig(aMessageMetadata.mTtlConfig)
|
||||
, mLeaseConfig(aMessageMetadata.mLeaseConfig)
|
||||
, mHost(aHost)
|
||||
, mIsDirectRxFromClient(aMessageMetadata.IsDirectRxFromClient())
|
||||
|
|
|
@ -129,6 +129,12 @@ public:
|
|||
*/
|
||||
typedef otSrpServerServiceUpdateId ServiceUpdateId;
|
||||
|
||||
/**
|
||||
* The SRP server lease information of a host/service.
|
||||
*
|
||||
*/
|
||||
typedef otSrpServerLeaseInfo LeaseInfo;
|
||||
|
||||
/**
|
||||
* This enumeration represents the address mode used by the SRP server.
|
||||
*
|
||||
|
@ -253,6 +259,14 @@ public:
|
|||
*/
|
||||
Error GetServiceSubTypeLabel(char *aLabel, uint8_t aMaxSize) const;
|
||||
|
||||
/**
|
||||
* This method returns the TTL of the service instance.
|
||||
*
|
||||
* @returns The TTL of the service instance.
|
||||
*
|
||||
*/
|
||||
uint32_t GetTtl(void) const { return mDescription->mTtl; }
|
||||
|
||||
/**
|
||||
* This method returns the port of the service instance.
|
||||
*
|
||||
|
@ -301,6 +315,22 @@ public:
|
|||
*/
|
||||
const Host &GetHost(void) const { return *mDescription->mHost; }
|
||||
|
||||
/**
|
||||
* This method returns the LEASE time of the service.
|
||||
*
|
||||
* @returns The LEASE time in seconds.
|
||||
*
|
||||
*/
|
||||
uint32_t GetLease(void) const { return mDescription->mLease; }
|
||||
|
||||
/**
|
||||
* This method returns the KEY-LEASE time of the key of the service.
|
||||
*
|
||||
* @returns The KEY-LEASE time in seconds.
|
||||
*
|
||||
*/
|
||||
uint32_t GetKeyLease(void) const { return mDescription->mKeyLease; }
|
||||
|
||||
/**
|
||||
* This method returns the expire time (in milliseconds) of the service.
|
||||
*
|
||||
|
@ -317,6 +347,15 @@ public:
|
|||
*/
|
||||
TimeMilli GetKeyExpireTime(void) const;
|
||||
|
||||
/**
|
||||
* This method gets the LEASE and KEY-LEASE information of a given service.
|
||||
*
|
||||
* @param[out] aLeaseInfo A reference to a LeaseInfo instance. It contains the LEASE time, KEY-LEASE time,
|
||||
* remaining LEASE time and the remaining KEY-LEASE time.
|
||||
*
|
||||
*/
|
||||
void GetLeaseInfo(LeaseInfo &aLeaseInfo) const;
|
||||
|
||||
/**
|
||||
* This method indicates whether this service matches a given service instance name.
|
||||
*
|
||||
|
@ -359,6 +398,7 @@ public:
|
|||
uint16_t mPriority;
|
||||
uint16_t mWeight;
|
||||
uint16_t mPort;
|
||||
uint32_t mTtl; // The TTL in seconds.
|
||||
uint32_t mLease; // The LEASE time in seconds.
|
||||
uint32_t mKeyLease; // The KEY-LEASE time in seconds.
|
||||
TimeMilli mUpdateTime;
|
||||
|
@ -436,6 +476,14 @@ public:
|
|||
return mAddresses.AsCArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the TTL of the host.
|
||||
*
|
||||
* @returns The TTL of the host.
|
||||
*
|
||||
*/
|
||||
uint32_t GetTtl(void) const { return mTtl; }
|
||||
|
||||
/**
|
||||
* This method returns the LEASE time of the host.
|
||||
*
|
||||
|
@ -452,6 +500,15 @@ public:
|
|||
*/
|
||||
uint32_t GetKeyLease(void) const { return mKeyLease; }
|
||||
|
||||
/**
|
||||
* This method gets the LEASE and KEY-LEASE information of a given host.
|
||||
*
|
||||
* @param[out] aLeaseInfo A reference to a LeaseInfo instance. It contains the LEASE time, KEY-LEASE time,
|
||||
* remaining LEASE time and the remaining KEY-LEASE time.
|
||||
*
|
||||
*/
|
||||
void GetLeaseInfo(LeaseInfo &aLeaseInfo) const;
|
||||
|
||||
/**
|
||||
* This method returns the KEY resource record of the host.
|
||||
*
|
||||
|
@ -515,16 +572,20 @@ public:
|
|||
Host(Instance &aInstance, TimeMilli aUpdateTime);
|
||||
~Host(void);
|
||||
|
||||
Error SetFullName(const char *aFullName);
|
||||
void SetKeyRecord(Dns::Ecdsa256KeyRecord &aKeyRecord);
|
||||
void SetLease(uint32_t aLease) { mLease = aLease; }
|
||||
void SetKeyLease(uint32_t aKeyLease) { mKeyLease = aKeyLease; }
|
||||
Error SetFullName(const char *aFullName);
|
||||
void SetKeyRecord(Dns::Ecdsa256KeyRecord &aKeyRecord);
|
||||
void SetTtl(uint32_t aTtl) { mTtl = aTtl; }
|
||||
void SetLease(uint32_t aLease) { mLease = aLease; }
|
||||
void SetKeyLease(uint32_t aKeyLease) { mKeyLease = aKeyLease; }
|
||||
Error ProcessTtl(uint32_t aTtl);
|
||||
|
||||
LinkedList<Service> &GetServices(void) { return mServices; }
|
||||
Service * AddNewService(const char *aServiceName,
|
||||
const char *aInstanceName,
|
||||
bool aIsSubType,
|
||||
TimeMilli aUpdateTime);
|
||||
void RemoveService(Service *aService, RetainName aRetainName, NotifyMode aNotifyServiceHandler);
|
||||
Error AddCopyOfServiceAsDeletedIfNotPresent(const Service &aService, TimeMilli aUpdateTime);
|
||||
void FreeAllServices(void);
|
||||
void ClearResources(void);
|
||||
Error MergeServicesAndResourcesFrom(Host &aHost);
|
||||
|
@ -534,6 +595,8 @@ public:
|
|||
const RetainPtr<Service::Description> FindServiceDescription(const char *aInstanceName) const;
|
||||
Service * FindService(const char *aServiceName, const char *aInstanceName);
|
||||
const Service * FindService(const char *aServiceName, const char *aInstanceName) const;
|
||||
Service * FindBaseService(const char *aInstanceName);
|
||||
const Service * FindBaseService(const char *aInstanceName) const;
|
||||
|
||||
Host * mNext;
|
||||
Heap::String mFullName;
|
||||
|
@ -542,12 +605,33 @@ public:
|
|||
// TODO(wgtdkp): there is no necessary to save the entire resource
|
||||
// record, saving only the ECDSA-256 public key should be enough.
|
||||
Dns::Ecdsa256KeyRecord mKeyRecord;
|
||||
uint32_t mTtl; // The TTL in seconds.
|
||||
uint32_t mLease; // The LEASE time in seconds.
|
||||
uint32_t mKeyLease; // The KEY-LEASE time in seconds.
|
||||
TimeMilli mUpdateTime;
|
||||
LinkedList<Service> mServices;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class handles TTL configuration.
|
||||
*
|
||||
*/
|
||||
class TtlConfig : public otSrpServerTtlConfig
|
||||
{
|
||||
friend class Server;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes to default TTL configuration.
|
||||
*
|
||||
*/
|
||||
TtlConfig(void);
|
||||
|
||||
private:
|
||||
bool IsValid(void) const { return mMinTtl <= mMaxTtl; }
|
||||
uint32_t GrantTtl(uint32_t aLease, uint32_t aTtl) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class handles LEASE and KEY-LEASE configurations.
|
||||
*
|
||||
|
@ -704,6 +788,14 @@ public:
|
|||
*/
|
||||
State GetState(void) const { return mState; }
|
||||
|
||||
/**
|
||||
* This method tells the port the SRP server is listening to.
|
||||
*
|
||||
* @returns An integer that represents the port of the server. It returns 0 if the SRP server is not running.
|
||||
*
|
||||
*/
|
||||
uint16_t GetPort(void) const { return IsRunning() ? mPort : 0; }
|
||||
|
||||
/**
|
||||
* This method enables/disables the SRP server.
|
||||
*
|
||||
|
@ -712,6 +804,25 @@ public:
|
|||
*/
|
||||
void SetEnabled(bool aEnabled);
|
||||
|
||||
/**
|
||||
* This method returns the TTL configuration.
|
||||
*
|
||||
* @param[out] aTtlConfig A reference to the `TtlConfig` instance.
|
||||
*
|
||||
*/
|
||||
void GetTtlConfig(TtlConfig &aTtlConfig) const { aTtlConfig = mTtlConfig; }
|
||||
|
||||
/**
|
||||
* This method sets the TTL configuration.
|
||||
*
|
||||
* @param[in] aTtlConfig A reference to the `TtlConfig` instance.
|
||||
*
|
||||
* @retval kErrorNone Successfully set the TTL configuration
|
||||
* @retval kErrorInvalidArgs The TTL range is not valid.
|
||||
*
|
||||
*/
|
||||
Error SetTtlConfig(const TtlConfig &aTtlConfig);
|
||||
|
||||
/**
|
||||
* This method returns the LEASE and KEY-LEASE configurations.
|
||||
*
|
||||
|
@ -745,6 +856,14 @@ public:
|
|||
*/
|
||||
const Host *GetNextHost(const Host *aHost);
|
||||
|
||||
/**
|
||||
* This method returns the response counters of the SRP server.
|
||||
*
|
||||
* @returns A pointer to the response counters of the SRP server.
|
||||
*
|
||||
*/
|
||||
const otSrpServerResponseCounters *GetResponseCounters(void) const { return &mResponseCounters; }
|
||||
|
||||
/**
|
||||
* This method receives the service update result from service handler set by
|
||||
* SetServiceHandler.
|
||||
|
@ -758,6 +877,8 @@ public:
|
|||
private:
|
||||
static constexpr uint16_t kUdpPayloadSize = Ip6::kMaxDatagramLength - sizeof(Ip6::Udp::Header);
|
||||
|
||||
static constexpr uint32_t kDefaultMinTtl = 60u; // 1 min (in seconds).
|
||||
static constexpr uint32_t kDefaultMaxTtl = 3600u * 2; // 2 hours (in seconds).
|
||||
static constexpr uint32_t kDefaultMinLease = 60u * 30; // 30 min (in seconds).
|
||||
static constexpr uint32_t kDefaultMaxLease = 3600u * 2; // 2 hours (in seconds).
|
||||
static constexpr uint32_t kDefaultMinKeyLease = 3600u * 24; // 1 day (in seconds).
|
||||
|
@ -780,6 +901,7 @@ private:
|
|||
Dns::Zone mDnsZone;
|
||||
uint16_t mOffset;
|
||||
TimeMilli mRxTime;
|
||||
TtlConfig mTtlConfig;
|
||||
LeaseConfig mLeaseConfig;
|
||||
const Ip6::MessageInfo *mMessageInfo; // Set to `nullptr` when from SRPL.
|
||||
};
|
||||
|
@ -797,6 +919,7 @@ private:
|
|||
TimeMilli GetExpireTime(void) const { return mExpireTime; }
|
||||
const Dns::UpdateHeader &GetDnsHeader(void) const { return mDnsHeader; }
|
||||
ServiceUpdateId GetId(void) const { return mId; }
|
||||
const TtlConfig & GetTtlConfig(void) const { return mTtlConfig; }
|
||||
const LeaseConfig & GetLeaseConfig(void) const { return mLeaseConfig; }
|
||||
Host & GetHost(void) { return mHost; }
|
||||
const Ip6::MessageInfo & GetMessageInfo(void) const { return mMessageInfo; }
|
||||
|
@ -810,6 +933,7 @@ private:
|
|||
TimeMilli mExpireTime;
|
||||
Dns::UpdateHeader mDnsHeader;
|
||||
ServiceUpdateId mId; // The ID of this service update transaction.
|
||||
TtlConfig mTtlConfig; // TTL config to use when processing the message.
|
||||
LeaseConfig mLeaseConfig; // Lease config to use when processing the message.
|
||||
Host & mHost; // The `UpdateMetadata` has no ownership of this host.
|
||||
Ip6::MessageInfo mMessageInfo; // Valid when `mIsDirectRxFromClient` is true.
|
||||
|
@ -831,16 +955,19 @@ private:
|
|||
|
||||
ServiceUpdateId AllocateId(void) { return mServiceUpdateId++; }
|
||||
|
||||
void InformUpdateHandlerOrCommit(Error aError, Host &aHost, const MessageMetadata &aMetadata);
|
||||
void CommitSrpUpdate(Error aError, Host &aHost, const MessageMetadata &aMessageMetadata);
|
||||
void CommitSrpUpdate(Error aError, UpdateMetadata &aUpdateMetadata);
|
||||
void CommitSrpUpdate(Error aError,
|
||||
Host & aHost,
|
||||
const Dns::UpdateHeader &aDnsHeader,
|
||||
const Ip6::MessageInfo * aMessageInfo,
|
||||
const TtlConfig & aTtlConfig,
|
||||
const LeaseConfig & aLeaseConfig);
|
||||
Error ProcessMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
Error ProcessMessage(Message & aMessage,
|
||||
TimeMilli aRxTime,
|
||||
const TtlConfig & aTtlConfig,
|
||||
const LeaseConfig & aLeaseConfig,
|
||||
const Ip6::MessageInfo *aMessageInfo);
|
||||
void ProcessDnsUpdate(Message &aMessage, MessageMetadata &aMetadata);
|
||||
|
@ -853,6 +980,7 @@ private:
|
|||
uint16_t aSigRdataOffset,
|
||||
uint16_t aSigRdataLength,
|
||||
const char * aSignerName) const;
|
||||
Error ValidateServiceSubTypes(Host &aHost, const MessageMetadata &aMetadata);
|
||||
Error ProcessZoneSection(const Message &aMessage, MessageMetadata &aMetadata) const;
|
||||
Error ProcessHostDescriptionInstruction(Host & aHost,
|
||||
const Message & aMessage,
|
||||
|
@ -886,12 +1014,15 @@ private:
|
|||
const UpdateMetadata *FindOutstandingUpdate(const MessageMetadata &aMessageMetadata) const;
|
||||
static const char * AddressModeToString(AddressMode aMode);
|
||||
|
||||
void UpdateResponseCounters(Dns::Header::Response aResponseCode);
|
||||
|
||||
Ip6::Udp::Socket mSocket;
|
||||
otSrpServerServiceUpdateHandler mServiceUpdateHandler;
|
||||
void * mServiceUpdateHandlerContext;
|
||||
|
||||
Heap::String mDomain;
|
||||
|
||||
TtlConfig mTtlConfig;
|
||||
LeaseConfig mLeaseConfig;
|
||||
|
||||
LinkedList<Host> mHosts;
|
||||
|
@ -906,10 +1037,13 @@ private:
|
|||
AddressMode mAddressMode;
|
||||
uint8_t mAnycastSequenceNumber;
|
||||
bool mHasRegisteredAnyService : 1;
|
||||
|
||||
otSrpServerResponseCounters mResponseCounters;
|
||||
};
|
||||
|
||||
} // namespace Srp
|
||||
|
||||
DefineCoreType(otSrpServerTtlConfig, Srp::Server::TtlConfig);
|
||||
DefineCoreType(otSrpServerLeaseConfig, Srp::Server::LeaseConfig);
|
||||
DefineCoreType(otSrpServerHost, Srp::Server::Host);
|
||||
DefineCoreType(otSrpServerService, Srp::Server::Service);
|
||||
|
|
|
@ -123,11 +123,9 @@ exit:
|
|||
return error;
|
||||
}
|
||||
|
||||
Instance &Tcp::Endpoint::GetInstance(void)
|
||||
Instance &Tcp::Endpoint::GetInstance(void) const
|
||||
{
|
||||
struct tcpcb &tp = GetTcb();
|
||||
|
||||
return AsCoreType(tp.instance);
|
||||
return AsNonConst(AsCoreType(GetTcb().instance));
|
||||
}
|
||||
|
||||
const SockAddr &Tcp::Endpoint::GetLocalAddress(void) const
|
||||
|
@ -160,7 +158,7 @@ Error Tcp::Endpoint::Bind(const SockAddr &aSockName)
|
|||
struct tcpcb &tp = GetTcb();
|
||||
|
||||
VerifyOrExit(!AsCoreType(&aSockName.mAddress).IsUnspecified(), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(GetInstance().Get<Tcp>().CanBind(aSockName), error = kErrorInvalidState);
|
||||
VerifyOrExit(Get<Tcp>().CanBind(aSockName), error = kErrorInvalidState);
|
||||
|
||||
memcpy(&tp.laddr, &aSockName.mAddress, sizeof(tp.laddr));
|
||||
tp.lport = HostSwap16(aSockName.mPort);
|
||||
|
@ -275,9 +273,7 @@ Error Tcp::Endpoint::Deinitialize(void)
|
|||
{
|
||||
Error error;
|
||||
|
||||
Tcp &tcp = GetInstance().Get<Tcp>();
|
||||
|
||||
SuccessOrExit(error = tcp.mEndpoints.Remove(*this));
|
||||
SuccessOrExit(error = Get<Tcp>().mEndpoints.Remove(*this));
|
||||
SetNext(nullptr);
|
||||
|
||||
SuccessOrExit(error = Abort());
|
||||
|
@ -356,7 +352,7 @@ void Tcp::Endpoint::SetTimer(uint8_t aTimerFlag, uint32_t aDelay)
|
|||
LogDebg("Endpoint %p set timer %u to %u ms", static_cast<void *>(this), static_cast<unsigned int>(timerIndex),
|
||||
static_cast<unsigned int>(aDelay));
|
||||
|
||||
GetInstance().Get<Tcp>().mTimer.FireAtIfEarlier(newFireTime);
|
||||
Get<Tcp>().mTimer.FireAtIfEarlier(newFireTime);
|
||||
}
|
||||
|
||||
void Tcp::Endpoint::CancelTimer(uint8_t aTimerFlag)
|
||||
|
@ -451,7 +447,7 @@ void Tcp::Endpoint::PostCallbacksAfterSend(size_t aSent, size_t aBacklogBefore)
|
|||
if (backlogAfter < aBacklogBefore + aSent && mForwardProgressCallback != nullptr)
|
||||
{
|
||||
mPendingCallbacks |= kForwardProgressCallbackFlag;
|
||||
GetInstance().Get<Tcp>().mTasklet.Post();
|
||||
Get<Tcp>().mTasklet.Post();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -542,11 +538,9 @@ exit:
|
|||
return error;
|
||||
}
|
||||
|
||||
Instance &Tcp::Listener::GetInstance(void)
|
||||
Instance &Tcp::Listener::GetInstance(void) const
|
||||
{
|
||||
struct tcpcb_listen *tpl = &GetTcbListen();
|
||||
|
||||
return AsCoreType(tpl->instance);
|
||||
return AsNonConst(AsCoreType(GetTcbListen().instance));
|
||||
}
|
||||
|
||||
Error Tcp::Listener::Listen(const SockAddr &aSockName)
|
||||
|
@ -555,7 +549,7 @@ Error Tcp::Listener::Listen(const SockAddr &aSockName)
|
|||
uint16_t port = HostSwap16(aSockName.mPort);
|
||||
struct tcpcb_listen *tpl = &GetTcbListen();
|
||||
|
||||
VerifyOrExit(GetInstance().Get<Tcp>().CanBind(aSockName), error = kErrorInvalidState);
|
||||
VerifyOrExit(Get<Tcp>().CanBind(aSockName), error = kErrorInvalidState);
|
||||
|
||||
memcpy(&tpl->laddr, &aSockName.mAddress, sizeof(tpl->laddr));
|
||||
tpl->lport = port;
|
||||
|
@ -580,9 +574,7 @@ Error Tcp::Listener::Deinitialize(void)
|
|||
{
|
||||
Error error;
|
||||
|
||||
Tcp &tcp = GetInstance().Get<Tcp>();
|
||||
|
||||
SuccessOrExit(error = tcp.mListeners.Remove(*this));
|
||||
SuccessOrExit(error = Get<Tcp>().mListeners.Remove(*this));
|
||||
SetNext(nullptr);
|
||||
|
||||
exit:
|
||||
|
@ -812,7 +804,7 @@ bool Tcp::AutoBind(const SockAddr &aPeer, SockAddr &aToBind, bool aBindAddress,
|
|||
|
||||
peerInfo.Clear();
|
||||
peerInfo.SetPeerAddr(aPeer.GetAddress());
|
||||
netifAddress = InstanceLocator::GetInstance().Get<Ip6>().SelectSourceAddress(peerInfo);
|
||||
netifAddress = Get<Ip6>().SelectSourceAddress(peerInfo);
|
||||
VerifyOrExit(netifAddress != nullptr, success = false);
|
||||
aToBind.GetAddress() = netifAddress->GetAddress();
|
||||
}
|
||||
|
@ -854,12 +846,12 @@ exit:
|
|||
|
||||
void Tcp::HandleTimer(Timer &aTimer)
|
||||
{
|
||||
OT_ASSERT(&aTimer == &aTimer.GetInstance().Get<Tcp>().mTimer);
|
||||
OT_ASSERT(&aTimer == &aTimer.Get<Tcp>().mTimer);
|
||||
LogDebg("Main TCP timer expired");
|
||||
aTimer.GetInstance().Get<Tcp>().ProcessTimers();
|
||||
aTimer.Get<Tcp>().ProcessTimers();
|
||||
}
|
||||
|
||||
void Tcp::ProcessTimers()
|
||||
void Tcp::ProcessTimers(void)
|
||||
{
|
||||
TimeMilli now = TimerMilli::GetNow();
|
||||
bool pendingTimer;
|
||||
|
@ -1014,7 +1006,7 @@ void tcplp_sys_stop_timer(struct tcpcb *aTcb, uint8_t aTimerFlag)
|
|||
struct tcpcb *tcplp_sys_accept_ready(struct tcpcb_listen *aTcbListen, struct in6_addr *aAddr, uint16_t aPort)
|
||||
{
|
||||
Tcp::Listener & listener = Tcp::Listener::FromTcbListen(*aTcbListen);
|
||||
Tcp & tcp = listener.GetInstance().Get<Tcp>();
|
||||
Tcp & tcp = listener.Get<Tcp>();
|
||||
struct tcpcb * rv = (struct tcpcb *)-1;
|
||||
otSockAddr addr;
|
||||
otTcpEndpoint * endpointPtr;
|
||||
|
@ -1065,7 +1057,7 @@ bool tcplp_sys_accepted_connection(struct tcpcb_listen *aTcbListen,
|
|||
{
|
||||
Tcp::Listener &listener = Tcp::Listener::FromTcbListen(*aTcbListen);
|
||||
Tcp::Endpoint &endpoint = Tcp::Endpoint::FromTcb(*aAccepted);
|
||||
Tcp & tcp = endpoint.GetInstance().Get<Tcp>();
|
||||
Tcp & tcp = endpoint.Get<Tcp>();
|
||||
bool accepted = true;
|
||||
|
||||
if (listener.mAcceptDoneCallback != nullptr)
|
||||
|
|
|
@ -83,7 +83,7 @@ public:
|
|||
* This class represents an endpoint of a TCP/IPv6 connection.
|
||||
*
|
||||
*/
|
||||
class Endpoint : public otTcpEndpoint, public LinkedListEntry<Endpoint>
|
||||
class Endpoint : public otTcpEndpoint, public LinkedListEntry<Endpoint>, public GetProvider<Endpoint>
|
||||
{
|
||||
friend class Tcp;
|
||||
friend class LinkedList<Endpoint>;
|
||||
|
@ -118,7 +118,7 @@ public:
|
|||
* @returns The Instance pointer associated with this Endpoint.
|
||||
*
|
||||
*/
|
||||
Instance &GetInstance(void);
|
||||
Instance &GetInstance(void) const;
|
||||
|
||||
/**
|
||||
* Obtains the context pointer that was associated this Endpoint upon
|
||||
|
@ -402,7 +402,7 @@ public:
|
|||
* This class represents a TCP/IPv6 listener.
|
||||
*
|
||||
*/
|
||||
class Listener : public otTcpListener, public LinkedListEntry<Listener>
|
||||
class Listener : public otTcpListener, public LinkedListEntry<Listener>, public GetProvider<Listener>
|
||||
{
|
||||
friend class LinkedList<Listener>;
|
||||
|
||||
|
@ -436,7 +436,7 @@ public:
|
|||
* @returns The otInstance pointer associated with this Listener.
|
||||
*
|
||||
*/
|
||||
Instance &GetInstance(void);
|
||||
Instance &GetInstance(void) const;
|
||||
|
||||
/**
|
||||
* Obtains the context pointer that was associated with this Listener upon
|
||||
|
|
|
@ -37,8 +37,10 @@
|
|||
#include <openthread/config.h>
|
||||
|
||||
#define OT_THREAD_VERSION_INVALID 0
|
||||
|
||||
#define OT_THREAD_VERSION_1_1 2
|
||||
#define OT_THREAD_VERSION_1_2 3
|
||||
#define OT_THREAD_VERSION_1_3 4
|
||||
|
||||
#define OPENTHREAD_CORE_CONFIG_H_IN
|
||||
|
||||
|
@ -51,7 +53,7 @@
|
|||
#endif
|
||||
|
||||
#ifndef OPENTHREAD_CONFIG_THREAD_VERSION
|
||||
#define OPENTHREAD_CONFIG_THREAD_VERSION OT_THREAD_VERSION_1_2
|
||||
#define OPENTHREAD_CONFIG_THREAD_VERSION OT_THREAD_VERSION_1_3
|
||||
#endif
|
||||
|
||||
#include "config/announce_sender.h"
|
||||
|
|
|
@ -522,6 +522,7 @@ public:
|
|||
* @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned.
|
||||
*
|
||||
* @retval kErrorNone Successfully started scanning the channel.
|
||||
* @retval kErrorBusy The radio is performing energy scanning.
|
||||
* @retval kErrorNotImplemented The radio doesn't support energy scanning.
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -47,8 +47,12 @@ if(OT_VENDOR_EXTENSION)
|
|||
target_sources(openthread-radio-cli PRIVATE ${OT_VENDOR_EXTENSION})
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED OT_MBEDTLS_RCP)
|
||||
set(OT_MBEDTLS_RCP ${OT_MBEDTLS})
|
||||
endif()
|
||||
|
||||
target_link_libraries(openthread-radio-cli
|
||||
PRIVATE
|
||||
${OT_MBEDTLS}
|
||||
${OT_MBEDTLS_RCP}
|
||||
ot-config
|
||||
)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue