mirror of
https://github.com/espressif/openthread.git
synced 2026-08-19 08:59:52 +00:00
Thread Commissioning. (#399)
This commit is contained in:
@@ -433,6 +433,85 @@ MBEDTLS_CPPFLAGS="${MBEDTLS_CPPFLAGS} -I\${abs_top_srcdir}/third_party/mbedtls/r
|
||||
MBEDTLS_CPPFLAGS="${MBEDTLS_CPPFLAGS} -I\${abs_top_srcdir}/third_party/mbedtls/repo/include/mbedtls"
|
||||
MBEDTLS_CPPFLAGS="${MBEDTLS_CPPFLAGS} -DMBEDTLS_CONFIG_FILE=\\\"mbedtls-config.h\\\""
|
||||
|
||||
#
|
||||
# Thread Commissioner
|
||||
#
|
||||
|
||||
AC_ARG_ENABLE(commissioner,
|
||||
[AS_HELP_STRING([--enable-commissioner],[Enable commissioner suport @<:@default=no@:>@.])],
|
||||
[
|
||||
case "${enableval}" in
|
||||
|
||||
no|yes)
|
||||
enable_commissioner=${enableval}
|
||||
;;
|
||||
|
||||
*)
|
||||
AC_MSG_ERROR([Invalid value ${enable_commissioner} for --enable-commissioner])
|
||||
;;
|
||||
esac
|
||||
],
|
||||
[enable_commissioner=no])
|
||||
|
||||
if test "$enable_commissioner" = "yes"; then
|
||||
OPENTHREAD_ENABLE_COMMISSIONER=1
|
||||
else
|
||||
OPENTHREAD_ENABLE_COMMISSIONER=0
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT(${enable_commissioner})
|
||||
AC_SUBST(OPENTHREAD_ENABLE_COMMISSIONER)
|
||||
AM_CONDITIONAL([OPENTHREAD_ENABLE_COMMISSIONER], [test "${enable_commissioner}" = "yes"])
|
||||
AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_COMMISSIONER],[${OPENTHREAD_ENABLE_COMMISSIONER}],[Define to 1 to enable the commissioner role.])
|
||||
|
||||
#
|
||||
# Thread Joiner
|
||||
#
|
||||
|
||||
AC_ARG_ENABLE(joiner,
|
||||
[AS_HELP_STRING([--enable-joiner],[Enable joiner suport @<:@default=no@:>@.])],
|
||||
[
|
||||
case "${enableval}" in
|
||||
|
||||
no|yes)
|
||||
enable_joiner=${enableval}
|
||||
;;
|
||||
|
||||
*)
|
||||
AC_MSG_ERROR([Invalid value ${enable_joiner} for --enable-joiner])
|
||||
;;
|
||||
esac
|
||||
],
|
||||
[enable_joiner=no])
|
||||
|
||||
if test "$enable_joiner" = "yes"; then
|
||||
OPENTHREAD_ENABLE_JOINER=1
|
||||
else
|
||||
OPENTHREAD_ENABLE_JOINER=0
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT(${enable_joiner})
|
||||
AC_SUBST(OPENTHREAD_ENABLE_JOINER)
|
||||
AM_CONDITIONAL([OPENTHREAD_ENABLE_JOINER], [test "${enable_joiner}" = "yes"])
|
||||
AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_JOINER],[${OPENTHREAD_ENABLE_JOINER}],[Define to 1 to enable the joiner role.])
|
||||
|
||||
if test "${enable_commissioner}" = "yes" -o "${enable_joiner}" = "yes"; then
|
||||
enable_dtls="yes"
|
||||
OPENTHREAD_ENABLE_DTLS=1
|
||||
MBEDTLS_CPPFLAGS="-I\${abs_top_srcdir}/third_party/mbedtls"
|
||||
MBEDTLS_CPPFLAGS="${MBEDTLS_CPPFLAGS} -I\${abs_top_srcdir}/third_party/mbedtls/repo/include"
|
||||
MBEDTLS_CPPFLAGS="${MBEDTLS_CPPFLAGS} -I\${abs_top_srcdir}/third_party/mbedtls/repo/include/mbedtls"
|
||||
MBEDTLS_CPPFLAGS="${MBEDTLS_CPPFLAGS} -DMBEDTLS_CONFIG_FILE=\\\"mbedtls-config.h\\\""
|
||||
else
|
||||
enable_dtls="no"
|
||||
OPENTHREAD_ENABLE_DTLS=0
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT(${enable_dtls})
|
||||
AC_SUBST(OPENTHREAD_ENABLE_DTLS)
|
||||
AM_CONDITIONAL([OPENTHREAD_ENABLE_DTLS], [test "${enable_dtls}" = "yes"])
|
||||
AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_DTLS],[${OPENTHREAD_ENABLE_DTLS}],[Define to 1 to enable dtls support.])
|
||||
|
||||
#
|
||||
# Diagnostics Library
|
||||
#
|
||||
@@ -629,6 +708,7 @@ AC_CONFIG_FILES([
|
||||
Makefile
|
||||
include/Makefile
|
||||
include/cli/Makefile
|
||||
include/commissioning/Makefile
|
||||
include/ncp/Makefile
|
||||
include/platform/Makefile
|
||||
src/Makefile
|
||||
@@ -712,6 +792,9 @@ AC_MSG_NOTICE([
|
||||
Pretty check args : ${PRETTY_CHECK_ARGS:--}
|
||||
OpenThread CLI support : ${enable_cli}
|
||||
OpenThread NCP support : ${enable_ncp}
|
||||
OpenThread Commissioner support : ${enable_commissioner}
|
||||
OpenThread Joiner support : ${enable_joiner}
|
||||
OpenThread DTLS support : ${enable_dtls}
|
||||
OpenThread Diagnostics support : ${enable_diag}
|
||||
OpenThread examples : ${OPENTHREAD_EXAMPLES}
|
||||
OpenThread platform information : ${PLATFORM_INFO}
|
||||
|
||||
@@ -32,6 +32,7 @@ include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
|
||||
|
||||
DIST_SUBDIRS = \
|
||||
cli \
|
||||
commissioning \
|
||||
ncp \
|
||||
platform \
|
||||
$(NULL)
|
||||
@@ -40,6 +41,7 @@ DIST_SUBDIRS = \
|
||||
|
||||
SUBDIRS = \
|
||||
cli \
|
||||
commissioning \
|
||||
ncp \
|
||||
platform \
|
||||
$(NULL)
|
||||
@@ -48,6 +50,7 @@ SUBDIRS = \
|
||||
|
||||
PRETTY_SUBDIRS = \
|
||||
cli \
|
||||
commissioning \
|
||||
ncp \
|
||||
platform \
|
||||
$(NULL)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#
|
||||
# Copyright (c) 2016, Nest Labs, Inc.
|
||||
# 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.
|
||||
#
|
||||
|
||||
include $(abs_top_nlbuild_autotools_dir)/automake/pre.am
|
||||
|
||||
ot_commissioning_headers = \
|
||||
commissioner.h \
|
||||
joiner.h \
|
||||
$(NULL)
|
||||
|
||||
ot_commissioningdir = $(includedir)/commissioning
|
||||
dist_ot_commissioning_HEADERS = $(ot_commissioning_headers)
|
||||
|
||||
install-headers: install-includeHEADERS
|
||||
|
||||
include $(abs_top_nlbuild_autotools_dir)/automake/post.am
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief
|
||||
* This file includes the platform abstraction for the Thread Commissioner role.
|
||||
*/
|
||||
|
||||
#ifndef OPENTHREAD_COMMISSIONER_H_
|
||||
#define OPENTHREAD_COMMISSIONER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup core-commissioning
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This function enables the Thread Commissioner role.
|
||||
*
|
||||
*/
|
||||
ThreadError otCommissionerStart(void);
|
||||
|
||||
/**
|
||||
* This function disables the Thread Commissioner role.
|
||||
*
|
||||
*/
|
||||
ThreadError otCommissionerStop(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // end of extern "C"
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_COMMISSIONER_H_
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief
|
||||
* This file includes the platform abstraction for the Thread Joiner role.
|
||||
*/
|
||||
|
||||
#ifndef OPENTHREAD_JOINER_H_
|
||||
#define OPENTHREAD_JOINER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup core-commissioning
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This function enables the Thread Joiner role.
|
||||
*
|
||||
*/
|
||||
ThreadError otJoinerStart(void);
|
||||
|
||||
/**
|
||||
* This function disables the Thread Joiner role.
|
||||
*
|
||||
*/
|
||||
ThreadError otJoinerStop(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // end of extern "C"
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_JOINER_H_
|
||||
@@ -333,11 +333,19 @@ typedef enum otMeshcopTlvType
|
||||
OT_MESHCOP_TLV_NETWORKNAME = 3, ///< meshcop Network Name TLV
|
||||
OT_MESHCOP_TLV_PSKC = 4, ///< meshcop PSKc TLV
|
||||
OT_MESHCOP_TLV_MASTERKEY = 5, ///< meshcop Network Master Key TLV
|
||||
OT_MESHCOP_TLV_LOCALPREFIX = 7, ///< meshcop Mesh Local Prefix TLV
|
||||
OT_MESHCOP_TLV_MESHLOCALPREFIX = 7, ///< meshcop Mesh Local Prefix TLV
|
||||
OT_MESHCOP_TLV_STEERING_DATA = 8, ///< meshcop Steering Data TLV
|
||||
OT_MESHCOP_TLV_BORDER_AGENT_RLOC = 9, ///< meshcop Border Agent Locator TLV
|
||||
OT_MESHCOP_TLV_COMMISSIONER_ID = 10, ///< meshcop Commissioner ID TLV
|
||||
OT_MESHCOP_TLV_COMM_SESSION_ID = 11, ///< meshcop Commissioner Session ID TLV
|
||||
OT_MESHCOP_TLV_SECURITYPOLICY = 12, ///< meshcop Security Policy TLV
|
||||
OT_MESHCOP_TLV_GET = 13, ///< meshcop Get TLV
|
||||
OT_MESHCOP_TLV_ACTIVETIMESTAMP = 14, ///< meshcop Active Timestamp TLV
|
||||
OT_MESHCOP_TLV_STATE = 16, ///< meshcop State TLV
|
||||
OT_MESHCOP_TLV_JOINER_DTLS = 17, ///< meshcop Joiner DTLS Encapsulation TLV
|
||||
OT_MESHCOP_TLV_JOINER_UDP_PORT = 18, ///< meshcop Joiner UDP Port TLV
|
||||
OT_MESHCOP_TLV_JOINER_IID = 19, ///< meshcop Joiner IID TLV
|
||||
OT_MESHCOP_TLV_JOINER_ROUTER_KEK = 21, ///< meshcop Joiner Router KEK TLV
|
||||
OT_MESHCOP_TLV_PENDINGTIMESTAMP = 51, ///< meshcop Pending Timestamp TLV
|
||||
OT_MESHCOP_TLV_DELAYTIMER = 52, ///< meshcop Delay Timer TLV
|
||||
OT_MESHCOP_TLV_CHANNELMASK = 53, ///< meshcop Channel Mask TLV
|
||||
|
||||
+57
-3
@@ -37,6 +37,8 @@
|
||||
|
||||
#include <openthread.h>
|
||||
#include <openthread-diag.h>
|
||||
#include <commissioning/commissioner.h>
|
||||
#include <commissioning/joiner.h>
|
||||
|
||||
#include "cli.hpp"
|
||||
#include "cli_dataset.hpp"
|
||||
@@ -63,15 +65,24 @@ const struct Command Interpreter::sCommands[] =
|
||||
{ "child", &ProcessChild },
|
||||
{ "childmax", &ProcessChildMax },
|
||||
{ "childtimeout", &ProcessChildTimeout },
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
{ "commissioner", &ProcessCommissioner },
|
||||
#endif
|
||||
{ "contextreusedelay", &ProcessContextIdReuseDelay },
|
||||
{ "counter", &ProcessCounters },
|
||||
{ "dataset", &ProcessDataset },
|
||||
#if OPENTHREAD_ENABLE_DIAG
|
||||
{ "diag", &ProcessDiag },
|
||||
#endif
|
||||
{ "discover", &ProcessDiscover },
|
||||
{ "eidcache", &ProcessEidCache },
|
||||
{ "extaddr", &ProcessExtAddress },
|
||||
{ "extpanid", &ProcessExtPanId },
|
||||
{ "ifconfig", &ProcessIfconfig },
|
||||
{ "ipaddr", &ProcessIpAddr },
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
{ "joiner", &ProcessJoiner },
|
||||
#endif
|
||||
{ "keysequence", &ProcessKeySequence },
|
||||
{ "leaderdata", &ProcessLeaderData },
|
||||
{ "leaderpartitionid", &ProcessLeaderPartitionId },
|
||||
@@ -101,9 +112,6 @@ const struct Command Interpreter::sCommands[] =
|
||||
{ "thread", &ProcessThread },
|
||||
{ "version", &ProcessVersion },
|
||||
{ "whitelist", &ProcessWhitelist },
|
||||
#if OPENTHREAD_ENABLE_DIAG
|
||||
{ "diag", &ProcessDiag },
|
||||
#endif
|
||||
};
|
||||
|
||||
static otDEFINE_ALIGNED_VAR(sPingTimerBuf, sizeof(Timer), uint64_t);
|
||||
@@ -1818,6 +1826,52 @@ void Interpreter::ProcessVersion(int argc, char *argv[])
|
||||
(void)argv;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
|
||||
void Interpreter::ProcessCommissioner(int argc, char *argv[])
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(argc > 0, error = kThreadError_Parse);
|
||||
|
||||
if (strcmp(argv[0], "start") == 0)
|
||||
{
|
||||
otCommissionerStart();
|
||||
}
|
||||
else if (strcmp(argv[0], "stop") == 0)
|
||||
{
|
||||
otCommissionerStop();
|
||||
}
|
||||
|
||||
exit:
|
||||
AppendResult(error);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER
|
||||
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
|
||||
void Interpreter::ProcessJoiner(int argc, char *argv[])
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(argc > 0, error = kThreadError_Parse);
|
||||
|
||||
if (strcmp(argv[0], "start") == 0)
|
||||
{
|
||||
otJoinerStart();
|
||||
}
|
||||
else if (strcmp(argv[0], "stop") == 0)
|
||||
{
|
||||
otJoinerStop();
|
||||
}
|
||||
|
||||
exit:
|
||||
AppendResult(error);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_JOINER
|
||||
|
||||
void Interpreter::ProcessWhitelist(int argc, char *argv[])
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
+11
-5
@@ -36,10 +36,11 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <openthread-config.h>
|
||||
|
||||
#include <cli/cli_server.hpp>
|
||||
#include <net/icmp6.hpp>
|
||||
#include <common/timer.hpp>
|
||||
#include <openthread-config.h>
|
||||
|
||||
namespace Thread {
|
||||
|
||||
@@ -135,9 +136,15 @@ private:
|
||||
static void ProcessChild(int argc, char *argv[]);
|
||||
static void ProcessChildTimeout(int argc, char *argv[]);
|
||||
static void ProcessChildMax(int argc, char *argv[]);
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
static void ProcessCommissioner(int argc, char *argv[]);
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER
|
||||
static void ProcessContextIdReuseDelay(int argc, char *argv[]);
|
||||
static void ProcessCounters(int argc, char *argv[]);
|
||||
static void ProcessDataset(int argc, char *argv[]);
|
||||
#if OPENTHREAD_ENABLE_DIAG
|
||||
static void ProcessDiag(int argc, char *argv[]);
|
||||
#endif // OPENTHREAD_ENABLE_DIAG
|
||||
static void ProcessDiscover(int argc, char *argv[]);
|
||||
static void ProcessEidCache(int argc, char *argv[]);
|
||||
static void ProcessExtAddress(int argc, char *argv[]);
|
||||
@@ -146,6 +153,9 @@ private:
|
||||
static void ProcessIpAddr(int argc, char *argv[]);
|
||||
static ThreadError ProcessIpAddrAdd(int argc, char *argv[]);
|
||||
static ThreadError ProcessIpAddrDel(int argc, char *argv[]);
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
static void ProcessJoiner(int argc, char *argv[]);
|
||||
#endif // OPENTHREAD_ENABLE_JOINER
|
||||
static void ProcessKeySequence(int argc, char *argv[]);
|
||||
static void ProcessLeaderData(int argc, char *argv[]);
|
||||
static void ProcessLeaderPartitionId(int argc, char *argv[]);
|
||||
@@ -181,10 +191,6 @@ private:
|
||||
static void ProcessVersion(int argc, char *argv[]);
|
||||
static void ProcessWhitelist(int argc, char *argv[]);
|
||||
|
||||
#if OPENTHREAD_ENABLE_DIAG
|
||||
static void ProcessDiag(int argc, char *argv[]);
|
||||
#endif
|
||||
|
||||
static void HandleEchoResponse(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
static void HandlePingTimer(void *aContext);
|
||||
static void HandleActiveScanResult(otActiveScanResult *aResult, void *aContext);
|
||||
|
||||
@@ -507,7 +507,7 @@ ThreadError Dataset::ProcessMgmtGetCommand(int argc, char *argv[])
|
||||
}
|
||||
else if (strcmp(argv[index], "localprefix") == 0)
|
||||
{
|
||||
tlvs[length++] = OT_MESHCOP_TLV_LOCALPREFIX;
|
||||
tlvs[length++] = OT_MESHCOP_TLV_MESHLOCALPREFIX;
|
||||
}
|
||||
else if (strcmp(argv[index], "delaytimer") == 0)
|
||||
{
|
||||
|
||||
@@ -47,10 +47,13 @@ libopenthread_a_SOURCES = \
|
||||
crypto/aes_ecb.cpp \
|
||||
crypto/hmac_sha256.cpp \
|
||||
crypto/mbedtls.cpp \
|
||||
crypto/sha256.cpp \
|
||||
mac/mac.cpp \
|
||||
mac/mac_frame.cpp \
|
||||
mac/mac_whitelist.cpp \
|
||||
mac/mac_blacklist.cpp \
|
||||
meshcop/joiner_router.cpp \
|
||||
meshcop/leader.cpp \
|
||||
net/icmp6.cpp \
|
||||
net/ip6.cpp \
|
||||
net/ip6_address.cpp \
|
||||
@@ -77,6 +80,24 @@ libopenthread_a_SOURCES = \
|
||||
thread/thread_tlvs.cpp \
|
||||
$(NULL)
|
||||
|
||||
if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
libopenthread_a_SOURCES += \
|
||||
meshcop/commissioner.cpp \
|
||||
$(NULL)
|
||||
endif # OPENTHREAD_ENABLE_COMMISSIONER
|
||||
|
||||
if OPENTHREAD_ENABLE_JOINER
|
||||
libopenthread_a_SOURCES += \
|
||||
meshcop/joiner.cpp \
|
||||
$(NULL)
|
||||
endif # OPENTHREAD_ENABLE_JOINER
|
||||
|
||||
if OPENTHREAD_ENABLE_DTLS
|
||||
libopenthread_a_SOURCES += \
|
||||
meshcop/dtls.cpp \
|
||||
$(NULL)
|
||||
endif # OPENTHREAD_ENABLE_DTLS
|
||||
|
||||
noinst_HEADERS = \
|
||||
openthread-core-config.h \
|
||||
openthread-core-default-config.h \
|
||||
@@ -94,10 +115,16 @@ noinst_HEADERS = \
|
||||
crypto/aes_ecb.hpp \
|
||||
crypto/hmac_sha256.hpp \
|
||||
crypto/mbedtls.hpp \
|
||||
crypto/sha256.hpp \
|
||||
mac/mac.hpp \
|
||||
mac/mac_frame.hpp \
|
||||
mac/mac_whitelist.hpp \
|
||||
mac/mac_blacklist.hpp \
|
||||
meshcop/commissioner.hpp \
|
||||
meshcop/dtls.hpp \
|
||||
meshcop/joiner.hpp \
|
||||
meshcop/joiner_router.hpp \
|
||||
meshcop/leader.hpp \
|
||||
net/icmp6.hpp \
|
||||
net/ip6.hpp \
|
||||
net/ip6_address.hpp \
|
||||
|
||||
@@ -552,6 +552,16 @@ void Message::SetMleDiscoverResponse(bool aMleDiscoverResponse)
|
||||
mInfo.mMleDiscoverResponse = aMleDiscoverResponse;
|
||||
}
|
||||
|
||||
bool Message::IsJoinerEntrust(void) const
|
||||
{
|
||||
return mInfo.mJoinerEntrust;
|
||||
}
|
||||
|
||||
void Message::SetJoinerEntrust(bool aJoinerEntrust)
|
||||
{
|
||||
mInfo.mJoinerEntrust = aJoinerEntrust;
|
||||
}
|
||||
|
||||
uint16_t Message::UpdateChecksum(uint16_t aChecksum, uint16_t aOffset, uint16_t aLength) const
|
||||
{
|
||||
Buffer *curBuffer;
|
||||
|
||||
@@ -121,6 +121,7 @@ struct MessageInfo
|
||||
bool mLinkSecurity : 1; ///< Indicates whether or not link security is enabled.
|
||||
bool mMleDiscoverRequest : 1; ///< Identifies MLE Discover Request.
|
||||
bool mMleDiscoverResponse : 1; ///< Identifies MLE Discover Response.
|
||||
bool mJoinerEntrust : 1; ///< Indicates whether or not this message is a Joiner Entrust.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -522,6 +523,23 @@ public:
|
||||
*/
|
||||
void SetMleDiscoverResponse(bool aMleDiscoverResponse);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not this message is an Joiner Entrust.
|
||||
*
|
||||
* @retval TRUE If this message is an Joiner Entrust.
|
||||
* @retval FALSE If this message is not an Joiner Entrust.
|
||||
*
|
||||
*/
|
||||
bool IsJoinerEntrust(void) const;
|
||||
|
||||
/**
|
||||
* This method sets whether or not this message is an Joiner Entrust.
|
||||
*
|
||||
* @param[in] aLinkSecurityEnabled TRUE if this message is an Joiner Entrust, FALSE otherwise.
|
||||
*
|
||||
*/
|
||||
void SetJoinerEntrust(bool aJoinerEntrust);
|
||||
|
||||
/**
|
||||
* This method is used to update a checksum value.
|
||||
*
|
||||
|
||||
@@ -34,8 +34,7 @@
|
||||
#ifndef OT_MBEDTLS_HPP_
|
||||
#define OT_MBEDTLS_HPP_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <openthread-config.h>
|
||||
#include <mbedtls/memory_buffer_alloc.h>
|
||||
|
||||
namespace Thread {
|
||||
@@ -57,7 +56,11 @@ class MbedTls
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kMemorySize = 512, ///< Size of memory buffer (bytes).
|
||||
#if OPENTHREAD_ENABLE_DTLS
|
||||
kMemorySize = 2048 * sizeof(void *), ///< Size of memory buffer (bytes).
|
||||
#else
|
||||
kMemorySize = 512, ///< Size of memory buffer (bytes).
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* 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 SHA-256.
|
||||
*/
|
||||
|
||||
#include <crypto/sha256.hpp>
|
||||
|
||||
namespace Thread {
|
||||
namespace Crypto {
|
||||
|
||||
void Sha256::Start(void)
|
||||
{
|
||||
mbedtls_sha256_init(&mContext);
|
||||
mbedtls_sha256_starts(&mContext, 0);
|
||||
}
|
||||
|
||||
void Sha256::Update(const uint8_t *aBuf, uint16_t aBufLength)
|
||||
{
|
||||
mbedtls_sha256_update(&mContext, aBuf, aBufLength);
|
||||
}
|
||||
|
||||
void Sha256::Finish(uint8_t aHash[kHashSize])
|
||||
{
|
||||
mbedtls_sha256_finish(&mContext, aHash);
|
||||
mbedtls_sha256_free(&mContext);
|
||||
}
|
||||
|
||||
} // namespace Crypto
|
||||
} // namespace Thread
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* 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 performing SHA-256 computations.
|
||||
*/
|
||||
|
||||
#ifndef SHA256_HPP_
|
||||
#define SHA256_HPP_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <mbedtls/sha256.h>
|
||||
|
||||
namespace Thread {
|
||||
namespace Crypto {
|
||||
|
||||
/**
|
||||
* @addtogroup core-security
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class implements SHA-256 computation.
|
||||
*
|
||||
*/
|
||||
class Sha256
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kHashSize = 32, ///< SHA-256 hash size (bytes)
|
||||
};
|
||||
|
||||
/**
|
||||
* This method starts the SHA-256 computation.
|
||||
*
|
||||
*/
|
||||
void Start(void);
|
||||
|
||||
/**
|
||||
* This method inputs bytes into the SHA-256 computation.
|
||||
*
|
||||
* @param[in] aBuf A pointer to the input buffer.
|
||||
* @param[in] aBufLength The length of @p aBuf in bytes.
|
||||
*
|
||||
*/
|
||||
void Update(const uint8_t *aBuf, uint16_t aBufLength);
|
||||
|
||||
/**
|
||||
* This method finalizes the hash computation.
|
||||
*
|
||||
* @param[out] aHash A pointer to the output buffer.
|
||||
*
|
||||
*/
|
||||
void Finish(uint8_t aHash[kHashSize]);
|
||||
|
||||
private:
|
||||
mbedtls_sha256_context mContext;
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
} // namespace Crypto
|
||||
} // namespace Thread
|
||||
|
||||
#endif // SHA256_HPP_
|
||||
+89
-47
@@ -33,6 +33,8 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openthread-config.h>
|
||||
|
||||
#include <common/code_utils.hpp>
|
||||
#include <common/debug.hpp>
|
||||
#include <common/logging.hpp>
|
||||
@@ -442,24 +444,46 @@ void Mac::HandleBeginTransmit(void *aContext)
|
||||
|
||||
void Mac::ProcessTransmitSecurity(Frame &aFrame)
|
||||
{
|
||||
uint32_t frameCounter;
|
||||
uint8_t securityLevel;
|
||||
uint8_t keyIdMode;
|
||||
uint8_t nonce[kNonceSize];
|
||||
uint8_t tagLength;
|
||||
Crypto::AesCcm aesCcm;
|
||||
const uint8_t *key;
|
||||
|
||||
if (aFrame.GetSecurityEnabled() == false)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
aFrame.GetKeyIdMode(keyIdMode);
|
||||
|
||||
switch (keyIdMode)
|
||||
{
|
||||
case Frame::kKeyIdMode0:
|
||||
key = mKeyManager.GetKek();
|
||||
frameCounter = mKeyManager.GetKekFrameCounter();
|
||||
break;
|
||||
|
||||
case Frame::kKeyIdMode1:
|
||||
key = mKeyManager.GetCurrentMacKey();
|
||||
frameCounter = mKeyManager.GetMacFrameCounter();
|
||||
mKeyManager.IncrementMacFrameCounter();
|
||||
aFrame.SetKeyId((mKeyManager.GetCurrentKeySequence() & 0x7f) + 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
aFrame.GetSecurityLevel(securityLevel);
|
||||
aFrame.SetFrameCounter(mKeyManager.GetMacFrameCounter());
|
||||
aFrame.SetFrameCounter(frameCounter);
|
||||
|
||||
aFrame.SetKeyId((mKeyManager.GetCurrentKeySequence() & 0x7f) + 1);
|
||||
GenerateNonce(mExtAddress, frameCounter, securityLevel, nonce);
|
||||
|
||||
GenerateNonce(mExtAddress, mKeyManager.GetMacFrameCounter(), securityLevel, nonce);
|
||||
|
||||
aesCcm.SetKey(mKeyManager.GetCurrentMacKey(), 16);
|
||||
aesCcm.SetKey(key, 16);
|
||||
tagLength = aFrame.GetFooterLength() - Frame::kFcsSize;
|
||||
|
||||
aesCcm.Init(aFrame.GetHeaderLength(), aFrame.GetPayloadLength(), tagLength, nonce, sizeof(nonce));
|
||||
@@ -468,8 +492,6 @@ void Mac::ProcessTransmitSecurity(Frame &aFrame)
|
||||
aesCcm.Payload(aFrame.GetPayload(), aFrame.GetPayload(), aFrame.GetPayloadLength(), true);
|
||||
aesCcm.Finalize(aFrame.GetFooter(), &tagLength);
|
||||
|
||||
mKeyManager.IncrementMacFrameCounter();
|
||||
|
||||
exit:
|
||||
{}
|
||||
}
|
||||
@@ -736,12 +758,13 @@ ThreadError Mac::ProcessReceiveSecurity(Frame &aFrame, const Address &aSrcAddr,
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
uint8_t securityLevel;
|
||||
uint8_t keyIdMode;
|
||||
uint32_t frameCounter;
|
||||
uint8_t nonce[kNonceSize];
|
||||
uint8_t tag[Frame::kMaxMicSize];
|
||||
uint8_t tagLength;
|
||||
uint8_t keyid;
|
||||
uint32_t keySequence;
|
||||
uint32_t keySequence = 0;
|
||||
const uint8_t *macKey;
|
||||
Crypto::AesCcm aesCcm;
|
||||
|
||||
@@ -752,44 +775,60 @@ ThreadError Mac::ProcessReceiveSecurity(Frame &aFrame, const Address &aSrcAddr,
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
VerifyOrExit(aNeighbor != NULL, error = kThreadError_Security);
|
||||
|
||||
aFrame.GetSecurityLevel(securityLevel);
|
||||
aFrame.GetFrameCounter(frameCounter);
|
||||
|
||||
GenerateNonce(aSrcAddr.mExtAddress, frameCounter, securityLevel, nonce);
|
||||
aFrame.GetKeyIdMode(keyIdMode);
|
||||
|
||||
tagLength = aFrame.GetFooterLength() - Frame::kFcsSize;
|
||||
switch (keyIdMode)
|
||||
{
|
||||
case Frame::kKeyIdMode0:
|
||||
VerifyOrExit((macKey = mKeyManager.GetKek()) != NULL, error = kThreadError_Security);
|
||||
break;
|
||||
|
||||
aFrame.GetKeyId(keyid);
|
||||
keyid--;
|
||||
case Frame::kKeyIdMode1:
|
||||
VerifyOrExit(aNeighbor != NULL, error = kThreadError_Security);
|
||||
|
||||
if (keyid == (mKeyManager.GetCurrentKeySequence() & 0x7f))
|
||||
{
|
||||
// same key index
|
||||
keySequence = mKeyManager.GetCurrentKeySequence();
|
||||
macKey = mKeyManager.GetCurrentMacKey();
|
||||
}
|
||||
else if (keyid == ((mKeyManager.GetCurrentKeySequence() - 1) & 0x7f))
|
||||
{
|
||||
// previous key index
|
||||
keySequence = mKeyManager.GetCurrentKeySequence() - 1;
|
||||
macKey = mKeyManager.GetTemporaryMacKey(keySequence);
|
||||
}
|
||||
else if (keyid == ((mKeyManager.GetCurrentKeySequence() + 1) & 0x7f))
|
||||
{
|
||||
// next key index
|
||||
keySequence = mKeyManager.GetCurrentKeySequence() + 1;
|
||||
macKey = mKeyManager.GetTemporaryMacKey(keySequence);
|
||||
}
|
||||
else
|
||||
{
|
||||
aFrame.GetKeyId(keyid);
|
||||
keyid--;
|
||||
|
||||
if (keyid == (mKeyManager.GetCurrentKeySequence() & 0x7f))
|
||||
{
|
||||
// same key index
|
||||
keySequence = mKeyManager.GetCurrentKeySequence();
|
||||
macKey = mKeyManager.GetCurrentMacKey();
|
||||
}
|
||||
else if (keyid == ((mKeyManager.GetCurrentKeySequence() - 1) & 0x7f))
|
||||
{
|
||||
// previous key index
|
||||
keySequence = mKeyManager.GetCurrentKeySequence() - 1;
|
||||
macKey = mKeyManager.GetTemporaryMacKey(keySequence);
|
||||
}
|
||||
else if (keyid == ((mKeyManager.GetCurrentKeySequence() + 1) & 0x7f))
|
||||
{
|
||||
// next key index
|
||||
keySequence = mKeyManager.GetCurrentKeySequence() + 1;
|
||||
macKey = mKeyManager.GetTemporaryMacKey(keySequence);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(error = kThreadError_Security);
|
||||
}
|
||||
|
||||
VerifyOrExit((keySequence > aNeighbor->mKeySequence) ||
|
||||
((keySequence == aNeighbor->mKeySequence) &&
|
||||
(frameCounter >= aNeighbor->mValid.mLinkFrameCounter)),
|
||||
error = kThreadError_Security);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ExitNow(error = kThreadError_Security);
|
||||
break;
|
||||
}
|
||||
|
||||
VerifyOrExit((keySequence > aNeighbor->mKeySequence) ||
|
||||
((keySequence == aNeighbor->mKeySequence) && (frameCounter >= aNeighbor->mValid.mLinkFrameCounter)),
|
||||
error = kThreadError_Security);
|
||||
GenerateNonce(aSrcAddr.mExtAddress, frameCounter, securityLevel, nonce);
|
||||
tagLength = aFrame.GetFooterLength() - Frame::kFcsSize;
|
||||
|
||||
aesCcm.SetKey(macKey, 16);
|
||||
aesCcm.Init(aFrame.GetHeaderLength(), aFrame.GetPayloadLength(), tagLength, nonce, sizeof(nonce));
|
||||
@@ -799,21 +838,24 @@ ThreadError Mac::ProcessReceiveSecurity(Frame &aFrame, const Address &aSrcAddr,
|
||||
|
||||
VerifyOrExit(memcmp(tag, aFrame.GetFooter(), tagLength) == 0, error = kThreadError_Security);
|
||||
|
||||
if (aNeighbor->mKeySequence != keySequence)
|
||||
if (keyIdMode == Frame::kKeyIdMode1)
|
||||
{
|
||||
aNeighbor->mKeySequence = keySequence;
|
||||
aNeighbor->mValid.mMleFrameCounter = 0;
|
||||
}
|
||||
if (aNeighbor->mKeySequence != keySequence)
|
||||
{
|
||||
aNeighbor->mKeySequence = keySequence;
|
||||
aNeighbor->mValid.mMleFrameCounter = 0;
|
||||
}
|
||||
|
||||
aNeighbor->mValid.mLinkFrameCounter = frameCounter + 1;
|
||||
aNeighbor->mValid.mLinkFrameCounter = frameCounter + 1;
|
||||
|
||||
if (keySequence > mKeyManager.GetCurrentKeySequence())
|
||||
{
|
||||
mKeyManager.SetCurrentKeySequence(keySequence);
|
||||
}
|
||||
}
|
||||
|
||||
aFrame.SetSecurityValid(true);
|
||||
|
||||
if (keySequence > mKeyManager.GetCurrentKeySequence())
|
||||
{
|
||||
mKeyManager.SetCurrentKeySequence(keySequence);
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None)
|
||||
|
||||
@@ -556,6 +556,19 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError Frame::GetKeyIdMode(uint8_t &aKeyIdMode)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
uint8_t *buf;
|
||||
|
||||
VerifyOrExit((buf = FindSecurityHeader()) != NULL, error = kThreadError_Parse);
|
||||
|
||||
aKeyIdMode = buf[0] & kKeyIdModeMask;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError Frame::GetFrameCounter(uint32_t &aFrameCounter)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
@@ -419,6 +419,16 @@ public:
|
||||
*/
|
||||
ThreadError GetSecurityLevel(uint8_t &aSecurityLevel);
|
||||
|
||||
/**
|
||||
* This method gets the Key Identifier Mode.
|
||||
*
|
||||
* @param[out] aSecurityLevel The Key Identifier Mode.
|
||||
*
|
||||
* @retval kThreadError_None Successfully retrieved the Key Identifier Mode.
|
||||
*
|
||||
*/
|
||||
ThreadError GetKeyIdMode(uint8_t &aKeyIdMode);
|
||||
|
||||
/**
|
||||
* This method gets the Frame Counter.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,489 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* 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 a Commissioner role.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openthread-config.h>
|
||||
|
||||
#include <coap/coap_header.hpp>
|
||||
#include <common/logging.hpp>
|
||||
#include <meshcop/commissioner.hpp>
|
||||
#include <meshcop/joiner_router.hpp>
|
||||
#include <platform/random.h>
|
||||
#include <thread/meshcop_tlvs.hpp>
|
||||
#include <thread/thread_netif.hpp>
|
||||
#include <thread/thread_tlvs.hpp>
|
||||
#include <thread/thread_uris.hpp>
|
||||
|
||||
namespace Thread {
|
||||
namespace MeshCoP {
|
||||
|
||||
Commissioner::Commissioner(ThreadNetif &aThreadNetif):
|
||||
mTimer(aThreadNetif.GetIp6().mTimerScheduler, HandleTimer, this),
|
||||
mTransmitTask(aThreadNetif.GetIp6().mTaskletScheduler, &HandleUdpTransmit, this),
|
||||
mSendKek(false),
|
||||
mSocket(aThreadNetif.GetIp6().mUdp),
|
||||
mRelayReceive(OPENTHREAD_URI_RELAY_RX, &HandleRelayReceive, this),
|
||||
mNetif(aThreadNetif)
|
||||
{
|
||||
aThreadNetif.GetCoapServer().AddResource(mRelayReceive);
|
||||
}
|
||||
|
||||
ThreadError Commissioner::Start(void)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(mState == kStateDisabled, error = kThreadError_InvalidState);
|
||||
|
||||
SuccessOrExit(error = mSocket.Open(HandleUdpReceive, this));
|
||||
mState = kStatePetition;
|
||||
SendPetition();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError Commissioner::Stop(void)
|
||||
{
|
||||
mState = kStateDisabled;
|
||||
SendKeepAlive();
|
||||
mTimer.Start(1000);
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
void Commissioner::HandleTimer(void *aContext)
|
||||
{
|
||||
static_cast<Commissioner *>(aContext)->HandleTimer();
|
||||
}
|
||||
|
||||
void Commissioner::HandleTimer(void)
|
||||
{
|
||||
switch (mState)
|
||||
{
|
||||
case kStateDisabled:
|
||||
mSocket.Close();
|
||||
break;
|
||||
|
||||
case kStatePetition:
|
||||
SendPetition();
|
||||
break;
|
||||
|
||||
case kStateActive:
|
||||
SendKeepAlive();
|
||||
mTimer.Start(5000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ThreadError Commissioner::SendPetition(void)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Coap::Header header;
|
||||
Message *message;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
CommissionerIdTlv commissionerId;
|
||||
|
||||
for (size_t i = 0; i < sizeof(mCoapToken); i++)
|
||||
{
|
||||
mCoapToken[i] = otPlatRandomGet() & 0xff;
|
||||
}
|
||||
|
||||
header.Init();
|
||||
header.SetVersion(1);
|
||||
header.SetType(Coap::Header::kTypeConfirmable);
|
||||
header.SetCode(Coap::Header::kCodePost);
|
||||
header.SetMessageId(++mCoapMessageId);
|
||||
header.SetToken(mCoapToken, sizeof(mCoapToken));
|
||||
header.AppendUriPathOptions(OPENTHREAD_URI_LEADER_PETITION);
|
||||
header.AppendContentFormatOption(Coap::Header::kApplicationOctetStream);
|
||||
header.Finalize();
|
||||
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
SuccessOrExit(error = message->Append(header.GetBytes(), header.GetLength()));
|
||||
|
||||
commissionerId.Init();
|
||||
commissionerId.SetCommissionerId("OpenThread Commissioner");
|
||||
|
||||
SuccessOrExit(error = message->Append(&commissionerId, sizeof(Tlv) + commissionerId.GetLength()));
|
||||
|
||||
memset(&messageInfo, 0, sizeof(messageInfo));
|
||||
mNetif.GetMle().GetLeaderAddress(*static_cast<Ip6::Address *>(&messageInfo.mPeerAddr));
|
||||
messageInfo.mPeerPort = kCoapUdpPort;
|
||||
SuccessOrExit(error = mSocket.SendTo(*message, messageInfo));
|
||||
|
||||
otLogInfoMeshCoP("sent petition\r\n");
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError Commissioner::SendKeepAlive(void)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Coap::Header header;
|
||||
Message *message;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
StateTlv state;
|
||||
CommissionerSessionIdTlv sessionId;
|
||||
|
||||
for (size_t i = 0; i < sizeof(mCoapToken); i++)
|
||||
{
|
||||
mCoapToken[i] = otPlatRandomGet() & 0xff;
|
||||
}
|
||||
|
||||
header.Init();
|
||||
header.SetVersion(1);
|
||||
header.SetType(Coap::Header::kTypeConfirmable);
|
||||
header.SetCode(Coap::Header::kCodePost);
|
||||
header.SetMessageId(++mCoapMessageId);
|
||||
header.SetToken(mCoapToken, sizeof(mCoapToken));
|
||||
header.AppendUriPathOptions(OPENTHREAD_URI_LEADER_KEEP_ALIVE);
|
||||
header.AppendContentFormatOption(Coap::Header::kApplicationOctetStream);
|
||||
header.Finalize();
|
||||
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
SuccessOrExit(error = message->Append(header.GetBytes(), header.GetLength()));
|
||||
|
||||
state.Init();
|
||||
state.SetState(mState == kStateActive ? StateTlv::kAccept : StateTlv::kReject);
|
||||
SuccessOrExit(error = message->Append(&state, sizeof(state)));
|
||||
|
||||
sessionId.Init();
|
||||
sessionId.SetCommissionerSessionId(mSessionId);
|
||||
SuccessOrExit(error = message->Append(&sessionId, sizeof(sessionId)));
|
||||
|
||||
memset(&messageInfo, 0, sizeof(messageInfo));
|
||||
mNetif.GetMle().GetLeaderAddress(*static_cast<Ip6::Address *>(&messageInfo.mPeerAddr));
|
||||
messageInfo.mPeerPort = kCoapUdpPort;
|
||||
SuccessOrExit(error = mSocket.SendTo(*message, messageInfo));
|
||||
|
||||
otLogInfoMeshCoP("sent keep alive\r\n");
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void Commissioner::HandleRelayReceive(void *aContext, Coap::Header &aHeader,
|
||||
Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
static_cast<Commissioner *>(aContext)->HandleRelayReceive(aHeader, aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
void Commissioner::HandleRelayReceive(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
ThreadError error;
|
||||
JoinerUdpPortTlv joinerPort;
|
||||
JoinerIidTlv joinerIid;
|
||||
uint16_t offset;
|
||||
uint16_t length;
|
||||
|
||||
VerifyOrExit(aHeader.GetType() == Coap::Header::kTypeNonConfirmable &&
|
||||
aHeader.GetCode() == Coap::Header::kCodePost, ;);
|
||||
|
||||
otLogInfoMeshCoP("Received relay receive\r\n");
|
||||
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kJoinerUdpPort, sizeof(joinerPort), joinerPort));
|
||||
VerifyOrExit(joinerPort.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kJoinerIid, sizeof(joinerIid), joinerIid));
|
||||
VerifyOrExit(joinerIid.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
SuccessOrExit(error = Tlv::GetValueOffset(aMessage, Tlv::kJoinerDtlsEncapsulation, offset, length));
|
||||
|
||||
memcpy(mJoinerIid, joinerIid.GetIid(), sizeof(mJoinerIid));
|
||||
mNetif.GetDtls().SetClientId(mJoinerIid, sizeof(mJoinerIid));
|
||||
mJoinerPort = joinerPort.GetUdpPort();
|
||||
mJoinerRouterAddress = aMessageInfo.GetPeerAddr();
|
||||
|
||||
mNetif.GetDtls().Receive(aMessage, offset, length);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Commissioner::HandleUdpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo)
|
||||
{
|
||||
static_cast<Commissioner *>(aContext)->HandleUdpReceive(*static_cast<Message *>(aMessage),
|
||||
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
|
||||
}
|
||||
|
||||
void Commissioner::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
Coap::Header header;
|
||||
StateTlv state;
|
||||
CommissionerSessionIdTlv sessionId;
|
||||
|
||||
SuccessOrExit(header.FromMessage(aMessage));
|
||||
VerifyOrExit(header.GetType() == Coap::Header::kTypeAcknowledgment &&
|
||||
header.GetCode() == Coap::Header::kCodeChanged &&
|
||||
header.GetMessageId() == mCoapMessageId &&
|
||||
header.GetTokenLength() == sizeof(mCoapToken) &&
|
||||
memcmp(mCoapToken, header.GetToken(), sizeof(mCoapToken)) == 0, ;);
|
||||
aMessage.MoveOffset(header.GetLength());
|
||||
|
||||
SuccessOrExit(Tlv::GetTlv(aMessage, Tlv::kState, sizeof(state), state));
|
||||
VerifyOrExit(state.IsValid(), ;);
|
||||
|
||||
VerifyOrExit(state.GetState() == StateTlv::kAccept, mState = kStateDisabled);
|
||||
|
||||
switch (mState)
|
||||
{
|
||||
case kStateDisabled:
|
||||
break;
|
||||
|
||||
case kStatePetition:
|
||||
SuccessOrExit(Tlv::GetTlv(aMessage, Tlv::kCommissionerSessionId, sizeof(sessionId), sessionId));
|
||||
VerifyOrExit(sessionId.IsValid(), ;);
|
||||
|
||||
mSessionId = sessionId.GetCommissionerSessionId();
|
||||
mState = kStateActive;
|
||||
mTimer.Start(5000);
|
||||
|
||||
mNetif.GetDtls().Start(false, HandleDtlsReceive, HandleDtlsSend, this);
|
||||
|
||||
otLogInfoMeshCoP("received petition response\r\n");
|
||||
break;
|
||||
|
||||
case kStateActive:
|
||||
otLogInfoMeshCoP("received keep alive response\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
exit:
|
||||
(void)aMessageInfo;
|
||||
return;
|
||||
}
|
||||
|
||||
ThreadError Commissioner::HandleDtlsSend(void *aContext, const uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
otLogInfoMeshCoP("Commissioner::HandleDtlsTransmit\r\n");
|
||||
return static_cast<Commissioner *>(aContext)->HandleDtlsSend(aBuf, aLength);
|
||||
}
|
||||
|
||||
ThreadError Commissioner::HandleDtlsSend(const unsigned char *aBuf, uint16_t aLength)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
if (mTransmitMessage == NULL)
|
||||
{
|
||||
Coap::Header header;
|
||||
JoinerUdpPortTlv udpPort;
|
||||
JoinerIidTlv iid;
|
||||
ExtendedTlv tlv;
|
||||
|
||||
VerifyOrExit((mTransmitMessage = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
|
||||
header.Init();
|
||||
header.SetVersion(1);
|
||||
header.SetType(Coap::Header::kTypeNonConfirmable);
|
||||
header.SetCode(Coap::Header::kCodePost);
|
||||
header.SetMessageId(0);
|
||||
header.SetToken(NULL, 0);
|
||||
header.AppendUriPathOptions(OPENTHREAD_URI_RELAY_TX);
|
||||
header.AppendContentFormatOption(Coap::Header::kApplicationOctetStream);
|
||||
header.Finalize();
|
||||
SuccessOrExit(error = mTransmitMessage->Append(header.GetBytes(), header.GetLength()));
|
||||
|
||||
udpPort.Init();
|
||||
udpPort.SetUdpPort(mJoinerPort);
|
||||
SuccessOrExit(error = mTransmitMessage->Append(&udpPort, sizeof(udpPort)));
|
||||
|
||||
iid.Init();
|
||||
iid.SetIid(mJoinerIid);
|
||||
SuccessOrExit(error = mTransmitMessage->Append(&iid, sizeof(iid)));
|
||||
|
||||
if (mSendKek)
|
||||
{
|
||||
JoinerRouterKekTlv kek;
|
||||
kek.Init();
|
||||
kek.SetKek(mNetif.GetKeyManager().GetKek());
|
||||
SuccessOrExit(error = mTransmitMessage->Append(&kek, sizeof(kek)));
|
||||
}
|
||||
|
||||
mTransmitMessage->SetOffset(mTransmitMessage->GetLength());
|
||||
|
||||
tlv.SetType(Tlv::kJoinerDtlsEncapsulation);
|
||||
tlv.SetLength(0);
|
||||
SuccessOrExit(error = mTransmitMessage->Append(&tlv, sizeof(tlv)));
|
||||
}
|
||||
|
||||
VerifyOrExit(mTransmitMessage->Append(aBuf, aLength) == kThreadError_None, error = kThreadError_NoBufs);
|
||||
|
||||
mTransmitTask.Post();
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && mTransmitMessage != NULL)
|
||||
{
|
||||
mTransmitMessage->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void Commissioner::HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
otLogInfoMeshCoP("Commissioner::HandleDtlsReceive\r\n");
|
||||
static_cast<Commissioner *>(aContext)->HandleDtlsReceive(aBuf, aLength);
|
||||
}
|
||||
|
||||
void Commissioner::HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
ReceiveJoinerFinalize(aBuf, aLength);
|
||||
}
|
||||
|
||||
void Commissioner::HandleUdpTransmit(void *aContext)
|
||||
{
|
||||
otLogInfoMeshCoP("Commissioner::HandleUdpTransmit\r\n");
|
||||
static_cast<Commissioner *>(aContext)->HandleUdpTransmit();
|
||||
}
|
||||
|
||||
void Commissioner::HandleUdpTransmit(void)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
ExtendedTlv tlv;
|
||||
|
||||
VerifyOrExit(mTransmitMessage != NULL, error = kThreadError_NoBufs);
|
||||
|
||||
tlv.SetType(Tlv::kJoinerDtlsEncapsulation);
|
||||
tlv.SetLength(mTransmitMessage->GetLength() - mTransmitMessage->GetOffset() - sizeof(tlv));
|
||||
mTransmitMessage->Write(mTransmitMessage->GetOffset(), sizeof(tlv), &tlv);
|
||||
|
||||
memset(&messageInfo, 0, sizeof(messageInfo));
|
||||
messageInfo.GetPeerAddr() = mJoinerRouterAddress;
|
||||
messageInfo.mPeerPort = kCoapUdpPort;
|
||||
messageInfo.mInterfaceId = 1;
|
||||
|
||||
SuccessOrExit(error = mSocket.SendTo(*mTransmitMessage, messageInfo));
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && mTransmitMessage != NULL)
|
||||
{
|
||||
mTransmitMessage->Free();
|
||||
}
|
||||
|
||||
mTransmitMessage = NULL;
|
||||
}
|
||||
|
||||
void Commissioner::ReceiveJoinerFinalize(uint8_t *buf, uint16_t length)
|
||||
{
|
||||
Message *message;
|
||||
Coap::Header header;
|
||||
char uriPath[16];
|
||||
char *curUriPath = uriPath;
|
||||
const Coap::Header::Option *coapOption;
|
||||
|
||||
otLogInfoMeshCoP("receive joiner finalize 1\r\n");
|
||||
|
||||
VerifyOrExit((message = mNetif.GetIp6().mMessagePool.New(Message::kTypeIp6, 0)) != NULL, ;);
|
||||
SuccessOrExit(message->Append(buf, length));
|
||||
SuccessOrExit(header.FromMessage(*message));
|
||||
message->SetOffset(header.GetLength());
|
||||
|
||||
coapOption = header.GetCurrentOption();
|
||||
|
||||
while (coapOption != NULL)
|
||||
{
|
||||
switch (coapOption->mNumber)
|
||||
{
|
||||
case Coap::Header::Option::kOptionUriPath:
|
||||
VerifyOrExit(coapOption->mLength < sizeof(uriPath) - static_cast<uint16_t>(curUriPath - uriPath), ;);
|
||||
memcpy(curUriPath, coapOption->mValue, coapOption->mLength);
|
||||
curUriPath[coapOption->mLength] = '/';
|
||||
curUriPath += coapOption->mLength + 1;
|
||||
break;
|
||||
|
||||
case Coap::Header::Option::kOptionContentFormat:
|
||||
break;
|
||||
|
||||
default:
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
coapOption = header.GetNextOption();
|
||||
}
|
||||
|
||||
curUriPath[-1] = '\0';
|
||||
|
||||
SendJoinFinalizeResponse(header);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Commissioner::SendJoinFinalizeResponse(const Coap::Header &aRequestHeader)
|
||||
{
|
||||
Coap::Header responseHeader;
|
||||
MeshCoP::StateTlv *stateTlv;
|
||||
uint8_t buf[128];
|
||||
uint8_t *cur = buf;
|
||||
|
||||
responseHeader.Init();
|
||||
responseHeader.SetVersion(1);
|
||||
responseHeader.SetType(Coap::Header::kTypeAcknowledgment);
|
||||
responseHeader.SetCode(Coap::Header::kCodeChanged);
|
||||
responseHeader.SetMessageId(aRequestHeader.GetMessageId());
|
||||
responseHeader.SetToken(aRequestHeader.GetToken(), aRequestHeader.GetTokenLength());
|
||||
responseHeader.AppendContentFormatOption(Coap::Header::kApplicationOctetStream);
|
||||
responseHeader.Finalize();
|
||||
memcpy(cur, responseHeader.GetBytes(), responseHeader.GetLength());
|
||||
cur += responseHeader.GetLength();
|
||||
|
||||
stateTlv = reinterpret_cast<MeshCoP::StateTlv *>(cur);
|
||||
stateTlv->Init();
|
||||
stateTlv->SetState(MeshCoP::StateTlv::kAccept);
|
||||
cur += sizeof(*stateTlv);
|
||||
|
||||
mSendKek = true;
|
||||
mNetif.GetDtls().Send(buf, static_cast<uint16_t>(cur - buf));
|
||||
mSendKek = false;
|
||||
|
||||
otLogInfoMeshCoP("sent joiner finalize response\r\n");
|
||||
}
|
||||
|
||||
} // namespace MeshCoP
|
||||
} // namespace Thread
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* 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 the Commissioner role.
|
||||
*/
|
||||
|
||||
#ifndef COMMISSIONER_HPP_
|
||||
#define COMMISSIONER_HPP_
|
||||
|
||||
#include <coap/coap_server.hpp>
|
||||
#include <common/timer.hpp>
|
||||
#include <net/udp6.hpp>
|
||||
#include <thread/mle.hpp>
|
||||
|
||||
namespace Thread {
|
||||
|
||||
class ThreadNetif;
|
||||
|
||||
namespace MeshCoP {
|
||||
|
||||
class Commissioner
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the Commissioner object.
|
||||
*
|
||||
* @param[in] aThreadNetif A reference to the Thread network interface.
|
||||
*
|
||||
*/
|
||||
Commissioner(ThreadNetif &aThreadNetif);
|
||||
|
||||
/**
|
||||
* This method starts the Commissioner service.
|
||||
*
|
||||
* @retval kThreadError_None Successfully started the Commissioner service.
|
||||
*
|
||||
*/
|
||||
ThreadError Start(void);
|
||||
|
||||
/**
|
||||
* This method stops the Commissioner service.
|
||||
*
|
||||
* @retval kThreadError_None Successfully stopped the Commissioner service.
|
||||
*
|
||||
*/
|
||||
ThreadError Stop(void);
|
||||
|
||||
private:
|
||||
static void HandleTimer(void *aContext);
|
||||
void HandleTimer(void);
|
||||
|
||||
static void HandleRelayReceive(void *aContext, Coap::Header &aHeader,
|
||||
Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
void HandleRelayReceive(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
static void HandleUdpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo);
|
||||
void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
static void HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength);
|
||||
void HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength);
|
||||
|
||||
static ThreadError HandleDtlsSend(void *aContext, const uint8_t *aBuf, uint16_t aLength);
|
||||
ThreadError HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength);
|
||||
|
||||
static void HandleUdpTransmit(void *aContext);
|
||||
void HandleUdpTransmit(void);
|
||||
|
||||
void ReceiveJoinerFinalize(uint8_t *buf, uint16_t length);
|
||||
void SendJoinFinalizeResponse(const Coap::Header &aRequestHeader);
|
||||
|
||||
ThreadError SendPetition(void);
|
||||
ThreadError SendKeepAlive(void);
|
||||
|
||||
enum
|
||||
{
|
||||
kStateDisabled = 0,
|
||||
kStatePetition = 1,
|
||||
kStateActive = 2,
|
||||
};
|
||||
|
||||
uint8_t mState;
|
||||
|
||||
Ip6::Address mJoinerRouterAddress;
|
||||
uint8_t mJoinerIid[8];
|
||||
uint16_t mJoinerPort;
|
||||
|
||||
uint16_t mSessionId;
|
||||
Message *mTransmitMessage;
|
||||
Timer mTimer;
|
||||
Tasklet mTransmitTask;
|
||||
bool mSendKek;
|
||||
|
||||
Ip6::UdpSocket mSocket;
|
||||
uint8_t mCoapToken[2];
|
||||
uint16_t mCoapMessageId;
|
||||
|
||||
Coap::Resource mRelayReceive;
|
||||
ThreadNetif &mNetif;
|
||||
};
|
||||
|
||||
} // namespace MeshCoP
|
||||
} // namespace Thread
|
||||
|
||||
#endif // COMMISSIONER_HPP_
|
||||
@@ -0,0 +1,380 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* 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 the necessary hooks for mbedTLS.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <common/code_utils.hpp>
|
||||
#include <common/encoding.hpp>
|
||||
#include <common/logging.hpp>
|
||||
#include <common/timer.hpp>
|
||||
#include <crypto/sha256.hpp>
|
||||
#include <meshcop/dtls.hpp>
|
||||
#include <thread/thread_netif.hpp>
|
||||
|
||||
#include <mbedtls/debug.h>
|
||||
|
||||
namespace Thread {
|
||||
namespace MeshCoP {
|
||||
|
||||
Dtls::Dtls(ThreadNetif &aNetif):
|
||||
mStarted(false),
|
||||
mTimer(aNetif.GetIp6().mTimerScheduler, &HandleTimer, this),
|
||||
mTimerIntermediate(0),
|
||||
mTimerSet(false),
|
||||
mNetif(aNetif)
|
||||
{
|
||||
}
|
||||
|
||||
ThreadError Dtls::Start(bool aClient, ReceiveHandler aReceiveHandler, SendHandler aSendHandler, void *aContext)
|
||||
{
|
||||
static const int ciphersuites[2] = {0xC0FF, 0}; // EC-JPAKE cipher suite
|
||||
int rval;
|
||||
|
||||
mReceiveHandler = aReceiveHandler;
|
||||
mSendHandler = aSendHandler;
|
||||
mContext = aContext;
|
||||
mClient = aClient;
|
||||
|
||||
mbedtls_ssl_init(&mSsl);
|
||||
mbedtls_ssl_config_init(&mConf);
|
||||
mbedtls_ctr_drbg_init(&mCtrDrbg);
|
||||
mbedtls_entropy_init(&mEntropy);
|
||||
|
||||
mbedtls_debug_set_threshold(4);
|
||||
|
||||
// XXX: should set personalization data to hardware address
|
||||
rval = mbedtls_ctr_drbg_seed(&mCtrDrbg, mbedtls_entropy_func, &mEntropy, NULL, 0);
|
||||
VerifyOrExit(rval == 0, ;);
|
||||
|
||||
rval = mbedtls_ssl_config_defaults(&mConf, mClient ? MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
|
||||
MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT);
|
||||
VerifyOrExit(rval == 0, ;);
|
||||
|
||||
mbedtls_ssl_conf_rng(&mConf, mbedtls_ctr_drbg_random, &mCtrDrbg);
|
||||
mbedtls_ssl_conf_min_version(&mConf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
|
||||
mbedtls_ssl_conf_max_version(&mConf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
|
||||
mbedtls_ssl_conf_ciphersuites(&mConf, ciphersuites);
|
||||
mbedtls_ssl_conf_export_keys_cb(&mConf, HandleMbedtlsExportKeys, this);
|
||||
mbedtls_ssl_conf_handshake_timeout(&mConf, 8000, 60000);
|
||||
mbedtls_ssl_conf_dbg(&mConf, HandleMbedtlsDebug, stdout);
|
||||
|
||||
if (!mClient)
|
||||
{
|
||||
mbedtls_ssl_cookie_init(&mCookieCtx);
|
||||
|
||||
rval = mbedtls_ssl_cookie_setup(&mCookieCtx, mbedtls_ctr_drbg_random, &mCtrDrbg);
|
||||
VerifyOrExit(rval == 0, ;);
|
||||
|
||||
mbedtls_ssl_conf_dtls_cookies(&mConf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check, &mCookieCtx);
|
||||
}
|
||||
|
||||
rval = mbedtls_ssl_setup(&mSsl, &mConf);
|
||||
VerifyOrExit(rval == 0, ;);
|
||||
|
||||
mbedtls_ssl_set_bio(&mSsl, this, &HandleMbedtlsTransmit, HandleMbedtlsReceive, NULL);
|
||||
mbedtls_ssl_set_timer_cb(&mSsl, this, &HandleMbedtlsSetTimer, HandleMbedtlsGetTimer);
|
||||
|
||||
rval = mbedtls_ssl_set_hs_ecjpake_password(&mSsl, (const unsigned char *)"threadjpaketest", 15);
|
||||
VerifyOrExit(rval == 0, ;);
|
||||
|
||||
mStarted = true;
|
||||
Process();
|
||||
|
||||
otLogInfoMeshCoP("DTLS started\r\n");
|
||||
|
||||
exit:
|
||||
return MapError(rval);
|
||||
}
|
||||
|
||||
ThreadError Dtls::Stop(void)
|
||||
{
|
||||
mStarted = false;
|
||||
mbedtls_ssl_close_notify(&mSsl);
|
||||
mbedtls_ssl_free(&mSsl);
|
||||
mbedtls_ssl_config_free(&mConf);
|
||||
mbedtls_ctr_drbg_free(&mCtrDrbg);
|
||||
mbedtls_entropy_free(&mEntropy);
|
||||
mbedtls_ssl_cookie_free(&mCookieCtx);
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
ThreadError Dtls::SetClientId(const uint8_t *aClientId, uint8_t aLength)
|
||||
{
|
||||
int rval = mbedtls_ssl_set_client_transport_id(&mSsl, aClientId, aLength);
|
||||
return MapError(rval);
|
||||
}
|
||||
|
||||
bool Dtls::IsConnected(void)
|
||||
{
|
||||
return mSsl.state == MBEDTLS_SSL_HANDSHAKE_OVER;
|
||||
}
|
||||
|
||||
ThreadError Dtls::Send(const uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
int rval = mbedtls_ssl_write(&mSsl, aBuf, aLength);
|
||||
return MapError(rval);
|
||||
}
|
||||
|
||||
ThreadError Dtls::Receive(Message &aMessage, uint16_t aOffset, uint16_t aLength)
|
||||
{
|
||||
mReceiveMessage = &aMessage;
|
||||
mReceiveOffset = aOffset;
|
||||
mReceiveLength = aLength;
|
||||
|
||||
Process();
|
||||
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
int Dtls::HandleMbedtlsTransmit(void *aContext, const unsigned char *aBuf, size_t aLength)
|
||||
{
|
||||
return static_cast<Dtls *>(aContext)->HandleMbedtlsTransmit(aBuf, aLength);
|
||||
}
|
||||
|
||||
int Dtls::HandleMbedtlsTransmit(const unsigned char *aBuf, size_t aLength)
|
||||
{
|
||||
ThreadError error;
|
||||
int rval;
|
||||
|
||||
otLogInfoMeshCoP("Dtls::HandleMbedtlsTransmit\r\n");
|
||||
|
||||
error = mSendHandler(mContext, aBuf, (uint16_t)aLength);
|
||||
|
||||
switch (error)
|
||||
{
|
||||
case kThreadError_None:
|
||||
rval = static_cast<int>(aLength);
|
||||
break;
|
||||
|
||||
case kThreadError_NoBufs:
|
||||
rval = MBEDTLS_ERR_SSL_WANT_WRITE;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int Dtls::HandleMbedtlsReceive(void *aContext, unsigned char *aBuf, size_t aLength)
|
||||
{
|
||||
return static_cast<Dtls *>(aContext)->HandleMbedtlsReceive(aBuf, aLength);
|
||||
}
|
||||
|
||||
int Dtls::HandleMbedtlsReceive(unsigned char *aBuf, size_t aLength)
|
||||
{
|
||||
int rval;
|
||||
|
||||
otLogInfoMeshCoP("Dtls::HandleMbedtlsReceive\r\n");
|
||||
|
||||
VerifyOrExit(mReceiveMessage != NULL && mReceiveLength != 0, rval = MBEDTLS_ERR_SSL_WANT_READ);
|
||||
|
||||
if (aLength > mReceiveLength)
|
||||
{
|
||||
aLength = mReceiveLength;
|
||||
}
|
||||
|
||||
rval = (int)mReceiveMessage->Read(mReceiveOffset, (uint16_t)aLength, aBuf);
|
||||
mReceiveOffset += rval;
|
||||
mReceiveLength -= rval;
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
int Dtls::HandleMbedtlsGetTimer(void *aContext)
|
||||
{
|
||||
return static_cast<Dtls *>(aContext)->HandleMbedtlsGetTimer();
|
||||
}
|
||||
|
||||
int Dtls::HandleMbedtlsGetTimer(void)
|
||||
{
|
||||
int rval;
|
||||
|
||||
otLogInfoMeshCoP("Dtls::HandleMbedtlsGetTimer\r\n");
|
||||
|
||||
if (!mTimerSet)
|
||||
{
|
||||
rval = -1;
|
||||
}
|
||||
else if (!mTimer.IsRunning())
|
||||
{
|
||||
rval = 2;
|
||||
}
|
||||
else if (static_cast<int32_t>(mTimerIntermediate - Timer::GetNow()) <= 0)
|
||||
{
|
||||
rval = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
rval = 0;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
void Dtls::HandleMbedtlsSetTimer(void *aContext, uint32_t aIntermediate, uint32_t aFinish)
|
||||
{
|
||||
static_cast<Dtls *>(aContext)->HandleMbedtlsSetTimer(aIntermediate, aFinish);
|
||||
}
|
||||
|
||||
void Dtls::HandleMbedtlsSetTimer(uint32_t aIntermediate, uint32_t aFinish)
|
||||
{
|
||||
otLogInfoMeshCoP("Dtls::SetTimer\r\n");
|
||||
|
||||
if (aFinish == 0)
|
||||
{
|
||||
mTimerSet = false;
|
||||
mTimer.Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
mTimerSet = true;
|
||||
mTimer.Start(aFinish);
|
||||
mTimerIntermediate = Timer::GetNow() + aIntermediate;
|
||||
}
|
||||
}
|
||||
|
||||
int Dtls::HandleMbedtlsExportKeys(void *aContext, const unsigned char *aMasterSecret, const unsigned char *aKeyBlock,
|
||||
size_t aMacLength, size_t aKeyLength, size_t aIvLength)
|
||||
{
|
||||
return static_cast<Dtls *>(aContext)->HandleMbedtlsExportKeys(aMasterSecret, aKeyBlock,
|
||||
aMacLength, aKeyLength, aIvLength);
|
||||
}
|
||||
|
||||
int Dtls::HandleMbedtlsExportKeys(const unsigned char *aMasterSecret, const unsigned char *aKeyBlock,
|
||||
size_t aMacLength, size_t aKeyLength, size_t aIvLength)
|
||||
{
|
||||
uint8_t kek[Crypto::Sha256::kHashSize];
|
||||
Crypto::Sha256 sha256;
|
||||
|
||||
sha256.Start();
|
||||
sha256.Update(aKeyBlock, static_cast<uint16_t>(aMacLength + aKeyLength + aIvLength));
|
||||
sha256.Finish(kek);
|
||||
|
||||
mNetif.GetKeyManager().SetKek(kek);
|
||||
|
||||
otLogInfoMeshCoP("Generated KEK\r\n");
|
||||
|
||||
(void)aMasterSecret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Dtls::HandleTimer(void *aContext)
|
||||
{
|
||||
static_cast<Dtls *>(aContext)->HandleTimer();
|
||||
}
|
||||
|
||||
void Dtls::HandleTimer(void)
|
||||
{
|
||||
Process();
|
||||
}
|
||||
|
||||
void Dtls::Process(void)
|
||||
{
|
||||
uint8_t buf[MBEDTLS_SSL_MAX_CONTENT_LEN];
|
||||
int rval;
|
||||
|
||||
while (mStarted)
|
||||
{
|
||||
if (mSsl.state != MBEDTLS_SSL_HANDSHAKE_OVER)
|
||||
{
|
||||
rval = mbedtls_ssl_handshake(&mSsl);
|
||||
}
|
||||
else
|
||||
{
|
||||
rval = mbedtls_ssl_read(&mSsl, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
if (rval > 0)
|
||||
{
|
||||
mReceiveHandler(mContext, buf, static_cast<uint16_t>(rval));
|
||||
}
|
||||
else if (rval == 0 || rval == MBEDTLS_ERR_SSL_WANT_READ || rval == MBEDTLS_ERR_SSL_WANT_WRITE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
mbedtls_ssl_session_reset(&mSsl);
|
||||
mbedtls_ssl_set_hs_ecjpake_password(&mSsl, (const unsigned char *)"threadjpaketest", 15);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ThreadError Dtls::MapError(int rval)
|
||||
{
|
||||
ThreadError error;
|
||||
|
||||
switch (rval)
|
||||
{
|
||||
case MBEDTLS_ERR_SSL_BAD_INPUT_DATA:
|
||||
error = kThreadError_InvalidArgs;
|
||||
break;
|
||||
|
||||
case MBEDTLS_ERR_SSL_ALLOC_FAILED:
|
||||
error = kThreadError_NoBufs;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (rval >= 0)
|
||||
{
|
||||
error = kThreadError_None;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void Dtls::HandleMbedtlsDebug(void *ctx, int level, const char *file, int line, const char *str)
|
||||
{
|
||||
otLogInfoMeshCoP("%s:%04d: %s\r\n", file, line, str);
|
||||
(void)ctx;
|
||||
(void)level;
|
||||
(void)file;
|
||||
(void)line;
|
||||
(void)str;
|
||||
}
|
||||
|
||||
} // namespace MeshCoP
|
||||
} // namespace Thread
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* 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 using mbedTLS.
|
||||
*/
|
||||
|
||||
#ifndef DTLS_HPP_
|
||||
#define DTLS_HPP_
|
||||
|
||||
#include <openthread-types.h>
|
||||
#include <common/message.hpp>
|
||||
#include <common/timer.hpp>
|
||||
#include <crypto/sha256.hpp>
|
||||
|
||||
#include <mbedtls/ssl.h>
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/error.h>
|
||||
#include <mbedtls/certs.h>
|
||||
#include <mbedtls/ssl_cookie.h>
|
||||
|
||||
namespace Thread {
|
||||
|
||||
class ThreadNetif;
|
||||
|
||||
namespace MeshCoP {
|
||||
|
||||
class Dtls
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the DTLS object.
|
||||
*
|
||||
* @param[in] aNetif A reference to the Thread network interface.
|
||||
*
|
||||
*/
|
||||
Dtls(ThreadNetif &aNetif);
|
||||
|
||||
/**
|
||||
* This function pointer is called when data is received from the DTLS session.
|
||||
*
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
* @param[in] aBuf A pointer to the received data buffer.
|
||||
* @param[in] aLength Number of bytes in the received data buffer.
|
||||
*
|
||||
*/
|
||||
typedef void (*ReceiveHandler)(void *aContext, uint8_t *aBuf, uint16_t aLength);
|
||||
|
||||
/**
|
||||
* This function pointer is called when data is ready to transmit for the DTLS session.
|
||||
*
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
* @param[in] aBuf A pointer to the transmit data buffer.
|
||||
* @param[in] aLength Number of bytes in the transmit data buffer.
|
||||
*
|
||||
*/
|
||||
typedef ThreadError(*SendHandler)(void *aContext, const uint8_t *aBuf, uint16_t aLength);
|
||||
|
||||
/**
|
||||
* This method starts the DTLS service.
|
||||
*
|
||||
* @param[in] aClient TRUE if operating as a client, FALSE if operating as a server.
|
||||
* @param[in] aReceiveHandler A pointer to the receive handler.
|
||||
* @param[in] aSendHandler A pointer to the send handler.
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*
|
||||
* @retval kThreadError_None Successfully started the DTLS service.
|
||||
*
|
||||
*/
|
||||
ThreadError Start(bool aClient, ReceiveHandler aReceiveHandler, SendHandler aSendHandler, void *aContext);
|
||||
|
||||
/**
|
||||
* This method stops the DTLS service.
|
||||
*
|
||||
* @retval kThreadError_None Successfully stopped the DTLS service.
|
||||
*
|
||||
*/
|
||||
ThreadError Stop(void);
|
||||
|
||||
/**
|
||||
* This method sets the Client ID used for generating the Hello Cookie.
|
||||
*
|
||||
* @param[in] aClientId A pointer to the Client ID.
|
||||
* @param[in] aLength Number of bytes in the Client ID.
|
||||
*
|
||||
* @retval kThreadError_None Successfully set the Client ID.
|
||||
*
|
||||
*/
|
||||
ThreadError SetClientId(const uint8_t *aClientId, uint8_t aLength);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the DTLS session is connected.
|
||||
*
|
||||
* @retval TRUE The DTLS session is connected.
|
||||
* @retval FALSE The DTLS session is not connected.
|
||||
*
|
||||
*/
|
||||
bool IsConnected(void);
|
||||
|
||||
/**
|
||||
* This method sends data within the DTLS session.
|
||||
*
|
||||
* @param[in] aBuf A pointer to the data buffer.
|
||||
* @param[in] aLength Number of bytes in the data buffer.
|
||||
*
|
||||
* @retval kThreadError_None Successfully sent the data via the DTLS session.
|
||||
*
|
||||
*/
|
||||
ThreadError Send(const uint8_t *aBuf, uint16_t aLength);
|
||||
|
||||
/**
|
||||
* This method provides a received DTLS message to the DTLS object.
|
||||
*
|
||||
* @param[in] aMessage A reference to the message.
|
||||
* @param[in] aOffset The offset within @p aMessage where the DTLS message starts.
|
||||
* @param[in] aLength The size of the DTLS message (bytes).
|
||||
*
|
||||
* @retval kThreadError_None Successfully processed the received DTLS message.
|
||||
*
|
||||
*/
|
||||
ThreadError Receive(Message &aMessage, uint16_t aOffset, uint16_t aLength);
|
||||
|
||||
private:
|
||||
static ThreadError MapError(int rval);
|
||||
|
||||
static void HandleMbedtlsDebug(void *ctx, int level, const char *file, int line, const char *str);
|
||||
|
||||
static int HandleMbedtlsGetTimer(void *aContext);
|
||||
int HandleMbedtlsGetTimer(void);
|
||||
|
||||
static void HandleMbedtlsSetTimer(void *aContext, uint32_t aIntermediate, uint32_t aFinish);
|
||||
void HandleMbedtlsSetTimer(uint32_t aIntermediate, uint32_t aFinish);
|
||||
|
||||
static int HandleMbedtlsReceive(void *aContext, unsigned char *aBuf, size_t aLength);
|
||||
int HandleMbedtlsReceive(unsigned char *aBuf, size_t aLength);
|
||||
|
||||
static int HandleMbedtlsTransmit(void *aContext, const unsigned char *aBuf, size_t aLength);
|
||||
int HandleMbedtlsTransmit(const unsigned char *aBuf, size_t aLength);
|
||||
|
||||
static int HandleMbedtlsExportKeys(void *aContext, const unsigned char *aMasterSecret,
|
||||
const unsigned char *aKeyBlock,
|
||||
size_t aMacLength, size_t aKeyLength, size_t aIvLength);
|
||||
int HandleMbedtlsExportKeys(const unsigned char *aMasterSecret, const unsigned char *aKeyBlock,
|
||||
size_t aMacLength, size_t aKeyLength, size_t aIvLength);
|
||||
|
||||
static void HandleTimer(void *aContext);
|
||||
void HandleTimer(void);
|
||||
|
||||
void Process(void);
|
||||
|
||||
mbedtls_entropy_context mEntropy;
|
||||
mbedtls_ctr_drbg_context mCtrDrbg;
|
||||
mbedtls_ssl_context mSsl;
|
||||
mbedtls_ssl_config mConf;
|
||||
mbedtls_ssl_cookie_ctx mCookieCtx;
|
||||
bool mStarted;
|
||||
|
||||
Timer mTimer;
|
||||
uint32_t mTimerIntermediate;
|
||||
bool mTimerSet;
|
||||
|
||||
Message *mReceiveMessage;
|
||||
uint16_t mReceiveOffset;
|
||||
uint16_t mReceiveLength;
|
||||
|
||||
ReceiveHandler mReceiveHandler;
|
||||
SendHandler mSendHandler;
|
||||
void *mContext;
|
||||
bool mClient;
|
||||
|
||||
ThreadNetif &mNetif;
|
||||
};
|
||||
|
||||
} // namspace MeshCoP
|
||||
} // namespace Thread
|
||||
|
||||
#endif // DTLS_HPP_
|
||||
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* 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 the Joiner role.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openthread-config.h>
|
||||
|
||||
#include <common/code_utils.hpp>
|
||||
#include <common/encoding.hpp>
|
||||
#include <common/logging.hpp>
|
||||
#include <meshcop/joiner.hpp>
|
||||
#include <thread/thread_netif.hpp>
|
||||
#include <thread/thread_uris.hpp>
|
||||
|
||||
using Thread::Encoding::BigEndian::HostSwap16;
|
||||
|
||||
namespace Thread {
|
||||
namespace MeshCoP {
|
||||
|
||||
Joiner::Joiner(ThreadNetif &aNetif):
|
||||
mTransmitMessage(NULL),
|
||||
mSocket(aNetif.GetIp6().mUdp),
|
||||
mTransmitTask(aNetif.GetIp6().mTaskletScheduler, &HandleUdpTransmit, this),
|
||||
mJoinerEntrust(OPENTHREAD_URI_JOINER_ENTRUST, &HandleJoinerEntrust, this),
|
||||
mNetif(aNetif)
|
||||
{
|
||||
mNetif.GetCoapServer().AddResource(mJoinerEntrust);
|
||||
}
|
||||
|
||||
ThreadError Joiner::Start(void)
|
||||
{
|
||||
return mNetif.GetMle().Discover(0, 0, OT_PANID_BROADCAST, HandleDiscoverResult, this);
|
||||
}
|
||||
|
||||
void Joiner::HandleDiscoverResult(otActiveScanResult *aResult, void *aContext)
|
||||
{
|
||||
static_cast<Joiner *>(aContext)->HandleDiscoverResult(aResult);
|
||||
}
|
||||
|
||||
void Joiner::HandleDiscoverResult(otActiveScanResult *aResult)
|
||||
{
|
||||
if (aResult != NULL)
|
||||
{
|
||||
memcpy(&mJoinerRouter, &aResult->mExtAddress, sizeof(mJoinerRouter));
|
||||
}
|
||||
else
|
||||
{
|
||||
// open UDP port
|
||||
Ip6::SockAddr sockaddr;
|
||||
sockaddr.mPort = 1000;
|
||||
mSocket.Open(&HandleUdpReceive, this);
|
||||
mSocket.Bind(sockaddr);
|
||||
|
||||
mNetif.GetIp6Filter().AddUnsecurePort(sockaddr.mPort);
|
||||
|
||||
mNetif.GetDtls().Start(true, HandleDtlsReceive, HandleDtlsSend, this);
|
||||
}
|
||||
}
|
||||
|
||||
ThreadError Joiner::Stop(void)
|
||||
{
|
||||
return kThreadError_NotImplemented;
|
||||
}
|
||||
|
||||
ThreadError Joiner::HandleDtlsSend(void *aContext, const uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
otLogInfoMeshCoP("Joiner::HandleDtlsTransmit\r\n");
|
||||
return static_cast<Joiner *>(aContext)->HandleDtlsSend(aBuf, aLength);
|
||||
}
|
||||
|
||||
ThreadError Joiner::HandleDtlsSend(const unsigned char *aBuf, uint16_t aLength)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
if (mTransmitMessage == NULL)
|
||||
{
|
||||
VerifyOrExit((mTransmitMessage = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
mTransmitMessage->SetLinkSecurityEnabled(false);
|
||||
}
|
||||
|
||||
VerifyOrExit(mTransmitMessage->Append(aBuf, aLength) == kThreadError_None, error = kThreadError_NoBufs);
|
||||
|
||||
mTransmitTask.Post();
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && mTransmitMessage != NULL)
|
||||
{
|
||||
mTransmitMessage->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void Joiner::HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
otLogInfoMeshCoP("Joiner::HandleDtlsReceive\r\n");
|
||||
static_cast<Joiner *>(aContext)->HandleDtlsReceive(aBuf, aLength);
|
||||
}
|
||||
|
||||
void Joiner::HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
ReceiveJoinerFinalizeResponse(aBuf, aLength);
|
||||
}
|
||||
|
||||
void Joiner::HandleUdpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo)
|
||||
{
|
||||
otLogInfoMeshCoP("Joiner::HandleUdpReceive\r\n");
|
||||
static_cast<Joiner *>(aContext)->HandleUdpReceive(*static_cast<Message *>(aMessage),
|
||||
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
|
||||
}
|
||||
|
||||
void Joiner::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
(void)aMessageInfo;
|
||||
|
||||
mNetif.GetDtls().Receive(aMessage, aMessage.GetOffset(), aMessage.GetLength() - aMessage.GetOffset());
|
||||
|
||||
if (mNetif.GetDtls().IsConnected())
|
||||
{
|
||||
SendJoinerFinalize();
|
||||
}
|
||||
}
|
||||
|
||||
void Joiner::HandleUdpTransmit(void *aContext)
|
||||
{
|
||||
otLogInfoMeshCoP("Joiner::HandleUdpTransmit\r\n");
|
||||
static_cast<Joiner *>(aContext)->HandleUdpTransmit();
|
||||
}
|
||||
|
||||
void Joiner::HandleUdpTransmit(void)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
VerifyOrExit(mTransmitMessage != NULL, error = kThreadError_NoBufs);
|
||||
|
||||
otLogInfoMeshCoP("transmit %d\r\n", mTransmitMessage->GetLength());
|
||||
|
||||
memset(&messageInfo, 0, sizeof(messageInfo));
|
||||
messageInfo.GetPeerAddr().mFields.m16[0] = HostSwap16(0xfe80);
|
||||
messageInfo.GetPeerAddr().SetIid(mJoinerRouter);
|
||||
messageInfo.mPeerPort = 1000;
|
||||
messageInfo.mInterfaceId = 1;
|
||||
|
||||
SuccessOrExit(error = mSocket.SendTo(*mTransmitMessage, messageInfo));
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && mTransmitMessage != NULL)
|
||||
{
|
||||
mTransmitMessage->Free();
|
||||
}
|
||||
|
||||
mTransmitMessage = NULL;
|
||||
}
|
||||
|
||||
void Joiner::SendJoinerFinalize(void)
|
||||
{
|
||||
Coap::Header header;
|
||||
MeshCoP::StateTlv *stateTlv;
|
||||
uint8_t buf[128];
|
||||
uint8_t *cur = buf;
|
||||
|
||||
header.Init();
|
||||
header.SetVersion(1);
|
||||
header.SetType(Coap::Header::kTypeConfirmable);
|
||||
header.SetCode(Coap::Header::kCodePost);
|
||||
header.SetMessageId(0);
|
||||
header.SetToken(NULL, 0);
|
||||
header.AppendUriPathOptions(OPENTHREAD_URI_JOINER_FINALIZE);
|
||||
header.AppendContentFormatOption(Coap::Header::kApplicationOctetStream);
|
||||
header.Finalize();
|
||||
memcpy(cur, header.GetBytes(), header.GetLength());
|
||||
cur += header.GetLength();
|
||||
|
||||
stateTlv = reinterpret_cast<MeshCoP::StateTlv *>(cur);
|
||||
stateTlv->Init();
|
||||
stateTlv->SetState(MeshCoP::StateTlv::kAccept);
|
||||
cur += sizeof(*stateTlv);
|
||||
|
||||
mNetif.GetDtls().Send(buf, static_cast<uint16_t>(cur - buf));
|
||||
|
||||
otLogInfoMeshCoP("Sent joiner finalize\r\n");
|
||||
}
|
||||
|
||||
void Joiner::ReceiveJoinerFinalizeResponse(uint8_t *buf, uint16_t length)
|
||||
{
|
||||
Message *message;
|
||||
Coap::Header header;
|
||||
|
||||
VerifyOrExit((message = mNetif.GetIp6().mMessagePool.New(Message::kTypeIp6, 0)) != NULL, ;);
|
||||
SuccessOrExit(message->Append(buf, length));
|
||||
SuccessOrExit(header.FromMessage(*message));
|
||||
|
||||
VerifyOrExit(header.GetType() == Coap::Header::kTypeAcknowledgment &&
|
||||
header.GetCode() == Coap::Header::kCodeChanged &&
|
||||
header.GetMessageId() == 0 &&
|
||||
header.GetTokenLength() == 0, ;);
|
||||
|
||||
otLogInfoMeshCoP("received joiner finalize response\r\n");
|
||||
|
||||
Close();
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Joiner::HandleJoinerEntrust(void *aContext, Coap::Header &aHeader,
|
||||
Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
static_cast<Joiner *>(aContext)->HandleJoinerEntrust(aHeader, aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
void Joiner::HandleJoinerEntrust(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
ThreadError error;
|
||||
|
||||
NetworkMasterKeyTlv masterKey;
|
||||
MeshLocalPrefixTlv meshLocalPrefix;
|
||||
ExtendedPanIdTlv extendedPanId;
|
||||
NetworkNameTlv networkName;
|
||||
ActiveTimestampTlv activeTimestamp;
|
||||
|
||||
VerifyOrExit(aHeader.GetType() == Coap::Header::kTypeConfirmable &&
|
||||
aHeader.GetCode() == Coap::Header::kCodePost, error = kThreadError_Drop);
|
||||
|
||||
otLogInfoMeshCoP("Received joiner entrust\r\n");
|
||||
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kNetworkMasterKey, sizeof(masterKey), masterKey));
|
||||
VerifyOrExit(masterKey.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kMeshLocalPrefix, sizeof(meshLocalPrefix), meshLocalPrefix));
|
||||
VerifyOrExit(meshLocalPrefix.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kExtendedPanId, sizeof(extendedPanId), extendedPanId));
|
||||
VerifyOrExit(extendedPanId.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kNetworkName, sizeof(networkName), networkName));
|
||||
VerifyOrExit(networkName.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp));
|
||||
VerifyOrExit(activeTimestamp.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
mNetif.GetKeyManager().SetMasterKey(masterKey.GetNetworkMasterKey(), masterKey.GetLength());
|
||||
mNetif.GetMle().SetMeshLocalPrefix(meshLocalPrefix.GetMeshLocalPrefix());
|
||||
mNetif.GetMac().SetExtendedPanId(extendedPanId.GetExtendedPanId());
|
||||
mNetif.GetMac().SetNetworkName(networkName.GetNetworkName());
|
||||
|
||||
otLogInfoMeshCoP("join success!\r\n");
|
||||
|
||||
exit:
|
||||
(void)aMessageInfo;
|
||||
return;
|
||||
}
|
||||
|
||||
void Joiner::Close(void)
|
||||
{
|
||||
mNetif.GetDtls().Stop();
|
||||
}
|
||||
|
||||
} // namespace Dtls
|
||||
} // namespace Thread
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* 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 the Joiner role.
|
||||
*/
|
||||
|
||||
#ifndef JOINER_HPP_
|
||||
#define JOINER_HPP_
|
||||
|
||||
#include <openthread-types.h>
|
||||
|
||||
#include <coap/coap_header.hpp>
|
||||
#include <coap/coap_server.hpp>
|
||||
#include <common/message.hpp>
|
||||
#include <net/udp6.hpp>
|
||||
#include <meshcop/dtls.hpp>
|
||||
#include <thread/meshcop_tlvs.hpp>
|
||||
|
||||
namespace Thread {
|
||||
|
||||
class ThreadNetif;
|
||||
|
||||
namespace MeshCoP {
|
||||
|
||||
class Joiner
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the Joiner object.
|
||||
*
|
||||
* @param[in] aThreadNetif A reference to the Thread network interface.
|
||||
*
|
||||
*/
|
||||
Joiner(ThreadNetif &aThreadNetif);
|
||||
|
||||
/**
|
||||
* This method starts the Joiner service.
|
||||
*
|
||||
* @retval kThreadError_None Successfully started the Joiner service.
|
||||
*
|
||||
*/
|
||||
ThreadError Start(void);
|
||||
|
||||
/**
|
||||
* This method stops the Joiner service.
|
||||
*
|
||||
* @retval kThreadError_None Successfully stopped the Joiner service.
|
||||
*
|
||||
*/
|
||||
ThreadError Stop(void);
|
||||
|
||||
private:
|
||||
static void HandleDiscoverResult(otActiveScanResult *aResult, void *aContext);
|
||||
void HandleDiscoverResult(otActiveScanResult *aResult);
|
||||
|
||||
static void HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength);
|
||||
void HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength);
|
||||
|
||||
static ThreadError HandleDtlsSend(void *aContext, const uint8_t *aBuf, uint16_t aLength);
|
||||
ThreadError HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength);
|
||||
|
||||
static void HandleUdpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo);
|
||||
void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
static void HandleUdpTransmit(void *aContext);
|
||||
void HandleUdpTransmit(void);
|
||||
|
||||
static void HandleJoinerEntrust(void *aContext, Coap::Header &aHeader,
|
||||
Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
void HandleJoinerEntrust(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
void Close(void);
|
||||
void ReceiveJoinerFinalizeResponse(uint8_t *buf, uint16_t length);
|
||||
void SendJoinerFinalize(void);
|
||||
|
||||
Mac::ExtAddress mJoinerRouter;
|
||||
Message *mTransmitMessage;
|
||||
Ip6::UdpSocket mSocket;
|
||||
|
||||
Tasklet mTransmitTask;
|
||||
Coap::Resource mJoinerEntrust;
|
||||
ThreadNetif &mNetif;
|
||||
};
|
||||
|
||||
} // namespace MeshCoP
|
||||
} // namespace Thread
|
||||
|
||||
#endif // JOINER_HPP_
|
||||
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* 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 the Joiner Router role.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <common/code_utils.hpp>
|
||||
#include <common/encoding.hpp>
|
||||
#include <common/logging.hpp>
|
||||
#include <meshcop/joiner_router.hpp>
|
||||
#include <thread/mle.hpp>
|
||||
#include <thread/meshcop_tlvs.hpp>
|
||||
#include <thread/thread_netif.hpp>
|
||||
#include <thread/thread_uris.hpp>
|
||||
|
||||
using Thread::Encoding::BigEndian::HostSwap16;
|
||||
|
||||
namespace Thread {
|
||||
namespace MeshCoP {
|
||||
|
||||
JoinerRouter::JoinerRouter(ThreadNetif &aNetif):
|
||||
mJoinerPort(OPENTHREAD_CONFIG_JOINER_UDP_PORT),
|
||||
mSocket(aNetif.GetIp6().mUdp),
|
||||
mRelayTransmit(OPENTHREAD_URI_RELAY_TX, &HandleRelayTransmit, this),
|
||||
mNetif(aNetif)
|
||||
{
|
||||
mNetif.GetCoapServer().AddResource(mRelayTransmit);
|
||||
mNetifCallback.Set(HandleNetifStateChanged, this);
|
||||
mNetif.RegisterCallback(mNetifCallback);
|
||||
}
|
||||
|
||||
void JoinerRouter::HandleNetifStateChanged(uint32_t aFlags, void *aContext)
|
||||
{
|
||||
static_cast<JoinerRouter *>(aContext)->HandleNetifStateChanged(aFlags);
|
||||
}
|
||||
|
||||
void JoinerRouter::HandleNetifStateChanged(uint32_t aFlags)
|
||||
{
|
||||
uint8_t length;
|
||||
|
||||
VerifyOrExit(mNetif.GetMle().GetDeviceMode() & Mle::ModeTlv::kModeFFD, ;);
|
||||
VerifyOrExit(aFlags & OT_THREAD_NETDATA_UPDATED, ;);
|
||||
|
||||
mNetif.GetIp6Filter().RemoveUnsecurePort(mJoinerPort);
|
||||
|
||||
if (mNetif.GetNetworkDataLeader().GetCommissioningData(length) != NULL)
|
||||
{
|
||||
Ip6::SockAddr sockaddr;
|
||||
|
||||
if (GetJoinerPort(mJoinerPort) != kThreadError_None)
|
||||
{
|
||||
mJoinerPort = OPENTHREAD_CONFIG_JOINER_UDP_PORT;
|
||||
}
|
||||
|
||||
sockaddr.mPort = mJoinerPort;
|
||||
mSocket.Open(&HandleUdpReceive, this);
|
||||
mSocket.Bind(sockaddr);
|
||||
mNetif.GetIp6Filter().AddUnsecurePort(sockaddr.mPort);
|
||||
otLogInfoMeshCoP("Joiner Router: start\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
mSocket.Close();
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
ThreadError JoinerRouter::GetBorderAgentRloc(uint16_t &aRloc)
|
||||
{
|
||||
ThreadError error = kThreadError_NotFound;
|
||||
uint8_t *cur;
|
||||
uint8_t *end;
|
||||
uint8_t length;
|
||||
|
||||
VerifyOrExit((cur = mNetif.GetNetworkDataLeader().GetCommissioningData(length)) != NULL, ;);
|
||||
|
||||
end = cur + length;
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
Tlv *tlv = reinterpret_cast<Tlv *>(cur);
|
||||
|
||||
if (tlv->GetType() == Tlv::kBorderAgentLocator)
|
||||
{
|
||||
aRloc = reinterpret_cast<BorderAgentLocatorTlv *>(tlv)->GetBorderAgentLocator();
|
||||
ExitNow(error = kThreadError_None);
|
||||
}
|
||||
|
||||
cur += sizeof(Tlv) + tlv->GetLength();
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError JoinerRouter::GetJoinerPort(uint16_t &aJoinerPort)
|
||||
{
|
||||
ThreadError error = kThreadError_NotFound;
|
||||
uint8_t *cur;
|
||||
uint8_t *end;
|
||||
uint8_t length;
|
||||
|
||||
VerifyOrExit((cur = mNetif.GetNetworkDataLeader().GetCommissioningData(length)) != NULL, ;);
|
||||
|
||||
end = cur + length;
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
Tlv *tlv = reinterpret_cast<Tlv *>(cur);
|
||||
|
||||
if (tlv->GetType() == Tlv::kJoinerUdpPort)
|
||||
{
|
||||
aJoinerPort = reinterpret_cast<JoinerUdpPortTlv *>(tlv)->GetUdpPort();
|
||||
ExitNow(error = kThreadError_None);
|
||||
}
|
||||
|
||||
cur += sizeof(Tlv) + tlv->GetLength();
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void JoinerRouter::HandleUdpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo)
|
||||
{
|
||||
static_cast<JoinerRouter *>(aContext)->HandleUdpReceive(*static_cast<Message *>(aMessage),
|
||||
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
|
||||
}
|
||||
|
||||
void JoinerRouter::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
ThreadError error;
|
||||
Message *message = NULL;
|
||||
Coap::Header header;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
JoinerUdpPortTlv udpPort;
|
||||
JoinerIidTlv iid;
|
||||
ExtendedTlv tlv;
|
||||
uint16_t borderAgentRloc;
|
||||
|
||||
otLogInfoMeshCoP("JoinerRouter::HandleUdpReceive\r\n");
|
||||
|
||||
SuccessOrExit(error = GetBorderAgentRloc(borderAgentRloc));
|
||||
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
|
||||
header.Init();
|
||||
header.SetVersion(1);
|
||||
header.SetType(Coap::Header::kTypeNonConfirmable);
|
||||
header.SetCode(Coap::Header::kCodePost);
|
||||
header.SetMessageId(0);
|
||||
header.SetToken(NULL, 0);
|
||||
header.AppendUriPathOptions(OPENTHREAD_URI_RELAY_RX);
|
||||
header.AppendContentFormatOption(Coap::Header::kApplicationOctetStream);
|
||||
header.Finalize();
|
||||
SuccessOrExit(error = message->Append(header.GetBytes(), header.GetLength()));
|
||||
|
||||
udpPort.Init();
|
||||
udpPort.SetUdpPort(aMessageInfo.mPeerPort);
|
||||
SuccessOrExit(error = message->Append(&udpPort, sizeof(udpPort)));
|
||||
|
||||
iid.Init();
|
||||
iid.SetIid(aMessageInfo.GetPeerAddr().mFields.m8 + 8);
|
||||
SuccessOrExit(error = message->Append(&iid, sizeof(iid)));
|
||||
|
||||
tlv.SetType(Tlv::kJoinerDtlsEncapsulation);
|
||||
tlv.SetLength(aMessage.GetLength() - aMessage.GetOffset());
|
||||
SuccessOrExit(error = message->Append(&tlv, sizeof(tlv)));
|
||||
|
||||
while (aMessage.GetOffset() < aMessage.GetLength())
|
||||
{
|
||||
uint16_t length = aMessage.GetLength() - aMessage.GetOffset();
|
||||
uint8_t tmp[16];
|
||||
|
||||
if (length >= sizeof(tmp))
|
||||
{
|
||||
length = sizeof(tmp);
|
||||
}
|
||||
|
||||
aMessage.Read(aMessage.GetOffset(), length, tmp);
|
||||
aMessage.MoveOffset(length);
|
||||
|
||||
SuccessOrExit(error = message->Append(tmp, length));
|
||||
}
|
||||
|
||||
memset(&messageInfo, 0, sizeof(messageInfo));
|
||||
memcpy(messageInfo.GetPeerAddr().mFields.m8, mNetif.GetMle().GetMeshLocalPrefix(), 8);
|
||||
messageInfo.GetPeerAddr().mFields.m16[5] = HostSwap16(0x00ff);
|
||||
messageInfo.GetPeerAddr().mFields.m16[6] = HostSwap16(0xfe00);
|
||||
messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(borderAgentRloc);
|
||||
messageInfo.mPeerPort = kCoapUdpPort;
|
||||
|
||||
SuccessOrExit(error = mSocket.SendTo(*message, messageInfo));
|
||||
|
||||
otLogInfoMeshCoP("Sent relay rx\r\n");
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
|
||||
void JoinerRouter::HandleRelayTransmit(void *aContext, Coap::Header &aHeader,
|
||||
Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
static_cast<JoinerRouter *>(aContext)->HandleRelayTransmit(aHeader, aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
void JoinerRouter::HandleRelayTransmit(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
ThreadError error;
|
||||
JoinerUdpPortTlv joinerPort;
|
||||
JoinerIidTlv joinerIid;
|
||||
JoinerRouterKekTlv kek;
|
||||
uint16_t offset;
|
||||
uint16_t length;
|
||||
Message *message = NULL;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
VerifyOrExit(aHeader.GetType() == Coap::Header::kTypeNonConfirmable &&
|
||||
aHeader.GetCode() == Coap::Header::kCodePost, error = kThreadError_Drop);
|
||||
|
||||
otLogInfoMeshCoP("Received relay transmit\r\n");
|
||||
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kJoinerUdpPort, sizeof(joinerPort), joinerPort));
|
||||
VerifyOrExit(joinerPort.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kJoinerIid, sizeof(joinerIid), joinerIid));
|
||||
VerifyOrExit(joinerIid.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
SuccessOrExit(error = Tlv::GetValueOffset(aMessage, Tlv::kJoinerDtlsEncapsulation, offset, length));
|
||||
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
message->SetLinkSecurityEnabled(false);
|
||||
|
||||
while (length)
|
||||
{
|
||||
uint16_t copyLength = length;
|
||||
uint8_t tmp[16];
|
||||
|
||||
if (copyLength >= sizeof(tmp))
|
||||
{
|
||||
copyLength = sizeof(tmp);
|
||||
}
|
||||
|
||||
aMessage.Read(offset, copyLength, tmp);
|
||||
SuccessOrExit(error = message->Append(tmp, copyLength));
|
||||
|
||||
offset += copyLength;
|
||||
length -= copyLength;
|
||||
}
|
||||
|
||||
aMessage.CopyTo(offset, 0, length, *message);
|
||||
|
||||
memset(&messageInfo, 0, sizeof(messageInfo));
|
||||
messageInfo.mPeerAddr.mFields.m16[0] = HostSwap16(0xfe80);
|
||||
memcpy(messageInfo.mPeerAddr.mFields.m8 + 8, joinerIid.GetIid(), 8);
|
||||
messageInfo.mPeerPort = joinerPort.GetUdpPort();
|
||||
messageInfo.mInterfaceId = mNetif.GetInterfaceId();
|
||||
|
||||
SuccessOrExit(error = mSocket.SendTo(*message, messageInfo));
|
||||
|
||||
if (Tlv::GetTlv(aMessage, Tlv::kJoinerRouterKek, sizeof(kek), kek) == kThreadError_None)
|
||||
{
|
||||
otLogInfoMeshCoP("Received kek\r\n");
|
||||
mNetif.GetKeyManager().SetKek(kek.GetKek());
|
||||
SendJoinerEntrust(messageInfo);
|
||||
}
|
||||
|
||||
exit:
|
||||
(void)aMessageInfo;
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
}
|
||||
|
||||
ThreadError JoinerRouter::SendJoinerEntrust(const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
ThreadError error;
|
||||
Message *message = NULL;
|
||||
Coap::Header header;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
NetworkMasterKeyTlv masterKey;
|
||||
MeshLocalPrefixTlv meshLocalPrefix;
|
||||
ExtendedPanIdTlv extendedPanId;
|
||||
NetworkNameTlv networkName;
|
||||
ActiveTimestampTlv activeTimestamp;
|
||||
Tlv *tlv;
|
||||
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
message->SetJoinerEntrust(true);
|
||||
|
||||
header.Init();
|
||||
header.SetVersion(1);
|
||||
header.SetType(Coap::Header::kTypeConfirmable);
|
||||
header.SetCode(Coap::Header::kCodePost);
|
||||
header.SetMessageId(0);
|
||||
header.SetToken(NULL, 0);
|
||||
header.AppendUriPathOptions(OPENTHREAD_URI_JOINER_ENTRUST);
|
||||
header.AppendContentFormatOption(Coap::Header::kApplicationOctetStream);
|
||||
header.Finalize();
|
||||
SuccessOrExit(error = message->Append(header.GetBytes(), header.GetLength()));
|
||||
|
||||
masterKey.Init();
|
||||
masterKey.SetNetworkMasterKey(mNetif.GetKeyManager().GetMasterKey(NULL));
|
||||
SuccessOrExit(error = message->Append(&masterKey, sizeof(masterKey)));
|
||||
|
||||
meshLocalPrefix.Init();
|
||||
meshLocalPrefix.SetMeshLocalPrefix(mNetif.GetMle().GetMeshLocalPrefix());
|
||||
SuccessOrExit(error = message->Append(&meshLocalPrefix, sizeof(meshLocalPrefix)));
|
||||
|
||||
extendedPanId.Init();
|
||||
extendedPanId.SetExtendedPanId(mNetif.GetMac().GetExtendedPanId());
|
||||
SuccessOrExit(error = message->Append(&extendedPanId, sizeof(extendedPanId)));
|
||||
|
||||
networkName.Init();
|
||||
networkName.SetNetworkName(mNetif.GetMac().GetNetworkName());
|
||||
SuccessOrExit(error = message->Append(&networkName, sizeof(Tlv) + networkName.GetLength()));
|
||||
|
||||
activeTimestamp.Init();
|
||||
*static_cast<Timestamp *>(&activeTimestamp) = mNetif.GetActiveDataset().GetNetwork().GetTimestamp();
|
||||
SuccessOrExit(error = message->Append(&activeTimestamp, sizeof(activeTimestamp)));
|
||||
|
||||
if ((tlv = mNetif.GetActiveDataset().GetNetwork().Get(Tlv::kChannelMask)) != NULL)
|
||||
{
|
||||
SuccessOrExit(error = message->Append(tlv, sizeof(Tlv) + tlv->GetLength()));
|
||||
}
|
||||
else
|
||||
{
|
||||
ChannelMaskTlv channelMask;
|
||||
channelMask.Init();
|
||||
SuccessOrExit(error = message->Append(&channelMask, sizeof(channelMask)));
|
||||
}
|
||||
|
||||
if ((tlv = mNetif.GetActiveDataset().GetNetwork().Get(Tlv::kPSKc)) != NULL)
|
||||
{
|
||||
SuccessOrExit(error = message->Append(tlv, sizeof(Tlv) + tlv->GetLength()));
|
||||
}
|
||||
else
|
||||
{
|
||||
PSKcTlv pskc;
|
||||
pskc.Init();
|
||||
SuccessOrExit(error = message->Append(&pskc, sizeof(pskc)));
|
||||
}
|
||||
|
||||
if ((tlv = mNetif.GetActiveDataset().GetNetwork().Get(Tlv::kSecurityPolicy)) != NULL)
|
||||
{
|
||||
SuccessOrExit(error = message->Append(tlv, sizeof(Tlv) + tlv->GetLength()));
|
||||
}
|
||||
else
|
||||
{
|
||||
SecurityPolicyTlv securityPolicy;
|
||||
securityPolicy.Init();
|
||||
SuccessOrExit(error = message->Append(&securityPolicy, sizeof(securityPolicy)));
|
||||
}
|
||||
|
||||
messageInfo = aMessageInfo;
|
||||
messageInfo.mPeerPort = kCoapUdpPort;
|
||||
SuccessOrExit(error = mSocket.SendTo(*message, messageInfo));
|
||||
|
||||
otLogInfoMeshCoP("Sent joiner entrust length = %d\r\n", message->GetLength());
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace Dtls
|
||||
} // namespace Thread
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* 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 the Joiner Router role.
|
||||
*/
|
||||
|
||||
#ifndef JOINER_ROUTER_HPP_
|
||||
#define JOINER_ROUTER_HPP_
|
||||
|
||||
#include <openthread-types.h>
|
||||
|
||||
#include <coap/coap_header.hpp>
|
||||
#include <coap/coap_server.hpp>
|
||||
#include <common/message.hpp>
|
||||
#include <mac/mac_frame.hpp>
|
||||
#include <net/udp6.hpp>
|
||||
|
||||
namespace Thread {
|
||||
|
||||
class ThreadNetif;
|
||||
|
||||
namespace MeshCoP {
|
||||
|
||||
class JoinerRouter
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the Joiner Router object.
|
||||
*
|
||||
* @param[in] aThreadNetif A reference to the Thread network interface.
|
||||
*
|
||||
*/
|
||||
JoinerRouter(ThreadNetif &aNetif);
|
||||
|
||||
private:
|
||||
static void HandleNetifStateChanged(uint32_t aFlags, void *aContext);
|
||||
void HandleNetifStateChanged(uint32_t aFlags);
|
||||
|
||||
static void HandleUdpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo);
|
||||
void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
static void HandleRelayTransmit(void *aContext, Coap::Header &aHeader,
|
||||
Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
void HandleRelayTransmit(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
ThreadError SendJoinerEntrust(const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
ThreadError GetBorderAgentRloc(uint16_t &aRloc);
|
||||
ThreadError GetJoinerPort(uint16_t &aRloc);
|
||||
|
||||
Ip6::NetifCallback mNetifCallback;
|
||||
uint16_t mJoinerPort;
|
||||
|
||||
Ip6::UdpSocket mSocket;
|
||||
Coap::Resource mRelayTransmit;
|
||||
ThreadNetif &mNetif;
|
||||
};
|
||||
|
||||
} // namespace MeshCoP
|
||||
} // namespace Thread
|
||||
|
||||
#endif // JOINER_ROUTER_HPP_
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* 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 a MeshCoP Leader.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <coap/coap_header.hpp>
|
||||
#include <common/code_utils.hpp>
|
||||
#include <common/logging.hpp>
|
||||
#include <meshcop/leader.hpp>
|
||||
#include <platform/random.h>
|
||||
#include <thread/thread_netif.hpp>
|
||||
#include <thread/thread_tlvs.hpp>
|
||||
#include <thread/thread_uris.hpp>
|
||||
|
||||
namespace Thread {
|
||||
namespace MeshCoP {
|
||||
|
||||
Leader::Leader(ThreadNetif &aThreadNetif):
|
||||
mPetition(OPENTHREAD_URI_LEADER_PETITION, HandlePetition, this),
|
||||
mKeepAlive(OPENTHREAD_URI_LEADER_KEEP_ALIVE, HandleKeepAlive, this),
|
||||
mCoapServer(aThreadNetif.GetCoapServer()),
|
||||
mNetworkData(aThreadNetif.GetNetworkDataLeader()),
|
||||
mTimer(aThreadNetif.GetIp6().mTimerScheduler, HandleTimer, this)
|
||||
{
|
||||
mCoapServer.AddResource(mPetition);
|
||||
mCoapServer.AddResource(mKeepAlive);
|
||||
}
|
||||
|
||||
void Leader::HandlePetition(void *aContext, Coap::Header &aHeader, Message &aMessage,
|
||||
const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
static_cast<Leader *>(aContext)->HandlePetition(aHeader, aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
void Leader::HandlePetition(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
CommissioningData data;
|
||||
CommissionerIdTlv commissionerId;
|
||||
StateTlv::State state = StateTlv::kReject;
|
||||
|
||||
otLogInfoMeshCoP("received petition\r\n");
|
||||
|
||||
SuccessOrExit(Tlv::GetTlv(aMessage, Tlv::kCommissionerId, sizeof(commissionerId), commissionerId));
|
||||
|
||||
VerifyOrExit(!mTimer.IsRunning(), ;);
|
||||
|
||||
data.mBorderAgentLocator.Init();
|
||||
data.mBorderAgentLocator.SetBorderAgentLocator(HostSwap16(aMessageInfo.GetPeerAddr().mFields.m16[7]));
|
||||
|
||||
data.mCommissionerSessionId.Init();
|
||||
data.mCommissionerSessionId.SetCommissionerSessionId(++mSessionId);
|
||||
|
||||
data.mSteeringData.Init();
|
||||
data.mSteeringData.SetLength(1);
|
||||
data.mSteeringData.Clear();
|
||||
|
||||
SuccessOrExit(mNetworkData.SetCommissioningData(reinterpret_cast<uint8_t *>(&data), data.GetLength()));
|
||||
|
||||
mCommissionerId = commissionerId;
|
||||
|
||||
state = StateTlv::kAccept;
|
||||
mTimer.Start(Timer::SecToMsec(kTimeoutLeaderPetition));
|
||||
|
||||
exit:
|
||||
(void)aMessageInfo;
|
||||
SendPetitionResponse(aHeader, aMessageInfo, state);
|
||||
}
|
||||
|
||||
ThreadError Leader::SendPetitionResponse(const Coap::Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo,
|
||||
StateTlv::State aState)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Coap::Header responseHeader;
|
||||
StateTlv state;
|
||||
CommissionerSessionIdTlv sessionId;
|
||||
Message *message;
|
||||
|
||||
VerifyOrExit((message = mCoapServer.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
responseHeader.Init();
|
||||
responseHeader.SetVersion(1);
|
||||
responseHeader.SetType(Coap::Header::kTypeAcknowledgment);
|
||||
responseHeader.SetCode(Coap::Header::kCodeChanged);
|
||||
responseHeader.SetMessageId(aRequestHeader.GetMessageId());
|
||||
responseHeader.SetToken(aRequestHeader.GetToken(), aRequestHeader.GetTokenLength());
|
||||
responseHeader.AppendContentFormatOption(Coap::Header::kApplicationOctetStream);
|
||||
responseHeader.Finalize();
|
||||
SuccessOrExit(error = message->Append(responseHeader.GetBytes(), responseHeader.GetLength()));
|
||||
|
||||
state.Init();
|
||||
state.SetState(aState);
|
||||
SuccessOrExit(error = message->Append(&state, sizeof(state)));
|
||||
|
||||
if (mTimer.IsRunning())
|
||||
{
|
||||
SuccessOrExit(error = message->Append(&mCommissionerId, sizeof(mCommissionerId)));
|
||||
}
|
||||
|
||||
if (aState == StateTlv::kAccept)
|
||||
{
|
||||
sessionId.Init();
|
||||
sessionId.SetCommissionerSessionId(mSessionId);
|
||||
SuccessOrExit(error = message->Append(&sessionId, sizeof(sessionId)));
|
||||
|
||||
}
|
||||
|
||||
SuccessOrExit(error = mCoapServer.SendMessage(*message, aMessageInfo));
|
||||
|
||||
otLogInfoMeshCoP("sent petition response\r\n");
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void Leader::HandleKeepAlive(void *aContext, Coap::Header &aHeader, Message &aMessage,
|
||||
const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
static_cast<Leader *>(aContext)->HandleKeepAlive(aHeader, aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
void Leader::HandleKeepAlive(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
StateTlv state;
|
||||
CommissionerSessionIdTlv sessionId;
|
||||
StateTlv::State responseState;
|
||||
|
||||
otLogInfoMeshCoP("received keep alive\r\n");
|
||||
|
||||
SuccessOrExit(Tlv::GetTlv(aMessage, Tlv::kState, sizeof(state), state));
|
||||
SuccessOrExit(Tlv::GetTlv(aMessage, Tlv::kCommissionerSessionId, sizeof(sessionId), sessionId));
|
||||
|
||||
if (sessionId.GetCommissionerSessionId() != mSessionId)
|
||||
{
|
||||
responseState = StateTlv::kReject;
|
||||
}
|
||||
else if (state.GetState() != StateTlv::kAccept)
|
||||
{
|
||||
responseState = StateTlv::kReject;
|
||||
mTimer.Stop();
|
||||
mNetworkData.SetCommissioningData(NULL, 0);
|
||||
otLogInfoMeshCoP("commissioner inactive\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
responseState = StateTlv::kAccept;
|
||||
mTimer.Start(Timer::SecToMsec(kTimeoutLeaderPetition));
|
||||
}
|
||||
|
||||
SendKeepAliveResponse(aHeader, aMessageInfo, responseState);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
ThreadError Leader::SendKeepAliveResponse(const Coap::Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo,
|
||||
StateTlv::State aState)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Coap::Header responseHeader;
|
||||
StateTlv state;
|
||||
Message *message;
|
||||
|
||||
VerifyOrExit((message = mCoapServer.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
responseHeader.Init();
|
||||
responseHeader.SetVersion(1);
|
||||
responseHeader.SetType(Coap::Header::kTypeAcknowledgment);
|
||||
responseHeader.SetCode(Coap::Header::kCodeChanged);
|
||||
responseHeader.SetMessageId(aRequestHeader.GetMessageId());
|
||||
responseHeader.SetToken(aRequestHeader.GetToken(), aRequestHeader.GetTokenLength());
|
||||
responseHeader.AppendContentFormatOption(Coap::Header::kApplicationOctetStream);
|
||||
responseHeader.Finalize();
|
||||
SuccessOrExit(error = message->Append(responseHeader.GetBytes(), responseHeader.GetLength()));
|
||||
|
||||
state.Init();
|
||||
state.SetState(aState);
|
||||
SuccessOrExit(error = message->Append(&state, sizeof(state)));
|
||||
|
||||
SuccessOrExit(error = mCoapServer.SendMessage(*message, aMessageInfo));
|
||||
|
||||
otLogInfoMeshCoP("sent keep alive response\r\n");
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void Leader::HandleTimer(void *aContext)
|
||||
{
|
||||
static_cast<Leader *>(aContext)->HandleTimer();
|
||||
}
|
||||
|
||||
void Leader::HandleTimer(void)
|
||||
{
|
||||
otLogInfoMeshCoP("commissioner inactive\r\n");
|
||||
mNetworkData.SetCommissioningData(NULL, 0);
|
||||
}
|
||||
|
||||
} // namespace MeshCoP
|
||||
} // namespace Thread
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Nest Labs, Inc.
|
||||
* 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 a MeshCoP Leader.
|
||||
*/
|
||||
|
||||
#ifndef MESHCOP_LEADER_HPP_
|
||||
#define MESHCOP_LEADER_HPP_
|
||||
|
||||
#include <coap/coap_server.hpp>
|
||||
#include <common/timer.hpp>
|
||||
#include <net/udp6.hpp>
|
||||
#include <thread/meshcop_tlvs.hpp>
|
||||
#include <thread/mle.hpp>
|
||||
|
||||
namespace Thread {
|
||||
namespace MeshCoP {
|
||||
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class CommissioningData
|
||||
{
|
||||
public:
|
||||
uint8_t GetLength(void) const {
|
||||
return sizeof(Tlv) + mBorderAgentLocator.GetLength() +
|
||||
sizeof(Tlv) + mCommissionerSessionId.GetLength() +
|
||||
sizeof(Tlv) + mSteeringData.GetLength();
|
||||
}
|
||||
|
||||
BorderAgentLocatorTlv mBorderAgentLocator;
|
||||
CommissionerSessionIdTlv mCommissionerSessionId;
|
||||
SteeringDataTlv mSteeringData;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
class Leader
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the Leader object.
|
||||
*
|
||||
* @param[in] aThreadNetif A reference to the Thread network interface.
|
||||
*
|
||||
*/
|
||||
Leader(ThreadNetif &aThreadNetif);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kTimeoutLeaderPetition = 50, ///< TIMEOUT_LEAD_PET (seconds)
|
||||
};
|
||||
|
||||
static void HandleTimer(void *aContext);
|
||||
void HandleTimer(void);
|
||||
|
||||
static void HandlePetition(void *aContext, Coap::Header &aHeader, Message &aMessage,
|
||||
const Ip6::MessageInfo &aMessageInfo);
|
||||
void HandlePetition(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
ThreadError SendPetitionResponse(const Coap::Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo,
|
||||
StateTlv::State aState);
|
||||
|
||||
static void HandleKeepAlive(void *aContext, Coap::Header &aHeader, Message &aMessage,
|
||||
const Ip6::MessageInfo &aMessageInfo);
|
||||
void HandleKeepAlive(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
ThreadError SendKeepAliveResponse(const Coap::Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo,
|
||||
StateTlv::State aState);
|
||||
|
||||
Coap::Resource mPetition;
|
||||
Coap::Resource mKeepAlive;
|
||||
Coap::Server &mCoapServer;
|
||||
NetworkData::Leader &mNetworkData;
|
||||
|
||||
Timer mTimer;
|
||||
|
||||
CommissionerIdTlv mCommissionerId;
|
||||
uint16_t mSessionId;
|
||||
};
|
||||
|
||||
} // namespace MeshCoP
|
||||
} // namespace Thread
|
||||
|
||||
#endif // MESHCOP_LEADER_HPP_
|
||||
@@ -155,6 +155,16 @@
|
||||
#define OPENTHREAD_CONFIG_MPL_CACHE_ENTRY_LIFETIME 5
|
||||
#endif // OPENTHREAD_CONFIG_MPL_CACHE_ENTRY_LIFETIME
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_JOINER_UDP_PORT
|
||||
*
|
||||
* The MPL cache entry lifetime in seconds.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_JOINER_UDP_PORT
|
||||
#define OPENTHREAD_CONFIG_JOINER_UDP_PORT 1000
|
||||
#endif // OPENTHREAD_CONFIG_JOINER_UDP_PORT
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_LOG_LEVEL
|
||||
*
|
||||
|
||||
@@ -875,9 +875,11 @@ ThreadError otEnable(void)
|
||||
VerifyOrExit(!mEnabled, error = kThreadError_InvalidState);
|
||||
|
||||
otLogInfoApi("otEnable\n");
|
||||
|
||||
new(&sMbedTlsRaw) Crypto::MbedTls;
|
||||
sIp6 = new(&sIp6Raw) Ip6::Ip6;
|
||||
sThreadNetif = new(&sThreadNetifRaw) ThreadNetif(*sIp6);
|
||||
|
||||
mEnabled = true;
|
||||
|
||||
exit:
|
||||
@@ -1238,6 +1240,30 @@ ThreadError otSendPendingSet(const otOperationalDataset *aDataset, const uint8_t
|
||||
return sThreadNetif->GetPendingDataset().SendSetRequest(*aDataset, aTlvs, aLength);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
ThreadError otCommissionerStart(void)
|
||||
{
|
||||
return sThreadNetif->GetCommissioner().Start();
|
||||
}
|
||||
|
||||
ThreadError otCommissionerStop(void)
|
||||
{
|
||||
return sThreadNetif->GetCommissioner().Stop();
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER
|
||||
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
ThreadError otJoinerStart(void)
|
||||
{
|
||||
return sThreadNetif->GetJoiner().Start();
|
||||
}
|
||||
|
||||
ThreadError otJoinerStop(void)
|
||||
{
|
||||
return sThreadNetif->GetJoiner().Stop();
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_JOINER
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
@@ -161,4 +161,25 @@ void KeyManager::IncrementMleFrameCounter(void)
|
||||
mMleFrameCounter++;
|
||||
}
|
||||
|
||||
const uint8_t *KeyManager::GetKek(void) const
|
||||
{
|
||||
return mKek;
|
||||
}
|
||||
|
||||
void KeyManager::SetKek(const uint8_t *aKek)
|
||||
{
|
||||
memcpy(mKek, aKek, sizeof(mKek));
|
||||
mKekFrameCounter = 0;
|
||||
}
|
||||
|
||||
uint32_t KeyManager::GetKekFrameCounter(void) const
|
||||
{
|
||||
return mKekFrameCounter;
|
||||
}
|
||||
|
||||
void KeyManager::IncrementKekFrameCounter(void)
|
||||
{
|
||||
mKekFrameCounter++;
|
||||
}
|
||||
|
||||
} // namespace Thread
|
||||
|
||||
@@ -148,8 +148,6 @@ public:
|
||||
/**
|
||||
* This method increments the current MAC Frame Counter value.
|
||||
*
|
||||
* @returns The current MAC Frame Counter value.
|
||||
*
|
||||
*/
|
||||
void IncrementMacFrameCounter(void);
|
||||
|
||||
@@ -164,11 +162,39 @@ public:
|
||||
/**
|
||||
* This method increments the current MLE Frame Counter value.
|
||||
*
|
||||
* @returns The current MLE Frame Counter value.
|
||||
*
|
||||
*/
|
||||
void IncrementMleFrameCounter(void);
|
||||
|
||||
/**
|
||||
* This method returns the KEK.
|
||||
*
|
||||
* @returns A pointer to the KEK.
|
||||
*
|
||||
*/
|
||||
const uint8_t *GetKek(void) const;
|
||||
|
||||
/**
|
||||
* This method sets the KEK.
|
||||
*
|
||||
* @param[in] aKek A pointer to the KEK.
|
||||
*
|
||||
*/
|
||||
void SetKek(const uint8_t *aKek);
|
||||
|
||||
/**
|
||||
* This method returns the current KEK Frame Counter value.
|
||||
*
|
||||
* @returns The current KEK Frame Counter value.
|
||||
*
|
||||
*/
|
||||
uint32_t GetKekFrameCounter(void) const;
|
||||
|
||||
/**
|
||||
* This method increments the current KEK Frame Counter value.
|
||||
*
|
||||
*/
|
||||
void IncrementKekFrameCounter(void);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
@@ -188,6 +214,9 @@ private:
|
||||
uint32_t mMacFrameCounter;
|
||||
uint32_t mMleFrameCounter;
|
||||
|
||||
uint8_t mKek[kMaxKeyLength];
|
||||
uint32_t mKekFrameCounter;
|
||||
|
||||
ThreadNetif &mNetif;
|
||||
};
|
||||
|
||||
|
||||
@@ -820,6 +820,7 @@ ThreadError MeshForwarder::SendFragment(Message &aMessage, Mac::Frame &aFrame)
|
||||
int hcLength;
|
||||
uint16_t fragmentLength;
|
||||
uint16_t dstpan;
|
||||
uint8_t secCtl = Mac::Frame::kSecNone;
|
||||
|
||||
if (mAddMeshHeader)
|
||||
{
|
||||
@@ -848,6 +849,8 @@ ThreadError MeshForwarder::SendFragment(Message &aMessage, Mac::Frame &aFrame)
|
||||
if (aMessage.IsLinkSecurityEnabled())
|
||||
{
|
||||
fcf |= Mac::Frame::kFcfSecurityEnabled;
|
||||
secCtl = aMessage.IsJoinerEntrust() ? Mac::Frame::kKeyIdMode0 : Mac::Frame::kKeyIdMode1;
|
||||
secCtl |= Mac::Frame::kSecEncMic32;
|
||||
}
|
||||
|
||||
if (aMessage.IsMleDiscoverRequest() || aMessage.IsMleDiscoverResponse())
|
||||
@@ -864,7 +867,7 @@ ThreadError MeshForwarder::SendFragment(Message &aMessage, Mac::Frame &aFrame)
|
||||
fcf |= Mac::Frame::kFcfPanidCompression;
|
||||
}
|
||||
|
||||
aFrame.InitMacHeader(fcf, Mac::Frame::kKeyIdMode1 | Mac::Frame::kSecEncMic32);
|
||||
aFrame.InitMacHeader(fcf, secCtl);
|
||||
aFrame.SetDstPanId(dstpan);
|
||||
aFrame.SetSrcPanId(mMac.GetPanId());
|
||||
|
||||
|
||||
@@ -69,5 +69,71 @@ int Timestamp::Compare(const Timestamp &aCompare) const
|
||||
return rval;
|
||||
}
|
||||
|
||||
ThreadError Tlv::GetTlv(const Message &message, Type type, uint16_t maxLength, Tlv &tlv)
|
||||
{
|
||||
ThreadError error = kThreadError_Parse;
|
||||
uint16_t offset = message.GetOffset();
|
||||
uint16_t end = message.GetLength();
|
||||
|
||||
while (offset < end)
|
||||
{
|
||||
message.Read(offset, sizeof(Tlv), &tlv);
|
||||
|
||||
if (tlv.GetType() == type && (offset + sizeof(tlv) + tlv.GetLength()) <= end)
|
||||
{
|
||||
if (maxLength > sizeof(tlv) + tlv.GetLength())
|
||||
{
|
||||
maxLength = sizeof(tlv) + tlv.GetLength();
|
||||
}
|
||||
|
||||
message.Read(offset, maxLength, &tlv);
|
||||
|
||||
ExitNow(error = kThreadError_None);
|
||||
}
|
||||
|
||||
offset += sizeof(tlv) + tlv.GetLength();
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError Tlv::GetValueOffset(const Message &aMessage, Type aType, uint16_t &aOffset, uint16_t &aLength)
|
||||
{
|
||||
ThreadError error = kThreadError_Parse;
|
||||
uint16_t offset = aMessage.GetOffset();
|
||||
uint16_t end = aMessage.GetLength();
|
||||
|
||||
while (offset < end)
|
||||
{
|
||||
Tlv tlv;
|
||||
uint16_t length;
|
||||
|
||||
aMessage.Read(offset, sizeof(tlv), &tlv);
|
||||
offset += sizeof(tlv);
|
||||
|
||||
length = tlv.GetLength();
|
||||
|
||||
if (length == kExtendedLength)
|
||||
{
|
||||
aMessage.Read(offset, sizeof(length), &length);
|
||||
offset += sizeof(length);
|
||||
length = HostSwap16(length);
|
||||
}
|
||||
|
||||
if (tlv.GetType() == aType)
|
||||
{
|
||||
aOffset = offset;
|
||||
aLength = length;
|
||||
ExitNow(error = kThreadError_None);
|
||||
}
|
||||
|
||||
offset += length;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace MeshCoP
|
||||
} // namespace Thread
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#include <openthread-types.h>
|
||||
#include <common/encoding.hpp>
|
||||
#include <common/message.hpp>
|
||||
|
||||
using Thread::Encoding::BigEndian::HostSwap16;
|
||||
using Thread::Encoding::BigEndian::HostSwap32;
|
||||
@@ -60,22 +61,39 @@ public:
|
||||
*/
|
||||
enum Type
|
||||
{
|
||||
kChannel = OT_MESHCOP_TLV_CHANNEL, ///< Channel TLV
|
||||
kPanId = OT_MESHCOP_TLV_PANID, ///< PAN ID TLV
|
||||
kExtendedPanId = OT_MESHCOP_TLV_EXTPANID, ///< Extended PAN ID TLV
|
||||
kNetworkName = OT_MESHCOP_TLV_NETWORKNAME, ///< Network Name TLV
|
||||
kPSKc = OT_MESHCOP_TLV_PSKC, ///< PSKc TLV
|
||||
kNetworkMasterKey = OT_MESHCOP_TLV_MASTERKEY, ///< Network Master Key TLV
|
||||
kMeshLocalPrefix = OT_MESHCOP_TLV_LOCALPREFIX, ///< Mesh Local Prefix TLV
|
||||
kSecurityPolicy = OT_MESHCOP_TLV_SECURITYPOLICY, ///< Security Policy TLV
|
||||
kGet = OT_MESHCOP_TLV_GET, ///< Get TLV
|
||||
kActiveTimestamp = OT_MESHCOP_TLV_ACTIVETIMESTAMP, ///< Active Timestamp TLV
|
||||
kState = OT_MESHCOP_TLV_STATE, ///< State TLV
|
||||
kPendingTimestamp = OT_MESHCOP_TLV_PENDINGTIMESTAMP, ///< Pending Timestamp TLV
|
||||
kDelayTimer = OT_MESHCOP_TLV_DELAYTIMER, ///< Delay Timer TLV
|
||||
kChannelMask = OT_MESHCOP_TLV_CHANNELMASK, ///< Channel Mask TLV
|
||||
kDiscoveryRequest = OT_MESHCOP_TLV_DISCOVERYREQUEST, ///< Discovery Request TLV
|
||||
kDiscoveryResponse = OT_MESHCOP_TLV_DISCOVERYRESPONSE, ///< Discovery Response TLV
|
||||
kChannel = OT_MESHCOP_TLV_CHANNEL, ///< Channel TLV
|
||||
kPanId = OT_MESHCOP_TLV_PANID, ///< PAN ID TLV
|
||||
kExtendedPanId = OT_MESHCOP_TLV_EXTPANID, ///< Extended PAN ID TLV
|
||||
kNetworkName = OT_MESHCOP_TLV_NETWORKNAME, ///< Newtork Name TLV
|
||||
kPSKc = OT_MESHCOP_TLV_PSKC, ///< PSKc TLV
|
||||
kNetworkMasterKey = OT_MESHCOP_TLV_MASTERKEY, ///< Network Master Key TLV
|
||||
kMeshLocalPrefix = OT_MESHCOP_TLV_MESHLOCALPREFIX, ///< Mesh Local Prefix TLV
|
||||
kSteeringData = OT_MESHCOP_TLV_STEERING_DATA, ///< Steering Data TLV
|
||||
kBorderAgentLocator = OT_MESHCOP_TLV_BORDER_AGENT_RLOC, ///< Border Agent Locator TLV
|
||||
kCommissionerId = OT_MESHCOP_TLV_COMMISSIONER_ID, ///< Commissioner ID TLV
|
||||
kCommissionerSessionId = OT_MESHCOP_TLV_COMM_SESSION_ID, ///< Commissioner Session ID TLV
|
||||
kSecurityPolicy = OT_MESHCOP_TLV_SECURITYPOLICY, ///< Security Policy TLV
|
||||
kGet = OT_MESHCOP_TLV_GET, ///< Get TLV
|
||||
kActiveTimestamp = OT_MESHCOP_TLV_ACTIVETIMESTAMP, ///< Active Timestamp TLV
|
||||
kState = OT_MESHCOP_TLV_STATE, ///< State TLV
|
||||
kJoinerDtlsEncapsulation = OT_MESHCOP_TLV_JOINER_DTLS, ///< Joiner DTLS Encapsulation TLV
|
||||
kJoinerUdpPort = OT_MESHCOP_TLV_JOINER_UDP_PORT, ///< Joiner UDP Port TLV
|
||||
kJoinerIid = OT_MESHCOP_TLV_JOINER_IID, ///< Joiner IID TLV
|
||||
kJoinerRouterKek = OT_MESHCOP_TLV_JOINER_ROUTER_KEK, ///< Joiner Router KEK TLV
|
||||
kPendingTimestamp = OT_MESHCOP_TLV_PENDINGTIMESTAMP, ///< Pending Timestamp TLV
|
||||
kDelayTimer = OT_MESHCOP_TLV_DELAYTIMER, ///< Delay Timer TLV
|
||||
kChannelMask = OT_MESHCOP_TLV_CHANNELMASK, ///< Channel Mask TLV
|
||||
kDiscoveryRequest = OT_MESHCOP_TLV_DISCOVERYREQUEST, ///< Discovery Request TLV
|
||||
kDiscoveryResponse = OT_MESHCOP_TLV_DISCOVERYRESPONSE, ///< Discovery Response TLV
|
||||
};
|
||||
|
||||
/**
|
||||
* Length values.
|
||||
*
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kExtendedLength = 255, ///< Extended Length value
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -130,11 +148,61 @@ public:
|
||||
return reinterpret_cast<const Tlv *>(reinterpret_cast<const uint8_t *>(this) + sizeof(*this) + mLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* This static method reads the requested TLV out of @p aMessage.
|
||||
*
|
||||
* @param[in] aMessage A reference to the message.
|
||||
* @param[in] aType The Type value to search for.
|
||||
* @param[in] aMaxLength Maximum number of bytes to read.
|
||||
* @param[out] aTlv A reference to the TLV that will be copied to.
|
||||
*
|
||||
* @retval kThreadError_None Successfully copied the TLV.
|
||||
* @retval kThreadError_NotFound Could not find the TLV with Type @p aType.
|
||||
*
|
||||
*/
|
||||
static ThreadError GetTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, Tlv &aTlv);
|
||||
|
||||
/**
|
||||
* This static method finds the offset and length of a given TLV type.
|
||||
*
|
||||
* @param[in] aMessage A reference to the message.
|
||||
* @param[in] aType The Type value to search for.
|
||||
* @param[out] aOffset The offset where the value starts.
|
||||
* @param[out] aLength The length of the value.
|
||||
*
|
||||
* @retval kThreadError_None Successfully found the TLV.
|
||||
* @retval kThreadError_NotFound Could not find the TLV with Type @p aType.
|
||||
*
|
||||
*/
|
||||
static ThreadError GetValueOffset(const Message &aMesasge, Type aType, uint16_t &aOffset, uint16_t &aLength);
|
||||
|
||||
private:
|
||||
uint8_t mType;
|
||||
uint8_t mLength;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class ExtendedTlv: public Tlv
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method returns the Length value.
|
||||
*
|
||||
*/
|
||||
uint16_t GetLength() const { return HostSwap16(mLength); }
|
||||
|
||||
/**
|
||||
* This method sets the Length value.
|
||||
*
|
||||
* @param[in] aLength The Length value.
|
||||
*
|
||||
*/
|
||||
void SetLength(uint16_t aLength) { Tlv::SetLength(kExtendedLength); mLength = HostSwap16(aLength); }
|
||||
|
||||
private:
|
||||
uint16_t mLength;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements Channel TLV generation and parsing.
|
||||
*
|
||||
@@ -465,6 +533,206 @@ private:
|
||||
uint8_t mMeshLocalPrefix[8];
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements Steering Data TLV generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class SteeringDataTlv: public Tlv
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
*
|
||||
*/
|
||||
void Init(void) { SetType(kSteeringData); SetLength(sizeof(*this) - sizeof(Tlv)); Clear(); }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the TLV appears to be well-formed.
|
||||
*
|
||||
* @retval TRUE If the TLV appears to be well-formed.
|
||||
* @retval FALSE If the TLV does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const { return GetLength() == sizeof(*this) - sizeof(Tlv); }
|
||||
|
||||
/**
|
||||
* This method sets all bits in the Bloom Filter to zero.
|
||||
*
|
||||
*/
|
||||
void Clear(void) { memset(mSteeringData, 0, sizeof(mSteeringData)); }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not bit @p aBit is set.
|
||||
*
|
||||
* @param[in] aBit The bit offset.
|
||||
*
|
||||
* @retval TRUE If bit @p aBit is set.
|
||||
* @retval FALSE If bit @p aBit is not set.
|
||||
*
|
||||
*/
|
||||
bool GetBit(uint8_t aBit) const { return (mSteeringData[aBit / 8] & (1 << (aBit % 8))) != 0; }
|
||||
|
||||
/**
|
||||
* This method clears bit @p aBit.
|
||||
*
|
||||
* @param[in] aBit The bit offset.
|
||||
*
|
||||
*/
|
||||
void ClearBit(uint8_t aBit) { mSteeringData[aBit / 8] &= ~(1 << (aBit % 8)); }
|
||||
|
||||
/**
|
||||
* This method sets bit @p aBit.
|
||||
*
|
||||
* @param[in] aBit The bit offset.
|
||||
*
|
||||
*/
|
||||
void SetBit(uint8_t aBit) { mSteeringData[aBit / 8] |= 1 << (aBit % 8); }
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kMaxLength = 16,
|
||||
};
|
||||
uint8_t mSteeringData[kMaxLength];
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements Border Agent Locator TLV generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class BorderAgentLocatorTlv: public Tlv
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
*
|
||||
*/
|
||||
void Init(void) { SetType(kBorderAgentLocator); SetLength(sizeof(*this) - sizeof(Tlv)); }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the TLV appears to be well-formed.
|
||||
*
|
||||
* @retval TRUE If the TLV appears to be well-formed.
|
||||
* @retval FALSE If the TLV does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const { return GetLength() == sizeof(*this) - sizeof(Tlv); }
|
||||
|
||||
/**
|
||||
* This method returns the Border Agent Locator value.
|
||||
*
|
||||
* @returns The Border Agent Locator value.
|
||||
*
|
||||
*/
|
||||
uint16_t GetBorderAgentLocator(void) const { return HostSwap16(mLocator); }
|
||||
|
||||
/**
|
||||
* This method sets the Border Agent Locator value.
|
||||
*
|
||||
* @param[in] aBorderAgentLocator The Border Agent Locator value.
|
||||
*
|
||||
*/
|
||||
void SetBorderAgentLocator(uint16_t aLocator) { mLocator = HostSwap16(aLocator); }
|
||||
|
||||
private:
|
||||
uint16_t mLocator;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements the Commissioner ID TLV generation and parsing.
|
||||
*
|
||||
*/
|
||||
class CommissionerIdTlv: public Tlv
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
*
|
||||
*/
|
||||
void Init(void) { SetType(kCommissionerId); SetLength(sizeof(*this) - sizeof(Tlv)); }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the TLV appears to be well-formed.
|
||||
*
|
||||
* @retval TRUE If the TLV appears to be well-formed.
|
||||
* @retval FALSE If the TLV does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const { return GetLength() <= sizeof(*this) - sizeof(Tlv); }
|
||||
|
||||
/**
|
||||
* This method returns the Commissioner ID value.
|
||||
*
|
||||
* @returns The Commissioner ID value.
|
||||
*
|
||||
*/
|
||||
const char *GetCommissionerId(void) const { return mCommissionerId; }
|
||||
|
||||
/**
|
||||
* This method sets the Commissioner ID value.
|
||||
*
|
||||
* @param[in] aCommissionerId A pointer to the Commissioner ID value.
|
||||
*
|
||||
*/
|
||||
void SetCommissionerId(const char *aCommissionerId) {
|
||||
size_t length = strnlen(aCommissionerId, sizeof(mCommissionerId));
|
||||
memcpy(mCommissionerId, aCommissionerId, length);
|
||||
}
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kMaxLength = 64,
|
||||
};
|
||||
|
||||
char mCommissionerId[kMaxLength];
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements Commissioner Session ID TLV generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class CommissionerSessionIdTlv: public Tlv
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
*
|
||||
*/
|
||||
void Init(void) { SetType(kCommissionerSessionId); SetLength(sizeof(*this) - sizeof(Tlv)); }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the TLV appears to be well-formed.
|
||||
*
|
||||
* @retval TRUE If the TLV appears to be well-formed.
|
||||
* @retval FALSE If the TLV does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const { return GetLength() == sizeof(*this) - sizeof(Tlv); }
|
||||
|
||||
/**
|
||||
* This method returns the Commissioner Session ID value.
|
||||
*
|
||||
* @returns The Commissioner Session ID value.
|
||||
*
|
||||
*/
|
||||
uint16_t GetCommissionerSessionId(void) const { return HostSwap16(mSessionId); }
|
||||
|
||||
/**
|
||||
* This method sets the Commissioner Session ID value.
|
||||
*
|
||||
* @param[in] aCommissionerSessionId The Commissioner Session ID value.
|
||||
*
|
||||
*/
|
||||
void SetCommissionerSessionId(uint16_t aSessionId) { mSessionId = HostSwap16(aSessionId); }
|
||||
|
||||
private:
|
||||
uint16_t mSessionId;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements Security Policy TLV generation and parsing.
|
||||
*
|
||||
@@ -669,16 +937,6 @@ OT_TOOL_PACKED_BEGIN
|
||||
class StateTlv: public Tlv
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* State TLV values.
|
||||
*/
|
||||
enum State
|
||||
{
|
||||
kReject = -1, ///< Reject
|
||||
kPending = 0, ///< Pending
|
||||
kAccept = 1, ///< Accept
|
||||
};
|
||||
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
*
|
||||
@@ -694,6 +952,17 @@ public:
|
||||
*/
|
||||
bool IsValid(void) const { return GetLength() == sizeof(*this) - sizeof(Tlv); }
|
||||
|
||||
/**
|
||||
* State values.
|
||||
*
|
||||
*/
|
||||
enum State
|
||||
{
|
||||
kReject = -1, ///< Reject
|
||||
kPending = 0, ///< Pending
|
||||
kAccept = 1, ///< Accept
|
||||
};
|
||||
|
||||
/**
|
||||
* This method returns the State value.
|
||||
*
|
||||
@@ -714,6 +983,135 @@ private:
|
||||
uint8_t mState;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements Joiner UDP Port TLV generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class JoinerUdpPortTlv: public Tlv
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
*
|
||||
*/
|
||||
void Init(void) { SetType(kJoinerUdpPort); SetLength(sizeof(*this) - sizeof(Tlv)); }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the TLV appears to be well-formed.
|
||||
*
|
||||
* @retval TRUE If the TLV appears to be well-formed.
|
||||
* @retval FALSE If the TLV does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const { return GetLength() == sizeof(*this) - sizeof(Tlv); }
|
||||
|
||||
/**
|
||||
* This method returns the UDP Port value.
|
||||
*
|
||||
* @returns The UDP Port value.
|
||||
*
|
||||
*/
|
||||
uint16_t GetUdpPort(void) const { return HostSwap16(mUdpPort); }
|
||||
|
||||
/**
|
||||
* This method sets the UDP Port value.
|
||||
*
|
||||
* @param[in] aUdpPort The UDP Port value.
|
||||
*
|
||||
*/
|
||||
void SetUdpPort(uint16_t aUdpPort) { mUdpPort = HostSwap16(aUdpPort); }
|
||||
|
||||
private:
|
||||
uint16_t mUdpPort;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements Joiner IID TLV generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class JoinerIidTlv: public Tlv
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
*
|
||||
*/
|
||||
void Init() { SetType(kJoinerIid); SetLength(sizeof(*this) - sizeof(Tlv)); }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the TLV appears to be well-formed.
|
||||
*
|
||||
* @retval TRUE If the TLV appears to be well-formed.
|
||||
* @retval FALSE If the TLV does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid() const { return GetLength() == sizeof(*this) - sizeof(Tlv); }
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the Joiner IID.
|
||||
*
|
||||
* @returns A pointer to the Joiner IID.
|
||||
*
|
||||
*/
|
||||
const uint8_t *GetIid() const { return mIid; }
|
||||
|
||||
/**
|
||||
* This method sets the Joiner IID.
|
||||
*
|
||||
* @param[in] aIid A pointer to the Joiner IID.
|
||||
*
|
||||
*/
|
||||
void SetIid(const uint8_t *aIid) { memcpy(mIid, aIid, sizeof(mIid)); }
|
||||
|
||||
private:
|
||||
uint8_t mIid[8];
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements Joiner Router KEK TLV generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class JoinerRouterKekTlv: public Tlv
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
*
|
||||
*/
|
||||
void Init() { SetType(kJoinerRouterKek); SetLength(sizeof(*this) - sizeof(Tlv)); }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the TLV appears to be well-formed.
|
||||
*
|
||||
* @retval TRUE If the TLV appears to be well-formed.
|
||||
* @retval FALSE If the TLV does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid() const { return GetLength() == sizeof(*this) - sizeof(Tlv); }
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the Joiner Router KEK.
|
||||
*
|
||||
* @returns A pointer to the Joiner Router KEK.
|
||||
*
|
||||
*/
|
||||
const uint8_t *GetKek() const { return mKek; }
|
||||
|
||||
/**
|
||||
* This method sets the Joiner Router KEK.
|
||||
*
|
||||
* @param[in] aIid A pointer to the Joiner Router KEK.
|
||||
*
|
||||
*/
|
||||
void SetKek(const uint8_t *aKek) { memcpy(mKek, aKek, sizeof(mKek)); }
|
||||
|
||||
private:
|
||||
uint8_t mKek[16];
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements Pending Timestamp TLV generation and parsing.
|
||||
*
|
||||
|
||||
@@ -460,6 +460,70 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
ThreadError Leader::SetCommissioningData(const uint8_t *aValue, uint8_t aValueLength)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
uint8_t remaining = kMaxSize - mLength;
|
||||
CommissioningDataTlv *commissioningDataTlv;
|
||||
|
||||
VerifyOrExit(sizeof(NetworkDataTlv) + aValueLength < remaining, error = kThreadError_NoBufs);
|
||||
|
||||
RemoveCommissioningData();
|
||||
|
||||
if (aValueLength > 0)
|
||||
{
|
||||
commissioningDataTlv = reinterpret_cast<CommissioningDataTlv *>(mTlvs + mLength);
|
||||
Insert(reinterpret_cast<uint8_t *>(commissioningDataTlv), sizeof(CommissioningDataTlv) + aValueLength);
|
||||
commissioningDataTlv->Init();
|
||||
commissioningDataTlv->SetLength(aValueLength);
|
||||
memcpy(commissioningDataTlv->GetValue(), aValue, aValueLength);
|
||||
}
|
||||
|
||||
mVersion++;
|
||||
mNetif.SetStateChangedFlags(OT_THREAD_NETDATA_UPDATED);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
uint8_t *Leader::GetCommissioningData(uint8_t &aLength)
|
||||
{
|
||||
uint8_t *rval = NULL;
|
||||
|
||||
for (NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(mTlvs);
|
||||
cur < reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength);
|
||||
cur = cur->GetNext())
|
||||
{
|
||||
if (cur->GetType() == NetworkDataTlv::kTypeCommissioningData)
|
||||
{
|
||||
aLength = cur->GetLength();
|
||||
ExitNow(rval = cur->GetValue());
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
ThreadError Leader::RemoveCommissioningData(void)
|
||||
{
|
||||
ThreadError error = kThreadError_NotFound;
|
||||
|
||||
for (NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(mTlvs);
|
||||
cur < reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength);
|
||||
cur = cur->GetNext())
|
||||
{
|
||||
if (cur->GetType() == NetworkDataTlv::kTypeCommissioningData)
|
||||
{
|
||||
Remove(reinterpret_cast<uint8_t *>(cur), sizeof(NetworkDataTlv) + cur->GetLength());
|
||||
ExitNow(error = kThreadError_None);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Leader::HandleServerData(void *aContext, Coap::Header &aHeader, Message &aMessage,
|
||||
const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
|
||||
@@ -219,6 +219,28 @@ public:
|
||||
*/
|
||||
ThreadError SendServerDataNotification(uint16_t aRloc16);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the Commissioning Data.
|
||||
*
|
||||
* @param[out] aLength The length of the Commissioning Data in bytes.
|
||||
*
|
||||
* @returns A pointer to the Commissioning Data or NULL if no Commissioning Data exists.
|
||||
*
|
||||
*/
|
||||
uint8_t *GetCommissioningData(uint8_t &aLength);
|
||||
|
||||
/**
|
||||
* This method adds Commissioning Data to the Thread Network Data.
|
||||
*
|
||||
* @param[in] aValue A pointer to the Commissioning Data value.
|
||||
* @param[in] aValueLength The length of @p aValue.
|
||||
*
|
||||
* @retval kThreadError_None Successfully added the Commissioning Data.
|
||||
* @retval kThreadError_NoBufs Insufficient space to add the Commissioning Data.
|
||||
*
|
||||
*/
|
||||
ThreadError SetCommissioningData(const uint8_t *aValue, uint8_t aValueLength);
|
||||
|
||||
private:
|
||||
static void HandleServerData(void *aContext, Coap::Header &aHeader, Message &aMessage,
|
||||
const Ip6::MessageInfo &aMessageInfo);
|
||||
@@ -245,6 +267,8 @@ private:
|
||||
ThreadError RemoveContext(uint8_t aContextId);
|
||||
ThreadError RemoveContext(PrefixTlv &aPrefix, uint8_t aContextId);
|
||||
|
||||
ThreadError RemoveCommissioningData(void);
|
||||
|
||||
ThreadError RemoveRloc(uint16_t aRloc16);
|
||||
ThreadError RemoveRloc(PrefixTlv &aPrefix, uint16_t aRloc16);
|
||||
ThreadError RemoveRloc(PrefixTlv &aPrefix, HasRouteTlv &aHasRoute, uint16_t aRloc16);
|
||||
|
||||
@@ -662,6 +662,21 @@ private:
|
||||
uint8_t mContextLength;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class implements Commissioning Data TLV generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class CommissioningDataTlv: public NetworkDataTlv
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
*
|
||||
*/
|
||||
void Init() { NetworkDataTlv::Init(); SetType(kTypeCommissioningData); SetLength(0); }
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
||||
@@ -66,7 +66,18 @@ ThreadNetif::ThreadNetif(Ip6::Ip6 &aIp6):
|
||||
mMeshForwarder(*this),
|
||||
mMleRouter(*this),
|
||||
mNetworkDataLocal(*this),
|
||||
mNetworkDataLeader(*this)
|
||||
mNetworkDataLeader(*this),
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
mCommissioner(*this),
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER
|
||||
#if OPENTHREAD_ENABLE_DTLS
|
||||
mDtls(*this),
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
mJoiner(*this),
|
||||
#endif // OPENTHREAD_ENABLE_JOINER
|
||||
mJoinerRouter(*this),
|
||||
mLeader(*this)
|
||||
{
|
||||
mKeyManager.SetMasterKey(kThreadMasterKey, sizeof(kThreadMasterKey));
|
||||
}
|
||||
|
||||
@@ -34,8 +34,12 @@
|
||||
#ifndef THREAD_NETIF_HPP_
|
||||
#define THREAD_NETIF_HPP_
|
||||
|
||||
#include <openthread-config.h>
|
||||
#include <openthread-types.h>
|
||||
|
||||
#include <mac/mac.hpp>
|
||||
#include <meshcop/joiner_router.hpp>
|
||||
#include <meshcop/leader.hpp>
|
||||
#include <net/ip6_filter.hpp>
|
||||
#include <net/netif.hpp>
|
||||
#include <thread/address_resolver.hpp>
|
||||
@@ -46,6 +50,18 @@
|
||||
#include <thread/mle_router.hpp>
|
||||
#include <thread/network_data_local.hpp>
|
||||
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
#include <meshcop/commissioner.hpp>
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER
|
||||
|
||||
#if OPENTHREAD_ENABLE_DTLS
|
||||
#include <meshcop/dtls.hpp>
|
||||
#endif // OPENTHREAD_ENABLE_DTLS
|
||||
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
#include <meshcop/joiner.hpp>
|
||||
#endif // OPENTHREAD_ENABLE_JOINER
|
||||
|
||||
namespace Thread {
|
||||
|
||||
/**
|
||||
@@ -212,6 +228,20 @@ public:
|
||||
|
||||
MeshCoP::PendingDataset &GetPendingDataset(void) { return mPendingDataset; }
|
||||
|
||||
MeshCoP::JoinerRouter &GetJoinerRouter(void) { return mJoinerRouter; }
|
||||
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
MeshCoP::Commissioner &GetCommissioner(void) { return mCommissioner; }
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER
|
||||
|
||||
#if OPENTHREAD_ENABLE_DTLS
|
||||
MeshCoP::Dtls &GetDtls(void) { return mDtls; }
|
||||
#endif // OPENTHREAD_ENABLE_DTLS
|
||||
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
MeshCoP::Joiner &GetJoiner(void) { return mJoiner; }
|
||||
#endif // OPENTHREAD_ENABLE_JOINER
|
||||
|
||||
private:
|
||||
Coap::Server mCoapServer;
|
||||
AddressResolver mAddressResolver;
|
||||
@@ -226,6 +256,21 @@ private:
|
||||
NetworkData::Local mNetworkDataLocal;
|
||||
NetworkData::Leader mNetworkDataLeader;
|
||||
bool mIsUp;
|
||||
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
MeshCoP::Commissioner mCommissioner;
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER
|
||||
|
||||
#if OPENTHREAD_ENABLE_DTLS
|
||||
MeshCoP::Dtls mDtls;
|
||||
#endif// OPENTHREAD_ENABLE_DTLS
|
||||
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
MeshCoP::Joiner mJoiner;
|
||||
#endif // OPENTHREAD_ENABLE_JOINER
|
||||
|
||||
MeshCoP::JoinerRouter mJoinerRouter;
|
||||
MeshCoP::Leader mLeader;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -114,6 +114,54 @@ namespace Thread {
|
||||
*/
|
||||
#define OPENTHREAD_URI_SERVER_DATA "a/sd"
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_URI_RELAY_RX
|
||||
*
|
||||
* The URI Path for Relay RX.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_URI_RELAY_RX "c/rx"
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_URI_RELAY_TX
|
||||
*
|
||||
* The URI Path for Relay TX.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_URI_RELAY_TX "c/tx"
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_URI_JOINER_FINALIZE
|
||||
*
|
||||
* The URI Path for Joiner Finalize
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_URI_JOINER_FINALIZE "c/jf"
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_URI_JOINER_ENTRUST
|
||||
*
|
||||
* The URI Path for Joiner Entrust
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_URI_JOINER_ENTRUST "c/je"
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_URI_LEADER_PETITION
|
||||
*
|
||||
* The URI Path for Leader Petition
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_URI_LEADER_PETITION "c/lp"
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_URI_LEADER_KEEP_ALIVE
|
||||
*
|
||||
* The URI Path for Leader Keep Alive
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_URI_LEADER_KEEP_ALIVE "c/la"
|
||||
|
||||
} // namespace Thread
|
||||
|
||||
#endif // THREAD_URIS_HPP_
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <common/code_utils.hpp>
|
||||
#include <ncp/ncp.h>
|
||||
#include <ncp/ncp_base.hpp>
|
||||
#include <net/ip6.hpp>
|
||||
#include <openthread.h>
|
||||
#include <openthread-diag.h>
|
||||
#include <stdarg.h>
|
||||
@@ -44,9 +45,7 @@
|
||||
namespace Thread
|
||||
{
|
||||
|
||||
extern ThreadNetif *sThreadNetif;
|
||||
extern Ip6::Ip6 *sIp6;
|
||||
|
||||
static NcpBase *sNcpContext = NULL;
|
||||
|
||||
#define NCP_PLAT_RESET_REASON (1U<<31)
|
||||
@@ -427,7 +426,6 @@ NcpBase::NcpBase():
|
||||
mDroppedOutboundIpFrameCounter = 0;
|
||||
mDroppedInboundIpFrameCounter = 0;
|
||||
|
||||
assert(sThreadNetif != NULL);
|
||||
otSetStateChangedCallback(&HandleNetifStateChanged, this);
|
||||
otSetReceiveIp6DatagramCallback(&HandleDatagramFromStack, this);
|
||||
otSetIcmpEchoEnabled(false);
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include <openthread-types.h>
|
||||
#include <openthread-config.h>
|
||||
#include <common/message.hpp>
|
||||
#include <thread/thread_netif.hpp>
|
||||
#include <common/tasklet.hpp>
|
||||
|
||||
#include "spinel.h"
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <ncp/ncp.h>
|
||||
#include <common/code_utils.hpp>
|
||||
#include <common/new.hpp>
|
||||
#include <net/ip6.hpp>
|
||||
#include <ncp/ncp.h>
|
||||
#include <ncp/ncp_uart.hpp>
|
||||
#include <platform/uart.h>
|
||||
|
||||
Vendored
+26
@@ -27,6 +27,10 @@ lib_LIBRARIES = libmbedcrypto.a
|
||||
override CFLAGS := $(filter-out -Wconversion,$(CFLAGS))
|
||||
override CXXFLAGS := $(filter-out -Wconversion,$(CXXFLAGS))
|
||||
|
||||
# Do not enable -pedantic-errors for mbedtls
|
||||
override CFLAGS := $(filter-out -pedantic-errors,$(CFLAGS))
|
||||
override CXXFLAGS := $(filter-out -pedantic-errors,$(CXXFLAGS))
|
||||
|
||||
MBEDTLS_SRCDIR = $(top_srcdir)/third_party/mbedtls/repo
|
||||
|
||||
libmbedcrypto_a_CPPFLAGS = \
|
||||
@@ -46,6 +50,28 @@ libmbedcrypto_a_SOURCES = \
|
||||
repo/library/sha256.c \
|
||||
$(NULL)
|
||||
|
||||
if OPENTHREAD_ENABLE_DTLS
|
||||
libmbedcrypto_a_SOURCES += \
|
||||
repo/library/bignum.c \
|
||||
repo/library/ccm.c \
|
||||
repo/library/cipher.c \
|
||||
repo/library/cipher_wrap.c \
|
||||
repo/library/ctr_drbg.c \
|
||||
repo/library/debug.c \
|
||||
repo/library/ecjpake.c \
|
||||
repo/library/ecp.c \
|
||||
repo/library/ecp_curves.c \
|
||||
repo/library/entropy.c \
|
||||
repo/library/entropy_poll.c \
|
||||
repo/library/ssl_cookie.c \
|
||||
repo/library/ssl_ciphersuites.c \
|
||||
repo/library/ssl_cli.c \
|
||||
repo/library/ssl_srv.c \
|
||||
repo/library/ssl_ticket.c \
|
||||
repo/library/ssl_tls.c \
|
||||
$(NULL)
|
||||
endif # OPENTHREAD_ENABLE_DTLS
|
||||
|
||||
if OPENTHREAD_BUILD_COVERAGE
|
||||
CLEANFILES = $(wildcard *.gcda *.gcno)
|
||||
endif # OPENTHREAD_BUILD_COVERAGE
|
||||
|
||||
Vendored
+34
-34
@@ -422,7 +422,7 @@
|
||||
*/
|
||||
//#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
|
||||
//#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
|
||||
//#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
//#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
|
||||
//#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
|
||||
//#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
|
||||
@@ -442,7 +442,7 @@
|
||||
*
|
||||
* Comment this macro to disable NIST curves optimisation.
|
||||
*/
|
||||
//#define MBEDTLS_ECP_NIST_OPTIM
|
||||
#define MBEDTLS_ECP_NIST_OPTIM
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ECDSA_DETERMINISTIC
|
||||
@@ -717,7 +717,7 @@
|
||||
* enabled as well):
|
||||
* MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
|
||||
*/
|
||||
//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
|
||||
#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PK_PARSE_EC_EXTENDED
|
||||
@@ -933,7 +933,7 @@
|
||||
* a timing side-channel.
|
||||
*
|
||||
*/
|
||||
//#define MBEDTLS_SSL_DEBUG_ALL
|
||||
#define MBEDTLS_SSL_DEBUG_ALL
|
||||
|
||||
/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC
|
||||
*
|
||||
@@ -1052,7 +1052,7 @@
|
||||
*
|
||||
* Comment this macro to disable support for the max_fragment_length extension
|
||||
*/
|
||||
//#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
|
||||
#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SSL_PROTO_SSL3
|
||||
@@ -1100,7 +1100,7 @@
|
||||
*
|
||||
* Comment this macro to disable support for TLS 1.2 / DTLS 1.2
|
||||
*/
|
||||
//#define MBEDTLS_SSL_PROTO_TLS1_2
|
||||
#define MBEDTLS_SSL_PROTO_TLS1_2
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SSL_PROTO_DTLS
|
||||
@@ -1115,7 +1115,7 @@
|
||||
*
|
||||
* Comment this macro to disable support for DTLS
|
||||
*/
|
||||
//#define MBEDTLS_SSL_PROTO_DTLS
|
||||
#define MBEDTLS_SSL_PROTO_DTLS
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SSL_ALPN
|
||||
@@ -1139,7 +1139,7 @@
|
||||
*
|
||||
* Comment this to disable anti-replay in DTLS.
|
||||
*/
|
||||
//#define MBEDTLS_SSL_DTLS_ANTI_REPLAY
|
||||
#define MBEDTLS_SSL_DTLS_ANTI_REPLAY
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SSL_DTLS_HELLO_VERIFY
|
||||
@@ -1157,7 +1157,7 @@
|
||||
*
|
||||
* Comment this to disable support for HelloVerifyRequest.
|
||||
*/
|
||||
//#define MBEDTLS_SSL_DTLS_HELLO_VERIFY
|
||||
#define MBEDTLS_SSL_DTLS_HELLO_VERIFY
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
|
||||
@@ -1208,7 +1208,7 @@
|
||||
*
|
||||
* Comment this macro to disable support for key export
|
||||
*/
|
||||
//#define MBEDTLS_SSL_EXPORT_KEYS
|
||||
#define MBEDTLS_SSL_EXPORT_KEYS
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SSL_SERVER_NAME_INDICATION
|
||||
@@ -1478,7 +1478,7 @@
|
||||
* library/pkcs5.c
|
||||
* library/pkparse.c
|
||||
*/
|
||||
//#define MBEDTLS_ASN1_PARSE_C
|
||||
#define MBEDTLS_ASN1_PARSE_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ASN1_WRITE_C
|
||||
@@ -1492,7 +1492,7 @@
|
||||
* library/x509write_crt.c
|
||||
* library/mbedtls_x509write_csr.c
|
||||
*/
|
||||
//#define MBEDTLS_ASN1_WRITE_C
|
||||
#define MBEDTLS_ASN1_WRITE_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_BASE64_C
|
||||
@@ -1520,7 +1520,7 @@
|
||||
*
|
||||
* This module is required for RSA, DHM and ECC (ECDH, ECDSA) support.
|
||||
*/
|
||||
//#define MBEDTLS_BIGNUM_C
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_BLOWFISH_C
|
||||
@@ -1598,7 +1598,7 @@
|
||||
* This module enables the AES-CCM ciphersuites, if other requisites are
|
||||
* enabled as well.
|
||||
*/
|
||||
//#define MBEDTLS_CCM_C
|
||||
#define MBEDTLS_CCM_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_CERTS_C
|
||||
@@ -1636,7 +1636,7 @@
|
||||
*
|
||||
* This module provides the CTR_DRBG AES-256 random number generator.
|
||||
*/
|
||||
//#define MBEDTLS_CTR_DRBG_C
|
||||
#define MBEDTLS_CTR_DRBG_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_DEBUG_C
|
||||
@@ -1650,7 +1650,7 @@
|
||||
*
|
||||
* This module provides debugging functions.
|
||||
*/
|
||||
//#define MBEDTLS_DEBUG_C
|
||||
#define MBEDTLS_DEBUG_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_DES_C
|
||||
@@ -1740,7 +1740,7 @@
|
||||
*
|
||||
* Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C
|
||||
*/
|
||||
//#define MBEDTLS_ECJPAKE_C
|
||||
#define MBEDTLS_ECJPAKE_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ECP_C
|
||||
@@ -1754,7 +1754,7 @@
|
||||
*
|
||||
* Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED
|
||||
*/
|
||||
//#define MBEDTLS_ECP_C
|
||||
#define MBEDTLS_ECP_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ENTROPY_C
|
||||
@@ -1768,7 +1768,7 @@
|
||||
*
|
||||
* This module provides a generic entropy pool
|
||||
*/
|
||||
//#define MBEDTLS_ENTROPY_C
|
||||
#define MBEDTLS_ENTROPY_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ERROR_C
|
||||
@@ -1831,7 +1831,7 @@
|
||||
*
|
||||
* Uncomment to enable the HMAC_DRBG random number geerator.
|
||||
*/
|
||||
//#define MBEDTLS_HMAC_DRBG_C
|
||||
#define MBEDTLS_HMAC_DRBG_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_MD_C
|
||||
@@ -1940,7 +1940,7 @@
|
||||
*
|
||||
* This modules translates between OIDs and internal values.
|
||||
*/
|
||||
//#define MBEDTLS_OID_C
|
||||
#define MBEDTLS_OID_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PADLOCK_C
|
||||
@@ -2004,7 +2004,7 @@
|
||||
*
|
||||
* Uncomment to enable generic public key wrappers.
|
||||
*/
|
||||
//#define MBEDTLS_PK_C
|
||||
#define MBEDTLS_PK_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PK_PARSE_C
|
||||
@@ -2019,7 +2019,7 @@
|
||||
*
|
||||
* Uncomment to enable generic public key parse functions.
|
||||
*/
|
||||
//#define MBEDTLS_PK_PARSE_C
|
||||
#define MBEDTLS_PK_PARSE_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PK_WRITE_C
|
||||
@@ -2196,7 +2196,7 @@
|
||||
* Module: library/ssl_cookie.c
|
||||
* Caller:
|
||||
*/
|
||||
//#define MBEDTLS_SSL_COOKIE_C
|
||||
#define MBEDTLS_SSL_COOKIE_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SSL_TICKET_C
|
||||
@@ -2222,7 +2222,7 @@
|
||||
*
|
||||
* This module is required for SSL/TLS client support.
|
||||
*/
|
||||
//#define MBEDTLS_SSL_CLI_C
|
||||
#define MBEDTLS_SSL_CLI_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SSL_SRV_C
|
||||
@@ -2236,7 +2236,7 @@
|
||||
*
|
||||
* This module is required for SSL/TLS server support.
|
||||
*/
|
||||
//#define MBEDTLS_SSL_SRV_C
|
||||
#define MBEDTLS_SSL_SRV_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SSL_TLS_C
|
||||
@@ -2252,7 +2252,7 @@
|
||||
*
|
||||
* This module is required for SSL/TLS.
|
||||
*/
|
||||
//#define MBEDTLS_SSL_TLS_C
|
||||
#define MBEDTLS_SSL_TLS_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_THREADING_C
|
||||
@@ -2438,8 +2438,8 @@
|
||||
*/
|
||||
|
||||
/* MPI / BIGNUM options */
|
||||
//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */
|
||||
//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */
|
||||
#define MBEDTLS_MPI_WINDOW_SIZE 1 /**< Maximum windows size used. */
|
||||
#define MBEDTLS_MPI_MAX_SIZE 32 /**< Maximum number of bytes for usable MPIs. */
|
||||
|
||||
/* CTR_DRBG options */
|
||||
//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */
|
||||
@@ -2455,9 +2455,9 @@
|
||||
//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
|
||||
|
||||
/* ECP options */
|
||||
//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */
|
||||
//#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */
|
||||
//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */
|
||||
#define MBEDTLS_ECP_MAX_BITS 256 /**< Maximum bit size of groups */
|
||||
#define MBEDTLS_ECP_WINDOW_SIZE 2 /**< Maximum window size used */
|
||||
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0 /**< Enable fixed-point speed-up */
|
||||
|
||||
/* Entropy options */
|
||||
//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */
|
||||
@@ -2496,7 +2496,7 @@
|
||||
//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */
|
||||
|
||||
/* SSL options */
|
||||
//#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */
|
||||
#define MBEDTLS_SSL_MAX_CONTENT_LEN 768 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */
|
||||
//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */
|
||||
//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
|
||||
//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
|
||||
@@ -2513,7 +2513,7 @@
|
||||
*
|
||||
* The value below is only an example, not the default.
|
||||
*/
|
||||
//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||
#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
|
||||
|
||||
/* X509 options */
|
||||
//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */
|
||||
|
||||
Reference in New Issue
Block a user