Thread Commissioning. (#399)

This commit is contained in:
Jonathan Hui
2016-09-08 10:23:11 -07:00
committed by GitHub
parent 4f610ef082
commit 7c2b818d2e
46 changed files with 3987 additions and 130 deletions
+83
View File
@@ -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}
+3
View File
@@ -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)
+41
View File
@@ -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
+70
View File
@@ -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_
+70
View File
@@ -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_
+9 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+1 -1
View File
@@ -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)
{
+27
View File
@@ -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 \
+10
View File
@@ -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;
+18
View File
@@ -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.
*
+6 -3
View File
@@ -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
};
/**
+57
View File
@@ -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
+98
View File
@@ -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
View File
@@ -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)
+13
View File
@@ -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;
+10
View File
@@ -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.
*
+489
View File
@@ -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
+131
View File
@@ -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_
+380
View File
@@ -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
+204
View File
@@ -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_
+294
View File
@@ -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
+115
View File
@@ -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_
+411
View File
@@ -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
+89
View File
@@ -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_
+239
View File
@@ -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
+107
View File
@@ -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_
+10
View File
@@ -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
*
+26
View File
@@ -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
+21
View File
@@ -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
+33 -4
View File
@@ -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;
};
+4 -1
View File
@@ -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());
+66
View File
@@ -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
+424 -26
View File
@@ -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.
*
+64
View File
@@ -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)
{
+24
View File
@@ -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);
+15
View File
@@ -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;
/**
* @}
*
+12 -1
View File
@@ -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));
}
+45
View File
@@ -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;
};
/**
+48
View File
@@ -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_
+1 -3
View File
@@ -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);
+1 -1
View File
@@ -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"
+1
View File
@@ -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>
+26
View File
@@ -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
+34 -34
View File
@@ -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. */