Border agent proxy (#1590)

* initial commit for border agent proxy
This commit is contained in:
Buke Po
2017-04-28 01:13:00 +08:00
committed by Jonathan Hui
parent 6d982b07e1
commit 7705bf4c22
18 changed files with 797 additions and 2 deletions
+32
View File
@@ -535,6 +535,37 @@ AC_MSG_CHECKING([whether mbed TLS should be enabled])
AC_MSG_RESULT(${enable_builtin_mbedtls})
AM_CONDITIONAL([OPENTHREAD_ENABLE_BUILTIN_MBEDTLS], [test "${enable_builtin_mbedtls}" = "yes"])
#
# Thread Border Agent Proxy
#
AC_ARG_ENABLE(border_agent_proxy,
[AS_HELP_STRING([--enable-border-agent-proxy],[Enable border agent proxy support @<:@default=no@:>@.])],
[
case "${enableval}" in
no|yes)
enable_border_agent_proxy=${enableval}
;;
*)
AC_MSG_ERROR([Invalid value ${enable_border_agent_proxy} for --enable-border-agent-proxy])
;;
esac
],
[enable_border_agent_proxy=no])
if test "$enable_border_agent_proxy" = "yes"; then
OPENTHREAD_ENABLE_BORDER_AGENT_PROXY=1
else
OPENTHREAD_ENABLE_BORDER_AGENT_PROXY=0
fi
AC_MSG_RESULT(${enable_border_agent_proxy})
AC_SUBST(OPENTHREAD_ENABLE_BORDER_AGENT_PROXY)
AM_CONDITIONAL([OPENTHREAD_ENABLE_BORDER_AGENT_PROXY], [test "${enable_border_agent_proxy}" = "yes"])
AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_BORDER_AGENT_PROXY],[${OPENTHREAD_ENABLE_BORDER_AGENT_PROXY}],[Define to 1 to enable the border agent proxy feature.])
#
# Thread Commissioner
#
@@ -1269,6 +1300,7 @@ AC_MSG_NOTICE([
OpenThread NCP-FTD support : ${enable_ncp_app_ftd}
OpenThread NCP-BUS Configuration : ${with_ncp_bus}
OpenThread builtin mbedtls support : ${enable_builtin_mbedtls}
OpenThread Border Agent Proxy support : ${enable_border_agent_proxy}
OpenThread Commissioner support : ${enable_commissioner}
OpenThread Joiner support : ${enable_joiner}
OpenThread DTLS support : ${enable_dtls}
@@ -149,6 +149,8 @@ Currently defined values are:
* 49: `CAP_ROLE_SLEEPY`
* 52: `CAP_NET_THREAD_1_0`
* 512: `CAP_MAC_WHITELIST`
* 1024: `CAP_THREAD_COMMISSIONER`
* 1025: `CAP_THREAD_BA_PROXY`
Additionally, future capability allocations SHALL be made from the
following allocation plan:
@@ -254,3 +254,19 @@ When the Extended address is ommited all Devices which provided a valid PSKd are
* Packed-Encoding: `b`
Set to true to enable the native commissioner. It is mandatory before adding the joiner to the network.
### PROP 5393: PROP_THREAD_BA_PROXY_ENABLED {#prop-thread-ba-proxy-enabled}
* Type: Read-Write
* Packed-Encoding: `b`
Set to true to enable the border agent proxy.
### PROP 5394: PROP_THREAD_BA_PROXY_STREAM {#prop-thread-ba-proxy-stream}
* Type: Read-Write-Stream
* Packed-Encoding: `dSS`
Octects: | *n* | 2 | 2
---------|------|---------|------
Fields: | CoAP | locator | port
+2 -1
View File
@@ -90,8 +90,9 @@ configure_OPTIONS = \
--enable-raw-link-api=yes \
--with-examples=posix \
--with-platform-info=POSIX \
--enable-cert-log \
--enable-application-coap \
--enable-border-agent-proxy \
--enable-cert-log \
--enable-commissioner \
--enable-dhcp6-client \
--enable-dhcp6-server \
+3
View File
@@ -62,6 +62,9 @@
/* Define to 1 to enable MAC whitelist/blacklist feature. */
#define OPENTHREAD_ENABLE_MAC_WHITELIST 1
/* Define to 1 to enable border agent proxy feature. */
#define OPENTHREAD_ENABLE_BORDER_AGENT_PROXY 0
/* Define to 1 to enable raw link-layer API. */
#ifdef _KERNEL_MODE
#define OPENTHREAD_ENABLE_RAW_LINK_API 0
+1
View File
@@ -48,6 +48,7 @@ PRETTY_SUBDIRS = \
openthread_headers = \
cli.h \
border_agent_proxy.h \
coap.h \
commissioner.h \
crypto.h \
+128
View File
@@ -0,0 +1,128 @@
/*
* Copyright (c) 2017, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief
* This file includes the OpenThread API for Border Agent Proxy feature.
*/
#ifndef OPENTHREAD_BORDER_AGENT_PROXY_H_
#define OPENTHREAD_BORDER_AGENT_PROXY_H_
#ifdef OPENTHREAD_CONFIG_FILE
#include OPENTHREAD_CONFIG_FILE
#else
#include <openthread-config.h>
#endif
#include "openthread/types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup border-agent-proxy Border Agent Proxy
*
* @brief
* This module includes functions for signal border agent proxy feature.
*
* @{
*
*/
/**
* This function pointer is called when a CoAP packet for border agent is received.
*
* @param[in] aMessage A pointer to the CoAP Message.
* @param[in] aContext A pointer to application-specific context.
*
*/
typedef void (*otBorderAgentProxyStreamHandler)(otMessage *aMessage, uint16_t aLocator, uint16_t aPort, void *aContext);
/**
* Start the border agent proxy.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aHandler A pointer to a function called to deliver packet to border agent.
* @param[in] aContext A pointer to application-specific context.
*
* @retval kThreadError_None Successfully started the border agent proxy.
* @retval kThreadError_Already Border agent proxy has been started before.
*
*/
ThreadError otBorderAgentProxyStart(otInstance *aInstance, otBorderAgentProxyStreamHandler aHandler, void *aContext);
/**
* Stop the border agent proxy.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @retval kThreadError_None Successfully stopped the border agent proxy.
* @retval kThreadError_Already Border agent proxy is already stopped.
*
*/
ThreadError otBorderAgentProxyStop(otInstance *aInstance);
/**
* Send packet through border agent proxy.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aMessage A pointer to the CoAP Message.
* @param[in] aLocator Rloc of destination.
* @param[in] aPort Port of destination.
*
* @retval kThreadError_None Successfully send the message.
* @retval kThreadError_InvalidState Border agent proxy is not started.
*
* @warning No matter the call success or fail, the message is freed.
*
*/
ThreadError otBorderAgentProxySend(otInstance *aInstance, otMessage *aMessage,
uint16_t aLocator, uint16_t aPort);
/**
* Get the border agent proxy status (enabled/disabled)
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @returns The border agent proxy status (true if enabled, false otherwise).
*/
bool otBorderAgentProxyIsEnabled(otInstance *aInstance);
/**
* @}
*
*/
#ifdef __cplusplus
} // extern "C"
#endif
#endif // OPENTHREAD_BORDER_AGENT_PROXY_H_
+1 -1
View File
@@ -29,7 +29,7 @@
/**
* @file
* @brief
* This file includes the OenThread API for jam detection feature.
* This file includes the OpenThread API for jam detection feature.
*/
#ifndef OPENTHREAD_JAM_DETECTION_H_
+3
View File
@@ -91,6 +91,7 @@ libopenthread_mtd_a_CPPFLAGS = \
#
SOURCES_COMMON = \
api/border_agent_proxy_api.cpp \
api/coap_api.cpp \
api/commissioner_api.cpp \
api/crypto_api.cpp \
@@ -136,6 +137,7 @@ SOURCES_COMMON = \
mac/mac_frame.cpp \
mac/mac_whitelist.cpp \
meshcop/announce_begin_client.cpp \
meshcop/border_agent_proxy.cpp \
meshcop/commissioner.cpp \
meshcop/dataset.cpp \
meshcop/dataset_manager.cpp \
@@ -269,6 +271,7 @@ HEADERS_COMMON = \
mac/mac_whitelist_impl.hpp \
mac/mac_whitelist_stub.hpp \
meshcop/announce_begin_client.hpp \
meshcop/border_agent_proxy.hpp \
meshcop/commissioner.hpp \
meshcop/dataset.hpp \
meshcop/dataset_manager.hpp \
+63
View File
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2017, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements the OpenThread Border Agent Proxy API.
*/
#include "openthread/border_agent_proxy.h"
#include "openthread-instance.h"
using namespace Thread;
#if OPENTHREAD_FTD && OPENTHREAD_ENABLE_BORDER_AGENT_PROXY
ThreadError otBorderAgentProxyStart(otInstance *aInstance, otBorderAgentProxyStreamHandler aBorderAgentProxyCallback,
void *aContext)
{
return aInstance->mThreadNetif.GetBorderAgentProxy().Start(aBorderAgentProxyCallback, aContext);
}
ThreadError otBorderAgentProxyStop(otInstance *aInstance)
{
return aInstance->mThreadNetif.GetBorderAgentProxy().Stop();
}
ThreadError otBorderAgentProxySend(otInstance *aInstance, otMessage *aMessage, uint16_t aLocator, uint16_t aPort)
{
return aInstance->mThreadNetif.GetBorderAgentProxy().Send(*static_cast<Message *>(aMessage), aLocator, aPort);
}
bool otBorderAgentProxyIsEnabled(otInstance *aInstance)
{
return aInstance->mThreadNetif.GetBorderAgentProxy().IsEnabled();
}
#endif // OPENTHREAD_FTD && OPENTHREAD_ENABLE_BORDER_AGENT_PROXY
+178
View File
@@ -0,0 +1,178 @@
/*
* Copyright (c) 2017, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements the border agent proxy.
*/
#define WPP_NAME "border_agent_proxy.tmh"
#ifdef OPENTHREAD_CONFIG_FILE
#include OPENTHREAD_CONFIG_FILE
#else
#include <openthread-config.h>
#endif
#include <openthread/types.h>
#include <coap/coap_header.hpp>
#include <thread/thread_uris.hpp>
#include <thread/thread_tlvs.hpp>
#include <net/ip6_address.hpp>
#include "border_agent_proxy.hpp"
#if OPENTHREAD_FTD && OPENTHREAD_ENABLE_BORDER_AGENT_PROXY
namespace Thread {
namespace MeshCoP {
BorderAgentProxy::BorderAgentProxy(const Ip6::Address &aMeshLocal16, Coap::Server &aCoapServer,
Coap::Client &aCoapClient):
mRelayReceive(OPENTHREAD_URI_RELAY_RX, &BorderAgentProxy::HandleRelayReceive, this),
mStreamHandler(NULL),
mContext(NULL),
mMeshLocal16(aMeshLocal16),
mCoapServer(aCoapServer),
mCoapClient(aCoapClient)
{
}
ThreadError BorderAgentProxy::Start(otBorderAgentProxyStreamHandler aStreamHandler, void *aContext)
{
ThreadError error = kThreadError_None;
VerifyOrExit(!mStreamHandler, error = kThreadError_Already);
mCoapServer.AddResource(mRelayReceive);
mStreamHandler = aStreamHandler;
mContext = aContext;
exit:
return error;
}
ThreadError BorderAgentProxy::Stop(void)
{
ThreadError error = kThreadError_None;
VerifyOrExit(mStreamHandler != NULL, error = kThreadError_Already);
mCoapServer.RemoveResource(mRelayReceive);
mStreamHandler = NULL;
exit:
return error;
}
bool BorderAgentProxy::IsEnabled(void) const
{
return mStreamHandler != NULL;
}
void BorderAgentProxy::HandleRelayReceive(void *aContext, otCoapHeader *aHeader, otMessage *aMessage,
const otMessageInfo *aMessageInfo)
{
static_cast<BorderAgentProxy *>(aContext)->DeliverMessage(
*static_cast<Coap::Header *>(aHeader), *static_cast<Message *>(aMessage),
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
}
void BorderAgentProxy::HandleResponse(void *aContext, otCoapHeader *aHeader, otMessage *aMessage,
const otMessageInfo *aMessageInfo, ThreadError aResult)
{
VerifyOrExit(aResult == kThreadError_None);
static_cast<BorderAgentProxy *>(aContext)->DeliverMessage(*static_cast<Coap::Header *>(aHeader),
*static_cast<Message *>(aMessage),
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
exit:
return;
}
void BorderAgentProxy::DeliverMessage(Coap::Header &aHeader, Message &aMessage,
const Ip6::MessageInfo &aMessageInfo)
{
ThreadError error = kThreadError_None;
uint16_t rloc;
uint16_t port;
Message *message = NULL;
VerifyOrExit(mStreamHandler != NULL, error = kThreadError_InvalidState);
VerifyOrExit((message = aMessage.Clone()) != NULL, error = kThreadError_NoBufs);
message->RemoveHeader(message->GetOffset() - aHeader.GetLength());
rloc = HostSwap16(aMessageInfo.GetPeerAddr().mFields.m16[7]);
port = aMessageInfo.GetPeerPort();
mStreamHandler(message, rloc, port, mContext);
exit:
if (error != kThreadError_None && message != NULL)
{
message->Free();
}
}
ThreadError BorderAgentProxy::Send(Message &aMessage, uint16_t aLocator, uint16_t aPort)
{
ThreadError error = kThreadError_None;
Ip6::MessageInfo messageInfo;
VerifyOrExit(mStreamHandler != NULL, error = kThreadError_InvalidState);
messageInfo.SetPeerAddr(mMeshLocal16);
messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(aLocator);
messageInfo.SetPeerPort(aPort);
if (aPort == kCoapUdpPort)
{
// this is request to server, send with client
error = mCoapClient.SendMessage(aMessage, messageInfo, BorderAgentProxy::HandleResponse, this);
}
else
{
error = mCoapServer.SendMessage(aMessage, messageInfo);
}
exit:
if (error != kThreadError_None)
{
aMessage.Free();
}
return error;
}
} // namespace MeshCoP
} // namespace Thread
#endif // OPENTHREAD_FTD && OPENTHREAD_ENABLE_BORDER_AGENT_PROXY
+125
View File
@@ -0,0 +1,125 @@
/*
* Copyright (c) 2017, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes definitions for border agent proxy.
*/
#ifndef BORDER_AGENT_PROXY_HPP_
#define BORDER_AGENT_PROXY_HPP_
#include <openthread-core-config.h>
#include <openthread/border_agent_proxy.h>
#include <coap/coap_client.hpp>
#include <coap/coap_server.hpp>
namespace Thread {
namespace MeshCoP {
class BorderAgentProxy
{
public:
/**
* This constructor initializes the border agent proxy.
*
* @param[in] aMeshLocal16 A reference to the Mesh Local Routing Locator.
* @param[in] aCoapServer A reference to the Management CoAP Server.
* @param[in] aCoapClient A reference to the CoAP Client.
*
*/
BorderAgentProxy(const Ip6::Address &aMeshLocal16, Coap::Server &aCoapServer, Coap::Client &aCoapClient);
/**
* This method enables the border agent proxy service.
*
* @retval kThreadError_None Successfully started the service.
* @retval kThreadError_Already The service already started.
*
*/
ThreadError Start(otBorderAgentProxyStreamHandler aStreamHandler, void *aContext);
/**
* This method disables the border agent proxy service.
*
* @retval kThreadError_None Successfully stopped the border agent proxy service.
* @retval kThreadError_Already The service already stopped.
*
*/
ThreadError Stop(void);
/**
* This method sends the message into the thread network.
*
* @param[in] aMessage A reference to the message to send.
* @param[in] aLocator The destination's RLOC16 or ALOC16.
* @param[in] aPort The destination port.
*
* @retval kThreadError_None Successfully send the message.
* @retval kThreadError_InvalidState Border agent proxy is not started.
*
* @warning No matter the call success or fail, the message is freed.
*
*/
ThreadError Send(Message &aMessage, uint16_t aLocator, uint16_t aPort);
/**
* This method indicates whether or not the border agent proxy service is enabled.
*
* @retval TRUE If the service is enabled.
* @retval FALSE If the service is disabled.
*
*/
bool IsEnabled(void) const;
private:
static void HandleRelayReceive(void *aContext, otCoapHeader *aHeader, otMessage *aMessage,
const otMessageInfo *aMessageInfo);
static void HandleResponse(void *aContext, otCoapHeader *aHeader, otMessage *aMessage,
const otMessageInfo *aMessageInfo, ThreadError aResult);
void DeliverMessage(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
Coap::Resource mRelayReceive;
otBorderAgentProxyStreamHandler mStreamHandler;
void *mContext;
const Ip6::Address &mMeshLocal16;
Coap::Server &mCoapServer;
Coap::Client &mCoapClient;
};
} // namespace MeshCoP
} // namespace Thread
#endif // BORDER_AGENT_PROXY_HPP_
+3
View File
@@ -93,6 +93,9 @@ ThreadNetif::ThreadNetif(Ip6::Ip6 &aIp6):
mJamDetector(*this),
#endif // OPENTHREAD_ENABLE_JAM_DETECTTION
#if OPENTHREAD_FTD
#if OPENTHREAD_ENABLE_BORDER_AGENT_PROXY
mBorderAgentProxy(mMleRouter.GetMeshLocal16(), mCoapServer, mCoapClient),
#endif // OPENTHREAD_ENABLE_BORDER_AGENT_PROXY
mJoinerRouter(*this),
mLeader(*this),
#endif // OPENTHREAD_FTD
+11
View File
@@ -71,6 +71,10 @@
#include <utils/jam_detector.hpp>
#endif // OPENTHREAD_ENABLE_JAM_DETECTION
#if OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
#include <meshcop/border_agent_proxy.hpp>
#endif // OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
#if OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
#include <meshcop/commissioner.hpp>
#endif // OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
@@ -321,6 +325,10 @@ public:
Utils::JamDetector &GetJamDetector(void) { return mJamDetector; }
#endif // OPENTHREAD_ENABLE_JAM_DETECTION
#if OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
MeshCoP::BorderAgentProxy &GetBorderAgentProxy(void) { return mBorderAgentProxy; }
#endif // OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
/**
* This method returns the pointer to the parent otInstance structure.
*
@@ -374,6 +382,9 @@ private:
#endif // OPENTHREAD_ENABLE_JAM_DETECTION
#if OPENTHREAD_FTD
#if OPENTHREAD_ENABLE_BORDER_AGENT_PROXY
MeshCoP::BorderAgentProxy mBorderAgentProxy;
#endif // OPENTHREAD_ENABLE_BORDER_AGENT_PROXY
MeshCoP::JoinerRouter mJoinerRouter;
MeshCoP::Leader mLeader;
#endif // OPENTHREAD_FTD
+190
View File
@@ -43,6 +43,10 @@
#include "openthread/diag.h"
#include "openthread/icmp6.h"
#if OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
#include "openthread/border_agent_proxy.h"
#endif
#if OPENTHREAD_ENABLE_JAM_DETECTION
#include "openthread/jam_detection.h"
#endif
@@ -193,6 +197,10 @@ const NcpBase::GetPropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] =
{ SPINEL_PROP_JAM_DETECT_HISTORY_BITMAP, &NcpBase::GetPropertyHandler_JAM_DETECT_HISTORY_BITMAP },
#endif
#if OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
{ SPINEL_PROP_THREAD_BA_PROXY_ENABLED, &NcpBase::GetPropertyHandler_BA_PROXY_ENABLED },
#endif
{ SPINEL_PROP_CNTR_TX_PKT_TOTAL, &NcpBase::GetPropertyHandler_MAC_CNTR },
{ SPINEL_PROP_CNTR_TX_PKT_ACK_REQ, &NcpBase::GetPropertyHandler_MAC_CNTR },
{ SPINEL_PROP_CNTR_TX_PKT_ACKED, &NcpBase::GetPropertyHandler_MAC_CNTR },
@@ -311,6 +319,11 @@ const NcpBase::SetPropertyHandlerEntry NcpBase::mSetPropertyHandlerTable[] =
{ SPINEL_PROP_JAM_DETECT_BUSY, &NcpBase::SetPropertyHandler_JAM_DETECT_BUSY },
#endif
#if OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
{ SPINEL_PROP_THREAD_BA_PROXY_ENABLED, &NcpBase::SetPropertyHandler_BA_PROXY_ENABLED },
{ SPINEL_PROP_THREAD_BA_PROXY_STREAM, &NcpBase::SetPropertyHandler_THREAD_BA_PROXY_STREAM },
#endif // OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
#if OPENTHREAD_ENABLE_DIAG
{ SPINEL_PROP_NEST_STREAM_MFG, &NcpBase::SetPropertyHandler_NEST_STREAM_MFG },
#endif
@@ -596,6 +609,53 @@ ThreadError NcpBase::OutboundFrameEnd(void)
return mTxFrameBuffer.InFrameEnd();
}
#if OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
void NcpBase::HandleBorderAgentProxyStream(otMessage *aMessage, uint16_t aLocator, uint16_t aPort, void *aContext)
{
static_cast<NcpBase *>(aContext)->HandleBorderAgentProxyStream(aMessage, aLocator, aPort);
}
void NcpBase::HandleBorderAgentProxyStream(otMessage *aMessage, uint16_t aLocator, uint16_t aPort)
{
ThreadError errorCode = kThreadError_None;
uint16_t length = otMessageGetLength(aMessage);
SuccessOrExit(errorCode = OutboundFrameBegin());
SuccessOrExit(
errorCode = OutboundFrameFeedPacked(
SPINEL_DATATYPE_COMMAND_PROP_S SPINEL_DATATYPE_UINT16_S,
SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0,
SPINEL_CMD_PROP_VALUE_IS,
SPINEL_PROP_THREAD_BA_PROXY_STREAM,
length
));
SuccessOrExit(errorCode = OutboundFrameFeedMessage(aMessage));
SuccessOrExit(errorCode = OutboundFrameFeedPacked(SPINEL_DATATYPE_UINT16_S SPINEL_DATATYPE_UINT16_S, aLocator, aPort));
// Set the aMessage pointer to NULL, to indicate that it does not need to be freed at the exit.
// The aMessage is now owned by the OutboundFrame and will be freed when the frame is either successfully sent and
// then removed, or if the frame gets discarded.
aMessage = NULL;
SuccessOrExit(errorCode = OutboundFrameSend());
exit:
if (aMessage != NULL)
{
otMessageFree(aMessage);
}
if (errorCode != kThreadError_None)
{
SendLastStatus(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_STATUS_DROPPED);
}
}
#endif // OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
// ----------------------------------------------------------------------------
// MARK: Outbound Datagram Handling
// ----------------------------------------------------------------------------
@@ -1785,6 +1845,10 @@ ThreadError NcpBase::GetPropertyHandler_CAPS(uint8_t header, spinel_prop_key_t k
SuccessOrExit(errorCode = OutboundFrameFeedPacked(SPINEL_DATATYPE_UINT_PACKED_S, SPINEL_CAP_NEST_LEGACY_INTERFACE));
#endif
#if OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
SuccessOrExit(errorCode = OutboundFrameFeedPacked(SPINEL_DATATYPE_UINT_PACKED_S, SPINEL_CAP_THREAD_BA_PROXY));
#endif
// End adding capabilities /////////////////////////////////////////////////
SuccessOrExit(errorCode = OutboundFrameSend());
@@ -2832,6 +2896,19 @@ ThreadError NcpBase::GetPropertyHandler_STREAM_NET(uint8_t header, spinel_prop_k
return SendLastStatus(header, SPINEL_STATUS_UNIMPLEMENTED);
}
#if OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
ThreadError NcpBase::GetPropertyHandler_BA_PROXY_ENABLED(uint8_t header, spinel_prop_key_t key)
{
return SendPropertyUpdate(
header,
SPINEL_CMD_PROP_VALUE_IS,
key,
SPINEL_DATATYPE_BOOL_S,
otBorderAgentProxyIsEnabled(mInstance)
);
}
#endif // OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
#if OPENTHREAD_ENABLE_JAM_DETECTION
ThreadError NcpBase::GetPropertyHandler_JAM_DETECT_ENABLE(uint8_t header, spinel_prop_key_t key)
@@ -4493,6 +4570,75 @@ ThreadError NcpBase::SetPropertyHandler_STREAM_NET_INSECURE(uint8_t header, spin
return errorCode;
}
#if OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
ThreadError NcpBase::SetPropertyHandler_THREAD_BA_PROXY_STREAM(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len)
{
spinel_ssize_t parsedLength;
ThreadError errorCode = kThreadError_None;
const uint8_t *frame_ptr(NULL);
unsigned int frame_len(0);
uint16_t locator;
uint16_t port;
// THREAD_BA_PROXY_STREAM requires layer 2 security.
otMessage *message = otIp6NewMessage(mInstance, true);
if (message == NULL)
{
errorCode = kThreadError_NoBufs;
}
else
{
parsedLength = spinel_datatype_unpack(
value_ptr,
value_len,
SPINEL_DATATYPE_DATA_WLEN_S SPINEL_DATATYPE_UINT16_S SPINEL_DATATYPE_UINT16_S,
&frame_ptr,
&frame_len,
&locator,
&port
);
if (parsedLength > 0)
{
errorCode = otMessageAppend(message, frame_ptr, static_cast<uint16_t>(frame_len));
}
else
{
errorCode = kThreadError_Parse;
}
}
if (errorCode == kThreadError_None)
{
errorCode = otBorderAgentProxySend(mInstance, message, locator, port);
}
else if (message)
{
otMessageFree(message);
}
if (errorCode == kThreadError_None)
{
if (SPINEL_HEADER_GET_TID(header) != 0)
{
// Only send a successful status update if
// there was a transaction id in the header.
errorCode = SendLastStatus(header, SPINEL_STATUS_OK);
}
}
else
{
errorCode = SendLastStatus(header, ThreadErrorToSpinelStatus(errorCode));
}
(void)key;
return errorCode;
}
#endif // OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
ThreadError NcpBase::SetPropertyHandler_STREAM_NET(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len)
{
@@ -5484,6 +5630,50 @@ ThreadError NcpBase::SetPropertyHandler_THREAD_NETWORK_ID_TIMEOUT(uint8_t header
return errorCode;
}
#if OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
ThreadError NcpBase::SetPropertyHandler_BA_PROXY_ENABLED(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len)
{
bool isEnabled;
spinel_ssize_t parsedLength;
ThreadError errorCode = kThreadError_None;
parsedLength = spinel_datatype_unpack(
value_ptr,
value_len,
SPINEL_DATATYPE_BOOL_S,
&isEnabled
);
if (parsedLength > 0)
{
if (isEnabled)
{
SuccessOrExit(errorCode = otBorderAgentProxyStart(mInstance, &NcpBase::HandleBorderAgentProxyStream, this));
}
else
{
SuccessOrExit(errorCode = otBorderAgentProxyStop(mInstance));
}
SuccessOrExit(errorCode = HandleCommandPropertyGet(header, key));
}
else
{
errorCode = kThreadError_Parse;
}
exit:
if (errorCode != kThreadError_None)
{
errorCode = SendLastStatus(header, ThreadErrorToSpinelStatus(errorCode));
}
return errorCode;
}
#endif // OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
#if OPENTHREAD_ENABLE_JAM_DETECTION
ThreadError NcpBase::SetPropertyHandler_JAM_DETECT_ENABLE(uint8_t header, spinel_prop_key_t key,
+14
View File
@@ -144,6 +144,15 @@ private:
ThreadError OutboundFrameSend(void);
#if OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
/**
* Trampoline for HandleBorderAgentProxyStream().
*/
static void HandleBorderAgentProxyStream(otMessage *aMessage, uint16_t aLocator, uint16_t aPort, void *aContext);
void HandleBorderAgentProxyStream(otMessage *aMessage, uint16_t aLocator, uint16_t aPort);
#endif // OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
/**
* Trampoline for HandleDatagramFromStack().
*/
@@ -401,6 +410,7 @@ private:
ThreadError GetPropertyHandler_THREAD_COMMISSIONER_ENABLED(uint8_t header, spinel_prop_key_t key);
#endif
ThreadError GetPropertyHandler_BA_PROXY_ENABLED(uint8_t header, spinel_prop_key_t key);
#if OPENTHREAD_ENABLE_JAM_DETECTION
ThreadError GetPropertyHandler_JAM_DETECT_ENABLE(uint8_t header, spinel_prop_key_t key);
ThreadError GetPropertyHandler_JAM_DETECTED(uint8_t header, spinel_prop_key_t key);
@@ -466,6 +476,8 @@ private:
ThreadError SetPropertyHandler_THREAD_RLOC16_DEBUG_PASSTHRU(uint8_t header, spinel_prop_key_t key,
const uint8_t *value_ptr, uint16_t value_len);
ThreadError SetPropertyHandler_THREAD_BA_PROXY_STREAM(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len);
#if OPENTHREAD_ENABLE_RAW_LINK_API
ThreadError SetPropertyHandler_PHY_ENABLED(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len);
@@ -525,6 +537,8 @@ private:
const uint8_t *value_ptr, uint16_t value_len);
#endif
ThreadError SetPropertyHandler_BA_PROXY_ENABLED(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len);
#if OPENTHREAD_ENABLE_JAM_DETECTION
ThreadError SetPropertyHandler_JAM_DETECT_ENABLE(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len);
+8
View File
@@ -1171,6 +1171,14 @@ spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
ret = "SPINEL_PROP_THREAD_COMMISSIONER_ENABLED";
break;
case SPINEL_PROP_THREAD_BA_PROXY_ENABLED:
ret = "SPINEL_PROP_THREAD_BA_PROXY_ENABLED";
break;
case SPINEL_PROP_THREAD_BA_PROXY_STREAM:
ret = "SPINEL_PROP_THREAD_BA_PROXY_STREAM";
break;
case SPINEL_PROP_THREAD_RLOC16_DEBUG_PASSTHRU:
ret = "PROP_THREAD_RLOC16_DEBUG_PASSTHRU";
break;
+17
View File
@@ -360,6 +360,11 @@ enum
SPINEL_CAP_MAC_RAW = (SPINEL_CAP_OPENTHREAD__BEGIN + 1),
SPINEL_CAP_OPENTHREAD__END = 640,
SPINEL_CAP_THREAD__BEGIN = 1024,
SPINEL_CAP_THREAD_COMMISSIONER = (SPINEL_CAP_THREAD__BEGIN + 0),
SPINEL_CAP_THREAD_BA_PROXY = (SPINEL_CAP_THREAD__BEGIN + 1),
SPINEL_CAP_THREAD__END = 1152,
SPINEL_CAP_NEST__BEGIN = 15296,
SPINEL_CAP_NEST_LEGACY_INTERFACE = (SPINEL_CAP_NEST__BEGIN + 0),
SPINEL_CAP_NEST_LEGACY_NET_WAKE = (SPINEL_CAP_NEST__BEGIN + 1),
@@ -826,6 +831,18 @@ typedef enum
SPINEL_PROP_THREAD_COMMISSIONER_ENABLED
= SPINEL_PROP_THREAD_EXT__BEGIN + 16,
/// Thread border agent proxy enable
/** Format `b`
*
* Default value is `false`.
*/
SPINEL_PROP_THREAD_BA_PROXY_ENABLED = SPINEL_PROP_THREAD_EXT__BEGIN + 17,
/// Thread border agent proxy stream
/** Format `dSS`
*/
SPINEL_PROP_THREAD_BA_PROXY_STREAM = SPINEL_PROP_THREAD_EXT__BEGIN + 18,
SPINEL_PROP_THREAD_EXT__END = 0x1600,
SPINEL_PROP_IPV6__BEGIN = 0x60,