mirror of
https://github.com/espressif/openthread.git
synced 2026-09-17 22:50:07 +00:00
Secure CoAP Client and Server (#949)
* Secure CoAP client && server implemntation. * Joiner && Commissioner refactoring to support secure CoAP.
This commit is contained in:
committed by
Jonathan Hui
parent
2bc79217d2
commit
49144266e4
@@ -54,9 +54,12 @@
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\core\coap\coap_base.cpp" />
|
||||
<ClCompile Include="..\..\src\core\coap\coap_client.cpp" />
|
||||
<ClCompile Include="..\..\src\core\coap\coap_header.cpp" />
|
||||
<ClCompile Include="..\..\src\core\coap\coap_server.cpp" />
|
||||
<ClCompile Include="..\..\src\core\coap\secure_coap_client.cpp" />
|
||||
<ClCompile Include="..\..\src\core\coap\secure_coap_server.cpp" />
|
||||
<ClCompile Include="..\..\src\core\common\crc16.cpp" />
|
||||
<ClCompile Include="..\..\src\core\common\logging.cpp" />
|
||||
<ClCompile Include="..\..\src\core\common\message.cpp" />
|
||||
@@ -116,9 +119,12 @@
|
||||
<ClCompile Include="..\..\src\core\utils\jam_detector.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\core\coap\coap_base.hpp" />
|
||||
<ClInclude Include="..\..\src\core\coap\coap_client.hpp" />
|
||||
<ClInclude Include="..\..\src\core\coap\coap_header.hpp" />
|
||||
<ClInclude Include="..\..\src\core\coap\coap_server.hpp" />
|
||||
<ClInclude Include="..\..\src\core\coap\secure_coap_client.hpp" />
|
||||
<ClInclude Include="..\..\src\core\coap\secure_coap_server.hpp" />
|
||||
<ClInclude Include="..\..\src\core\common\code_utils.hpp" />
|
||||
<ClInclude Include="..\..\src\core\common\crc16.hpp" />
|
||||
<ClInclude Include="..\..\src\core\common\debug.hpp" />
|
||||
|
||||
@@ -57,6 +57,9 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\core\coap\coap_base.cpp">
|
||||
<Filter>Source Files\coap</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\coap\coap_client.cpp">
|
||||
<Filter>Source Files\coap</Filter>
|
||||
</ClCompile>
|
||||
@@ -66,6 +69,12 @@
|
||||
<ClCompile Include="..\..\src\core\coap\coap_server.cpp">
|
||||
<Filter>Source Files\coap</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\coap\secure_coap_client.cpp">
|
||||
<Filter>Source Files\coap</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\coap\secure_coap_server.cpp">
|
||||
<Filter>Source Files\coap</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\common\logging.cpp">
|
||||
<Filter>Source Files\common</Filter>
|
||||
</ClCompile>
|
||||
@@ -245,6 +254,9 @@
|
||||
<ClInclude Include="..\..\src\core\openthread-core-config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\coap\coap_base.hpp">
|
||||
<Filter>Header Files\coap</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\coap\coap_client.hpp">
|
||||
<Filter>Header Files\coap</Filter>
|
||||
</ClInclude>
|
||||
@@ -254,6 +266,12 @@
|
||||
<ClInclude Include="..\..\src\core\coap\coap_server.hpp">
|
||||
<Filter>Header Files\coap</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\coap\secure_coap_client.hpp">
|
||||
<Filter>Header Files\coap</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\coap\secure_coap_server.hpp">
|
||||
<Filter>Header Files\coap</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\common\code_utils.hpp">
|
||||
<Filter>Header Files\common</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -64,9 +64,12 @@
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\core\coap\coap_base.cpp" />
|
||||
<ClCompile Include="..\..\src\core\coap\coap_client.cpp" />
|
||||
<ClCompile Include="..\..\src\core\coap\coap_header.cpp" />
|
||||
<ClCompile Include="..\..\src\core\coap\coap_server.cpp" />
|
||||
<ClCompile Include="..\..\src\core\coap\secure_coap_client.cpp" />
|
||||
<ClCompile Include="..\..\src\core\coap\secure_coap_server.cpp" />
|
||||
<ClCompile Include="..\..\src\core\common\crc16.cpp" />
|
||||
<ClCompile Include="..\..\src\core\common\logging.cpp" />
|
||||
<ClCompile Include="..\..\src\core\common\message.cpp" />
|
||||
@@ -129,9 +132,12 @@
|
||||
<ClInclude Include="..\..\include\openthread.h" />
|
||||
<ClInclude Include="..\..\include\openthread-types.h" />
|
||||
<ClInclude Include="..\..\include\openthread-windows-config.h" />
|
||||
<ClInclude Include="..\..\src\core\coap\coap_base.hpp" />
|
||||
<ClInclude Include="..\..\src\core\coap\coap_client.hpp" />
|
||||
<ClInclude Include="..\..\src\core\coap\coap_header.hpp" />
|
||||
<ClInclude Include="..\..\src\core\coap\coap_server.hpp" />
|
||||
<ClInclude Include="..\..\src\core\coap\secure_coap_client.hpp" />
|
||||
<ClInclude Include="..\..\src\core\coap\secure_coap_server.hpp" />
|
||||
<ClInclude Include="..\..\src\core\common\code_utils.hpp" />
|
||||
<ClInclude Include="..\..\src\core\common\crc16.hpp" />
|
||||
<ClInclude Include="..\..\src\core\common\debug.hpp" />
|
||||
|
||||
@@ -57,6 +57,9 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\core\coap\coap_base.cpp">
|
||||
<Filter>Source Files\coap</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\coap\coap_client.cpp">
|
||||
<Filter>Source Files\coap</Filter>
|
||||
</ClCompile>
|
||||
@@ -66,6 +69,12 @@
|
||||
<ClCompile Include="..\..\src\core\coap\coap_server.cpp">
|
||||
<Filter>Source Files\coap</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\coap\secure_coap_client.cpp">
|
||||
<Filter>Source Files\coap</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\coap\secure_coap_server.cpp">
|
||||
<Filter>Source Files\coap</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\common\logging.cpp">
|
||||
<Filter>Source Files\common</Filter>
|
||||
</ClCompile>
|
||||
@@ -233,6 +242,9 @@
|
||||
<ClInclude Include="..\..\src\core\openthread-core-config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\coap\coap_base.hpp">
|
||||
<Filter>Header Files\coap</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\coap\coap_client.hpp">
|
||||
<Filter>Header Files\coap</Filter>
|
||||
</ClInclude>
|
||||
@@ -242,6 +254,12 @@
|
||||
<ClInclude Include="..\..\src\core\coap\coap_server.hpp">
|
||||
<Filter>Header Files\coap</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\coap\secure_coap_client.hpp">
|
||||
<Filter>Header Files\coap</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\coap\secure_coap_server.hpp">
|
||||
<Filter>Header Files\coap</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\common\code_utils.hpp">
|
||||
<Filter>Header Files\common</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -37,6 +37,7 @@ libopenthread_a_CPPFLAGS = \
|
||||
|
||||
libopenthread_a_SOURCES = \
|
||||
openthread.cpp \
|
||||
coap/coap_base.cpp \
|
||||
coap/coap_client.cpp \
|
||||
coap/coap_header.cpp \
|
||||
coap/coap_server.cpp \
|
||||
@@ -92,6 +93,7 @@ libopenthread_a_SOURCES = \
|
||||
|
||||
if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
libopenthread_a_SOURCES += \
|
||||
coap/secure_coap_server.cpp \
|
||||
meshcop/announce_begin_client.cpp \
|
||||
meshcop/commissioner.cpp \
|
||||
meshcop/energy_scan_client.cpp \
|
||||
@@ -107,6 +109,7 @@ endif # OPENTHREAD_ENABLE_JOINER
|
||||
|
||||
if OPENTHREAD_ENABLE_DTLS
|
||||
libopenthread_a_SOURCES += \
|
||||
coap/secure_coap_client.cpp \
|
||||
meshcop/dtls.cpp \
|
||||
$(NULL)
|
||||
endif # OPENTHREAD_ENABLE_DTLS
|
||||
@@ -133,9 +136,12 @@ noinst_HEADERS = \
|
||||
openthread-core-config.h \
|
||||
openthread-core-default-config.h \
|
||||
openthread-instance.h \
|
||||
coap/coap_base.hpp \
|
||||
coap/coap_client.hpp \
|
||||
coap/coap_header.hpp \
|
||||
coap/coap_server.hpp \
|
||||
coap/secure_coap_client.hpp \
|
||||
coap/secure_coap_server.hpp \
|
||||
common/code_utils.hpp \
|
||||
common/crc16.hpp \
|
||||
common/debug.hpp \
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2016, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <common/code_utils.hpp>
|
||||
#include <coap/coap_base.hpp>
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file contains common code base for CoAP client and server.
|
||||
*/
|
||||
|
||||
namespace Thread {
|
||||
namespace Coap {
|
||||
|
||||
Message *CoapBase::NewMessage(const Header &aHeader)
|
||||
{
|
||||
Message *message = NULL;
|
||||
|
||||
// Ensure that header has minimum required length.
|
||||
VerifyOrExit(aHeader.GetLength() >= Header::kMinHeaderLength, ;);
|
||||
|
||||
VerifyOrExit((message = mSocket.NewMessage(aHeader.GetLength())) != NULL, ;);
|
||||
message->Prepend(aHeader.GetBytes(), aHeader.GetLength());
|
||||
message->SetOffset(0);
|
||||
|
||||
exit:
|
||||
return message;
|
||||
}
|
||||
|
||||
ThreadError CoapBase::Start(const Ip6::SockAddr &aSockAddr)
|
||||
{
|
||||
ThreadError error;
|
||||
|
||||
SuccessOrExit(error = mSocket.Open(&CoapBase::HandleUdpReceive, this));
|
||||
SuccessOrExit(error = mSocket.Bind(aSockAddr));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError CoapBase::Stop(void)
|
||||
{
|
||||
return mSocket.Close();
|
||||
}
|
||||
|
||||
void CoapBase::HandleUdpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo)
|
||||
{
|
||||
static_cast<CoapBase *>(aContext)->mReceiver(aContext, *static_cast<Message *>(aMessage),
|
||||
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
|
||||
}
|
||||
|
||||
} // namespace Coap
|
||||
} // namespace Thread
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2016, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COAP_BASE_HPP_
|
||||
#define COAP_BASE_HPP_
|
||||
|
||||
#include <openthread-types.h>
|
||||
#include <coap/coap_header.hpp>
|
||||
#include <common/message.hpp>
|
||||
#include <net/netif.hpp>
|
||||
#include <net/udp6.hpp>
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file contains common code base for CoAP client and server.
|
||||
*/
|
||||
|
||||
namespace Thread {
|
||||
namespace Coap {
|
||||
|
||||
/**
|
||||
* @addtogroup core-coap
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class implements a common code base for CoAP client/server.
|
||||
*
|
||||
*/
|
||||
class CoapBase
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* This function pointer is called when CoAP client/server wants to send a message.
|
||||
*
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
* @param[in] aMessage A reference to the message to send.
|
||||
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
|
||||
*
|
||||
*/
|
||||
typedef ThreadError(* SenderFunction)(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
/**
|
||||
* This function pointer is called when CoAP client/server receives a message.
|
||||
*
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
* @param[in] aMessage A reference to the received message.
|
||||
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
|
||||
*
|
||||
*/
|
||||
typedef void (* ReceiverFunction)(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
* @param[in] aUdp A reference to the UDP object.
|
||||
* @param[in] aSender A pointer to a function for sending messages.
|
||||
* @param[in] aReceiver A pointer to a function for handling received messages.
|
||||
*
|
||||
*/
|
||||
CoapBase(Ip6::Udp &aUdp, SenderFunction aSender, ReceiverFunction aReceiver):
|
||||
mSocket(aUdp),
|
||||
mSender(aSender),
|
||||
mReceiver(aReceiver) {};
|
||||
|
||||
/**
|
||||
* This method creates a new message with a CoAP header.
|
||||
*
|
||||
* @param[in] aHeader A reference to a CoAP header that is used to create the message.
|
||||
*
|
||||
* @returns A pointer to the message or NULL if failed to allocate message.
|
||||
*
|
||||
*/
|
||||
Message *NewMessage(const Header &aHeader);
|
||||
|
||||
/**
|
||||
* This method returns a port number used by CoAP client.
|
||||
*
|
||||
* @returns A port number.
|
||||
*
|
||||
*/
|
||||
uint16_t GetPort(void) { return mSocket.GetSockName().mPort; };
|
||||
|
||||
protected:
|
||||
ThreadError Start(const Ip6::SockAddr &aSockAddr);
|
||||
ThreadError Stop(void);
|
||||
|
||||
Ip6::UdpSocket mSocket;
|
||||
SenderFunction mSender;
|
||||
ReceiverFunction mReceiver;
|
||||
|
||||
private:
|
||||
static void HandleUdpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo);
|
||||
};
|
||||
|
||||
} // namespace Coap
|
||||
} // namespace Thread
|
||||
|
||||
#endif // COAP_BASE_HPP_
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <common/debug.hpp>
|
||||
#include <common/code_utils.hpp>
|
||||
#include <net/ip6.hpp>
|
||||
#include <net/udp6.hpp>
|
||||
#include <platform/random.h>
|
||||
|
||||
/**
|
||||
@@ -42,8 +43,8 @@
|
||||
namespace Thread {
|
||||
namespace Coap {
|
||||
|
||||
Client::Client(Ip6::Netif &aNetif):
|
||||
mSocket(aNetif.GetIp6().mUdp),
|
||||
Client::Client(Ip6::Netif &aNetif, SenderFunction aSender, ReceiverFunction aReceiver):
|
||||
CoapBase(aNetif.GetIp6().mUdp, aSender, aReceiver),
|
||||
mRetransmissionTimer(aNetif.GetIp6().mTimerScheduler, &Client::HandleRetransmissionTimer, this)
|
||||
{
|
||||
mMessageId = static_cast<uint16_t>(otPlatRandomGet());
|
||||
@@ -51,7 +52,10 @@ Client::Client(Ip6::Netif &aNetif):
|
||||
|
||||
ThreadError Client::Start()
|
||||
{
|
||||
return mSocket.Open(&Client::HandleUdpReceive, this);
|
||||
Ip6::SockAddr addr;
|
||||
addr.mPort = static_cast<Ip6::Udp *>(mSocket.mTransport)->GetEphemeralPort();
|
||||
|
||||
return CoapBase::Start(addr);
|
||||
}
|
||||
|
||||
ThreadError Client::Stop()
|
||||
@@ -70,22 +74,7 @@ ThreadError Client::Stop()
|
||||
FinalizeCoapTransaction(*messageToRemove, requestMetadata, NULL, NULL, kThreadError_Abort);
|
||||
}
|
||||
|
||||
return mSocket.Close();
|
||||
}
|
||||
|
||||
Message *Client::NewMessage(const Header &aHeader)
|
||||
{
|
||||
Message *message = NULL;
|
||||
|
||||
// Ensure that header has minimum required length.
|
||||
VerifyOrExit(aHeader.GetLength() >= Header::kMinHeaderLength, ;);
|
||||
|
||||
VerifyOrExit((message = mSocket.NewMessage(aHeader.GetLength())) != NULL, ;);
|
||||
message->Prepend(aHeader.GetBytes(), aHeader.GetLength());
|
||||
message->SetOffset(0);
|
||||
|
||||
exit:
|
||||
return message;
|
||||
return CoapBase::Stop();
|
||||
}
|
||||
|
||||
ThreadError Client::SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo,
|
||||
@@ -124,7 +113,7 @@ ThreadError Client::SendMessage(Message &aMessage, const Ip6::MessageInfo &aMess
|
||||
error = kThreadError_NoBufs);
|
||||
}
|
||||
|
||||
SuccessOrExit(error = mSocket.SendTo(aMessage, aMessageInfo));
|
||||
SuccessOrExit(error = mSender(this, aMessage, aMessageInfo));
|
||||
|
||||
exit:
|
||||
|
||||
@@ -206,7 +195,7 @@ ThreadError Client::SendCopy(const Message &aMessage, const Ip6::MessageInfo &aM
|
||||
error = kThreadError_NoBufs);
|
||||
|
||||
// Send the copy.
|
||||
SuccessOrExit(error = mSocket.SendTo(*messageCopy, aMessageInfo));
|
||||
SuccessOrExit(error = mSender(this, *messageCopy, aMessageInfo));
|
||||
|
||||
exit:
|
||||
|
||||
@@ -233,7 +222,7 @@ void Client::SendEmptyMessage(const Ip6::Address &aAddress, uint16_t aPort, uint
|
||||
messageInfo.SetPeerAddr(aAddress);
|
||||
messageInfo.SetPeerPort(aPort);
|
||||
|
||||
SuccessOrExit(error = mSocket.SendTo(*message, messageInfo));
|
||||
SuccessOrExit(error = mSender(this, *message, messageInfo));
|
||||
|
||||
exit:
|
||||
|
||||
@@ -364,13 +353,7 @@ void Client::FinalizeCoapTransaction(Message &aRequest, const RequestMetadata &a
|
||||
}
|
||||
}
|
||||
|
||||
void Client::HandleUdpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo)
|
||||
{
|
||||
static_cast<Client *>(aContext)->HandleUdpReceive(*static_cast<Message *>(aMessage),
|
||||
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
|
||||
}
|
||||
|
||||
void Client::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
void Client::ProcessReceivedMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
Header responseHeader;
|
||||
Header requestHeader;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include <openthread-types.h>
|
||||
#include <openthread-coap.h>
|
||||
#include <coap/coap_base.hpp>
|
||||
#include <coap/coap_header.hpp>
|
||||
#include <common/message.hpp>
|
||||
#include <common/timer.hpp>
|
||||
@@ -184,17 +185,19 @@ private:
|
||||
* This class implements CoAP client.
|
||||
*
|
||||
*/
|
||||
class Client
|
||||
class Client : public CoapBase
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
* @param[in] aNetif A reference to the network interface that CoAP client should be assigned to.
|
||||
* @param[in] aNetif A reference to the network interface that CoAP client should be assigned to.
|
||||
* @param[in] aSender A pointer to a function for sending messages.
|
||||
* @param[in] aReceiver A pointer to a function for handling received messages.
|
||||
*
|
||||
*/
|
||||
Client(Ip6::Netif &aNetif);
|
||||
Client(Ip6::Netif &aNetif, SenderFunction aSender = &Client::Send, ReceiverFunction aReceiver = &Client::Receive);
|
||||
|
||||
/**
|
||||
* This method starts the CoAP client.
|
||||
@@ -212,16 +215,6 @@ public:
|
||||
*/
|
||||
ThreadError Stop(void);
|
||||
|
||||
/**
|
||||
* This method creates a new message with a CoAP header.
|
||||
*
|
||||
* @param[in] aHeader A reference to a CoAP header that is used to create the message.
|
||||
*
|
||||
* @returns A pointer to the message or NULL if failed to allocate message.
|
||||
*
|
||||
*/
|
||||
Message *NewMessage(const Header &aHeader);
|
||||
|
||||
/**
|
||||
* This method sends a CoAP message.
|
||||
*
|
||||
@@ -249,6 +242,9 @@ public:
|
||||
*/
|
||||
const MessageQueue &GetRequestMessages(void) const { return mPendingRequests; }
|
||||
|
||||
protected:
|
||||
void ProcessReceivedMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
private:
|
||||
Message *CopyAndEnqueueMessage(const Message &aMessage, uint16_t aCopyLength,
|
||||
const RequestMetadata &aRequestMetadata);
|
||||
@@ -270,10 +266,14 @@ private:
|
||||
static void HandleRetransmissionTimer(void *aContext);
|
||||
void HandleRetransmissionTimer(void);
|
||||
|
||||
static void HandleUdpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo);
|
||||
void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
static ThreadError Send(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo) {
|
||||
return (static_cast<Client *>(aContext))->mSocket.SendTo(aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
static void Receive(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo) {
|
||||
(static_cast<Client *>(aContext))->ProcessReceivedMessage(aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
Ip6::UdpSocket mSocket;
|
||||
MessageQueue mPendingRequests;
|
||||
uint16_t mMessageId;
|
||||
Timer mRetransmissionTimer;
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
namespace Thread {
|
||||
namespace Coap {
|
||||
|
||||
Server::Server(Ip6::Udp &aUdp, uint16_t aPort):
|
||||
mSocket(aUdp)
|
||||
Server::Server(Ip6::Udp &aUdp, uint16_t aPort, SenderFunction aSender, ReceiverFunction aReceiver):
|
||||
CoapBase(aUdp, aSender, aReceiver)
|
||||
{
|
||||
mPort = aPort;
|
||||
mResources = NULL;
|
||||
@@ -46,20 +46,15 @@ Server::Server(Ip6::Udp &aUdp, uint16_t aPort):
|
||||
|
||||
ThreadError Server::Start()
|
||||
{
|
||||
ThreadError error;
|
||||
Ip6::SockAddr sockaddr;
|
||||
sockaddr.mPort = mPort;
|
||||
|
||||
SuccessOrExit(error = mSocket.Open(&Server::HandleUdpReceive, this));
|
||||
SuccessOrExit(error = mSocket.Bind(sockaddr));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
return CoapBase::Start(sockaddr);
|
||||
}
|
||||
|
||||
ThreadError Server::Stop()
|
||||
{
|
||||
return mSocket.Close();
|
||||
return CoapBase::Stop();
|
||||
}
|
||||
|
||||
ThreadError Server::AddResource(Resource &aResource)
|
||||
@@ -100,13 +95,17 @@ exit:
|
||||
aResource.mNext = NULL;
|
||||
}
|
||||
|
||||
void Server::HandleUdpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo)
|
||||
Message *Server::NewMessage(uint16_t aReserved)
|
||||
{
|
||||
static_cast<Server *>(aContext)->HandleUdpReceive(*static_cast<Message *>(aMessage),
|
||||
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
|
||||
return mSocket.NewMessage(aReserved);
|
||||
}
|
||||
|
||||
void Server::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
ThreadError Server::SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
return mSender(this, aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
void Server::ProcessReceivedMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
Header header;
|
||||
char uriPath[Resource::kMaxReceivedUriPath] = "";
|
||||
@@ -159,15 +158,5 @@ exit:
|
||||
{}
|
||||
}
|
||||
|
||||
Message *Server::NewMessage(uint16_t aReserved)
|
||||
{
|
||||
return mSocket.NewMessage(aReserved);
|
||||
}
|
||||
|
||||
ThreadError Server::SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
return mSocket.SendTo(aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
} // namespace Coap
|
||||
} // namespace Thread
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#ifndef COAP_SERVER_HPP_
|
||||
#define COAP_SERVER_HPP_
|
||||
|
||||
#include <coap/coap_base.hpp>
|
||||
#include <coap/coap_header.hpp>
|
||||
#include <common/message.hpp>
|
||||
#include <net/udp6.hpp>
|
||||
@@ -103,17 +104,20 @@ private:
|
||||
* This class implements the CoAP server.
|
||||
*
|
||||
*/
|
||||
class Server
|
||||
class Server : public CoapBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
* @param[in] aUdp A reference to the UDP object.
|
||||
* @param[in] aPort The port to listen on.
|
||||
* @param[in] aUdp A reference to the UDP object.
|
||||
* @param[in] aPort The port to listen on.
|
||||
* @param[in] aSender A pointer to a function for sending messages.
|
||||
* @param[in] aReceiver A pointer to a function for handling received messages.
|
||||
*
|
||||
*/
|
||||
Server(Ip6::Udp &aUdp, uint16_t aPort);
|
||||
Server(Ip6::Udp &aUdp, uint16_t aPort, SenderFunction aSender = &Server::Send,
|
||||
ReceiverFunction aReceiver = &Server::Receive);
|
||||
|
||||
/**
|
||||
* This method starts the CoAP server.
|
||||
@@ -160,6 +164,16 @@ public:
|
||||
*/
|
||||
Message *NewMessage(uint16_t aReserved);
|
||||
|
||||
/**
|
||||
* This method creates a new message with a CoAP header.
|
||||
*
|
||||
* @param[in] aHeader A reference to a CoAP header that is used to create the message.
|
||||
*
|
||||
* @returns A pointer to the message or NULL if failed to allocate message.
|
||||
*
|
||||
*/
|
||||
Message *NewMessage(const Header &aHeader) { return CoapBase::NewMessage(aHeader); };
|
||||
|
||||
/**
|
||||
* This method sends a CoAP response from the server.
|
||||
*
|
||||
@@ -172,11 +186,18 @@ public:
|
||||
*/
|
||||
ThreadError SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
protected:
|
||||
void ProcessReceivedMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
private:
|
||||
static void HandleUdpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo);
|
||||
void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
static ThreadError Send(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo) {
|
||||
return (static_cast<Server *>(aContext))->mSocket.SendTo(aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
static void Receive(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo) {
|
||||
(static_cast<Server *>(aContext))->ProcessReceivedMessage(aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
Ip6::UdpSocket mSocket;
|
||||
uint16_t mPort;
|
||||
Resource *mResources;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (c) 2016, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define WPP_NAME "secure_coap_client.tmh"
|
||||
|
||||
#include <coap/secure_coap_client.hpp>
|
||||
#include <common/logging.hpp>
|
||||
#include <meshcop/dtls.hpp>
|
||||
#include <thread/thread_netif.hpp>
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements the secure CoAP client.
|
||||
*/
|
||||
|
||||
namespace Thread {
|
||||
namespace Coap {
|
||||
|
||||
SecureClient::SecureClient(ThreadNetif &aNetif):
|
||||
Client(aNetif, &SecureClient::Send, &SecureClient::Receive),
|
||||
mConnectedCallback(NULL),
|
||||
mContext(NULL),
|
||||
mNetif(aNetif),
|
||||
mTransmitMessage(NULL),
|
||||
mTransmitTask(aNetif.GetIp6().mTaskletScheduler, &SecureClient::HandleUdpTransmit, this)
|
||||
{
|
||||
}
|
||||
|
||||
ThreadError SecureClient::Stop(void)
|
||||
{
|
||||
if (IsConnectionActive())
|
||||
{
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
if (mTransmitMessage != NULL)
|
||||
{
|
||||
mTransmitMessage->Free();
|
||||
mTransmitMessage = NULL;
|
||||
}
|
||||
|
||||
return Client::Stop();
|
||||
}
|
||||
|
||||
ThreadError SecureClient::Connect(const Ip6::MessageInfo &aMessageInfo, ConnectedCallback aCallback, void *aContext)
|
||||
{
|
||||
mPeerAddress = aMessageInfo;
|
||||
mConnectedCallback = aCallback;
|
||||
mContext = aContext;
|
||||
|
||||
return mNetif.GetDtls().Start(true, &SecureClient::HandleDtlsReceive, &SecureClient::HandleDtlsSend, this);
|
||||
}
|
||||
|
||||
bool SecureClient::IsConnectionActive(void)
|
||||
{
|
||||
return mNetif.GetDtls().IsStarted();
|
||||
};
|
||||
|
||||
bool SecureClient::IsConnected(void)
|
||||
{
|
||||
return mNetif.GetDtls().IsConnected();
|
||||
};
|
||||
|
||||
ThreadError SecureClient::Disconnect(void)
|
||||
{
|
||||
return mNetif.GetDtls().Stop();
|
||||
}
|
||||
|
||||
MeshCoP::Dtls &SecureClient::GetDtls(void)
|
||||
{
|
||||
return mNetif.GetDtls();
|
||||
};
|
||||
|
||||
ThreadError SecureClient::SendMessage(Message &aMessage, otCoapResponseHandler aHandler, void *aContext)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
otLogFuncEntry();
|
||||
|
||||
VerifyOrExit(IsConnected(), error = kThreadError_InvalidState);
|
||||
|
||||
error = Client::SendMessage(aMessage, mPeerAddress, aHandler, aContext);
|
||||
|
||||
exit:
|
||||
otLogFuncExitErr(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError SecureClient::Send(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
return static_cast<SecureClient *>(aContext)->Send(aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
ThreadError SecureClient::Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
(void)aMessageInfo;
|
||||
return mNetif.GetDtls().Send(aMessage, aMessage.GetLength());
|
||||
}
|
||||
|
||||
void SecureClient::Receive(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
return static_cast<SecureClient *>(aContext)->Receive(aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
void SecureClient::Receive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
otLogFuncEntry();
|
||||
|
||||
VerifyOrExit((mPeerAddress.GetPeerAddr() == aMessageInfo.GetPeerAddr()) &&
|
||||
(mPeerAddress.GetPeerPort() == aMessageInfo.GetPeerPort()), ;);
|
||||
|
||||
mNetif.GetDtls().Receive(aMessage, aMessage.GetOffset(), aMessage.GetLength() - aMessage.GetOffset());
|
||||
|
||||
if ((IsConnected()) && (mConnectedCallback != NULL))
|
||||
{
|
||||
mConnectedCallback(mContext);
|
||||
mConnectedCallback = NULL;
|
||||
mContext = NULL;
|
||||
}
|
||||
|
||||
exit:
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
void SecureClient::HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
return static_cast<SecureClient *>(aContext)->HandleDtlsReceive(aBuf, aLength);
|
||||
}
|
||||
|
||||
void SecureClient::HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
Message *message = NULL;
|
||||
|
||||
otLogFuncEntry();
|
||||
|
||||
VerifyOrExit((message = mNetif.GetIp6().mMessagePool.New(Message::kTypeIp6, 0)) != NULL, ;);
|
||||
SuccessOrExit(message->Append(aBuf, aLength));
|
||||
|
||||
ProcessReceivedMessage(*message, mPeerAddress);
|
||||
|
||||
exit:
|
||||
|
||||
if (message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
ThreadError SecureClient::HandleDtlsSend(void *aContext, const uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
return static_cast<SecureClient *>(aContext)->HandleDtlsSend(aBuf, aLength);
|
||||
}
|
||||
|
||||
ThreadError SecureClient::HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
otLogFuncEntry();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
otLogFuncExitErr(error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void SecureClient::HandleUdpTransmit(void *aContext)
|
||||
{
|
||||
return static_cast<SecureClient *>(aContext)->HandleUdpTransmit();
|
||||
}
|
||||
|
||||
void SecureClient::HandleUdpTransmit(void)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
otLogFuncEntry();
|
||||
|
||||
VerifyOrExit(mTransmitMessage != NULL, error = kThreadError_NoBufs);
|
||||
|
||||
SuccessOrExit(error = mSocket.SendTo(*mTransmitMessage, mPeerAddress));
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && mTransmitMessage != NULL)
|
||||
{
|
||||
mTransmitMessage->Free();
|
||||
}
|
||||
|
||||
mTransmitMessage = NULL;
|
||||
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
} // namespace Coap
|
||||
} // namespace Thread
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 2016, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SECURE_COAP_CLIENT_HPP_
|
||||
#define SECURE_COAP_CLIENT_HPP_
|
||||
|
||||
#include <coap/coap_client.hpp>
|
||||
#include <meshcop/dtls.hpp>
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes definitions for the secure CoAP client.
|
||||
*/
|
||||
|
||||
namespace Thread {
|
||||
|
||||
class ThreadNetif;
|
||||
|
||||
namespace Coap {
|
||||
|
||||
class SecureClient: public Client
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This function pointer is called once DTLS connection is established.
|
||||
*
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
*/
|
||||
typedef void (*ConnectedCallback)(void *aContext);
|
||||
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
* @param[in] aNetif A reference to the network interface that secure CoAP client should be assigned to.
|
||||
*
|
||||
*/
|
||||
SecureClient(ThreadNetif &aNetif);
|
||||
|
||||
/**
|
||||
* This method stops the secure CoAP client.
|
||||
*
|
||||
* @retval kThreadError_None Successfully stopped the secure CoAP client.
|
||||
*
|
||||
*/
|
||||
ThreadError Stop(void);
|
||||
|
||||
/**
|
||||
* This method initializes DTLS session with a peer.
|
||||
*
|
||||
* @param[in] aMessageInfo A reference to an address of the peer.
|
||||
* @param[in] aCallback A pointer to a function that will be called once DTLS connection is established.
|
||||
*
|
||||
* @retval kThreadError_None Successfully started DTLS connection.
|
||||
*
|
||||
*/
|
||||
ThreadError Connect(const Ip6::MessageInfo &aMessageInfo, ConnectedCallback aCallback, void *aContext);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the DTLS session is active.
|
||||
*
|
||||
* @retval TRUE If DTLS session is active.
|
||||
* @retval FALSE If DTLS session is not active.
|
||||
*
|
||||
*/
|
||||
bool IsConnectionActive(void);
|
||||
|
||||
/**
|
||||
* 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 stops the DTLS connection.
|
||||
*
|
||||
* @retval kThreadError_None Successfully stopped the DTLS connection.
|
||||
*
|
||||
*/
|
||||
ThreadError Disconnect(void);
|
||||
|
||||
/**
|
||||
* This method returns a reference to the DTLS object.
|
||||
*
|
||||
* @returns A reference to the DTLS object.
|
||||
*
|
||||
*/
|
||||
MeshCoP::Dtls &GetDtls(void);
|
||||
|
||||
/**
|
||||
* This method sends a CoAP message over secure DTLS connection.
|
||||
*
|
||||
* If a response for a request is expected, respective function and context information should be provided.
|
||||
* If no response is expected, these arguments should be NULL pointers.
|
||||
* If Message Id was not set in the header (equal to 0), this function will assign unique Message Id to the message.
|
||||
*
|
||||
* @param[in] aMessage A reference to the message to send.
|
||||
* @param[in] aHandler A function pointer that shall be called on response reception or time-out.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
* @retval kThreadError_None Successfully sent CoAP message.
|
||||
* @retval kThreadError_NoBufs Failed to allocate retransmission data.
|
||||
* @retvak kThreadError_InvalidState DTLS connection was not initialized.
|
||||
*
|
||||
*/
|
||||
ThreadError SendMessage(Message &aMessage, otCoapResponseHandler aHandler = NULL, void *aContext = NULL);
|
||||
|
||||
private:
|
||||
static ThreadError Send(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
ThreadError Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
static void Receive(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
void Receive(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);
|
||||
|
||||
Ip6::MessageInfo mPeerAddress;
|
||||
ConnectedCallback mConnectedCallback;
|
||||
void *mContext;
|
||||
ThreadNetif &mNetif;
|
||||
Message *mTransmitMessage;
|
||||
Tasklet mTransmitTask;
|
||||
};
|
||||
|
||||
} // namespace Coap
|
||||
} // namespace Thread
|
||||
|
||||
#endif // SECURE_COAP_CLIENT_HPP_
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (c) 2016, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define WPP_NAME "secure_coap_server.tmh"
|
||||
|
||||
#include <coap/secure_coap_server.hpp>
|
||||
#include <common/logging.hpp>
|
||||
#include <meshcop/dtls.hpp>
|
||||
#include <thread/thread_netif.hpp>
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements the secure CoAP server.
|
||||
*/
|
||||
|
||||
namespace Thread {
|
||||
namespace Coap {
|
||||
|
||||
SecureServer::SecureServer(ThreadNetif &aNetif, uint16_t aPort):
|
||||
Server(aNetif.GetIp6().mUdp, aPort, &SecureServer::Send, &SecureServer::Receive),
|
||||
mTransmitCallback(NULL),
|
||||
mContext(NULL),
|
||||
mNetif(aNetif),
|
||||
mTransmitMessage(NULL),
|
||||
mTransmitTask(aNetif.GetIp6().mTaskletScheduler, &SecureServer::HandleUdpTransmit, this)
|
||||
{
|
||||
}
|
||||
|
||||
ThreadError SecureServer::Start(TransportCallback aCallback, void *aContext)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
mTransmitCallback = aCallback;
|
||||
mContext = aContext;
|
||||
|
||||
// Passing mTransmitCallback means that we do not want to use socket
|
||||
// to transmit/receive messages, so do not open it in that case.
|
||||
if (mTransmitCallback == NULL)
|
||||
{
|
||||
error = Server::Start();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError SecureServer::Stop()
|
||||
{
|
||||
if (mNetif.GetDtls().IsStarted())
|
||||
{
|
||||
mNetif.GetDtls().Stop();
|
||||
}
|
||||
|
||||
if (mTransmitMessage != NULL)
|
||||
{
|
||||
mTransmitMessage->Free();
|
||||
mTransmitMessage = NULL;
|
||||
}
|
||||
|
||||
mTransmitCallback = NULL;
|
||||
mContext = NULL;
|
||||
|
||||
otLogFuncExit();
|
||||
|
||||
return Server::Stop();
|
||||
}
|
||||
|
||||
bool SecureServer::IsConnectionActive(void)
|
||||
{
|
||||
return mNetif.GetDtls().IsStarted();
|
||||
};
|
||||
|
||||
ThreadError SecureServer::Send(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
return static_cast<SecureServer *>(aContext)->Send(aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
ThreadError SecureServer::Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
(void)aMessageInfo;
|
||||
return mNetif.GetDtls().Send(aMessage, aMessage.GetLength());
|
||||
}
|
||||
|
||||
void SecureServer::Receive(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
return static_cast<SecureServer *>(aContext)->Receive(aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
void SecureServer::Receive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
otLogFuncEntry();
|
||||
|
||||
if (!mNetif.GetDtls().IsStarted())
|
||||
{
|
||||
mPeerAddress.SetPeerAddr(aMessageInfo.GetPeerAddr());
|
||||
mPeerAddress.SetPeerPort(aMessageInfo.GetPeerPort());
|
||||
|
||||
mNetif.GetDtls().Start(false, HandleDtlsReceive, HandleDtlsSend, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Once DTLS session is started, communicate only with a peer.
|
||||
VerifyOrExit((mPeerAddress.GetPeerAddr() == aMessageInfo.GetPeerAddr()) &&
|
||||
(mPeerAddress.GetPeerPort() == aMessageInfo.GetPeerPort()), ;);
|
||||
}
|
||||
|
||||
mNetif.GetDtls().SetClientId(mPeerAddress.GetPeerAddr().mFields.m8,
|
||||
sizeof(mPeerAddress.GetPeerAddr().mFields));
|
||||
mNetif.GetDtls().Receive(aMessage, aMessage.GetOffset(), aMessage.GetLength() - aMessage.GetOffset());
|
||||
|
||||
exit:
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
ThreadError SecureServer::SetPsk(const uint8_t *aPsk, uint8_t aPskLength)
|
||||
{
|
||||
return mNetif.GetDtls().SetPsk(aPsk, aPskLength);
|
||||
}
|
||||
|
||||
void SecureServer::HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
return static_cast<SecureServer *>(aContext)->HandleDtlsReceive(aBuf, aLength);
|
||||
}
|
||||
|
||||
void SecureServer::HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
Message *message;
|
||||
|
||||
otLogFuncEntry();
|
||||
|
||||
VerifyOrExit((message = mNetif.GetIp6().mMessagePool.New(Message::kTypeIp6, 0)) != NULL, ;);
|
||||
SuccessOrExit(message->Append(aBuf, aLength));
|
||||
|
||||
ProcessReceivedMessage(*message, mPeerAddress);
|
||||
|
||||
exit:
|
||||
|
||||
if (message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
ThreadError SecureServer::HandleDtlsSend(void *aContext, const uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
return static_cast<SecureServer *>(aContext)->HandleDtlsSend(aBuf, aLength);
|
||||
}
|
||||
|
||||
ThreadError SecureServer::HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
otLogFuncEntry();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
otLogFuncExitErr(error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void SecureServer::HandleUdpTransmit(void *aContext)
|
||||
{
|
||||
return static_cast<SecureServer *>(aContext)->HandleUdpTransmit();
|
||||
}
|
||||
|
||||
void SecureServer::HandleUdpTransmit(void)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
otLogFuncEntry();
|
||||
|
||||
VerifyOrExit(mTransmitMessage != NULL, error = kThreadError_NoBufs);
|
||||
|
||||
if (mTransmitCallback)
|
||||
{
|
||||
SuccessOrExit(error = mTransmitCallback(mContext, *mTransmitMessage, mPeerAddress));
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = mSocket.SendTo(*mTransmitMessage, mPeerAddress));
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && mTransmitMessage != NULL)
|
||||
{
|
||||
mTransmitMessage->Free();
|
||||
}
|
||||
|
||||
mTransmitMessage = NULL;
|
||||
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
} // namespace Coap
|
||||
} // namespace Thread
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 2016, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SECURE_COAP_SERVER_HPP_
|
||||
#define SECURE_COAP_SERVER_HPP_
|
||||
|
||||
#include "coap/coap_server.hpp"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes definitions for the secure CoAP server.
|
||||
*/
|
||||
|
||||
namespace Thread {
|
||||
|
||||
class ThreadNetif;
|
||||
|
||||
namespace Coap {
|
||||
|
||||
class SecureServer : public Server
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This function pointer is called when secure CoAP server want to send encrypted message.
|
||||
*
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
* @param[in] aMessage A reference to the message to send.
|
||||
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
|
||||
*
|
||||
*/
|
||||
typedef ThreadError(*TransportCallback)(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
* @param[in] aNetif A reference to the network interface that secure CoAP server should be assigned to.
|
||||
* @param[in] aPort The port to listen on.
|
||||
*
|
||||
*/
|
||||
SecureServer(ThreadNetif &aNetif, uint16_t aPort);
|
||||
|
||||
/**
|
||||
* This method starts the secure CoAP server.
|
||||
*
|
||||
* @param[in] aCallback A pointer to a function for sending messages. If NULL, the message is sent directly to server socket.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
* @retval kThreadError_None Successfully started the CoAP server.
|
||||
*
|
||||
*/
|
||||
ThreadError Start(TransportCallback aCallback = NULL, void *aContext = NULL);
|
||||
|
||||
/**
|
||||
* This method stops the secure CoAP server.
|
||||
*
|
||||
* @retval kThreadError_None Successfully stopped the CoAP server.
|
||||
*
|
||||
*/
|
||||
ThreadError Stop(void);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the DTLS session is active.
|
||||
*
|
||||
* @retval TRUE If DTLS session is active.
|
||||
* @retval FALSE If DTLS session is not active.
|
||||
*
|
||||
*/
|
||||
bool IsConnectionActive(void);
|
||||
|
||||
/**
|
||||
* This method is used to pass messages to the secure CoAP server.
|
||||
* It can be used when messages are received other way that via server's socket.
|
||||
*
|
||||
* @param[in] aMessage A reference to the received message.
|
||||
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
|
||||
*
|
||||
*/
|
||||
void Receive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
/**
|
||||
* This method sets the PSK.
|
||||
*
|
||||
* @param[in] aPSK A pointer to the PSK.
|
||||
* @param[in] aPskLenght A PSK length.
|
||||
*
|
||||
* @retval kThreadError_None Successfully set the PSK.
|
||||
* @retval kThreadError_InvalidArgs The PSK is invalid.
|
||||
*
|
||||
*/
|
||||
ThreadError SetPsk(const uint8_t *aPsk, uint8_t aPskLength);
|
||||
|
||||
private:
|
||||
static ThreadError Send(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
ThreadError Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
static void Receive(void *aContext, 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);
|
||||
|
||||
Ip6::MessageInfo mPeerAddress;
|
||||
TransportCallback mTransmitCallback;
|
||||
void *mContext;
|
||||
ThreadNetif &mNetif;
|
||||
Message *mTransmitMessage;
|
||||
Tasklet mTransmitTask;
|
||||
};
|
||||
|
||||
} // namespace Coap
|
||||
} // namespace Thread
|
||||
|
||||
#endif // SECURE_COAP_SERVER_HPP_
|
||||
+147
-203
@@ -65,17 +65,19 @@ Commissioner::Commissioner(ThreadNetif &aThreadNetif):
|
||||
mPanIdQuery(aThreadNetif),
|
||||
mState(kStateDisabled),
|
||||
mTimer(aThreadNetif.GetIp6().mTimerScheduler, HandleTimer, this),
|
||||
mTransmitTask(aThreadNetif.GetIp6().mTaskletScheduler, &Commissioner::HandleUdpTransmit, this),
|
||||
mSendKek(false),
|
||||
mRelayReceive(OPENTHREAD_URI_RELAY_RX, &Commissioner::HandleRelayReceive, this),
|
||||
mDatasetChanged(OPENTHREAD_URI_DATASET_CHANGED, &Commissioner::HandleDatasetChanged, this),
|
||||
mJoinerFinalize(OPENTHREAD_URI_JOINER_FINALIZE, &Commissioner::HandleJoinerFinalize, this),
|
||||
mCoapServer(aThreadNetif.GetCoapServer()),
|
||||
mCoapClient(aThreadNetif.GetCoapClient()),
|
||||
mSecureCoapServer(aThreadNetif.GetSecureCoapServer()),
|
||||
mNetif(aThreadNetif)
|
||||
{
|
||||
memset(mJoiners, 0, sizeof(mJoiners));
|
||||
mCoapServer.AddResource(mRelayReceive);
|
||||
mCoapServer.AddResource(mDatasetChanged);
|
||||
mSecureCoapServer.AddResource(mJoinerFinalize);
|
||||
}
|
||||
|
||||
ThreadError Commissioner::Start(void)
|
||||
@@ -85,8 +87,11 @@ ThreadError Commissioner::Start(void)
|
||||
otLogFuncEntry();
|
||||
VerifyOrExit(mState == kStateDisabled, error = kThreadError_InvalidState);
|
||||
|
||||
SuccessOrExit(error = mSecureCoapServer.Start(SendRelayTransmit, this));
|
||||
|
||||
mState = kStatePetition;
|
||||
mTransmitAttempts = 0;
|
||||
mSendKek = false;
|
||||
|
||||
SendPetition();
|
||||
|
||||
@@ -102,8 +107,11 @@ ThreadError Commissioner::Stop(void)
|
||||
otLogFuncEntry();
|
||||
VerifyOrExit(mState != kStateDisabled, error = kThreadError_InvalidState);
|
||||
|
||||
mSecureCoapServer.Stop();
|
||||
|
||||
mState = kStateDisabled;
|
||||
mTransmitAttempts = 0;
|
||||
mSendKek = false;
|
||||
|
||||
mTimer.Stop();
|
||||
|
||||
@@ -640,8 +648,10 @@ void Commissioner::HandleRelayReceive(Coap::Header &aHeader, Message &aMessage,
|
||||
JoinerUdpPortTlv joinerPort;
|
||||
JoinerIidTlv joinerIid;
|
||||
JoinerRouterLocatorTlv joinerRloc;
|
||||
Ip6::MessageInfo joinerMessageInfo;
|
||||
uint16_t offset;
|
||||
uint16_t length;
|
||||
bool enableJoiner = false;
|
||||
|
||||
otLogFuncEntry();
|
||||
|
||||
@@ -659,14 +669,14 @@ void Commissioner::HandleRelayReceive(Coap::Header &aHeader, Message &aMessage,
|
||||
|
||||
SuccessOrExit(error = Tlv::GetValueOffset(aMessage, Tlv::kJoinerDtlsEncapsulation, offset, length));
|
||||
|
||||
memcpy(mJoinerIid, joinerIid.GetIid(), sizeof(mJoinerIid));
|
||||
mJoinerPort = joinerPort.GetUdpPort();
|
||||
mJoinerRloc = joinerRloc.GetJoinerRouterLocator();
|
||||
|
||||
otLogInfoMeshCoP("Received relay receive for %llX, rloc:%x", HostSwap64(mJoinerIid64), mJoinerRloc);
|
||||
|
||||
if (!mNetif.GetDtls().IsStarted())
|
||||
if (!mSecureCoapServer.IsConnectionActive())
|
||||
{
|
||||
memcpy(mJoinerIid, joinerIid.GetIid(), sizeof(mJoinerIid));
|
||||
mJoinerPort = joinerPort.GetUdpPort();
|
||||
mJoinerRloc = joinerRloc.GetJoinerRouterLocator();
|
||||
|
||||
otLogInfoMeshCoP("Received relay receive for %llX, rloc:%x", HostSwap64(mJoinerIid64), mJoinerRloc);
|
||||
|
||||
mJoinerIid[0] ^= 0x2;
|
||||
|
||||
for (size_t i = 0; i < sizeof(mJoiners) / sizeof(mJoiners[0]); i++)
|
||||
@@ -678,21 +688,32 @@ void Commissioner::HandleRelayReceive(Coap::Header &aHeader, Message &aMessage,
|
||||
|
||||
if (mJoiners[i].mAny || !memcmp(&mJoiners[i].mExtAddress, mJoinerIid, sizeof(mJoiners[i].mExtAddress)))
|
||||
{
|
||||
SuccessOrExit(error = mNetif.GetDtls().SetPsk(reinterpret_cast<const uint8_t *>(mJoiners[i].mPsk),
|
||||
static_cast<uint8_t>(strlen(mJoiners[i].mPsk))));
|
||||
SuccessOrExit(error = mNetif.GetDtls().Start(false, HandleDtlsReceive, HandleDtlsSend, this));
|
||||
|
||||
SuccessOrExit(error = mSecureCoapServer.SetPsk(reinterpret_cast<const uint8_t *>(mJoiners[i].mPsk),
|
||||
static_cast<uint8_t>(strlen(mJoiners[i].mPsk))));
|
||||
otLogInfoMeshCoP("found joiner, starting new session");
|
||||
enableJoiner = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mJoinerIid[0] ^= 0x2;
|
||||
}
|
||||
else
|
||||
{
|
||||
enableJoiner = (memcmp(mJoinerIid, joinerIid.GetIid(), sizeof(mJoinerIid)) == 0);
|
||||
}
|
||||
|
||||
VerifyOrExit(mNetif.GetDtls().IsStarted() && memcmp(mJoinerIid, joinerIid.GetIid(), sizeof(mJoinerIid)) == 0,);
|
||||
VerifyOrExit(enableJoiner, ;);
|
||||
|
||||
SuccessOrExit(error = mNetif.GetDtls().SetClientId(mJoinerIid, sizeof(mJoinerIid)));
|
||||
mNetif.GetDtls().Receive(aMessage, offset, length);
|
||||
aMessage.SetOffset(offset);
|
||||
SuccessOrExit(error = aMessage.SetLength(offset + length));
|
||||
|
||||
joinerMessageInfo.SetPeerAddr(mNetif.GetMle().GetMeshLocal64());
|
||||
joinerMessageInfo.GetPeerAddr().SetIid(mJoinerIid);
|
||||
joinerMessageInfo.SetPeerPort(mJoinerPort);
|
||||
|
||||
mSecureCoapServer.Receive(aMessage, joinerMessageInfo);
|
||||
|
||||
exit:
|
||||
(void)aMessageInfo;
|
||||
@@ -728,10 +749,10 @@ void Commissioner::SendDatasetChangedResponse(const Coap::Header &aRequestHeader
|
||||
|
||||
otLogFuncEntry();
|
||||
VerifyOrExit((message = mCoapServer.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
responseHeader.Init(kCoapTypeAcknowledgment, kCoapResponseChanged);
|
||||
responseHeader.SetMessageId(aRequestHeader.GetMessageId());
|
||||
responseHeader.SetToken(aRequestHeader.GetToken(), aRequestHeader.GetTokenLength());
|
||||
|
||||
responseHeader.SetDefaultResponseHeader(aRequestHeader);
|
||||
responseHeader.SetPayloadMarker();
|
||||
|
||||
SuccessOrExit(error = message->Append(responseHeader.GetBytes(), responseHeader.GetLength()));
|
||||
SuccessOrExit(error = mCoapServer.SendMessage(*message, aMessageInfo));
|
||||
|
||||
@@ -747,177 +768,22 @@ exit:
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
ThreadError Commissioner::HandleDtlsSend(void *aContext, const uint8_t *aBuf, uint16_t aLength)
|
||||
void Commissioner::HandleJoinerFinalize(void *aContext, Coap::Header &aHeader,
|
||||
Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
otLogInfoMeshCoP("Commissioner::HandleDtlsTransmit");
|
||||
return static_cast<Commissioner *>(aContext)->HandleDtlsSend(aBuf, aLength);
|
||||
static_cast<Commissioner *>(aContext)->HandleJoinerFinalize(aHeader, aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
ThreadError Commissioner::HandleDtlsSend(const unsigned char *aBuf, uint16_t aLength)
|
||||
void Commissioner::HandleJoinerFinalize(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
otLogFuncEntry();
|
||||
|
||||
if (mTransmitMessage == NULL)
|
||||
{
|
||||
Coap::Header header;
|
||||
JoinerUdpPortTlv udpPort;
|
||||
JoinerIidTlv iid;
|
||||
JoinerRouterLocatorTlv rloc;
|
||||
ExtendedTlv tlv;
|
||||
|
||||
header.Init(kCoapTypeNonConfirmable, kCoapRequestPost);
|
||||
header.AppendUriPathOptions(OPENTHREAD_URI_RELAY_TX);
|
||||
header.SetPayloadMarker();
|
||||
|
||||
VerifyOrExit((mTransmitMessage = mCoapClient.NewMessage(header)) != NULL, error = kThreadError_NoBufs);
|
||||
|
||||
udpPort.Init();
|
||||
udpPort.SetUdpPort(mJoinerPort);
|
||||
SuccessOrExit(error = mTransmitMessage->Append(&udpPort, sizeof(udpPort)));
|
||||
|
||||
iid.Init();
|
||||
iid.SetIid(mJoinerIid);
|
||||
SuccessOrExit(error = mTransmitMessage->Append(&iid, sizeof(iid)));
|
||||
|
||||
rloc.Init();
|
||||
rloc.SetJoinerRouterLocator(mJoinerRloc);
|
||||
SuccessOrExit(error = mTransmitMessage->Append(&rloc, sizeof(rloc)));
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
otLogFuncExitErr(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
void Commissioner::HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
otLogInfoMeshCoP("Commissioner::HandleDtlsReceive");
|
||||
static_cast<Commissioner *>(aContext)->HandleDtlsReceive(aBuf, aLength);
|
||||
}
|
||||
|
||||
void Commissioner::HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
otLogFuncEntry();
|
||||
ReceiveJoinerFinalize(aBuf, aLength);
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
void Commissioner::HandleUdpTransmit(void *aContext)
|
||||
{
|
||||
otLogInfoMeshCoP("Commissioner::HandleUdpTransmit");
|
||||
static_cast<Commissioner *>(aContext)->HandleUdpTransmit();
|
||||
}
|
||||
|
||||
void Commissioner::HandleUdpTransmit(void)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
ExtendedTlv tlv;
|
||||
|
||||
otLogFuncEntry();
|
||||
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);
|
||||
mTransmitMessage->SetOffset(0);
|
||||
|
||||
messageInfo.SetPeerAddr(mNetif.GetMle().GetMeshLocal16());
|
||||
messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(mJoinerRloc);
|
||||
messageInfo.SetPeerPort(kCoapUdpPort);
|
||||
messageInfo.SetInterfaceId(mNetif.GetInterfaceId());
|
||||
|
||||
SuccessOrExit(error = mCoapClient.SendMessage(*mTransmitMessage, messageInfo));
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && mTransmitMessage != NULL)
|
||||
{
|
||||
mTransmitMessage->Free();
|
||||
}
|
||||
|
||||
mTransmitMessage = NULL;
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
void Commissioner::ReceiveJoinerFinalize(uint8_t *buf, uint16_t length)
|
||||
{
|
||||
Message *message = NULL;
|
||||
Coap::Header header;
|
||||
char uriPath[Coap::Resource::kMaxReceivedUriPath] = "";
|
||||
char *curUriPath = uriPath;
|
||||
const Coap::Header::Option *coapOption;
|
||||
|
||||
(void)aMessageInfo;
|
||||
StateTlv::State state = StateTlv::kAccept;
|
||||
ProvisioningUrlTlv provisioningUrl;
|
||||
|
||||
otLogFuncEntry();
|
||||
otLogInfoMeshCoP("receive joiner finalize");
|
||||
otLogInfoMeshCoP("received joiner finalize");
|
||||
|
||||
VerifyOrExit((message = mNetif.GetIp6().mMessagePool.New(Message::kTypeIp6, 0)) != NULL, ;);
|
||||
SuccessOrExit(message->Append(buf, length));
|
||||
SuccessOrExit(header.FromMessage(*message));
|
||||
SuccessOrExit(message->SetOffset(header.GetLength()));
|
||||
|
||||
coapOption = header.GetCurrentOption();
|
||||
|
||||
while (coapOption != NULL)
|
||||
{
|
||||
switch (coapOption->mNumber)
|
||||
{
|
||||
case kCoapOptionUriPath:
|
||||
if (curUriPath != uriPath)
|
||||
{
|
||||
*curUriPath++ = '/';
|
||||
}
|
||||
|
||||
VerifyOrExit(coapOption->mLength < sizeof(uriPath) - static_cast<size_t>(curUriPath + 1 - uriPath), ;);
|
||||
|
||||
memcpy(curUriPath, coapOption->mValue, coapOption->mLength);
|
||||
curUriPath += coapOption->mLength;
|
||||
break;
|
||||
|
||||
case kCoapOptionContentFormat:
|
||||
break;
|
||||
|
||||
default:
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
coapOption = header.GetNextOption();
|
||||
}
|
||||
|
||||
curUriPath[0] = '\0';
|
||||
|
||||
VerifyOrExit(strcmp(uriPath, OPENTHREAD_URI_JOINER_FINALIZE) == 0,);
|
||||
|
||||
if (Tlv::GetTlv(*message, Tlv::kProvisioningUrl, sizeof(provisioningUrl), provisioningUrl) == kThreadError_None)
|
||||
if (Tlv::GetTlv(aMessage, Tlv::kProvisioningUrl, sizeof(provisioningUrl), provisioningUrl) == kThreadError_None)
|
||||
{
|
||||
if (provisioningUrl.GetLength() != mNetif.GetDtls().mProvisioningUrl.GetLength() ||
|
||||
memcmp(provisioningUrl.GetProvisioningUrl(), mNetif.GetDtls().mProvisioningUrl.GetProvisioningUrl(),
|
||||
@@ -927,47 +793,125 @@ void Commissioner::ReceiveJoinerFinalize(uint8_t *buf, uint16_t length)
|
||||
}
|
||||
}
|
||||
|
||||
otDumpCertMeshCoP("[THCI] direction=recv | type=JOIN_FIN.req |", buf + header.GetLength(), length - header.GetLength());
|
||||
otLogCertMeshCoP("[THCI] direction=recv | type=JOIN_FIN.req");
|
||||
|
||||
SendJoinFinalizeResponse(header, state);
|
||||
SendJoinFinalizeResponse(aHeader, state);
|
||||
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
|
||||
void Commissioner::SendJoinFinalizeResponse(const Coap::Header &aRequestHeader, StateTlv::State aState)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Coap::Header responseHeader;
|
||||
Ip6::MessageInfo joinerMessageInfo;
|
||||
MeshCoP::StateTlv stateTlv;
|
||||
Message *message;
|
||||
|
||||
otLogFuncEntry();
|
||||
|
||||
responseHeader.SetDefaultResponseHeader(aRequestHeader);
|
||||
responseHeader.SetPayloadMarker();
|
||||
|
||||
VerifyOrExit((message = mSecureCoapServer.NewMessage(responseHeader)) != NULL, error = kThreadError_NoBufs);
|
||||
|
||||
stateTlv.Init();
|
||||
stateTlv.SetState(aState);
|
||||
SuccessOrExit(error = message->Append(&stateTlv, sizeof(stateTlv)));
|
||||
|
||||
joinerMessageInfo.SetPeerAddr(mNetif.GetMle().GetMeshLocal64());
|
||||
joinerMessageInfo.GetPeerAddr().SetIid(mJoinerIid);
|
||||
joinerMessageInfo.SetPeerPort(mJoinerPort);
|
||||
|
||||
mSendKek = true;
|
||||
SuccessOrExit(error = mSecureCoapServer.SendMessage(*message, joinerMessageInfo));
|
||||
|
||||
otLogInfoMeshCoP("sent joiner finalize response");
|
||||
otLogCertMeshCoP("[THCI] direction=send | type=JOIN_FIN.rsp");
|
||||
exit:
|
||||
|
||||
if (message != NULL)
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
mSendKek = false;
|
||||
message->Free();
|
||||
}
|
||||
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
void Commissioner::SendJoinFinalizeResponse(const Coap::Header &aRequestHeader, StateTlv::State aState)
|
||||
ThreadError Commissioner::SendRelayTransmit(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
Coap::Header responseHeader;
|
||||
MeshCoP::StateTlv *stateTlv;
|
||||
uint8_t buf[128];
|
||||
uint8_t *cur = buf;
|
||||
return static_cast<Commissioner *>(aContext)->SendRelayTransmit(aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
ThreadError Commissioner::SendRelayTransmit(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
(void)aMessageInfo;
|
||||
ThreadError error = kThreadError_None;
|
||||
Coap::Header header;
|
||||
JoinerUdpPortTlv udpPort;
|
||||
JoinerIidTlv iid;
|
||||
JoinerRouterLocatorTlv rloc;
|
||||
ExtendedTlv tlv;
|
||||
Message *message;
|
||||
uint16_t offset;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
otLogFuncEntry();
|
||||
responseHeader.Init(kCoapTypeAcknowledgment, kCoapResponseChanged);
|
||||
responseHeader.SetMessageId(aRequestHeader.GetMessageId());
|
||||
responseHeader.SetToken(aRequestHeader.GetToken(), aRequestHeader.GetTokenLength());
|
||||
responseHeader.SetPayloadMarker();
|
||||
memcpy(cur, responseHeader.GetBytes(), responseHeader.GetLength());
|
||||
cur += responseHeader.GetLength();
|
||||
|
||||
stateTlv = reinterpret_cast<MeshCoP::StateTlv *>(cur);
|
||||
stateTlv->Init();
|
||||
stateTlv->SetState(aState);
|
||||
cur += sizeof(*stateTlv);
|
||||
header.Init(kCoapTypeNonConfirmable, kCoapRequestPost);
|
||||
header.AppendUriPathOptions(OPENTHREAD_URI_RELAY_TX);
|
||||
header.SetPayloadMarker();
|
||||
|
||||
mSendKek = true;
|
||||
mNetif.GetDtls().Send(buf, static_cast<uint16_t>(cur - buf));
|
||||
mSendKek = false;
|
||||
VerifyOrExit((message = mCoapClient.NewMessage(header)) != NULL, error = kThreadError_NoBufs);
|
||||
|
||||
otLogInfoMeshCoP("sent joiner finalize response");
|
||||
otLogCertMeshCoP("[THCI] direction=send | type=JOIN_FIN.rsp");
|
||||
otLogFuncExit();
|
||||
udpPort.Init();
|
||||
udpPort.SetUdpPort(mJoinerPort);
|
||||
SuccessOrExit(error = message->Append(&udpPort, sizeof(udpPort)));
|
||||
|
||||
iid.Init();
|
||||
iid.SetIid(mJoinerIid);
|
||||
SuccessOrExit(error = message->Append(&iid, sizeof(iid)));
|
||||
|
||||
rloc.Init();
|
||||
rloc.SetJoinerRouterLocator(mJoinerRloc);
|
||||
SuccessOrExit(error = message->Append(&rloc, sizeof(rloc)));
|
||||
|
||||
if (mSendKek)
|
||||
{
|
||||
JoinerRouterKekTlv kek;
|
||||
kek.Init();
|
||||
kek.SetKek(mNetif.GetKeyManager().GetKek());
|
||||
SuccessOrExit(error = message->Append(&kek, sizeof(kek)));
|
||||
mSendKek = false;
|
||||
}
|
||||
|
||||
tlv.SetType(Tlv::kJoinerDtlsEncapsulation);
|
||||
tlv.SetLength(aMessage.GetLength());
|
||||
SuccessOrExit(error = message->Append(&tlv, sizeof(tlv)));
|
||||
offset = message->GetLength();
|
||||
message->SetLength(offset + aMessage.GetLength());
|
||||
aMessage.CopyTo(0, offset, aMessage.GetLength(), *message);
|
||||
|
||||
messageInfo.SetPeerAddr(mNetif.GetMle().GetMeshLocal16());
|
||||
messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(mJoinerRloc);
|
||||
messageInfo.SetPeerPort(kCoapUdpPort);
|
||||
messageInfo.SetInterfaceId(mNetif.GetInterfaceId());
|
||||
|
||||
SuccessOrExit(error = mCoapClient.SendMessage(*message, messageInfo));
|
||||
|
||||
aMessage.Free();
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
|
||||
otLogFuncExitErr(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace MeshCoP
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#include <coap/coap_client.hpp>
|
||||
#include <coap/coap_server.hpp>
|
||||
#include <coap/secure_coap_server.hpp>
|
||||
#include <common/timer.hpp>
|
||||
#include <mac/mac_frame.hpp>
|
||||
#include <meshcop/announce_begin_client.hpp>
|
||||
@@ -210,18 +211,15 @@ private:
|
||||
Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
void HandleDatasetChanged(Coap::Header &aHeader, 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 void HandleJoinerFinalize(void *aContext, Coap::Header &aHeader,
|
||||
Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
void HandleJoinerFinalize(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
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, StateTlv::State aState);
|
||||
|
||||
static ThreadError SendRelayTransmit(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
ThreadError SendRelayTransmit(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
void SendDatasetChangedResponse(const Coap::Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo);
|
||||
ThreadError SendCommissionerSet(void);
|
||||
ThreadError SendPetition(void);
|
||||
@@ -247,16 +245,16 @@ private:
|
||||
uint16_t mJoinerRloc;
|
||||
|
||||
uint16_t mSessionId;
|
||||
Message *mTransmitMessage;
|
||||
Timer mTimer;
|
||||
Tasklet mTransmitTask;
|
||||
uint8_t mTransmitAttempts;
|
||||
bool mSendKek;
|
||||
|
||||
Coap::Resource mRelayReceive;
|
||||
Coap::Resource mDatasetChanged;
|
||||
Coap::Resource mJoinerFinalize;
|
||||
Coap::Server &mCoapServer;
|
||||
Coap::Client &mCoapClient;
|
||||
Coap::SecureServer &mSecureCoapServer;
|
||||
|
||||
ThreadNetif &mNetif;
|
||||
};
|
||||
|
||||
@@ -168,10 +168,21 @@ bool Dtls::IsConnected(void)
|
||||
return mSsl.state == MBEDTLS_SSL_HANDSHAKE_OVER;
|
||||
}
|
||||
|
||||
ThreadError Dtls::Send(const uint8_t *aBuf, uint16_t aLength)
|
||||
ThreadError Dtls::Send(Message &aMessage, uint16_t aLength)
|
||||
{
|
||||
int rval = mbedtls_ssl_write(&mSsl, aBuf, aLength);
|
||||
return MapError(rval);
|
||||
ThreadError error = kThreadError_None;
|
||||
uint8_t buffer[kApplicationDataMaxLength];
|
||||
|
||||
VerifyOrExit(aLength <= kApplicationDataMaxLength, error = kThreadError_NoBufs);
|
||||
|
||||
aMessage.Read(0, aLength, buffer);
|
||||
|
||||
SuccessOrExit(error = MapError(mbedtls_ssl_write(&mSsl, buffer, aLength)));
|
||||
|
||||
aMessage.Free();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError Dtls::Receive(Message &aMessage, uint16_t aOffset, uint16_t aLength)
|
||||
|
||||
@@ -59,6 +59,7 @@ public:
|
||||
enum
|
||||
{
|
||||
kPskMaxLength = 32,
|
||||
kApplicationDataMaxLength = 128,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -152,13 +153,14 @@ public:
|
||||
/**
|
||||
* 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.
|
||||
* @param[in] aMessage A message to send via DTLS.
|
||||
* @param[in] aLength Number of bytes in the data buffer.
|
||||
*
|
||||
* @retval kThreadError_None Successfully sent the data via the DTLS session.
|
||||
* @retval kThreadError_None Successfully sent the data via the DTLS session.
|
||||
* @retval kThreadError_NoBufs A message is too long.
|
||||
*
|
||||
*/
|
||||
ThreadError Send(const uint8_t *aBuf, uint16_t aLength);
|
||||
ThreadError Send(Message &aMessage, uint16_t aLength);
|
||||
|
||||
/**
|
||||
* This method provides a received DTLS message to the DTLS object.
|
||||
|
||||
+73
-165
@@ -59,12 +59,13 @@ namespace Thread {
|
||||
namespace MeshCoP {
|
||||
|
||||
Joiner::Joiner(ThreadNetif &aNetif):
|
||||
mTransmitMessage(NULL),
|
||||
mSocket(aNetif.GetIp6().mUdp),
|
||||
mTransmitTask(aNetif.GetIp6().mTaskletScheduler, &Joiner::HandleUdpTransmit, this),
|
||||
mJoinerRouterChannel(0),
|
||||
mJoinerRouterPanId(0),
|
||||
mJoinerUdpPort(0),
|
||||
mTimer(aNetif.GetIp6().mTimerScheduler, &Joiner::HandleTimer, this),
|
||||
mJoinerEntrust(OPENTHREAD_URI_JOINER_ENTRUST, &Joiner::HandleJoinerEntrust, this),
|
||||
mCoapServer(aNetif.GetCoapServer()),
|
||||
mSecureCoapClient(aNetif.GetSecureCoapClient()),
|
||||
mNetif(aNetif)
|
||||
{
|
||||
mCoapServer.AddResource(mJoinerEntrust);
|
||||
@@ -82,9 +83,9 @@ ThreadError Joiner::Start(const char *aPSKd, const char *aProvisioningUrl)
|
||||
mNetif.GetMac().SetExtAddress(extAddress);
|
||||
mNetif.GetMle().UpdateLinkLocalAddress();
|
||||
|
||||
SuccessOrExit(error = mNetif.GetDtls().SetPsk(reinterpret_cast<const uint8_t *>(aPSKd),
|
||||
static_cast<uint8_t>(strlen(aPSKd))));
|
||||
SuccessOrExit(error = mNetif.GetDtls().mProvisioningUrl.SetProvisioningUrl(aProvisioningUrl));
|
||||
SuccessOrExit(error = mSecureCoapClient.GetDtls().SetPsk(reinterpret_cast<const uint8_t *>(aPSKd),
|
||||
static_cast<uint8_t>(strlen(aPSKd))));
|
||||
SuccessOrExit(error = mSecureCoapClient.GetDtls().mProvisioningUrl.SetProvisioningUrl(aProvisioningUrl));
|
||||
|
||||
mJoinerRouterPanId = Mac::kPanIdBroadcast;
|
||||
SuccessOrExit(error = mNetif.GetMle().Discover(0, 0, mNetif.GetMac().GetPanId(), HandleDiscoverResult, this));
|
||||
@@ -97,13 +98,23 @@ exit:
|
||||
ThreadError Joiner::Stop(void)
|
||||
{
|
||||
otLogFuncEntry();
|
||||
mNetif.GetIp6Filter().RemoveUnsecurePort(mSocket.GetSockName().mPort);
|
||||
mSocket.Close();
|
||||
mNetif.GetDtls().Stop();
|
||||
|
||||
Close();
|
||||
|
||||
otLogFuncExit();
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
void Joiner::Close(void)
|
||||
{
|
||||
otLogFuncEntry();
|
||||
|
||||
mSecureCoapClient.Disconnect();
|
||||
mNetif.GetIp6Filter().RemoveUnsecurePort(mSecureCoapClient.GetPort());
|
||||
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
void Joiner::HandleDiscoverResult(otActiveScanResult *aResult, void *aContext)
|
||||
{
|
||||
static_cast<Joiner *>(aContext)->HandleDiscoverResult(aResult);
|
||||
@@ -111,6 +122,10 @@ void Joiner::HandleDiscoverResult(otActiveScanResult *aResult, void *aContext)
|
||||
|
||||
void Joiner::HandleDiscoverResult(otActiveScanResult *aResult)
|
||||
{
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
otLogFuncEntry();
|
||||
|
||||
if (aResult != NULL)
|
||||
{
|
||||
otLogFuncEntryMsg("aResult = %llX", HostSwap64(*reinterpret_cast<uint64_t *>(&aResult->mExtAddress)));
|
||||
@@ -148,196 +163,92 @@ void Joiner::HandleDiscoverResult(otActiveScanResult *aResult)
|
||||
{
|
||||
otLogFuncEntryMsg("aResult = NULL");
|
||||
|
||||
// open UDP port
|
||||
Ip6::SockAddr sockaddr;
|
||||
sockaddr.mPort = mJoinerUdpPort;
|
||||
mSocket.Open(&Joiner::HandleUdpReceive, this);
|
||||
mSocket.Bind(sockaddr);
|
||||
|
||||
mNetif.GetMac().SetPanId(mJoinerRouterPanId);
|
||||
mNetif.GetMac().SetChannel(mJoinerRouterChannel);
|
||||
mNetif.GetIp6Filter().AddUnsecurePort(sockaddr.mPort);
|
||||
mNetif.GetIp6Filter().AddUnsecurePort(mSecureCoapClient.GetPort());
|
||||
|
||||
mNetif.GetDtls().Start(true, HandleDtlsReceive, HandleDtlsSend, this);
|
||||
messageInfo.GetPeerAddr().mFields.m16[0] = HostSwap16(0xfe80);
|
||||
messageInfo.GetPeerAddr().SetIid(mJoinerRouter);
|
||||
messageInfo.mPeerPort = mJoinerUdpPort;
|
||||
messageInfo.mInterfaceId = OT_NETIF_INTERFACE_ID_THREAD;
|
||||
|
||||
mSecureCoapClient.Connect(messageInfo, Joiner::HandleSecureCoapClientConnect, this);
|
||||
}
|
||||
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
ThreadError Joiner::HandleDtlsSend(void *aContext, const uint8_t *aBuf, uint16_t aLength)
|
||||
void Joiner::HandleSecureCoapClientConnect(void *aContext)
|
||||
{
|
||||
otLogInfoMeshCoP("Joiner::HandleDtlsTransmit");
|
||||
return static_cast<Joiner *>(aContext)->HandleDtlsSend(aBuf, aLength);
|
||||
}
|
||||
|
||||
ThreadError Joiner::HandleDtlsSend(const unsigned char *aBuf, uint16_t aLength)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
otLogFuncEntry();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
otLogFuncExitErr(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
void Joiner::HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength)
|
||||
{
|
||||
otLogInfoMeshCoP("Joiner::HandleDtlsReceive");
|
||||
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");
|
||||
static_cast<Joiner *>(aContext)->HandleUdpReceive(*static_cast<Message *>(aMessage),
|
||||
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
|
||||
}
|
||||
|
||||
void Joiner::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
otLogFuncEntry();
|
||||
(void)aMessageInfo;
|
||||
|
||||
mNetif.GetDtls().Receive(aMessage, aMessage.GetOffset(), aMessage.GetLength() - aMessage.GetOffset());
|
||||
|
||||
if (mNetif.GetDtls().IsConnected())
|
||||
{
|
||||
SendJoinerFinalize();
|
||||
}
|
||||
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
void Joiner::HandleUdpTransmit(void *aContext)
|
||||
{
|
||||
otLogInfoMeshCoP("Joiner::HandleUdpTransmit");
|
||||
static_cast<Joiner *>(aContext)->HandleUdpTransmit();
|
||||
}
|
||||
|
||||
void Joiner::HandleUdpTransmit(void)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
otLogFuncEntry();
|
||||
|
||||
VerifyOrExit(mTransmitMessage != NULL, error = kThreadError_NoBufs);
|
||||
|
||||
otLogInfoMeshCoP("transmit %d (to %llX)", mTransmitMessage->GetLength(),
|
||||
HostSwap64(*reinterpret_cast<uint64_t *>(&mJoinerRouter)));
|
||||
|
||||
messageInfo.GetPeerAddr().mFields.m16[0] = HostSwap16(0xfe80);
|
||||
messageInfo.GetPeerAddr().SetIid(mJoinerRouter);
|
||||
messageInfo.SetPeerPort(mJoinerUdpPort);
|
||||
messageInfo.SetInterfaceId(OT_NETIF_INTERFACE_ID_THREAD);
|
||||
|
||||
SuccessOrExit(error = mSocket.SendTo(*mTransmitMessage, messageInfo));
|
||||
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && mTransmitMessage != NULL)
|
||||
{
|
||||
mTransmitMessage->Free();
|
||||
}
|
||||
|
||||
mTransmitMessage = NULL;
|
||||
otLogFuncExit();
|
||||
static_cast<Joiner *>(aContext)->SendJoinerFinalize();
|
||||
}
|
||||
|
||||
void Joiner::SendJoinerFinalize(void)
|
||||
{
|
||||
Coap::Header header;
|
||||
StateTlv *stateTlv;
|
||||
ThreadError error = kThreadError_None;
|
||||
Message *message = NULL;
|
||||
StateTlv stateTlv;
|
||||
uint8_t length;
|
||||
uint8_t buf[128];
|
||||
uint8_t *cur = buf;
|
||||
|
||||
otLogFuncEntry();
|
||||
|
||||
header.Init(kCoapTypeConfirmable, kCoapRequestPost);
|
||||
header.SetMessageId(0);
|
||||
header.SetToken(NULL, 0);
|
||||
header.AppendUriPathOptions(OPENTHREAD_URI_JOINER_FINALIZE);
|
||||
header.SetPayloadMarker();
|
||||
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);
|
||||
VerifyOrExit((message = mSecureCoapClient.NewMessage(header)) != NULL, error = kThreadError_NoBufs);
|
||||
|
||||
length = mNetif.GetDtls().mProvisioningUrl.GetLength();
|
||||
stateTlv.Init();
|
||||
stateTlv.SetState(MeshCoP::StateTlv::kAccept);
|
||||
SuccessOrExit(error = message->Append(&stateTlv, sizeof(stateTlv)));
|
||||
|
||||
length = mSecureCoapClient.GetDtls().mProvisioningUrl.GetLength();
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
length += sizeof(Tlv);
|
||||
memcpy(cur, &mNetif.GetDtls().mProvisioningUrl, length);
|
||||
cur += length;
|
||||
SuccessOrExit(error = message->Append(&stateTlv, length + sizeof(Tlv)));
|
||||
}
|
||||
|
||||
mNetif.GetDtls().Send(buf, static_cast<uint16_t>(cur - buf));
|
||||
mSecureCoapClient.SendMessage(*message, Joiner::HandleJoinerFinalizeResponse, this);
|
||||
|
||||
otLogInfoMeshCoP("Sent joiner finalize");
|
||||
otDumpCertMeshCoP("[THCI] direction=send | type=JOIN_FIN.req |", buf + header.GetLength(),
|
||||
cur - buf - header.GetLength());
|
||||
otLogCertMeshCoP("[THCI] direction=send | type=JOIN_FIN.req");
|
||||
exit:
|
||||
|
||||
if (error != kThreadError_None && message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
void Joiner::ReceiveJoinerFinalizeResponse(uint8_t *buf, uint16_t length)
|
||||
void Joiner::HandleJoinerFinalizeResponse(void *aContext, otCoapHeader *aHeader,
|
||||
otMessage aMessage, ThreadError result)
|
||||
{
|
||||
static_cast<Joiner *>(aContext)->HandleJoinerFinalizeResponse(
|
||||
static_cast<Coap::Header *>(aHeader), static_cast<Message *>(aMessage), result);
|
||||
}
|
||||
|
||||
void Joiner::HandleJoinerFinalizeResponse(Coap::Header *aHeader, Message *aMessage, ThreadError result)
|
||||
{
|
||||
Message *message = NULL;
|
||||
Coap::Header header;
|
||||
StateTlv state;
|
||||
|
||||
otLogFuncEntry();
|
||||
|
||||
VerifyOrExit((message = mNetif.GetIp6().mMessagePool.New(Message::kTypeIp6, 0)) != NULL, ;);
|
||||
SuccessOrExit(message->Append(buf, length));
|
||||
SuccessOrExit(header.FromMessage(*message));
|
||||
SuccessOrExit(message->SetOffset(header.GetLength()));
|
||||
VerifyOrExit(result == kThreadError_None &&
|
||||
aHeader->GetType() == kCoapTypeAcknowledgment &&
|
||||
aHeader->GetCode() == kCoapResponseChanged, ;);
|
||||
|
||||
VerifyOrExit(header.GetType() == kCoapTypeAcknowledgment &&
|
||||
header.GetCode() == kCoapResponseChanged &&
|
||||
header.GetMessageId() == 0 &&
|
||||
header.GetTokenLength() == 0, ;);
|
||||
|
||||
SuccessOrExit(Tlv::GetTlv(*message, Tlv::kState, sizeof(state), state));
|
||||
SuccessOrExit(Tlv::GetTlv(*aMessage, Tlv::kState, sizeof(state), state));
|
||||
VerifyOrExit(state.IsValid(), ;);
|
||||
|
||||
otLogInfoMeshCoP("received joiner finalize response %d", static_cast<uint8_t>(state.GetState()));
|
||||
otLogCertMeshCoP("[THCI] direction=recv | type=JOIN_FIN.rsp");
|
||||
|
||||
Close();
|
||||
|
||||
exit:
|
||||
|
||||
if (message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
|
||||
Close();
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
@@ -400,13 +311,15 @@ exit:
|
||||
void Joiner::SendJoinerEntrustResponse(const Coap::Header &aRequestHeader,
|
||||
const Ip6::MessageInfo &aRequestInfo)
|
||||
{
|
||||
|
||||
ThreadError error = kThreadError_None;
|
||||
Message *message;
|
||||
Coap::Header responseHeader;
|
||||
Ip6::MessageInfo responseInfo(aRequestInfo);
|
||||
|
||||
otLogFuncEntry();
|
||||
|
||||
VerifyOrExit((message = mCoapServer.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
|
||||
message->SetSubType(Message::kSubTypeJoinerEntrust);
|
||||
|
||||
responseHeader.SetDefaultResponseHeader(aRequestHeader);
|
||||
|
||||
@@ -415,7 +328,7 @@ void Joiner::SendJoinerEntrustResponse(const Coap::Header &aRequestHeader,
|
||||
memset(&responseInfo.mSockAddr, 0, sizeof(responseInfo.mSockAddr));
|
||||
SuccessOrExit(error = mCoapServer.SendMessage(*message, responseInfo));
|
||||
|
||||
otLogInfoArp("Sent address notification acknowledgment");
|
||||
otLogInfoArp("Sent Joiner Entrust response");
|
||||
|
||||
exit:
|
||||
|
||||
@@ -423,6 +336,8 @@ exit:
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
void Joiner::HandleTimer(void *aContext)
|
||||
@@ -443,12 +358,5 @@ void Joiner::HandleTimer(void)
|
||||
mNetif.GetMle().UpdateLinkLocalAddress();
|
||||
}
|
||||
|
||||
void Joiner::Close(void)
|
||||
{
|
||||
otLogFuncEntry();
|
||||
mNetif.GetDtls().Stop();
|
||||
otLogFuncExit();
|
||||
}
|
||||
|
||||
} // namespace Dtls
|
||||
} // namespace MeshCoP
|
||||
} // namespace Thread
|
||||
|
||||
+13
-22
@@ -38,6 +38,7 @@
|
||||
|
||||
#include <coap/coap_header.hpp>
|
||||
#include <coap/coap_server.hpp>
|
||||
#include <coap/secure_coap_client.hpp>
|
||||
#include <common/message.hpp>
|
||||
#include <net/udp6.hpp>
|
||||
#include <meshcop/dtls.hpp>
|
||||
@@ -88,42 +89,32 @@ 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 SendJoinerEntrustResponse(const Coap::Header &aRequestHeader, const Ip6::MessageInfo &aRequestInfo);
|
||||
|
||||
static void HandleTimer(void *aContext);
|
||||
void HandleTimer(void);
|
||||
|
||||
void Close(void);
|
||||
void ReceiveJoinerFinalizeResponse(uint8_t *buf, uint16_t length);
|
||||
|
||||
static void HandleSecureCoapClientConnect(void *aContext);
|
||||
|
||||
void SendJoinerFinalize(void);
|
||||
static void HandleJoinerFinalizeResponse(void *aContext, otCoapHeader *aHeader,
|
||||
otMessage aMessage, ThreadError result);
|
||||
void HandleJoinerFinalizeResponse(Coap::Header *aHeader, Message *aMessage, ThreadError result);
|
||||
|
||||
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 SendJoinerEntrustResponse(const Coap::Header &aRequestHeader, const Ip6::MessageInfo &aRequestInfo);
|
||||
|
||||
uint8_t mJoinerRouterChannel;
|
||||
uint16_t mJoinerRouterPanId;
|
||||
uint16_t mJoinerUdpPort;
|
||||
Mac::ExtAddress mJoinerRouter;
|
||||
Message *mTransmitMessage;
|
||||
Ip6::UdpSocket mSocket;
|
||||
|
||||
Tasklet mTransmitTask;
|
||||
Timer mTimer;
|
||||
Coap::Resource mJoinerEntrust;
|
||||
Coap::Server &mCoapServer;
|
||||
Coap::SecureClient &mSecureCoapClient;
|
||||
ThreadNetif &mNetif;
|
||||
};
|
||||
|
||||
|
||||
@@ -75,12 +75,14 @@ ThreadNetif::ThreadNetif(Ip6::Ip6 &aIp6):
|
||||
mNetworkDataLeader(*this),
|
||||
mNetworkDiagnostic(*this),
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
mSecureCoapServer(*this, OPENTHREAD_CONFIG_JOINER_UDP_PORT),
|
||||
mCommissioner(*this),
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER
|
||||
#if OPENTHREAD_ENABLE_DTLS
|
||||
mDtls(*this),
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
mSecureCoapClient(*this),
|
||||
mJoiner(*this),
|
||||
#endif // OPENTHREAD_ENABLE_JOINER
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
@@ -103,11 +105,14 @@ ThreadError ThreadNetif::Up(void)
|
||||
mIp6.AddNetif(*this);
|
||||
mMeshForwarder.Start();
|
||||
mCoapServer.Start();
|
||||
mCoapClient.Start();
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
mSecureCoapClient.Start();
|
||||
#endif
|
||||
mMleRouter.Enable();
|
||||
mIsUp = true;
|
||||
}
|
||||
|
||||
mCoapClient.Start();
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
@@ -115,6 +120,9 @@ ThreadError ThreadNetif::Down(void)
|
||||
{
|
||||
mCoapServer.Stop();
|
||||
mCoapClient.Stop();
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
mSecureCoapClient.Stop();
|
||||
#endif
|
||||
mMleRouter.Disable();
|
||||
mMeshForwarder.Stop();
|
||||
mIp6.RemoveNetif(*this);
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
|
||||
#include <coap/coap_server.hpp>
|
||||
#include <coap/coap_client.hpp>
|
||||
#include <coap/secure_coap_client.hpp>
|
||||
#include <coap/secure_coap_server.hpp>
|
||||
#include <mac/mac.hpp>
|
||||
#include <meshcop/joiner_router.hpp>
|
||||
#include <meshcop/leader.hpp>
|
||||
@@ -282,6 +284,8 @@ public:
|
||||
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
MeshCoP::Commissioner &GetCommissioner(void) { return mCommissioner; }
|
||||
|
||||
Coap::SecureServer &GetSecureCoapServer(void) { return mSecureCoapServer; }
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER
|
||||
|
||||
#if OPENTHREAD_ENABLE_DTLS
|
||||
@@ -290,6 +294,8 @@ public:
|
||||
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
MeshCoP::Joiner &GetJoiner(void) { return mJoiner; }
|
||||
|
||||
Coap::SecureClient &GetSecureCoapClient(void) { return mSecureCoapClient; }
|
||||
#endif // OPENTHREAD_ENABLE_JOINER
|
||||
|
||||
#if OPENTHREAD_ENABLE_JAM_DETECTION
|
||||
@@ -334,6 +340,7 @@ private:
|
||||
bool mIsUp;
|
||||
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER
|
||||
Coap::SecureServer mSecureCoapServer;
|
||||
MeshCoP::Commissioner mCommissioner;
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER
|
||||
|
||||
@@ -342,6 +349,7 @@ private:
|
||||
#endif// OPENTHREAD_ENABLE_DTLS
|
||||
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
Coap::SecureClient mSecureCoapClient;
|
||||
MeshCoP::Joiner mJoiner;
|
||||
#endif // OPENTHREAD_ENABLE_JOINER
|
||||
|
||||
|
||||
Reference in New Issue
Block a user