diff --git a/etc/visual-studio/libopenthread.vcxproj b/etc/visual-studio/libopenthread.vcxproj
index 5d9541738..46ddf244e 100644
--- a/etc/visual-studio/libopenthread.vcxproj
+++ b/etc/visual-studio/libopenthread.vcxproj
@@ -72,12 +72,9 @@
-
-
+
-
-
-
+
@@ -146,12 +143,9 @@
-
-
+
-
-
-
+
diff --git a/etc/visual-studio/libopenthread.vcxproj.filters b/etc/visual-studio/libopenthread.vcxproj.filters
index b39290f9b..2834e2da5 100644
--- a/etc/visual-studio/libopenthread.vcxproj.filters
+++ b/etc/visual-studio/libopenthread.vcxproj.filters
@@ -114,22 +114,13 @@
Source Files\api
-
- Source Files\coap
-
-
+
Source Files\coap
Source Files\coap
-
- Source Files\coap
-
-
- Source Files\coap
-
-
+
Source Files\coap
@@ -329,22 +320,13 @@
-
- Header Files\coap
-
-
+
Header Files\coap
Header Files\coap
-
- Header Files\coap
-
-
- Header Files\coap
-
-
+
Header Files\coap
diff --git a/etc/visual-studio/libopenthread_k.vcxproj b/etc/visual-studio/libopenthread_k.vcxproj
index b04e77e9f..4b957f91b 100644
--- a/etc/visual-studio/libopenthread_k.vcxproj
+++ b/etc/visual-studio/libopenthread_k.vcxproj
@@ -81,12 +81,9 @@
-
-
+
-
-
-
+
@@ -177,12 +174,9 @@
-
-
+
-
-
-
+
diff --git a/etc/visual-studio/libopenthread_k.vcxproj.filters b/etc/visual-studio/libopenthread_k.vcxproj.filters
index 97cf5ad50..4184400bd 100644
--- a/etc/visual-studio/libopenthread_k.vcxproj.filters
+++ b/etc/visual-studio/libopenthread_k.vcxproj.filters
@@ -114,22 +114,13 @@
Source Files\api
-
- Source Files\coap
-
-
+
Source Files\coap
Source Files\coap
-
- Source Files\coap
-
-
- Source Files\coap
-
-
+
Source Files\coap
@@ -329,22 +320,13 @@
Header Files
-
- Header Files\coap
-
-
+
Header Files\coap
Header Files\coap
-
- Header Files\coap
-
-
- Header Files\coap
-
-
+
Header Files\coap
diff --git a/include/openthread/coap.h b/include/openthread/coap.h
index 4c650e67b..6f355e863 100644
--- a/include/openthread/coap.h
+++ b/include/openthread/coap.h
@@ -449,11 +449,12 @@ ThreadError otCoapSendRequest(otInstance *aInstance, otMessage *aMessage, const
* This function starts the CoAP server.
*
* @param[in] aInstance A pointer to an OpenThread instance.
+ * @param[in] aPort The local UDP port to bind to.
*
* @retval kThreadError_None Successfully started the CoAP server.
*
*/
-ThreadError otCoapServerStart(otInstance *aInstance);
+ThreadError otCoapStart(otInstance *aInstance, uint16_t aPort);
/**
* This function stops the CoAP server.
@@ -463,18 +464,7 @@ ThreadError otCoapServerStart(otInstance *aInstance);
* @retval kThreadError_None Successfully stopped the CoAP server.
*
*/
-ThreadError otCoapServerStop(otInstance *aInstance);
-
-/**
- * This function sets CoAP server's port number.
- *
- * @param[in] aInstance A pointer to an OpenThread instance.
- * @param[in] aPort A port number to set.
- *
- * @retval kThreadError_None Binding with a port succeeded.
- *
- */
-ThreadError otCoapServerSetPort(otInstance *aInstance, uint16_t aPort);
+ThreadError otCoapStop(otInstance *aInstance);
/**
* This function adds a resource to the CoAP server.
@@ -486,7 +476,7 @@ ThreadError otCoapServerSetPort(otInstance *aInstance, uint16_t aPort);
* @retval kThreadError_Already The @p aResource was already added.
*
*/
-ThreadError otCoapServerAddResource(otInstance *aInstance, otCoapResource *aResource);
+ThreadError otCoapAddResource(otInstance *aInstance, otCoapResource *aResource);
/**
* This function removes a resource from the CoAP server.
@@ -495,7 +485,7 @@ ThreadError otCoapServerAddResource(otInstance *aInstance, otCoapResource *aReso
* @param[in] aResource A pointer to the resource.
*
*/
-void otCoapServerRemoveResource(otInstance *aInstance, otCoapResource *aResource);
+void otCoapRemoveResource(otInstance *aInstance, otCoapResource *aResource);
/**
* This function sends a CoAP response from the server.
diff --git a/include/openthread/platform/logging-windows.h b/include/openthread/platform/logging-windows.h
index 1ea015628..0f55f0ad1 100644
--- a/include/openthread/platform/logging-windows.h
+++ b/include/openthread/platform/logging-windows.h
@@ -57,12 +57,13 @@
WPP_DEFINE_BIT(OT_MAC) /* 0x00000400 */ \
WPP_DEFINE_BIT(OT_MEM) /* 0x00000800 */ \
WPP_DEFINE_BIT(OT_NCP) /* 0x00001000 */ \
- WPP_DEFINE_BIT(OT_COAP) /* 0x00002000 */ \
+ WPP_DEFINE_BIT(OT_MESHCOP) /* 0x00002000 */ \
WPP_DEFINE_BIT(OT_DEFAULT) /* 0x00004000 */ \
WPP_DEFINE_BIT(OT_MBEDTLS) /* 0x00008000 */ \
WPP_DEFINE_BIT(OT_DUMP) /* 0x00010000 */ \
WPP_DEFINE_BIT(OT_NDIAG) /* 0x00020000 */ \
- WPP_DEFINE_BIT(API_DEFAULT) /* 0x00040000 */ \
+ WPP_DEFINE_BIT(OT_COAP) /* 0x00040000 */ \
+ WPP_DEFINE_BIT(API_DEFAULT) /* 0x00080000 */ \
)
#define WPP_LEVEL_FLAGS_LOGGER(lvl,flag) WPP_FLAG_LOGGER(flag)
@@ -197,31 +198,31 @@
// otLogDebgNcp{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=OT_NCP}(CTX, MSG, ...);
// end_wpp
-// ==COAP==
+// ==MESHCOP==
// begin_wpp config
-// USEPREFIX (otLogCritMeshCoP, "[%p]COAP%!SPACE!", CTX);
-// otLogCritMeshCoP{LEVEL=TRACE_LEVEL_ERROR,FLAGS=OT_COAP}(CTX, MSG, ...);
+// USEPREFIX (otLogCritMeshCoP, "[%p]MESHCOP%!SPACE!", CTX);
+// otLogCritMeshCoP{LEVEL=TRACE_LEVEL_ERROR,FLAGS=OT_MESHCOP}(CTX, MSG, ...);
// end_wpp
// begin_wpp config
-// USEPREFIX (otLogWarnMeshCoP, "[%p]COAP%!SPACE!", CTX);
-// otLogWarnMeshCoP{LEVEL=TRACE_LEVEL_WARNING,FLAGS=OT_COAP}(CTX, MSG, ...);
+// USEPREFIX (otLogWarnMeshCoP, "[%p]MESHCOP%!SPACE!", CTX);
+// otLogWarnMeshCoP{LEVEL=TRACE_LEVEL_WARNING,FLAGS=OT_MESHCOP}(CTX, MSG, ...);
// end_wpp
// begin_wpp config
-// USEPREFIX (otLogInfoMeshCoP, "[%p]COAP%!SPACE!", CTX);
-// otLogInfoMeshCoP{LEVEL=TRACE_LEVEL_INFORMATION,FLAGS=OT_COAP}(CTX, MSG, ...);
+// USEPREFIX (otLogInfoMeshCoP, "[%p]MESHCOP%!SPACE!", CTX);
+// otLogInfoMeshCoP{LEVEL=TRACE_LEVEL_INFORMATION,FLAGS=OT_MESHCOP}(CTX, MSG, ...);
// end_wpp
// begin_wpp config
-// USEPREFIX (otLogDebgMeshCoP, "[%p]COAP%!SPACE!", CTX);
-// otLogDebgMeshCoP{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=OT_COAP}(CTX, MSG, ...);
+// USEPREFIX (otLogDebgMeshCoP, "[%p]MESHCOP%!SPACE!", CTX);
+// otLogDebgMeshCoP{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=OT_MESHCOP}(CTX, MSG, ...);
// end_wpp
// begin_wpp config
-// USEPREFIX (otLogCertMeshCoP, "[%p]COAP%!SPACE!", CTX);
-// otLogCertMeshCoP{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=OT_COAP}(CTX, MSG, ...);
+// USEPREFIX (otLogCertMeshCoP, "[%p]MESHCOP%!SPACE!", CTX);
+// otLogCertMeshCoP{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=OT_MESHCOP}(CTX, MSG, ...);
// end_wpp
// ==MBEDTLS==
@@ -440,6 +441,34 @@
// otLogDebgNetDiag{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=OT_NDIAG}(CTX, MSG, ...);
// end_wpp
+// ==COAP==
+
+// begin_wpp config
+// USEPREFIX (otLogCritCoap, "[%p]COAP%!SPACE!", CTX);
+// otLogCritCoap{LEVEL=TRACE_LEVEL_ERROR,FLAGS=OT_COAP}(CTX, MSG, ...);
+// end_wpp
+
+// begin_wpp config
+// USEPREFIX (otLogWarnCoap, "[%p]COAP%!SPACE!", CTX);
+// otLogWarnCoap{LEVEL=TRACE_LEVEL_WARNING,FLAGS=OT_COAP}(CTX, MSG, ...);
+// end_wpp
+
+// begin_wpp config
+// USEPREFIX (otLogInfoCoap, "[%p]COAP%!SPACE!", CTX);
+// otLogInfoCoap{LEVEL=TRACE_LEVEL_INFORMATION,FLAGS=OT_COAP}(CTX, MSG, ...);
+// end_wpp
+
+// begin_wpp config
+// USEPREFIX (otLogInfoCoapErr, "[%p]COAP%!SPACE!", CTX);
+// otLogInfoCoapErr{LEVEL=TRACE_LEVEL_INFORMATION,FLAGS=OT_COAP}(CTX, EXP, MSG, ...);
+// USESUFFIX(otLogInfoCoapErr, ", %!otError!", EXP);
+// end_wpp
+
+// begin_wpp config
+// USEPREFIX (otLogDebgCoap, "[%p]COAP%!SPACE!", CTX);
+// otLogDebgCoap{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=OT_COAP}(CTX, MSG, ...);
+// end_wpp
+
// ==FUNC==
// begin_wpp config
diff --git a/include/openthread/platform/logging.h b/include/openthread/platform/logging.h
index 1b518cf88..b708034ac 100644
--- a/include/openthread/platform/logging.h
+++ b/include/openthread/platform/logging.h
@@ -91,6 +91,7 @@ typedef enum otLogRegion
kLogRegionMeshCoP = 10, ///< Mesh Commissioning Protocol
kLogRegionNetDiag = 11, ///< Network Diagnostic
kLogRegionPlatform = 12, ///< Platform
+ kLogRegionCoap = 13, ///< CoAP
} otLogRegion;
/**
diff --git a/include/openthread/types.h b/include/openthread/types.h
index 009233ade..5f6e5c9de 100644
--- a/include/openthread/types.h
+++ b/include/openthread/types.h
@@ -903,10 +903,10 @@ typedef struct otBufferInfo
uint16_t mMleBuffers; ///< The number of buffers in the MLE send queue.
uint16_t mArpMessages; ///< The number of messages in the ARP send queue.
uint16_t mArpBuffers; ///< The number of buffers in the ARP send queue.
- uint16_t mCoapClientMessages; ///< The number of messages in the CoAP client send queue.
- uint16_t mCoapClientBuffers; ///< The number of buffers in the CoAP client send queue.
- uint16_t mCoapServerMessages; ///< The number of messages in the CoAP server responses queue.
- uint16_t mCoapServerBuffers; ///< The number of buffers in the CoAP server responses queue.
+ uint16_t mCoapMessages; ///< The number of messages in the CoAP send queue.
+ uint16_t mCoapBuffers; ///< The number of buffers in the CoAP send queue.
+ uint16_t mCoapSecureMessages; ///< The number of messages in the CoAP secure send queue.
+ uint16_t mCoapSecureBuffers; ///< The number of buffers in the CoAP secure send queue.
} otBufferInfo;
/**
diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp
index cc1cb3f14..2518ef814 100644
--- a/src/cli/cli.cpp
+++ b/src/cli/cli.cpp
@@ -469,8 +469,8 @@ void Interpreter::ProcessBufferInfo(int argc, char *argv[])
sServer->OutputFormat("mpl: %d %d\r\n", bufferInfo.mMplMessages, bufferInfo.mMplBuffers);
sServer->OutputFormat("mle: %d %d\r\n", bufferInfo.mMleMessages, bufferInfo.mMleBuffers);
sServer->OutputFormat("arp: %d %d\r\n", bufferInfo.mArpMessages, bufferInfo.mArpBuffers);
- sServer->OutputFormat("coap client: %d %d\r\n", bufferInfo.mCoapClientMessages, bufferInfo.mCoapClientBuffers);
- sServer->OutputFormat("coap server: %d %d\r\n", bufferInfo.mCoapServerMessages, bufferInfo.mCoapServerBuffers);
+ sServer->OutputFormat("coap: %d %d\r\n", bufferInfo.mCoapMessages, bufferInfo.mCoapBuffers);
+ sServer->OutputFormat("coap secure: %d %d\r\n", bufferInfo.mCoapSecureMessages, bufferInfo.mCoapSecureBuffers);
AppendResult(kThreadError_None);
}
diff --git a/src/cli/cli_coap.cpp b/src/cli/cli_coap.cpp
index 305e72034..7796410e4 100644
--- a/src/cli/cli_coap.cpp
+++ b/src/cli/cli_coap.cpp
@@ -140,14 +140,14 @@ ThreadError Coap::ProcessServer(int argc, char *argv[])
if (strcmp(argv[0], "start") == 0)
{
- SuccessOrExit(error = otCoapServerStart(sInstance));
- SuccessOrExit(error = otCoapServerAddResource(sInstance, &sResource));
+ SuccessOrExit(error = otCoapStart(sInstance, OT_DEFAULT_COAP_PORT));
+ SuccessOrExit(error = otCoapAddResource(sInstance, &sResource));
sServer->OutputFormat("Server started with resource '%s': ", sResource.mUriPath);
}
else if (strcmp(argv[0], "stop") == 0)
{
- otCoapServerRemoveResource(sInstance, &sResource);
- SuccessOrExit(error = otCoapServerStop(sInstance));
+ otCoapRemoveResource(sInstance, &sResource);
+ SuccessOrExit(error = otCoapStop(sInstance));
sServer->OutputFormat("Server stopped: ");
}
else if (strcmp(argv[0], "name") == 0)
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index b43090a86..e4e534305 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -113,12 +113,9 @@ SOURCES_COMMON = \
api/thread_api.cpp \
api/thread_ftd_api.cpp \
api/udp_api.cpp \
- coap/coap_base.cpp \
- coap/coap_client.cpp \
+ coap/coap.cpp \
coap/coap_header.cpp \
- coap/coap_server.cpp \
- coap/secure_coap_client.cpp \
- coap/secure_coap_server.cpp \
+ coap/coap_secure.cpp \
common/crc16.cpp \
common/logging.cpp \
common/message.cpp \
@@ -202,12 +199,9 @@ HEADERS_COMMON = \
openthread-core-default-config.h \
openthread-instance.h \
api/link_raw.hpp \
- coap/coap_base.hpp \
- coap/coap_client.hpp \
+ coap/coap.hpp \
coap/coap_header.hpp \
- coap/coap_server.hpp \
- coap/secure_coap_client.hpp \
- coap/secure_coap_server.hpp \
+ coap/coap_secure.hpp \
common/code_utils.hpp \
common/crc16.hpp \
common/debug.hpp \
diff --git a/src/core/api/coap_api.cpp b/src/core/api/coap_api.cpp
index 66ea20d59..0649224b9 100644
--- a/src/core/api/coap_api.cpp
+++ b/src/core/api/coap_api.cpp
@@ -135,7 +135,7 @@ otMessage *otCoapNewMessage(otInstance *aInstance, const otCoapHeader *aHeader)
{
Message *message;
VerifyOrExit(aHeader != NULL, message = NULL);
- message = aInstance->mThreadNetif.GetCoapClient().NewMessage(*(static_cast(aHeader)));
+ message = aInstance->mThreadNetif.GetCoap().NewMessage(*(static_cast(aHeader)));
exit:
return message;
}
@@ -143,40 +143,35 @@ exit:
ThreadError otCoapSendRequest(otInstance *aInstance, otMessage *aMessage, const otMessageInfo *aMessageInfo,
otCoapResponseHandler aHandler, void *aContext)
{
- return aInstance->mThreadNetif.GetCoapClient().SendMessage(
+ return aInstance->mThreadNetif.GetCoap().SendMessage(
*static_cast(aMessage),
*static_cast(aMessageInfo),
aHandler, aContext);
}
-ThreadError otCoapServerStart(otInstance *aInstance)
+ThreadError otCoapStart(otInstance *aInstance, uint16_t aPort)
{
- return aInstance->mApplicationCoapServer.Start();
+ return aInstance->mApplicationCoap.Start(aPort);
}
-ThreadError otCoapServerStop(otInstance *aInstance)
+ThreadError otCoapStop(otInstance *aInstance)
{
- return aInstance->mApplicationCoapServer.Stop();
+ return aInstance->mApplicationCoap.Stop();
}
-ThreadError otCoapServerSetPort(otInstance *aInstance, uint16_t aPort)
+ThreadError otCoapAddResource(otInstance *aInstance, otCoapResource *aResource)
{
- return aInstance->mApplicationCoapServer.SetPort(aPort);
+ return aInstance->mApplicationCoap.AddResource(*static_cast(aResource));
}
-ThreadError otCoapServerAddResource(otInstance *aInstance, otCoapResource *aResource)
+void otCoapRemoveResource(otInstance *aInstance, otCoapResource *aResource)
{
- return aInstance->mApplicationCoapServer.AddResource(*static_cast(aResource));
-}
-
-void otCoapServerRemoveResource(otInstance *aInstance, otCoapResource *aResource)
-{
- aInstance->mApplicationCoapServer.RemoveResource(*static_cast(aResource));
+ aInstance->mApplicationCoap.RemoveResource(*static_cast(aResource));
}
ThreadError otCoapSendResponse(otInstance *aInstance, otMessage *aMessage, const otMessageInfo *aMessageInfo)
{
- return aInstance->mApplicationCoapServer.SendMessage(
+ return aInstance->mApplicationCoap.SendMessage(
*static_cast(aMessage), *static_cast(aMessageInfo));
}
diff --git a/src/core/api/instance_api.cpp b/src/core/api/instance_api.cpp
index aabfa4a8f..af43cf55b 100644
--- a/src/core/api/instance_api.cpp
+++ b/src/core/api/instance_api.cpp
@@ -64,7 +64,7 @@ otInstance::otInstance(void) :
, mLinkRaw(*this)
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
#if OPENTHREAD_ENABLE_APPLICATION_COAP
- , mApplicationCoapServer(mThreadNetif, OT_DEFAULT_COAP_PORT)
+ , mApplicationCoap(mThreadNetif)
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP
#if OPENTHREAD_CONFIG_ENABLE_DYNAMIC_LOG_LEVEL
, mLogLevel(static_cast(OPENTHREAD_CONFIG_LOG_LEVEL))
diff --git a/src/core/api/message_api.cpp b/src/core/api/message_api.cpp
index a00450a1f..e19527c11 100644
--- a/src/core/api/message_api.cpp
+++ b/src/core/api/message_api.cpp
@@ -167,9 +167,6 @@ void otMessageGetBufferInfo(otInstance *aInstance, otBufferInfo *aBufferInfo)
aInstance->mThreadNetif.GetMle().GetMessageQueue().GetInfo(aBufferInfo->mMleMessages,
aBufferInfo->mMleBuffers);
- aInstance->mThreadNetif.GetCoapClient().GetRequestMessages().GetInfo(aBufferInfo->mCoapClientMessages,
- aBufferInfo->mCoapClientBuffers);
-
- aInstance->mThreadNetif.GetCoapServer().GetCachedResponses().GetInfo(aBufferInfo->mCoapServerMessages,
- aBufferInfo->mCoapServerBuffers);
+ aInstance->mThreadNetif.GetCoap().GetRequestMessages().GetInfo(aBufferInfo->mCoapMessages,
+ aBufferInfo->mCoapBuffers);
}
diff --git a/src/core/coap/coap.cpp b/src/core/coap/coap.cpp
new file mode 100644
index 000000000..0092646ed
--- /dev/null
+++ b/src/core/coap/coap.cpp
@@ -0,0 +1,869 @@
+/*
+ * 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 "coap.tmh"
+
+#ifdef OPENTHREAD_CONFIG_FILE
+#include OPENTHREAD_CONFIG_FILE
+#else
+#include
+#endif
+
+#include "coap.hpp"
+
+#include
+
+#include "common/code_utils.hpp"
+#include "common/debug.hpp"
+#include "common/logging.hpp"
+#include "net/ip6.hpp"
+#include "net/udp6.hpp"
+#include "thread/thread_netif.hpp"
+
+/**
+ * @file
+ * This file contains common code base for CoAP client and server.
+ */
+
+namespace ot {
+namespace Coap {
+
+Coap::Coap(ThreadNetif &aNetif):
+ mNetif(aNetif),
+ mSocket(aNetif.GetIp6().mUdp),
+ mRetransmissionTimer(aNetif.GetIp6().mTimerScheduler, &Coap::HandleRetransmissionTimer, this),
+ mResources(NULL),
+ mInterceptor(NULL),
+ mResponsesQueue(aNetif)
+{
+ mMessageId = static_cast(otPlatRandomGet());
+}
+
+ThreadError Coap::Start(uint16_t aPort)
+{
+ ThreadError error;
+ Ip6::SockAddr sockaddr;
+ sockaddr.mPort = aPort;
+
+ SuccessOrExit(error = mSocket.Open(&Coap::HandleUdpReceive, this));
+ SuccessOrExit(error = mSocket.Bind(sockaddr));
+
+exit:
+ return error;
+}
+
+ThreadError Coap::Stop(void)
+{
+ Message *message = mPendingRequests.GetHead();
+ Message *messageToRemove;
+ CoapMetadata coapMetadata;
+
+ // Remove all pending messages.
+ while (message != NULL)
+ {
+ messageToRemove = message;
+ message = message->GetNext();
+
+ coapMetadata.ReadFrom(*messageToRemove);
+ FinalizeCoapTransaction(*messageToRemove, coapMetadata, NULL, NULL, NULL, kThreadError_Abort);
+ }
+
+ mResponsesQueue.DequeueAllResponses();
+
+ return mSocket.Close();
+}
+
+ThreadError Coap::AddResource(Resource &aResource)
+{
+ ThreadError error = kThreadError_None;
+
+ for (Resource *cur = mResources; cur; cur = cur->GetNext())
+ {
+ VerifyOrExit(cur != &aResource, error = kThreadError_Already);
+ }
+
+ aResource.mNext = mResources;
+ mResources = &aResource;
+
+exit:
+ return error;
+}
+
+void Coap::RemoveResource(Resource &aResource)
+{
+ if (mResources == &aResource)
+ {
+ mResources = aResource.GetNext();
+ }
+ else
+ {
+ for (Resource *cur = mResources; cur; cur = cur->GetNext())
+ {
+ if (cur->mNext == &aResource)
+ {
+ cur->mNext = aResource.mNext;
+ ExitNow();
+ }
+ }
+ }
+
+exit:
+ aResource.mNext = NULL;
+}
+
+Message *Coap::NewMessage(const Header &aHeader, uint8_t aPriority)
+{
+ 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);
+ message->SetPriority(aPriority);
+
+exit:
+ return message;
+}
+
+ThreadError Coap::SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo,
+ otCoapResponseHandler aHandler, void *aContext)
+{
+ ThreadError error;
+ Header header;
+ CoapMetadata coapMetadata;
+ Message *storedCopy = NULL;
+ uint16_t copyLength = 0;
+
+ SuccessOrExit(error = header.FromMessage(aMessage, 0));
+
+ if ((header.GetType() == kCoapTypeAcknowledgment || header.GetType() == kCoapTypeReset) &&
+ header.GetCode() != kCoapCodeEmpty)
+ {
+ mResponsesQueue.EnqueueResponse(aMessage, aMessageInfo);
+ }
+
+ // Set Message Id if it was not already set.
+ if (header.GetMessageId() == 0)
+ {
+ header.SetMessageId(mMessageId++);
+ aMessage.Write(0, Header::kMinHeaderLength, header.GetBytes());
+ }
+
+ if (header.IsConfirmable())
+ {
+ // Create a copy of entire message and enqueue it.
+ copyLength = aMessage.GetLength();
+ }
+ else if (header.IsNonConfirmable() && header.IsRequest() && (aHandler != NULL))
+ {
+ // As we do not retransmit non confirmable messages, create a copy of header only, for token information.
+ copyLength = header.GetLength();
+ }
+
+ if (copyLength > 0)
+ {
+ coapMetadata = CoapMetadata(header.IsConfirmable(), aMessageInfo, aHandler, aContext);
+ VerifyOrExit((storedCopy = CopyAndEnqueueMessage(aMessage, copyLength, coapMetadata)) != NULL,
+ error = kThreadError_NoBufs);
+ }
+
+ SuccessOrExit(error = Send(aMessage, aMessageInfo));
+
+exit:
+
+ if (error != kThreadError_None && storedCopy != NULL)
+ {
+ DequeueMessage(*storedCopy);
+ }
+
+ return error;
+}
+
+ThreadError Coap::Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+{
+ return mSocket.SendTo(aMessage, aMessageInfo);
+}
+
+ThreadError Coap::SendEmptyMessage(Header::Type aType, const Header &aRequestHeader,
+ const Ip6::MessageInfo &aMessageInfo)
+{
+ ThreadError error = kThreadError_None;
+ Header responseHeader;
+ Message *message = NULL;
+
+ VerifyOrExit(aRequestHeader.GetType() == kCoapTypeConfirmable, error = kThreadError_InvalidArgs);
+
+ responseHeader.Init(aType, kCoapCodeEmpty);
+ responseHeader.SetMessageId(aRequestHeader.GetMessageId());
+
+ VerifyOrExit((message = NewMessage(responseHeader)) != NULL, error = kThreadError_NoBufs);
+
+ SuccessOrExit(error = Send(*message, aMessageInfo));
+
+exit:
+
+ if (error != kThreadError_None && message != NULL)
+ {
+ message->Free();
+ }
+
+ return error;
+}
+
+ThreadError Coap::SendEmptyAck(const Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo)
+{
+ ThreadError error = kThreadError_None;
+ Header responseHeader;
+ Message *message = NULL;
+
+ VerifyOrExit(aRequestHeader.GetType() == kCoapTypeConfirmable, error = kThreadError_InvalidArgs);
+
+ responseHeader.SetDefaultResponseHeader(aRequestHeader);
+
+ VerifyOrExit((message = NewMessage(responseHeader)) != NULL, error = kThreadError_NoBufs);
+
+ SuccessOrExit(error = SendMessage(*message, aMessageInfo));
+
+exit:
+
+ if (error != kThreadError_None && message != NULL)
+ {
+ message->Free();
+ }
+
+ return error;
+}
+
+void Coap::HandleRetransmissionTimer(void *aContext)
+{
+ static_cast(aContext)->HandleRetransmissionTimer();
+}
+
+void Coap::HandleRetransmissionTimer(void)
+{
+ uint32_t now = otPlatAlarmGetNow();
+ uint32_t nextDelta = 0xffffffff;
+ CoapMetadata coapMetadata;
+ Message *message = mPendingRequests.GetHead();
+ Message *nextMessage = NULL;
+ Ip6::MessageInfo messageInfo;
+
+ while (message != NULL)
+ {
+ nextMessage = message->GetNext();
+ coapMetadata.ReadFrom(*message);
+
+ if (coapMetadata.IsLater(now))
+ {
+ // Calculate the next delay and choose the lowest.
+ if (coapMetadata.mNextTimerShot - now < nextDelta)
+ {
+ nextDelta = coapMetadata.mNextTimerShot - now;
+ }
+ }
+ else if ((coapMetadata.mConfirmable) &&
+ (coapMetadata.mRetransmissionCount < kMaxRetransmit))
+ {
+ // Increment retransmission counter and timer.
+ coapMetadata.mRetransmissionCount++;
+ coapMetadata.mRetransmissionTimeout *= 2;
+ coapMetadata.mNextTimerShot = now + coapMetadata.mRetransmissionTimeout;
+ coapMetadata.UpdateIn(*message);
+
+ // Check if retransmission time is lower than current lowest.
+ if (coapMetadata.mRetransmissionTimeout < nextDelta)
+ {
+ nextDelta = coapMetadata.mRetransmissionTimeout;
+ }
+
+ // Retransmit
+ if (!coapMetadata.mAcknowledged)
+ {
+ messageInfo.SetPeerAddr(coapMetadata.mDestinationAddress);
+ messageInfo.SetPeerPort(coapMetadata.mDestinationPort);
+ messageInfo.SetSockAddr(coapMetadata.mSourceAddress);
+
+ SendCopy(*message, messageInfo);
+ }
+ }
+ else
+ {
+ // No expected response or acknowledgment.
+ FinalizeCoapTransaction(*message, coapMetadata, NULL, NULL, NULL, kThreadError_ResponseTimeout);
+ }
+
+ message = nextMessage;
+ }
+
+ if (nextDelta != 0xffffffff)
+ {
+ mRetransmissionTimer.Start(nextDelta);
+ }
+}
+
+void Coap::FinalizeCoapTransaction(Message &aRequest, const CoapMetadata &aCoapMetadata,
+ Header *aResponseHeader, Message *aResponse,
+ const Ip6::MessageInfo *aMessageInfo, ThreadError aResult)
+{
+ DequeueMessage(aRequest);
+
+ if (aCoapMetadata.mResponseHandler != NULL)
+ {
+ aCoapMetadata.mResponseHandler(aCoapMetadata.mResponseContext, aResponseHeader,
+ aResponse, aMessageInfo, aResult);
+ }
+}
+
+ThreadError Coap::AbortTransaction(otCoapResponseHandler aHandler, void *aContext)
+{
+ ThreadError error = kThreadError_NotFound;
+ Message *message;
+ CoapMetadata coapMetadata;
+
+ for (message = mPendingRequests.GetHead(); message != NULL; message = message->GetNext())
+ {
+ coapMetadata.ReadFrom(*message);
+
+ if (coapMetadata.mResponseHandler == aHandler && coapMetadata.mResponseContext == aContext)
+ {
+ DequeueMessage(*message);
+ error = kThreadError_None;
+ }
+ }
+
+ return error;
+}
+
+
+Message *Coap::CopyAndEnqueueMessage(const Message &aMessage, uint16_t aCopyLength,
+ const CoapMetadata &aCoapMetadata)
+{
+ ThreadError error = kThreadError_None;
+ Message *messageCopy = NULL;
+ uint32_t alarmFireTime;
+
+ // Create a message copy of requested size.
+ VerifyOrExit((messageCopy = aMessage.Clone(aCopyLength)) != NULL, error = kThreadError_NoBufs);
+
+ // Append the copy with retransmission data.
+ SuccessOrExit(error = aCoapMetadata.AppendTo(*messageCopy));
+
+ // Setup the timer.
+ if (mRetransmissionTimer.IsRunning())
+ {
+ // If timer is already running, check if it should be restarted with earlier fire time.
+ alarmFireTime = mRetransmissionTimer.Gett0() + mRetransmissionTimer.Getdt();
+
+ if (aCoapMetadata.IsEarlier(alarmFireTime))
+ {
+ mRetransmissionTimer.Start(aCoapMetadata.mRetransmissionTimeout);
+ }
+ }
+ else
+ {
+ mRetransmissionTimer.Start(aCoapMetadata.mRetransmissionTimeout);
+ }
+
+ // Enqueue the message.
+ mPendingRequests.Enqueue(*messageCopy);
+
+exit:
+
+ if (error != kThreadError_None && messageCopy != NULL)
+ {
+ messageCopy->Free();
+ messageCopy = NULL;
+ }
+
+ return messageCopy;
+}
+
+void Coap::DequeueMessage(Message &aMessage)
+{
+ mPendingRequests.Dequeue(aMessage);
+
+ if (mRetransmissionTimer.IsRunning() && (mPendingRequests.GetHead() == NULL))
+ {
+ // No more requests pending, stop the timer.
+ mRetransmissionTimer.Stop();
+ }
+
+ // Free the message memory.
+ aMessage.Free();
+
+ // No need to worry that the earliest pending message was removed -
+ // the timer would just shoot earlier and then it'd be setup again.
+}
+
+ThreadError Coap::SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+{
+ ThreadError error;
+ Message *messageCopy = NULL;
+
+ // Create a message copy for lower layers.
+ VerifyOrExit((messageCopy = aMessage.Clone(aMessage.GetLength() - sizeof(CoapMetadata))) != NULL,
+ error = kThreadError_NoBufs);
+
+ // Send the copy.
+ SuccessOrExit(error = Send(*messageCopy, aMessageInfo));
+
+exit:
+
+ if (error != kThreadError_None && messageCopy != NULL)
+ {
+ messageCopy->Free();
+ }
+
+ return error;
+}
+
+Message *Coap::FindRelatedRequest(const Header &aResponseHeader, const Ip6::MessageInfo &aMessageInfo,
+ Header &aRequestHeader, CoapMetadata &aCoapMetadata)
+{
+ Message *message = mPendingRequests.GetHead();
+
+ while (message != NULL)
+ {
+ aCoapMetadata.ReadFrom(*message);
+
+ if (((aCoapMetadata.mDestinationAddress == aMessageInfo.GetPeerAddr()) ||
+ aCoapMetadata.mDestinationAddress.IsMulticast() ||
+ aCoapMetadata.mDestinationAddress.IsAnycastRoutingLocator()) &&
+ (aCoapMetadata.mDestinationPort == aMessageInfo.GetPeerPort()))
+ {
+ assert(aRequestHeader.FromMessage(*message, sizeof(CoapMetadata)) == kThreadError_None);
+
+ switch (aResponseHeader.GetType())
+ {
+ case kCoapTypeReset:
+ case kCoapTypeAcknowledgment:
+ if (aResponseHeader.GetMessageId() == aRequestHeader.GetMessageId())
+ {
+ ExitNow();
+ }
+
+ break;
+
+ case kCoapTypeConfirmable:
+ case kCoapTypeNonConfirmable:
+ if (aResponseHeader.IsTokenEqual(aRequestHeader))
+ {
+ ExitNow();
+ }
+
+ break;
+ }
+ }
+
+ message = message->GetNext();
+ }
+
+exit:
+ return message;
+}
+
+void Coap::HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
+{
+ static_cast(aContext)->Receive(*static_cast(aMessage),
+ *static_cast(aMessageInfo));
+}
+
+void Coap::Receive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+{
+ ThreadError error;
+ Header header;
+
+ SuccessOrExit(error = header.FromMessage(aMessage, 0));
+
+ if (header.IsRequest())
+ {
+ ProcessReceivedRequest(header, aMessage, aMessageInfo);
+ }
+ else
+ {
+ ProcessReceivedResponse(header, aMessage, aMessageInfo);
+ }
+
+exit:
+ otLogInfoCoapErr(mNetif.GetInstance(), error, "Receive failed");
+}
+
+void Coap::ProcessReceivedResponse(Header &aResponseHeader, Message &aMessage,
+ const Ip6::MessageInfo &aMessageInfo)
+{
+ Header requestHeader;
+ CoapMetadata coapMetadata;
+ Message *message = NULL;
+ ThreadError error = kThreadError_None;
+
+ aMessage.MoveOffset(aResponseHeader.GetLength());
+
+ message = FindRelatedRequest(aResponseHeader, aMessageInfo, requestHeader, coapMetadata);
+
+ if (message == NULL)
+ {
+ ExitNow();
+ }
+
+ switch (aResponseHeader.GetType())
+ {
+ case kCoapTypeReset:
+ if (aResponseHeader.IsEmpty())
+ {
+ FinalizeCoapTransaction(*message, coapMetadata, NULL, NULL, NULL, kThreadError_Abort);
+ }
+
+ // Silently ignore non-empty reset messages (RFC 7252, p. 4.2).
+ break;
+
+ case kCoapTypeAcknowledgment:
+ if (aResponseHeader.IsEmpty())
+ {
+ // Empty acknowledgment.
+ if (coapMetadata.mConfirmable)
+ {
+ coapMetadata.mAcknowledged = true;
+ coapMetadata.UpdateIn(*message);
+ }
+
+ // Remove the message if response is not expected, otherwise await response.
+ if (coapMetadata.mResponseHandler == NULL)
+ {
+ DequeueMessage(*message);
+ }
+ }
+ else if (aResponseHeader.IsResponse() && aResponseHeader.IsTokenEqual(requestHeader))
+ {
+ // Piggybacked response.
+ FinalizeCoapTransaction(*message, coapMetadata, &aResponseHeader, &aMessage, &aMessageInfo, kThreadError_None);
+ }
+
+ // Silently ignore acknowledgments carrying requests (RFC 7252, p. 4.2)
+ // or with no token match (RFC 7252, p. 5.3.2)
+ break;
+
+ case kCoapTypeConfirmable:
+ // Send empty ACK if it is a CON message.
+ SendAck(aResponseHeader, aMessageInfo);
+
+ // fall through
+ ;
+
+ case kCoapTypeNonConfirmable:
+ // Separate response.
+ FinalizeCoapTransaction(*message, coapMetadata, &aResponseHeader, &aMessage, &aMessageInfo, kThreadError_None);
+
+ break;
+ }
+
+exit:
+
+ if (error == kThreadError_None && message == NULL)
+ {
+ if (aResponseHeader.IsConfirmable() || aResponseHeader.IsNonConfirmable())
+ {
+ // Successfully parsed a header but no matching request was found - reject the message by sending reset.
+ SendReset(aResponseHeader, aMessageInfo);
+ }
+ }
+}
+
+void Coap::ProcessReceivedRequest(Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+{
+ char uriPath[Resource::kMaxReceivedUriPath] = "";
+ char *curUriPath = uriPath;
+ const Header::Option *coapOption;
+ Message *response;
+
+ if (mInterceptor != NULL)
+ {
+ SuccessOrExit(mInterceptor(aMessage, aMessageInfo));
+ }
+
+ SuccessOrExit(aHeader.FromMessage(aMessage, 0));
+ aMessage.MoveOffset(aHeader.GetLength());
+
+ switch (mResponsesQueue.GetMatchedResponseCopy(aHeader, aMessageInfo, &response))
+ {
+ case kThreadError_None:
+ SendMessage(*response, aMessageInfo);
+
+ // fall through
+
+ case kThreadError_NoBufs:
+ ExitNow();
+
+ case kThreadError_NotFound:
+ default:
+ break;
+ }
+
+ coapOption = aHeader.GetFirstOption();
+
+ while (coapOption != NULL)
+ {
+ switch (coapOption->mNumber)
+ {
+ case kCoapOptionUriPath:
+ if (curUriPath != uriPath)
+ {
+ *curUriPath++ = '/';
+ }
+
+ VerifyOrExit(coapOption->mLength < sizeof(uriPath) - static_cast(curUriPath + 1 - uriPath));
+
+ memcpy(curUriPath, coapOption->mValue, coapOption->mLength);
+ curUriPath += coapOption->mLength;
+ break;
+
+ default:
+ break;
+ }
+
+ coapOption = aHeader.GetNextOption();
+ }
+
+ curUriPath[0] = '\0';
+
+ for (Resource *resource = mResources; resource; resource = resource->GetNext())
+ {
+ if (strcmp(resource->mUriPath, uriPath) == 0)
+ {
+ resource->HandleRequest(aHeader, aMessage, aMessageInfo);
+ ExitNow();
+ }
+ }
+
+exit:
+ return;
+}
+
+CoapMetadata::CoapMetadata(bool aConfirmable, const Ip6::MessageInfo &aMessageInfo,
+ otCoapResponseHandler aHandler, void *aContext)
+{
+ mSourceAddress = aMessageInfo.GetSockAddr();
+ mDestinationPort = aMessageInfo.GetPeerPort();
+ mDestinationAddress = aMessageInfo.GetPeerAddr();
+ mResponseHandler = aHandler;
+ mResponseContext = aContext;
+ mRetransmissionCount = 0;
+ mRetransmissionTimeout = Timer::SecToMsec(kAckTimeout);
+ mRetransmissionTimeout += otPlatRandomGet() %
+ (Timer::SecToMsec(kAckTimeout) * kAckRandomFactorNumerator / kAckRandomFactorDenominator -
+ Timer::SecToMsec(kAckTimeout) + 1);
+
+ if (aConfirmable)
+ {
+ // Set next retransmission timeout.
+ mNextTimerShot = Timer::GetNow() + mRetransmissionTimeout;
+ }
+ else
+ {
+ // Set overall response timeout.
+ mNextTimerShot = Timer::GetNow() + kMaxTransmitWait;
+ }
+
+ mAcknowledged = false;
+ mConfirmable = aConfirmable;
+}
+
+ResponsesQueue::ResponsesQueue(ThreadNetif &aNetif):
+ mTimer(aNetif.GetIp6().mTimerScheduler, &ResponsesQueue::HandleTimer, this)
+{
+}
+
+ThreadError ResponsesQueue::GetMatchedResponseCopy(const Header &aHeader,
+ const Ip6::MessageInfo &aMessageInfo,
+ Message **aResponse)
+{
+ ThreadError error = kThreadError_NotFound;
+ Message *message;
+ EnqueuedResponseHeader enqueuedResponseHeader;
+ Ip6::MessageInfo messageInfo;
+ Header header;
+
+ for (message = mQueue.GetHead(); message != NULL; message = message->GetNext())
+ {
+ enqueuedResponseHeader.ReadFrom(*message);
+ messageInfo = enqueuedResponseHeader.GetMessageInfo();
+
+ // Check source endpoint
+ if (messageInfo.GetPeerPort() != aMessageInfo.GetPeerPort())
+ {
+ continue;
+ }
+
+ if (messageInfo.GetPeerAddr() != aMessageInfo.GetPeerAddr())
+ {
+ continue;
+ }
+
+ // Check Message Id
+ if (header.FromMessage(*message, sizeof(EnqueuedResponseHeader)) != kThreadError_None)
+ {
+ continue;
+ }
+
+ if (header.GetMessageId() != aHeader.GetMessageId())
+ {
+ continue;
+ }
+
+ *aResponse = message->Clone();
+ VerifyOrExit(*aResponse != NULL, error = kThreadError_NoBufs);
+
+ EnqueuedResponseHeader::RemoveFrom(**aResponse);
+
+ error = kThreadError_None;
+ break;
+ }
+
+exit:
+ return error;
+}
+
+ThreadError ResponsesQueue::GetMatchedResponseCopy(const Message &aRequest,
+ const Ip6::MessageInfo &aMessageInfo,
+ Message **aResponse)
+{
+ ThreadError error = kThreadError_None;
+ Header header;
+
+ SuccessOrExit(error = header.FromMessage(aRequest, 0));
+
+ error = GetMatchedResponseCopy(header, aMessageInfo, aResponse);
+
+exit:
+ return error;
+}
+
+void ResponsesQueue::EnqueueResponse(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+{
+ Header header;
+ Message *copy;
+ EnqueuedResponseHeader enqueuedResponseHeader(aMessageInfo);
+ uint16_t messageCount;
+ uint16_t bufferCount;
+
+ SuccessOrExit(header.FromMessage(aMessage, 0));
+
+ switch (GetMatchedResponseCopy(aMessage, aMessageInfo, ©))
+ {
+ case kThreadError_NotFound:
+ break;
+
+ case kThreadError_None:
+ copy->Free();
+
+ // fall through
+
+ case kThreadError_NoBufs:
+ default:
+ ExitNow();
+ }
+
+ mQueue.GetInfo(messageCount, bufferCount);
+
+ if (messageCount >= kMaxCachedResponses)
+ {
+ DequeueOldestResponse();
+ }
+
+ copy = aMessage.Clone();
+ VerifyOrExit(copy != NULL);
+
+ enqueuedResponseHeader.AppendTo(*copy);
+ mQueue.Enqueue(*copy);
+
+ if (!mTimer.IsRunning())
+ {
+ mTimer.Start(Timer::SecToMsec(kExchangeLifetime));
+ }
+
+exit:
+ return;
+}
+
+void ResponsesQueue::DequeueOldestResponse(void)
+{
+ Message *message;
+
+ VerifyOrExit((message = mQueue.GetHead()) != NULL);
+ DequeueResponse(*message);
+
+exit:
+ return;
+}
+
+void ResponsesQueue::DequeueAllResponses(void)
+{
+ Message *message;
+
+ while ((message = mQueue.GetHead()) != NULL)
+ {
+ DequeueResponse(*message);
+ }
+}
+
+void ResponsesQueue::HandleTimer(void *aContext)
+{
+ static_cast(aContext)->HandleTimer();
+}
+
+void ResponsesQueue::HandleTimer(void)
+{
+ Message *message;
+ EnqueuedResponseHeader enqueuedResponseHeader;
+
+ while ((message = mQueue.GetHead()) != NULL)
+ {
+ enqueuedResponseHeader.ReadFrom(*message);
+
+ if (enqueuedResponseHeader.IsEarlier(Timer::GetNow()))
+ {
+ DequeueResponse(*message);
+ }
+ else
+ {
+ mTimer.Start(enqueuedResponseHeader.GetRemainingTime());
+ break;
+ }
+ }
+}
+
+uint32_t EnqueuedResponseHeader::GetRemainingTime(void) const
+{
+ int32_t remainingTime = static_cast(mDequeueTime - Timer::GetNow());
+
+ return remainingTime >= 0 ? static_cast(remainingTime) : 0;
+}
+
+} // namespace Coap
+} // namespace ot
diff --git a/src/core/coap/coap_server.hpp b/src/core/coap/coap.hpp
similarity index 51%
rename from src/core/coap/coap_server.hpp
rename to src/core/coap/coap.hpp
index 0d3466839..2c051c3cc 100644
--- a/src/core/coap/coap_server.hpp
+++ b/src/core/coap/coap.hpp
@@ -26,25 +26,28 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-/**
- * @file
- * This file includes definitions for the CoAP server.
- */
-
-#ifndef COAP_SERVER_HPP_
-#define COAP_SERVER_HPP_
+#ifndef COAP_HPP_
+#define COAP_HPP_
#include
-#include "coap/coap_base.hpp"
#include "coap/coap_header.hpp"
#include "common/debug.hpp"
#include "common/message.hpp"
#include "common/timer.hpp"
#include "net/ip6.hpp"
+#include "net/netif.hpp"
#include "net/udp6.hpp"
+/**
+ * @file
+ * This file includes definitions for CoAP client and server functionality.
+ */
+
namespace ot {
+
+class ThreadNetif;
+
namespace Coap {
/**
@@ -54,13 +57,146 @@ namespace Coap {
*
*/
+/**
+ * Protocol Constants (RFC 7252).
+ *
+ */
+enum
+{
+ kAckTimeout = OPENTHREAD_CONFIG_COAP_ACK_TIMEOUT,
+ kAckRandomFactorNumerator = OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_NUMERATOR,
+ kAckRandomFactorDenominator = OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_DENOMINATOR,
+ kMaxRetransmit = OPENTHREAD_CONFIG_COAP_MAX_RETRANSMIT,
+ kNStart = 1,
+ kDefaultLeisure = 5,
+ kProbingRate = 1,
+
+ // Note that 2 << (kMaxRetransmit - 1) is equal to kMaxRetransmit power of 2
+ kMaxTransmitSpan = kAckTimeout * ((2 << (kMaxRetransmit - 1)) - 1) *
+ kAckRandomFactorNumerator / kAckRandomFactorDenominator,
+ kMaxTransmitWait = kAckTimeout * ((2 << kMaxRetransmit) - 1) *
+ kAckRandomFactorNumerator / kAckRandomFactorDenominator,
+ kMaxLatency = 100,
+ kProcessingDelay = kAckTimeout,
+ kMaxRtt = 2 * kMaxLatency + kProcessingDelay,
+ kExchangeLifetime = kMaxTransmitSpan + 2 * (kMaxLatency) + kProcessingDelay,
+ kNonLifetime = kMaxTransmitSpan + kMaxLatency
+};
+
+/**
+ * This class implements metadata required for CoAP retransmission.
+ *
+ */
+OT_TOOL_PACKED_BEGIN
+class CoapMetadata
+{
+ friend class Coap;
+
+public:
+
+ /**
+ * Default constructor for the object.
+ *
+ */
+ CoapMetadata(void):
+ mDestinationPort(0),
+ mResponseHandler(NULL),
+ mResponseContext(NULL),
+ mNextTimerShot(0),
+ mRetransmissionTimeout(0),
+ mRetransmissionCount(0),
+ mAcknowledged(false),
+ mConfirmable(false) {};
+
+ /**
+ * This constructor initializes the object with specific values.
+ *
+ * @param[in] aConfirmable Information if the request is confirmable or not.
+ * @param[in] aMessageInfo Addressing information.
+ * @param[in] aHandler Pointer to a handler function for the response.
+ * @param[in] aContext Context for the handler function.
+ *
+ */
+ CoapMetadata(bool aConfirmable, const Ip6::MessageInfo &aMessageInfo,
+ otCoapResponseHandler aHandler, void *aContext);
+
+ /**
+ * This method appends request data to the message.
+ *
+ * @param[in] aMessage A reference to the message.
+ *
+ * @retval kThreadError_None Successfully appended the bytes.
+ * @retval kThreadError_NoBufs Insufficient available buffers to grow the message.
+ *
+ */
+ ThreadError AppendTo(Message &aMessage) const {
+ return aMessage.Append(this, sizeof(*this));
+ };
+
+ /**
+ * This method reads request data from the message.
+ *
+ * @param[in] aMessage A reference to the message.
+ *
+ * @returns The number of bytes read.
+ *
+ */
+ uint16_t ReadFrom(const Message &aMessage) {
+ return aMessage.Read(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
+ };
+
+ /**
+ * This method updates request data in the message.
+ *
+ * @param[in] aMessage A reference to the message.
+ *
+ * @returns The number of bytes updated.
+ *
+ */
+ int UpdateIn(Message &aMessage) const {
+ return aMessage.Write(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
+ }
+
+ /**
+ * This method checks if the message shall be sent before the given time.
+ *
+ * @param[in] aTime A time to compare.
+ *
+ * @retval TRUE If the message shall be sent before the given time.
+ * @retval FALSE Otherwise.
+ */
+ bool IsEarlier(uint32_t aTime) const { return (static_cast(aTime - mNextTimerShot) > 0); };
+
+ /**
+ * This method checks if the message shall be sent after the given time.
+ *
+ * @param[in] aTime A time to compare.
+ *
+ * @retval TRUE If the message shall be sent after the given time.
+ * @retval FALSE Otherwise.
+ */
+ bool IsLater(uint32_t aTime) const { return (static_cast(aTime - mNextTimerShot) < 0); };
+
+private:
+ Ip6::Address mSourceAddress; ///< IPv6 address of the message source.
+ Ip6::Address mDestinationAddress; ///< IPv6 address of the message destination.
+ uint16_t mDestinationPort; ///< UDP port of the message destination.
+ otCoapResponseHandler mResponseHandler; ///< A function pointer that is called on response reception.
+ void *mResponseContext; ///< A pointer to arbitrary context information.
+ uint32_t mNextTimerShot; ///< Time when the timer should shoot for this message.
+ uint32_t mRetransmissionTimeout; ///< Delay that is applied to next retransmission.
+ uint8_t mRetransmissionCount; ///< Number of retransmissions.
+ bool mAcknowledged: 1; ///< Information that request was acknowledged.
+ bool mConfirmable: 1; ///< Information that message is confirmable.
+} OT_TOOL_PACKED_END;
+
/**
* This class implements CoAP resource handling.
*
*/
class Resource : public otCoapResource
{
- friend class Server;
+ friend class Coap;
public:
enum
@@ -196,8 +332,7 @@ public:
* @param[in] aNetif A reference to the network interface that CoAP server should be assigned to.
*
*/
- ResponsesQueue(Ip6::Netif &aNetif):
- mTimer(aNetif.GetIp6().mTimerScheduler, &ResponsesQueue::HandleTimer, this) {}
+ ResponsesQueue(ThreadNetif &aNetif);
/**
* Add given response to the cache.
@@ -281,10 +416,10 @@ private:
};
/**
- * This class implements the CoAP server.
+ * This class implements the CoAP client and server.
*
*/
-class Server : public CoapBase
+class Coap
{
public:
/**
@@ -304,30 +439,47 @@ public:
/**
* This constructor initializes the object.
*
- * @param[in] aNetif A reference to the network interface that CoAP server should be assigned to.
- * @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.
+ * @param[in] aNetif A reference to the Netif object.
*
*/
- Server(Ip6::Netif &aNetif, uint16_t aPort);
+ Coap(ThreadNetif &aNetif);
/**
- * This method starts the CoAP server.
+ * This method starts the CoAP service.
*
- * @retval kThreadError_None Successfully started the CoAP server.
+ * @param[in] aPort The local UDP port to bind to.
+ *
+ * @retval kThreadError_None Successfully started the CoAP service.
*
*/
- ThreadError Start(void);
+ ThreadError Start(uint16_t aPort);
/**
- * This method stops the CoAP server.
+ * This method stops the CoAP service.
*
- * @retval kThreadError_None Successfully stopped the CoAP server.
+ * @retval kThreadError_None Successfully stopped the CoAP service.
*
*/
ThreadError Stop(void);
+ /**
+ * This method returns a port number used by CoAP service.
+ *
+ * @returns A port number.
+ *
+ */
+ uint16_t GetPort(void) { return mSocket.GetSockName().mPort; };
+
+ /**
+ * This method sets CoAP server's port number.
+ *
+ * @param[in] aPort A port number to set.
+ *
+ * @retval kThreadError_None Binding with a port succeeded.
+ *
+ */
+ ThreadError SetPort(uint16_t aPort);
+
/**
* This method adds a resource to the CoAP server.
*
@@ -348,16 +500,64 @@ public:
void RemoveResource(Resource &aResource);
/**
- * This method sends a CoAP response from the server.
- *
- * @param[in] aMessage The CoAP response to send.
- * @param[in] aMessageInfo The message info corresponding to @p aMessage.
- *
- * @retval kThreadError_None Successfully enqueued the CoAP response message.
- * @retval kThreadError_NoBufs Insufficient buffers available to send the CoAP response.
- *
- */
- ThreadError SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+ * 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.
+ * @param[in] aPrority The message priority level.
+ *
+ * @returns A pointer to the message or NULL if failed to allocate message.
+ *
+ */
+ Message *NewMessage(const Header &aHeader, uint8_t aPriority = kDefaultCoapMessagePriority);
+
+ /**
+ * This method sends a CoAP message.
+ *
+ * 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] aMessageInfo A reference to the message info associated with @p aMessage.
+ * @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.
+ *
+ */
+ ThreadError SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo,
+ otCoapResponseHandler aHandler = NULL, void *aContext = NULL);
+
+ /**
+ * This method sends a CoAP reset message.
+ *
+ * @param[in] aRequestHeader A reference to the CoAP Header that was used in CoAP request.
+ * @param[in] aMessageInfo The message info corresponding to the CoAP request.
+ *
+ * @retval kThreadError_None Successfully enqueued the CoAP response message.
+ * @retval kThreadError_NoBufs Insufficient buffers available to send the CoAP response.
+ * @retval kThreadError_InvalidArgs The @p aRequestHeader header is not of confirmable type.
+ *
+ */
+ ThreadError SendReset(Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo) {
+ return SendEmptyMessage(kCoapTypeReset, aRequestHeader, aMessageInfo);
+ };
+
+ /**
+ * This method sends a CoAP ACK empty message which is used in Separate Response for confirmable requests.
+ *
+ * @param[in] aRequestHeader A reference to the CoAP Header that was used in CoAP request.
+ * @param[in] aMessageInfo The message info corresponding to the CoAP request.
+ *
+ * @retval kThreadError_None Successfully enqueued the CoAP response message.
+ * @retval kThreadError_NoBufs Insufficient buffers available to send the CoAP response.
+ * @retval kThreadError_InvalidArgs The @p aRequestHeader header is not of confirmable type.
+ *
+ */
+ ThreadError SendAck(Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo) {
+ return SendEmptyMessage(kCoapTypeAcknowledgment, aRequestHeader, aMessageInfo);
+ };
/**
* This method sends a CoAP ACK message on which a dummy CoAP response is piggybacked.
@@ -373,16 +573,16 @@ public:
ThreadError SendEmptyAck(const Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo);
/**
- * This method sets CoAP server's port number.
+ * This method aborts CoAP transactions associated with given handler and context.
*
- * @param[in] aPort A port number to set.
+ * @param[in] aHandler A function pointer that should be called when the transaction ends.
+ * @param[in] aContext A pointer to arbitrary context information.
*
- * @retval kThreadError_None Binding with a port succeeded.
+ * @retval kThreadError_None Successfully aborted CoAP transactions.
+ * @retval kThreadError_NotFound CoAP transaction associated with given handler was not found.
*
*/
- ThreadError SetPort(uint16_t aPort);
-
- const MessageQueue &GetCachedResponses(void) const { return mResponsesQueue.GetResponses(); }
+ ThreadError AbortTransaction(otCoapResponseHandler aHandler, void *aContext);
/**
* This method sets interceptor to be called before processing a CoAP packet.
@@ -394,28 +594,80 @@ public:
mInterceptor = aInterpreter;
}
+ /**
+ * This method returns a reference to the request message list.
+ *
+ * @returns A reference to the request message list.
+ *
+ */
+ const MessageQueue &GetRequestMessages(void) const { return mPendingRequests; }
+
+ /**
+ * This method returns a reference to the cached response list.
+ *
+ * @returns A reference to the cached response list.
+ *
+ */
+ const MessageQueue &GetCachedResponses(void) const { return mResponsesQueue.GetResponses(); }
+
protected:
+ /**
+ * This method send a message.
+ *
+ * @param[in] aMessage A reference to the message to send.
+ * @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
+ *
+ */
+ virtual ThreadError Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+
+ /**
+ * This method receives a message.
+ *
+ * @param[in] aMessage A reference to the received message.
+ * @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
+ *
+ */
virtual void Receive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
- virtual ThreadError Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) {
- return mSocket.SendTo(aMessage, aMessageInfo);
- }
+ ThreadNetif &mNetif;
+ Ip6::UdpSocket mSocket;
private:
- uint16_t mPort;
+ enum
+ {
+ kDefaultCoapMessagePriority = Message::kPriorityLow,
+ };
+
+ static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
+
+ Message *CopyAndEnqueueMessage(const Message &aMessage, uint16_t aCopyLength,
+ const CoapMetadata &aCoapMetadata);
+ void DequeueMessage(Message &aMessage);
+ Message *FindRelatedRequest(const Header &aResponseHeader, const Ip6::MessageInfo &aMessageInfo,
+ Header &aRequestHeader, CoapMetadata &aCoapMetadata);
+ void FinalizeCoapTransaction(Message &aRequest, const CoapMetadata &aCoapMetadata, Header *aResponseHeader,
+ Message *aResponse, const Ip6::MessageInfo *aMessageInfo, ThreadError aResult);
+
+ void ProcessReceivedRequest(Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+ void ProcessReceivedResponse(Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+
+ ThreadError SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+ ThreadError SendEmptyMessage(Header::Type aType, const Header &aRequestHeader,
+ const Ip6::MessageInfo &aMessageInfo);
+ static void HandleRetransmissionTimer(void *aContext);
+ void HandleRetransmissionTimer(void);
+
+ MessageQueue mPendingRequests;
+ uint16_t mMessageId;
+ Timer mRetransmissionTimer;
+
Resource *mResources;
Interceptor mInterceptor;
ResponsesQueue mResponsesQueue;
};
-
-/**
- * @}
- *
- */
-
} // namespace Coap
} // namespace ot
-#endif // COAP_SERVER_HPP_
+#endif // COAP_HPP_
diff --git a/src/core/coap/coap_base.cpp b/src/core/coap/coap_base.cpp
deleted file mode 100644
index 9060edf24..000000000
--- a/src/core/coap/coap_base.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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.
- */
-
-#ifdef OPENTHREAD_CONFIG_FILE
-#include OPENTHREAD_CONFIG_FILE
-#else
-#include
-#endif
-
-#include "coap_base.hpp"
-
-#include "common/code_utils.hpp"
-
-/**
- * @file
- * This file contains common code base for CoAP client and server.
- */
-
-namespace ot {
-namespace Coap {
-
-Message *CoapBase::NewMessage(const Header &aHeader, uint8_t aPriority)
-{
- 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);
- message->SetPriority(aPriority);
-
-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(aContext)->Receive(*static_cast(aMessage),
- *static_cast(aMessageInfo));
-}
-
-ThreadError CoapBase::SendEmptyMessage(Header::Type aType, const Header &aRequestHeader,
- const Ip6::MessageInfo &aMessageInfo)
-{
- ThreadError error = kThreadError_None;
- Coap::Header responseHeader;
- Message *message = NULL;
-
- VerifyOrExit(aRequestHeader.GetType() == kCoapTypeConfirmable, error = kThreadError_InvalidArgs);
-
- responseHeader.Init(aType, kCoapCodeEmpty);
- responseHeader.SetMessageId(aRequestHeader.GetMessageId());
-
- VerifyOrExit((message = NewMessage(responseHeader)) != NULL, error = kThreadError_NoBufs);
-
- SuccessOrExit(error = Send(*message, aMessageInfo));
-
-exit:
-
- if (error != kThreadError_None && message != NULL)
- {
- message->Free();
- }
-
- return error;
-}
-
-} // namespace Coap
-} // namespace ot
diff --git a/src/core/coap/coap_base.hpp b/src/core/coap/coap_base.hpp
deleted file mode 100644
index 4ce4db6df..000000000
--- a/src/core/coap/coap_base.hpp
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * 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
-
-#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 ot {
-namespace Coap {
-
-/**
- * @addtogroup core-coap
- *
- * @{
- *
- */
-
-/**
- * Protocol Constants (RFC 7252).
- *
- */
-enum
-{
- kAckTimeout = OPENTHREAD_CONFIG_COAP_ACK_TIMEOUT,
- kAckRandomFactorNumerator = OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_NUMERATOR,
- kAckRandomFactorDenominator = OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_DENOMINATOR,
- kMaxRetransmit = OPENTHREAD_CONFIG_COAP_MAX_RETRANSMIT,
- kNStart = 1,
- kDefaultLeisure = 5,
- kProbingRate = 1,
-
- // Note that 2 << (kMaxRetransmit - 1) is equal to kMaxRetransmit power of 2
- kMaxTransmitSpan = kAckTimeout * ((2 << (kMaxRetransmit - 1)) - 1) *
- kAckRandomFactorNumerator / kAckRandomFactorDenominator,
- kMaxTransmitWait = kAckTimeout * ((2 << kMaxRetransmit) - 1) *
- kAckRandomFactorNumerator / kAckRandomFactorDenominator,
- kMaxLatency = 100,
- kProcessingDelay = kAckTimeout,
- kMaxRtt = 2 * kMaxLatency + kProcessingDelay,
- kExchangeLifetime = kMaxTransmitSpan + 2 * (kMaxLatency) + kProcessingDelay,
- kNonLifetime = kMaxTransmitSpan + kMaxLatency
-};
-
-/**
- * This class implements a common code base for CoAP client/server.
- *
- */
-class CoapBase
-{
-public:
-
- /**
- * 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) :
- mSocket(aUdp) {};
-
- /**
- * 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.
- * @param[in] aPrority The message priority level.
- *
- * @returns A pointer to the message or NULL if failed to allocate message.
- *
- */
- Message *NewMessage(const Header &aHeader, uint8_t aPriority = kDefaultCoapMessagePriority);
-
- /**
- * This method returns a port number used by CoAP client.
- *
- * @returns A port number.
- *
- */
- uint16_t GetPort(void) { return mSocket.GetSockName().mPort; };
-
- /**
- * This method sends a CoAP reset message.
- *
- * @param[in] aRequestHeader A reference to the CoAP Header that was used in CoAP request.
- * @param[in] aMessageInfo The message info corresponding to the CoAP request.
- *
- * @retval kThreadError_None Successfully enqueued the CoAP response message.
- * @retval kThreadError_NoBufs Insufficient buffers available to send the CoAP response.
- * @retval kThreadError_InvalidArgs The @p aRequestHeader header is not of confirmable type.
- *
- */
- ThreadError SendReset(Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo) {
- return SendEmptyMessage(kCoapTypeReset, aRequestHeader, aMessageInfo);
- };
-
- /**
- * This method sends a CoAP ACK empty message which is used in Separate Response for confirmable requests.
- *
- * @param[in] aRequestHeader A reference to the CoAP Header that was used in CoAP request.
- * @param[in] aMessageInfo The message info corresponding to the CoAP request.
- *
- * @retval kThreadError_None Successfully enqueued the CoAP response message.
- * @retval kThreadError_NoBufs Insufficient buffers available to send the CoAP response.
- * @retval kThreadError_InvalidArgs The @p aRequestHeader header is not of confirmable type.
- *
- */
- ThreadError SendAck(Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo) {
- return SendEmptyMessage(kCoapTypeAcknowledgment, aRequestHeader, aMessageInfo);
- };
-
-protected:
- ThreadError Start(const Ip6::SockAddr &aSockAddr);
- ThreadError Stop(void);
-
- /**
- * This method 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.
- *
- */
- virtual ThreadError Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) = 0;
-
- /**
- * This method 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.
- *
- */
- virtual void Receive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) = 0;
-
- Ip6::UdpSocket mSocket;
-
-private:
- /**
- * This method sends a CoAP empty message, i.e. a header-only message with code equals kCoapCodeEmpty.
- *
- * @param[in] aType The message type
- * @param[in] aRequestHeader A reference to the CoAP Header that was used in CoAP request.
- * @param[in] aMessageInfo The message info corresponding to the CoAP request.
- *
- * @retval kThreadError_None Successfully enqueued the CoAP response message.
- * @retval kThreadError_NoBufs Insufficient buffers available to send the CoAP response.
- * @retval kThreadError_InvalidArgs The @p aRequestHeader header is not of confirmable type.
- *
- */
- ThreadError SendEmptyMessage(Header::Type aType, const Header &aRequestHeader,
- const Ip6::MessageInfo &aMessageInfo);
-
- enum
- {
- kDefaultCoapMessagePriority = Message::kPriorityLow,
- };
-
- static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
-};
-
-} // namespace Coap
-} // namespace ot
-
-#endif // COAP_BASE_HPP_
diff --git a/src/core/coap/coap_client.cpp b/src/core/coap/coap_client.cpp
deleted file mode 100644
index 54526f6e0..000000000
--- a/src/core/coap/coap_client.cpp
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * 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.
- */
-
-#ifdef OPENTHREAD_CONFIG_FILE
-#include OPENTHREAD_CONFIG_FILE
-#else
-#include
-#endif
-
-#include "coap_client.hpp"
-
-#include
-
-#include "common/code_utils.hpp"
-#include "common/debug.hpp"
-#include "net/ip6.hpp"
-#include "net/udp6.hpp"
-#include "utils/wrap_string.h"
-
-/**
- * @file
- * This file implements the CoAP client.
- */
-
-namespace ot {
-namespace Coap {
-
-Client::Client(Ip6::Netif &aNetif):
- CoapBase(aNetif.GetIp6().mUdp),
- mRetransmissionTimer(aNetif.GetIp6().mTimerScheduler, &Client::HandleRetransmissionTimer, this)
-{
- mMessageId = static_cast(otPlatRandomGet());
-}
-
-ThreadError Client::Start(void)
-{
- Ip6::SockAddr addr;
- addr.mPort = 0;
-
- return CoapBase::Start(addr);
-}
-
-ThreadError Client::Stop(void)
-{
- Message *message = mPendingRequests.GetHead();
- Message *messageToRemove;
- RequestMetadata requestMetadata;
-
- // Remove all pending messages.
- while (message != NULL)
- {
- messageToRemove = message;
- message = message->GetNext();
-
- requestMetadata.ReadFrom(*messageToRemove);
- FinalizeCoapTransaction(*messageToRemove, requestMetadata, NULL, NULL, NULL, kThreadError_Abort);
- }
-
- return CoapBase::Stop();
-}
-
-ThreadError Client::SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo,
- otCoapResponseHandler aHandler, void *aContext)
-{
- ThreadError error;
- Header header;
- RequestMetadata requestMetadata;
- Message *storedCopy = NULL;
- uint16_t copyLength = 0;
-
- SuccessOrExit(error = header.FromMessage(aMessage, 0));
-
- // Set Message Id if it was not already set.
- if (header.GetMessageId() == 0)
- {
- header.SetMessageId(mMessageId++);
- aMessage.Write(0, Header::kMinHeaderLength, header.GetBytes());
- }
-
- if (header.IsConfirmable())
- {
- // Create a copy of entire message and enqueue it.
- copyLength = aMessage.GetLength();
- }
- else if (header.IsNonConfirmable() && header.IsRequest() && (aHandler != NULL))
- {
- // As we do not retransmit non confirmable messages, create a copy of header only, for token information.
- copyLength = header.GetLength();
- }
-
- if (copyLength > 0)
- {
- requestMetadata = RequestMetadata(header.IsConfirmable(), aMessageInfo, aHandler, aContext);
- VerifyOrExit((storedCopy = CopyAndEnqueueMessage(aMessage, copyLength, requestMetadata)) != NULL,
- error = kThreadError_NoBufs);
- }
-
- SuccessOrExit(error = Send(aMessage, aMessageInfo));
-
-exit:
-
- if (error != kThreadError_None && storedCopy != NULL)
- {
- DequeueMessage(*storedCopy);
- }
-
- return error;
-}
-
-ThreadError Client::AbortTransaction(otCoapResponseHandler aHandler, void *aContext)
-{
- ThreadError error = kThreadError_NotFound;
- Message *message;
- RequestMetadata requestMetadata;
-
- for (message = mPendingRequests.GetHead(); message != NULL; message = message->GetNext())
- {
- requestMetadata.ReadFrom(*message);
-
- if (requestMetadata.mResponseHandler == aHandler && requestMetadata.mResponseContext == aContext)
- {
- DequeueMessage(*message);
- error = kThreadError_None;
- }
- }
-
- return error;
-}
-
-
-Message *Client::CopyAndEnqueueMessage(const Message &aMessage, uint16_t aCopyLength,
- const RequestMetadata &aRequestMetadata)
-{
- ThreadError error = kThreadError_None;
- Message *messageCopy = NULL;
- uint32_t alarmFireTime;
-
- // Create a message copy of requested size.
- VerifyOrExit((messageCopy = aMessage.Clone(aCopyLength)) != NULL, error = kThreadError_NoBufs);
-
- // Append the copy with retransmission data.
- SuccessOrExit(error = aRequestMetadata.AppendTo(*messageCopy));
-
- // Setup the timer.
- if (mRetransmissionTimer.IsRunning())
- {
- // If timer is already running, check if it should be restarted with earlier fire time.
- alarmFireTime = mRetransmissionTimer.Gett0() + mRetransmissionTimer.Getdt();
-
- if (aRequestMetadata.IsEarlier(alarmFireTime))
- {
- mRetransmissionTimer.Start(aRequestMetadata.mRetransmissionTimeout);
- }
- }
- else
- {
- mRetransmissionTimer.Start(aRequestMetadata.mRetransmissionTimeout);
- }
-
- // Enqueue the message.
- mPendingRequests.Enqueue(*messageCopy);
-
-exit:
-
- if (error != kThreadError_None && messageCopy != NULL)
- {
- messageCopy->Free();
- messageCopy = NULL;
- }
-
- return messageCopy;
-}
-
-void Client::DequeueMessage(Message &aMessage)
-{
- mPendingRequests.Dequeue(aMessage);
-
- if (mRetransmissionTimer.IsRunning() && (mPendingRequests.GetHead() == NULL))
- {
- // No more requests pending, stop the timer.
- mRetransmissionTimer.Stop();
- }
-
- // Free the message memory.
- aMessage.Free();
-
- // No need to worry that the earliest pending message was removed -
- // the timer would just shoot earlier and then it'd be setup again.
-}
-
-ThreadError Client::SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
-{
- ThreadError error;
- Message *messageCopy = NULL;
-
- // Create a message copy for lower layers.
- VerifyOrExit((messageCopy = aMessage.Clone(aMessage.GetLength() - sizeof(RequestMetadata))) != NULL,
- error = kThreadError_NoBufs);
-
- // Send the copy.
- SuccessOrExit(error = Send(*messageCopy, aMessageInfo));
-
-exit:
-
- if (error != kThreadError_None && messageCopy != NULL)
- {
- messageCopy->Free();
- }
-
- return error;
-}
-
-void Client::HandleRetransmissionTimer(void *aContext)
-{
- static_cast(aContext)->HandleRetransmissionTimer();
-}
-
-void Client::HandleRetransmissionTimer(void)
-{
- uint32_t now = otPlatAlarmGetNow();
- uint32_t nextDelta = 0xffffffff;
- RequestMetadata requestMetadata;
- Message *message = mPendingRequests.GetHead();
- Message *nextMessage = NULL;
- Ip6::MessageInfo messageInfo;
-
- while (message != NULL)
- {
- nextMessage = message->GetNext();
- requestMetadata.ReadFrom(*message);
-
- if (requestMetadata.IsLater(now))
- {
- // Calculate the next delay and choose the lowest.
- if (requestMetadata.mNextTimerShot - now < nextDelta)
- {
- nextDelta = requestMetadata.mNextTimerShot - now;
- }
- }
- else if ((requestMetadata.mConfirmable) &&
- (requestMetadata.mRetransmissionCount < kMaxRetransmit))
- {
- // Increment retransmission counter and timer.
- requestMetadata.mRetransmissionCount++;
- requestMetadata.mRetransmissionTimeout *= 2;
- requestMetadata.mNextTimerShot = now + requestMetadata.mRetransmissionTimeout;
- requestMetadata.UpdateIn(*message);
-
- // Check if retransmission time is lower than current lowest.
- if (requestMetadata.mRetransmissionTimeout < nextDelta)
- {
- nextDelta = requestMetadata.mRetransmissionTimeout;
- }
-
- // Retransmit
- if (!requestMetadata.mAcknowledged)
- {
- messageInfo.SetPeerAddr(requestMetadata.mDestinationAddress);
- messageInfo.SetPeerPort(requestMetadata.mDestinationPort);
- messageInfo.SetSockAddr(requestMetadata.mSourceAddress);
-
- SendCopy(*message, messageInfo);
- }
- }
- else
- {
- // No expected response or acknowledgment.
- FinalizeCoapTransaction(*message, requestMetadata, NULL, NULL, NULL, kThreadError_ResponseTimeout);
- }
-
- message = nextMessage;
- }
-
- if (nextDelta != 0xffffffff)
- {
- mRetransmissionTimer.Start(nextDelta);
- }
-}
-
-Message *Client::FindRelatedRequest(const Header &aResponseHeader, const Ip6::MessageInfo &aMessageInfo,
- Header &aRequestHeader, RequestMetadata &aRequestMetadata)
-{
- Message *message = mPendingRequests.GetHead();
-
- while (message != NULL)
- {
- aRequestMetadata.ReadFrom(*message);
-
- if (((aRequestMetadata.mDestinationAddress == aMessageInfo.GetPeerAddr()) ||
- aRequestMetadata.mDestinationAddress.IsMulticast() ||
- aRequestMetadata.mDestinationAddress.IsAnycastRoutingLocator()) &&
- (aRequestMetadata.mDestinationPort == aMessageInfo.GetPeerPort()))
- {
- assert(aRequestHeader.FromMessage(*message, sizeof(RequestMetadata)) == kThreadError_None);
-
- switch (aResponseHeader.GetType())
- {
- case kCoapTypeReset:
- case kCoapTypeAcknowledgment:
- if (aResponseHeader.GetMessageId() == aRequestHeader.GetMessageId())
- {
- ExitNow();
- }
-
- break;
-
- case kCoapTypeConfirmable:
- case kCoapTypeNonConfirmable:
- if (aResponseHeader.IsTokenEqual(aRequestHeader))
- {
- ExitNow();
- }
-
- break;
- }
- }
-
- message = message->GetNext();
- }
-
-exit:
- return message;
-}
-
-void Client::FinalizeCoapTransaction(Message &aRequest, const RequestMetadata &aRequestMetadata,
- Header *aResponseHeader, Message *aResponse,
- const Ip6::MessageInfo *aMessageInfo, ThreadError aResult)
-{
- DequeueMessage(aRequest);
-
- if (aRequestMetadata.mResponseHandler != NULL)
- {
- aRequestMetadata.mResponseHandler(aRequestMetadata.mResponseContext, aResponseHeader,
- aResponse, aMessageInfo, aResult);
- }
-}
-
-void Client::Receive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
-{
- Header responseHeader;
- Header requestHeader;
- RequestMetadata requestMetadata;
- Message *message = NULL;
- ThreadError error;
-
- SuccessOrExit(error = responseHeader.FromMessage(aMessage, 0));
- aMessage.MoveOffset(responseHeader.GetLength());
-
- message = FindRelatedRequest(responseHeader, aMessageInfo, requestHeader, requestMetadata);
-
- if (message == NULL)
- {
- ExitNow();
- }
-
- switch (responseHeader.GetType())
- {
- case kCoapTypeReset:
- if (responseHeader.IsEmpty())
- {
- FinalizeCoapTransaction(*message, requestMetadata, NULL, NULL, NULL, kThreadError_Abort);
- }
-
- // Silently ignore non-empty reset messages (RFC 7252, p. 4.2).
- break;
-
- case kCoapTypeAcknowledgment:
- if (responseHeader.IsEmpty())
- {
- // Empty acknowledgment.
- if (requestMetadata.mConfirmable)
- {
- requestMetadata.mAcknowledged = true;
- requestMetadata.UpdateIn(*message);
- }
-
- // Remove the message if response is not expected, otherwise await response.
- if (requestMetadata.mResponseHandler == NULL)
- {
- DequeueMessage(*message);
- }
- }
- else if (responseHeader.IsResponse() && responseHeader.IsTokenEqual(requestHeader))
- {
- // Piggybacked response.
- FinalizeCoapTransaction(*message, requestMetadata, &responseHeader, &aMessage, &aMessageInfo, kThreadError_None);
- }
-
- // Silently ignore acknowledgments carrying requests (RFC 7252, p. 4.2)
- // or with no token match (RFC 7252, p. 5.3.2)
- break;
-
- case kCoapTypeConfirmable:
- // Send empty ACK if it is a CON message.
- SendAck(responseHeader, aMessageInfo);
-
- // fall through
- ;
-
- case kCoapTypeNonConfirmable:
- // Separate response.
- FinalizeCoapTransaction(*message, requestMetadata, &responseHeader, &aMessage, &aMessageInfo, kThreadError_None);
-
- break;
- }
-
-exit:
-
- if (error == kThreadError_None && message == NULL)
- {
- if (responseHeader.IsConfirmable() || responseHeader.IsNonConfirmable())
- {
- // Successfully parsed a header but no matching request was found - reject the message by sending reset.
- SendReset(responseHeader, aMessageInfo);
- }
- }
-}
-
-RequestMetadata::RequestMetadata(bool aConfirmable, const Ip6::MessageInfo &aMessageInfo,
- otCoapResponseHandler aHandler, void *aContext)
-{
- mSourceAddress = aMessageInfo.GetSockAddr();
- mDestinationPort = aMessageInfo.GetPeerPort();
- mDestinationAddress = aMessageInfo.GetPeerAddr();
- mResponseHandler = aHandler;
- mResponseContext = aContext;
- mRetransmissionCount = 0;
- mRetransmissionTimeout = Timer::SecToMsec(kAckTimeout);
- mRetransmissionTimeout += otPlatRandomGet() %
- (Timer::SecToMsec(kAckTimeout) * kAckRandomFactorNumerator / kAckRandomFactorDenominator -
- Timer::SecToMsec(kAckTimeout) + 1);
-
- if (aConfirmable)
- {
- // Set next retransmission timeout.
- mNextTimerShot = Timer::GetNow() + mRetransmissionTimeout;
- }
- else
- {
- // Set overall response timeout.
- mNextTimerShot = Timer::GetNow() + kMaxTransmitWait;
- }
-
- mAcknowledged = false;
- mConfirmable = aConfirmable;
-}
-
-} // namespace Coap
-} // namespace ot
diff --git a/src/core/coap/coap_client.hpp b/src/core/coap/coap_client.hpp
deleted file mode 100644
index 8dfc4d76e..000000000
--- a/src/core/coap/coap_client.hpp
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * 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_CLIENT_HPP_
-#define COAP_CLIENT_HPP_
-
-#include
-
-#include "coap/coap_base.hpp"
-#include "coap/coap_header.hpp"
-#include "common/message.hpp"
-#include "common/timer.hpp"
-#include "net/netif.hpp"
-#include "net/udp6.hpp"
-
-/**
- * @file
- * This file includes definitions for the CoAP client.
- */
-
-namespace ot {
-namespace Coap {
-
-class Client;
-
-/**
- * This class implements metadata required for CoAP retransmission.
- *
- */
-OT_TOOL_PACKED_BEGIN
-class RequestMetadata
-{
- friend class Client;
-
-public:
-
- /**
- * Default constructor for the object.
- *
- */
- RequestMetadata(void):
- mDestinationPort(0),
- mResponseHandler(NULL),
- mResponseContext(NULL),
- mNextTimerShot(0),
- mRetransmissionTimeout(0),
- mRetransmissionCount(0),
- mAcknowledged(false),
- mConfirmable(false) {};
-
- /**
- * This constructor initializes the object with specific values.
- *
- * @param[in] aConfirmable Information if the request is confirmable or not.
- * @param[in] aMessageInfo Addressing information.
- * @param[in] aHandler Pointer to a handler function for the response.
- * @param[in] aContext Context for the handler function.
- *
- */
- RequestMetadata(bool aConfirmable, const Ip6::MessageInfo &aMessageInfo,
- otCoapResponseHandler aHandler, void *aContext);
-
- /**
- * This method appends request data to the message.
- *
- * @param[in] aMessage A reference to the message.
- *
- * @retval kThreadError_None Successfully appended the bytes.
- * @retval kThreadError_NoBufs Insufficient available buffers to grow the message.
- *
- */
- ThreadError AppendTo(Message &aMessage) const {
- return aMessage.Append(this, sizeof(*this));
- };
-
- /**
- * This method reads request data from the message.
- *
- * @param[in] aMessage A reference to the message.
- *
- * @returns The number of bytes read.
- *
- */
- uint16_t ReadFrom(const Message &aMessage) {
- return aMessage.Read(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
- };
-
- /**
- * This method updates request data in the message.
- *
- * @param[in] aMessage A reference to the message.
- *
- * @returns The number of bytes updated.
- *
- */
- int UpdateIn(Message &aMessage) const {
- return aMessage.Write(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
- }
-
- /**
- * This method checks if the message shall be sent before the given time.
- *
- * @param[in] aTime A time to compare.
- *
- * @retval TRUE If the message shall be sent before the given time.
- * @retval FALSE Otherwise.
- */
- bool IsEarlier(uint32_t aTime) const { return (static_cast(aTime - mNextTimerShot) > 0); };
-
- /**
- * This method checks if the message shall be sent after the given time.
- *
- * @param[in] aTime A time to compare.
- *
- * @retval TRUE If the message shall be sent after the given time.
- * @retval FALSE Otherwise.
- */
- bool IsLater(uint32_t aTime) const { return (static_cast(aTime - mNextTimerShot) < 0); };
-
-private:
- Ip6::Address mSourceAddress; ///< IPv6 address of the message source.
- Ip6::Address mDestinationAddress; ///< IPv6 address of the message destination.
- uint16_t mDestinationPort; ///< UDP port of the message destination.
- otCoapResponseHandler mResponseHandler; ///< A function pointer that is called on response reception.
- void *mResponseContext; ///< A pointer to arbitrary context information.
- uint32_t mNextTimerShot; ///< Time when the timer should shoot for this message.
- uint32_t mRetransmissionTimeout; ///< Delay that is applied to next retransmission.
- uint8_t mRetransmissionCount; ///< Number of retransmissions.
- bool mAcknowledged: 1; ///< Information that request was acknowledged.
- bool mConfirmable: 1; ///< Information that message is confirmable.
-} OT_TOOL_PACKED_END;
-
-/**
- * This class implements CoAP 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] 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);
-
- /**
- * This method starts the CoAP client.
- *
- * @retval kThreadError_None Successfully started the CoAP client.
- *
- */
- ThreadError Start(void);
-
- /**
- * This method stops the CoAP client.
- *
- * @retval kThreadError_None Successfully stopped the CoAP client.
- *
- */
- ThreadError Stop(void);
-
- /**
- * This method sends a CoAP message.
- *
- * 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] aMessageInfo A reference to the message info associated with @p aMessage.
- * @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.
- *
- */
- ThreadError SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo,
- otCoapResponseHandler aHandler = NULL, void *aContext = NULL);
-
- /**
- * This method aborts CoAP transactions associated with given handler and context.
- *
- * @param[in] aHandler A function pointer that should be called when the transaction ends.
- * @param[in] aContext A pointer to arbitrary context information.
- *
- * @retval kThreadError_None Successfully aborted CoAP transactions.
- * @retval kThreadError_NotFound CoAP transaction associated with given handler was not found.
- *
- */
- ThreadError AbortTransaction(otCoapResponseHandler aHandler, void *aContext);
-
- /**
- * This method returns a reference to the request message list.
- *
- * @returns A reference to the request message list.
- *
- */
- const MessageQueue &GetRequestMessages(void) const { return mPendingRequests; }
-
-protected:
- virtual void Receive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
-
- ThreadError Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) {
- return mSocket.SendTo(aMessage, aMessageInfo);
- }
-
-
-private:
- Message *CopyAndEnqueueMessage(const Message &aMessage, uint16_t aCopyLength,
- const RequestMetadata &aRequestMetadata);
- void DequeueMessage(Message &aMessage);
- Message *FindRelatedRequest(const Header &aResponseHeader, const Ip6::MessageInfo &aMessageInfo,
- Header &aRequestHeader, RequestMetadata &aRequestMetadata);
- void FinalizeCoapTransaction(Message &aRequest, const RequestMetadata &aRequestMetadata, Header *aResponseHeader,
- Message *aResponse, const Ip6::MessageInfo *aMessageInfo, ThreadError aResult);
-
- ThreadError SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
- static void HandleRetransmissionTimer(void *aContext);
- void HandleRetransmissionTimer(void);
-
- MessageQueue mPendingRequests;
- uint16_t mMessageId;
- Timer mRetransmissionTimer;
-};
-
-} // namespace Coap
-} // namespace ot
-
-#endif // COAP_CLIENT_HPP_
diff --git a/src/core/coap/coap_header.cpp b/src/core/coap/coap_header.cpp
index ec6add2a8..8dd1bda30 100644
--- a/src/core/coap/coap_header.cpp
+++ b/src/core/coap/coap_header.cpp
@@ -41,7 +41,7 @@
#include
-#include "coap/coap_client.hpp"
+#include "coap/coap.hpp"
#include "common/code_utils.hpp"
#include "common/debug.hpp"
#include "common/encoding.hpp"
diff --git a/src/core/coap/secure_coap_server.cpp b/src/core/coap/coap_secure.cpp
similarity index 58%
rename from src/core/coap/secure_coap_server.cpp
rename to src/core/coap/coap_secure.cpp
index 243efdcb0..911674412 100644
--- a/src/core/coap/secure_coap_server.cpp
+++ b/src/core/coap/coap_secure.cpp
@@ -26,7 +26,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#define WPP_NAME "secure_coap_server.tmh"
+#define WPP_NAME "coap_secure.tmh"
#ifdef OPENTHREAD_CONFIG_FILE
#include OPENTHREAD_CONFIG_FILE
@@ -34,53 +34,54 @@
#include
#endif
-#include "secure_coap_server.hpp"
+#include "coap_secure.hpp"
#include "common/logging.hpp"
#include "meshcop/dtls.hpp"
#include "thread/thread_netif.hpp"
-#if OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
+#if OPENTHREAD_ENABLE_DTLS
/**
* @file
- * This file implements the secure CoAP server.
+ * This file implements the secure CoAP agent.
*/
namespace ot {
namespace Coap {
-SecureServer::SecureServer(ThreadNetif &aNetif, uint16_t aPort):
- Server(aNetif, aPort),
- mTransmitCallback(NULL),
- mContext(NULL),
- mNetif(aNetif),
+CoapSecure::CoapSecure(ThreadNetif &aNetif):
+ Coap(aNetif),
+ mConnectedCallback(NULL),
+ mConnectedContext(NULL),
+ mTransportCallback(NULL),
+ mTransportContext(NULL),
mTransmitMessage(NULL),
- mTransmitTask(aNetif.GetIp6().mTaskletScheduler, &SecureServer::HandleUdpTransmit, this)
+ mTransmitTask(aNetif.GetIp6().mTaskletScheduler, &CoapSecure::HandleUdpTransmit, this)
{
}
-ThreadError SecureServer::Start(TransportCallback aCallback, void *aContext)
+ThreadError CoapSecure::Start(uint16_t aPort, TransportCallback aCallback, void *aContext)
{
ThreadError error = kThreadError_None;
- mTransmitCallback = aCallback;
- mContext = aContext;
+ mTransportCallback = aCallback;
+ mTransportContext = aContext;
- // Passing mTransmitCallback means that we do not want to use socket
+ // Passing mTransportCallback means that we do not want to use socket
// to transmit/receive messages, so do not open it in that case.
- if (mTransmitCallback == NULL)
+ if (mTransportCallback == NULL)
{
- error = Server::Start();
+ error = Coap::Start(aPort);
}
return error;
}
-ThreadError SecureServer::Stop()
+ThreadError CoapSecure::Stop(void)
{
- if (mNetif.GetDtls().IsStarted())
+ if (IsConnectionActive())
{
- mNetif.GetDtls().Stop();
+ Disconnect();
}
if (mTransmitMessage != NULL)
@@ -89,26 +90,75 @@ ThreadError SecureServer::Stop()
mTransmitMessage = NULL;
}
- mTransmitCallback = NULL;
- mContext = NULL;
+ mTransportCallback = NULL;
+ mTransportContext = NULL;
- otLogFuncExit();
-
- return Server::Stop();
+ return Coap::Stop();
}
-bool SecureServer::IsConnectionActive(void)
+ThreadError CoapSecure::Connect(const Ip6::MessageInfo &aMessageInfo, ConnectedCallback aCallback, void *aContext)
+{
+ mPeerAddress = aMessageInfo;
+ mConnectedCallback = aCallback;
+ mConnectedContext = aContext;
+
+ return mNetif.GetDtls().Start(true, &CoapSecure::HandleDtlsConnected, &CoapSecure::HandleDtlsReceive,
+ &CoapSecure::HandleDtlsSend, this);
+}
+
+bool CoapSecure::IsConnectionActive(void)
{
return mNetif.GetDtls().IsStarted();
-};
+}
-ThreadError SecureServer::Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+bool CoapSecure::IsConnected(void)
+{
+ return mNetif.GetDtls().IsConnected();
+}
+
+ThreadError CoapSecure::Disconnect(void)
+{
+ return mNetif.GetDtls().Stop();
+}
+
+MeshCoP::Dtls &CoapSecure::GetDtls(void)
+{
+ return mNetif.GetDtls();
+}
+
+ThreadError CoapSecure::SetPsk(const uint8_t *aPsk, uint8_t aPskLength)
+{
+ return mNetif.GetDtls().SetPsk(aPsk, aPskLength);
+}
+
+ThreadError CoapSecure::SendMessage(Message &aMessage, otCoapResponseHandler aHandler, void *aContext)
+{
+ ThreadError error = kThreadError_None;
+
+ otLogFuncEntry();
+
+ VerifyOrExit(IsConnected(), error = kThreadError_InvalidState);
+
+ error = Coap::SendMessage(aMessage, mPeerAddress, aHandler, aContext);
+
+exit:
+ otLogFuncExitErr(error);
+ return error;
+}
+
+ThreadError CoapSecure::SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo,
+ otCoapResponseHandler aHandler, void *aContext)
+{
+ return Coap::SendMessage(aMessage, aMessageInfo, aHandler, aContext);
+}
+
+ThreadError CoapSecure::Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
(void)aMessageInfo;
return mNetif.GetDtls().Send(aMessage, aMessage.GetLength());
}
-void SecureServer::Receive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+void CoapSecure::Receive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
otLogFuncEntry();
@@ -146,36 +196,34 @@ exit:
otLogFuncExit();
}
-ThreadError SecureServer::SetPsk(const uint8_t *aPsk, uint8_t aPskLength)
+void CoapSecure::HandleDtlsConnected(void *aContext, bool aConnected)
{
- return mNetif.GetDtls().SetPsk(aPsk, aPskLength);
+ return static_cast(aContext)->HandleDtlsConnected(aConnected);
}
-void SecureServer::HandleDtlsConnected(void *aContext, bool aConnected)
+void CoapSecure::HandleDtlsConnected(bool aConnected)
{
- return static_cast(aContext)->HandleDtlsConnected(aConnected);
+ if (mConnectedCallback != NULL)
+ {
+ mConnectedCallback(aConnected, mConnectedContext);
+ }
}
-void SecureServer::HandleDtlsConnected(bool aConnected)
+void CoapSecure::HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength)
{
- (void)aConnected;
+ return static_cast(aContext)->HandleDtlsReceive(aBuf, aLength);
}
-void SecureServer::HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength)
+void CoapSecure::HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength)
{
- return static_cast(aContext)->HandleDtlsReceive(aBuf, aLength);
-}
-
-void SecureServer::HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength)
-{
- Message *message;
+ Message *message = NULL;
otLogFuncEntry();
VerifyOrExit((message = mNetif.GetIp6().mMessagePool.New(Message::kTypeIp6, 0)) != NULL);
SuccessOrExit(message->Append(aBuf, aLength));
- Server::Receive(*message, mPeerAddress);
+ Coap::Receive(*message, mPeerAddress);
exit:
@@ -187,12 +235,12 @@ exit:
otLogFuncExit();
}
-ThreadError SecureServer::HandleDtlsSend(void *aContext, const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType)
+ThreadError CoapSecure::HandleDtlsSend(void *aContext, const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType)
{
- return static_cast(aContext)->HandleDtlsSend(aBuf, aLength, aMessageSubType);
+ return static_cast(aContext)->HandleDtlsSend(aBuf, aLength, aMessageSubType);
}
-ThreadError SecureServer::HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType)
+ThreadError CoapSecure::HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType)
{
ThreadError error = kThreadError_None;
@@ -227,12 +275,12 @@ exit:
return error;
}
-void SecureServer::HandleUdpTransmit(void *aContext)
+void CoapSecure::HandleUdpTransmit(void *aContext)
{
- return static_cast(aContext)->HandleUdpTransmit();
+ return static_cast(aContext)->HandleUdpTransmit();
}
-void SecureServer::HandleUdpTransmit(void)
+void CoapSecure::HandleUdpTransmit(void)
{
ThreadError error = kThreadError_None;
@@ -240,9 +288,9 @@ void SecureServer::HandleUdpTransmit(void)
VerifyOrExit(mTransmitMessage != NULL, error = kThreadError_NoBufs);
- if (mTransmitCallback)
+ if (mTransportCallback)
{
- SuccessOrExit(error = mTransmitCallback(mContext, *mTransmitMessage, mPeerAddress));
+ SuccessOrExit(error = mTransportCallback(mTransportContext, *mTransmitMessage, mPeerAddress));
}
else
{
@@ -264,4 +312,4 @@ exit:
} // namespace Coap
} // namespace ot
-#endif // OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
+#endif // OPENTHREAD_ENABLE_DTLS
diff --git a/src/core/coap/secure_coap_client.hpp b/src/core/coap/coap_secure.hpp
similarity index 61%
rename from src/core/coap/secure_coap_client.hpp
rename to src/core/coap/coap_secure.hpp
index 1df9c7b2d..2e513bf48 100644
--- a/src/core/coap/secure_coap_client.hpp
+++ b/src/core/coap/coap_secure.hpp
@@ -26,15 +26,15 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef SECURE_COAP_CLIENT_HPP_
-#define SECURE_COAP_CLIENT_HPP_
+#ifndef COAP_SECURE_HPP_
+#define COAP_SECURE_HPP_
-#include "coap/coap_client.hpp"
+#include "coap/coap.hpp"
#include "meshcop/dtls.hpp"
/**
* @file
- * This file includes definitions for the secure CoAP client.
+ * This file includes definitions for the secure CoAP agent.
*/
namespace ot {
@@ -43,7 +43,7 @@ class ThreadNetif;
namespace Coap {
-class SecureClient: public Client
+class CoapSecure: public Coap
{
public:
/**
@@ -56,17 +56,40 @@ public:
typedef void (*ConnectedCallback)(bool aConnected, void *aContext);
/**
- * This constructor initializes the object.
+ * This function pointer is called when secure CoAP server want to send encrypted message.
*
- * @param[in] aNetif A reference to the network interface that secure CoAP client should be assigned to.
+ * @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.
*
*/
- SecureClient(ThreadNetif &aNetif);
+ typedef ThreadError(*TransportCallback)(void *aContext, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
/**
- * This method stops the secure CoAP client.
+ * This constructor initializes the object.
*
- * @retval kThreadError_None Successfully stopped the secure CoAP client.
+ * @param[in] aNetif A reference to the network interface that the secure CoAP agent is bound to.
+ *
+ */
+ CoapSecure(ThreadNetif &aNetif);
+
+ /**
+ * This method starts the secure CoAP agent.
+ *
+ * @param[in] aPort The local UDP port to bind to.
+ * @param[in] aCallback A pointer to a function for sending messages.
+ * If NULL, the message is sent directly to the socket.
+ * @param[in] aContext A pointer to arbitrary context information.
+ *
+ * @retval kThreadError_None Successfully started the CoAP agent.
+ *
+ */
+ ThreadError Start(uint16_t aPort, TransportCallback aCallback = NULL, void *aContext = NULL);
+
+ /**
+ * This method stops the secure CoAP agent.
+ *
+ * @retval kThreadError_None Successfully stopped the secure CoAP agent.
*
*/
ThreadError Stop(void);
@@ -116,6 +139,18 @@ public:
*/
MeshCoP::Dtls &GetDtls(void);
+ /**
+ * This method sets the PSK.
+ *
+ * @param[in] aPSK A pointer to the PSK.
+ * @param[in] aPskLength The 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);
+
/**
* This method sends a CoAP message over secure DTLS connection.
*
@@ -134,11 +169,39 @@ public:
*/
ThreadError SendMessage(Message &aMessage, otCoapResponseHandler aHandler = NULL, void *aContext = NULL);
-private:
- ThreadError Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+ /**
+ * 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] aMessageInfo A reference to the message info associated with @p aMessage.
+ * @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, const Ip6::MessageInfo &aMessageInfo,
+ otCoapResponseHandler aHandler = NULL, void *aContext = NULL);
+ /**
+ * 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);
+private:
+ virtual ThreadError Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+
static void HandleDtlsConnected(void *aContext, bool aConnected);
void HandleDtlsConnected(bool aConnected);
@@ -153,8 +216,9 @@ private:
Ip6::MessageInfo mPeerAddress;
ConnectedCallback mConnectedCallback;
- void *mContext;
- ThreadNetif &mNetif;
+ void *mConnectedContext;
+ TransportCallback mTransportCallback;
+ void *mTransportContext;
Message *mTransmitMessage;
Tasklet mTransmitTask;
};
@@ -162,4 +226,4 @@ private:
} // namespace Coap
} // namespace ot
-#endif // SECURE_COAP_CLIENT_HPP_
+#endif // COAP_SECURE_HPP_
diff --git a/src/core/coap/coap_server.cpp b/src/core/coap/coap_server.cpp
deleted file mode 100644
index f187f51bf..000000000
--- a/src/core/coap/coap_server.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * @file
- * This file implements the CoAP server message dispatch.
- */
-
-#ifdef OPENTHREAD_CONFIG_FILE
-#include OPENTHREAD_CONFIG_FILE
-#else
-#include
-#endif
-
-#include "coap_server.hpp"
-
-#include "common/code_utils.hpp"
-#include "net/ip6.hpp"
-
-namespace ot {
-namespace Coap {
-
-Server::Server(Ip6::Netif &aNetif, uint16_t aPort) :
- CoapBase(aNetif.GetIp6().mUdp),
- mPort(aPort),
- mResources(NULL),
- mInterceptor(NULL),
- mResponsesQueue(aNetif)
-{
-}
-
-ThreadError Server::Start(void)
-{
- Ip6::SockAddr sockaddr;
- sockaddr.mPort = mPort;
-
- return CoapBase::Start(sockaddr);
-}
-
-ThreadError Server::Stop(void)
-{
- mResponsesQueue.DequeueAllResponses();
-
- return CoapBase::Stop();
-}
-
-ThreadError Server::AddResource(Resource &aResource)
-{
- ThreadError error = kThreadError_None;
-
- for (Resource *cur = mResources; cur; cur = cur->GetNext())
- {
- VerifyOrExit(cur != &aResource, error = kThreadError_Already);
- }
-
- aResource.mNext = mResources;
- mResources = &aResource;
-
-exit:
- return error;
-}
-
-void Server::RemoveResource(Resource &aResource)
-{
- if (mResources == &aResource)
- {
- mResources = aResource.GetNext();
- }
- else
- {
- for (Resource *cur = mResources; cur; cur = cur->GetNext())
- {
- if (cur->mNext == &aResource)
- {
- cur->mNext = aResource.mNext;
- ExitNow();
- }
- }
- }
-
-exit:
- aResource.mNext = NULL;
-}
-
-ThreadError Server::SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
-{
- mResponsesQueue.EnqueueResponse(aMessage, aMessageInfo);
-
- return Send(aMessage, aMessageInfo);
-}
-
-ThreadError Server::SendEmptyAck(const Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo)
-{
- ThreadError error = kThreadError_None;
- Coap::Header responseHeader;
- Message *message = NULL;
-
- VerifyOrExit(aRequestHeader.GetType() == kCoapTypeConfirmable, error = kThreadError_InvalidArgs);
-
- responseHeader.SetDefaultResponseHeader(aRequestHeader);
-
- VerifyOrExit((message = NewMessage(responseHeader)) != NULL, error = kThreadError_NoBufs);
-
- SuccessOrExit(error = SendMessage(*message, aMessageInfo));
-
-exit:
-
- if (error != kThreadError_None && message != NULL)
- {
- message->Free();
- }
-
- return error;
-}
-
-void Server::Receive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
-{
- Header header;
- char uriPath[Resource::kMaxReceivedUriPath] = "";
- char *curUriPath = uriPath;
- const Header::Option *coapOption;
- Message *response;
-
- if (mInterceptor != NULL)
- {
- SuccessOrExit(mInterceptor(aMessage, aMessageInfo));
- }
-
- SuccessOrExit(header.FromMessage(aMessage, 0));
- aMessage.MoveOffset(header.GetLength());
-
- switch (mResponsesQueue.GetMatchedResponseCopy(header, aMessageInfo, &response))
- {
- case kThreadError_None:
- SendMessage(*response, aMessageInfo);
-
- // fall through
-
- case kThreadError_NoBufs:
- ExitNow();
-
- case kThreadError_NotFound:
- default:
- break;
- }
-
- coapOption = header.GetFirstOption();
-
- while (coapOption != NULL)
- {
- switch (coapOption->mNumber)
- {
- case kCoapOptionUriPath:
- if (curUriPath != uriPath)
- {
- *curUriPath++ = '/';
- }
-
- VerifyOrExit(coapOption->mLength < sizeof(uriPath) - static_cast(curUriPath + 1 - uriPath));
-
- memcpy(curUriPath, coapOption->mValue, coapOption->mLength);
- curUriPath += coapOption->mLength;
- break;
-
- default:
- break;
- }
-
- coapOption = header.GetNextOption();
- }
-
- curUriPath[0] = '\0';
-
- for (Resource *resource = mResources; resource; resource = resource->GetNext())
- {
- if (strcmp(resource->mUriPath, uriPath) == 0)
- {
- resource->HandleRequest(header, aMessage, aMessageInfo);
- ExitNow();
- }
- }
-
-exit:
- return;
-}
-
-ThreadError Server::SetPort(uint16_t aPort)
-{
- mPort = aPort;
-
- Ip6::SockAddr sockaddr;
- sockaddr.mPort = mPort;
-
- return mSocket.Bind(sockaddr);
-}
-
-ThreadError ResponsesQueue::GetMatchedResponseCopy(const Header &aHeader,
- const Ip6::MessageInfo &aMessageInfo,
- Message **aResponse)
-{
- ThreadError error = kThreadError_NotFound;
- Message *message;
- EnqueuedResponseHeader enqueuedResponseHeader;
- Ip6::MessageInfo messageInfo;
- Header header;
-
- for (message = mQueue.GetHead(); message != NULL; message = message->GetNext())
- {
- enqueuedResponseHeader.ReadFrom(*message);
- messageInfo = enqueuedResponseHeader.GetMessageInfo();
-
- // Check source endpoint
- if (messageInfo.GetPeerPort() != aMessageInfo.GetPeerPort())
- {
- continue;
- }
-
- if (messageInfo.GetPeerAddr() != aMessageInfo.GetPeerAddr())
- {
- continue;
- }
-
- // Check Message Id
- if (header.FromMessage(*message, sizeof(EnqueuedResponseHeader)) != kThreadError_None)
- {
- continue;
- }
-
- if (header.GetMessageId() != aHeader.GetMessageId())
- {
- continue;
- }
-
- *aResponse = message->Clone();
- VerifyOrExit(*aResponse != NULL, error = kThreadError_NoBufs);
-
- EnqueuedResponseHeader::RemoveFrom(**aResponse);
-
- error = kThreadError_None;
- break;
- }
-
-exit:
- return error;
-}
-
-ThreadError ResponsesQueue::GetMatchedResponseCopy(const Message &aRequest,
- const Ip6::MessageInfo &aMessageInfo,
- Message **aResponse)
-{
- ThreadError error = kThreadError_None;
- Header header;
-
- SuccessOrExit(error = header.FromMessage(aRequest, 0));
-
- error = GetMatchedResponseCopy(header, aMessageInfo, aResponse);
-
-exit:
- return error;
-}
-
-void ResponsesQueue::EnqueueResponse(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
-{
- Header header;
- Message *copy;
- EnqueuedResponseHeader enqueuedResponseHeader(aMessageInfo);
- uint16_t messageCount;
- uint16_t bufferCount;
-
- SuccessOrExit(header.FromMessage(aMessage, 0));
- VerifyOrExit(header.GetType() == kCoapTypeAcknowledgment ||
- header.GetType() == kCoapTypeReset);
-
- switch (GetMatchedResponseCopy(aMessage, aMessageInfo, ©))
- {
- case kThreadError_NotFound:
- break;
-
- case kThreadError_None:
- copy->Free();
-
- // fall through
-
- case kThreadError_NoBufs:
- default:
- ExitNow();
- }
-
- mQueue.GetInfo(messageCount, bufferCount);
-
- if (messageCount >= kMaxCachedResponses)
- {
- DequeueOldestResponse();
- }
-
- copy = aMessage.Clone();
- VerifyOrExit(copy != NULL);
-
- enqueuedResponseHeader.AppendTo(*copy);
- mQueue.Enqueue(*copy);
-
- if (!mTimer.IsRunning())
- {
- mTimer.Start(Timer::SecToMsec(kExchangeLifetime));
- }
-
-exit:
- return;
-}
-
-void ResponsesQueue::DequeueOldestResponse(void)
-{
- Message *message;
-
- VerifyOrExit((message = mQueue.GetHead()) != NULL);
- DequeueResponse(*message);
-
-exit:
- return;
-}
-
-void ResponsesQueue::DequeueAllResponses(void)
-{
- Message *message;
-
- while ((message = mQueue.GetHead()) != NULL)
- {
- DequeueResponse(*message);
- }
-}
-
-void ResponsesQueue::HandleTimer(void *aContext)
-{
- static_cast(aContext)->HandleTimer();
-}
-
-void ResponsesQueue::HandleTimer(void)
-{
- Message *message;
- EnqueuedResponseHeader enqueuedResponseHeader;
-
- while ((message = mQueue.GetHead()) != NULL)
- {
- enqueuedResponseHeader.ReadFrom(*message);
-
- if (enqueuedResponseHeader.IsEarlier(Timer::GetNow()))
- {
- DequeueResponse(*message);
- }
- else
- {
- mTimer.Start(enqueuedResponseHeader.GetRemainingTime());
- break;
- }
- }
-}
-
-uint32_t EnqueuedResponseHeader::GetRemainingTime(void) const
-{
- int32_t remainingTime = static_cast(mDequeueTime - Timer::GetNow());
-
- return remainingTime >= 0 ? static_cast(remainingTime) : 0;
-}
-
-
-} // namespace Coap
-} // namespace ot
diff --git a/src/core/coap/secure_coap_client.cpp b/src/core/coap/secure_coap_client.cpp
deleted file mode 100644
index 63cbb981b..000000000
--- a/src/core/coap/secure_coap_client.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * 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"
-
-#ifdef OPENTHREAD_CONFIG_FILE
-#include OPENTHREAD_CONFIG_FILE
-#else
-#include
-#endif
-
-#include "secure_coap_client.hpp"
-
-#include "common/logging.hpp"
-#include "meshcop/dtls.hpp"
-#include "thread/thread_netif.hpp"
-
-#if OPENTHREAD_ENABLE_JOINER
-
-/**
- * @file
- * This file implements the secure CoAP client.
- */
-
-namespace ot {
-namespace Coap {
-
-SecureClient::SecureClient(ThreadNetif &aNetif):
- Client(aNetif),
- 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::HandleDtlsConnected, &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(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
-{
- (void)aMessageInfo;
- return mNetif.GetDtls().Send(aMessage, aMessage.GetLength());
-}
-
-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());
-
-exit:
- otLogFuncExit();
-}
-
-void SecureClient::HandleDtlsConnected(void *aContext, bool aConnected)
-{
- return static_cast(aContext)->HandleDtlsConnected(aConnected);
-}
-
-void SecureClient::HandleDtlsConnected(bool aConnected)
-{
- if (mConnectedCallback != NULL)
- {
- mConnectedCallback(aConnected, mContext);
- }
-}
-
-void SecureClient::HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength)
-{
- return static_cast(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));
-
- Client::Receive(*message, mPeerAddress);
-
-exit:
-
- if (message != NULL)
- {
- message->Free();
- }
-
- otLogFuncExit();
-}
-
-ThreadError SecureClient::HandleDtlsSend(void *aContext, const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType)
-{
- return static_cast(aContext)->HandleDtlsSend(aBuf, aLength, aMessageSubType);
-}
-
-ThreadError SecureClient::HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType)
-{
- ThreadError error = kThreadError_None;
-
- otLogFuncEntry();
-
- if (mTransmitMessage == NULL)
- {
- VerifyOrExit((mTransmitMessage = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs);
- mTransmitMessage->SetSubType(aMessageSubType);
- 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(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 ot
-
-#endif // OPENTHREAD_ENABLE_JOINER
diff --git a/src/core/coap/secure_coap_server.hpp b/src/core/coap/secure_coap_server.hpp
deleted file mode 100644
index b82ecfac0..000000000
--- a/src/core/coap/secure_coap_server.hpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * 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 ot {
-
-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);
-
-protected:
- virtual ThreadError Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
-
-private:
- static void HandleDtlsConnected(void *aContext, bool aConnected);
- void HandleDtlsConnected(bool aConnected);
-
- 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, uint8_t aMessageSubType);
- ThreadError HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType);
-
- static void HandleUdpTransmit(void *aContext);
- void HandleUdpTransmit(void);
-
- Ip6::MessageInfo mPeerAddress;
- TransportCallback mTransmitCallback;
- void *mContext;
- ThreadNetif &mNetif;
- Message *mTransmitMessage;
- Tasklet mTransmitTask;
-};
-
-} // namespace Coap
-} // namespace ot
-
-#endif // SECURE_COAP_SERVER_HPP_
diff --git a/src/core/common/logging.cpp b/src/core/common/logging.cpp
index 7a388c142..3e5088c04 100644
--- a/src/core/common/logging.cpp
+++ b/src/core/common/logging.cpp
@@ -210,6 +210,10 @@ const char *otLogRegionToString(otLogRegion aRegion)
retval = "-MLE-----";
break;
+ case kLogRegionCoap:
+ retval = "-COAP----";
+ break;
+
case kLogRegionArp:
retval = "-ARP-----";
break;
diff --git a/src/core/common/logging.hpp b/src/core/common/logging.hpp
index ea6f99aea..55ba57ea6 100644
--- a/src/core/common/logging.hpp
+++ b/src/core/common/logging.hpp
@@ -724,6 +724,60 @@ extern "C" {
#define otLogDebgPlat(aInstance, aFormat, ...)
#endif
+/**
+ * @def otLogCritCoap
+ *
+ * This method generates a log with level critical for the CoAP region.
+ *
+ * @param[in] aFormat A pointer to the format string.
+ * @param[in] ... Arguments for the format specification.
+ *
+ */
+
+/**
+ * @def otLogWarnCoap
+ *
+ * This method generates a log with level warning for the CoAP region.
+ *
+ * @param[in] aFormat A pointer to the format string.
+ * @param[in] ... Arguments for the format specification.
+ *
+ */
+
+/**
+ * @def otLogInfoCoap
+ *
+ * This method generates a log with level info for the CoAP region.
+ *
+ * @param[in] aFormat A pointer to the format string.
+ * @param[in] ... Arguments for the format specification.
+ *
+ */
+
+/**
+ * @def otLogDebgCoap
+ *
+ * This method generates a log with level debug for the CoAP region.
+ *
+ * @param[in] aFormat A pointer to the format string.
+ * @param[in] ... Arguments for the format specification.
+ *
+ */
+#if OPENTHREAD_CONFIG_LOG_COAP == 1
+#define otLogCritCoap(aInstance, aFormat, ...) otLogCrit(aInstance, kLogRegionCoap, aFormat, ## __VA_ARGS__)
+#define otLogWarnCoap(aInstance, aFormat, ...) otLogWarn(aInstance, kLogRegionCoap, aFormat, ## __VA_ARGS__)
+#define otLogInfoCoap(aInstance, aFormat, ...) otLogInfo(aInstance, kLogRegionCoap, aFormat, ## __VA_ARGS__)
+#define otLogInfoCoapErr(aInstance, aError, aFormat, ...) \
+ otLogInfo(aInstance, kLogRegionCoap, "Error %s: " aFormat, otThreadErrorToString(aError), ## __VA_ARGS__)
+#define otLogDebgCoap(aInstance, aFormat, ...) otLogDebg(aInstance, kLogRegionCoap, aFormat, ## __VA_ARGS__)
+#else
+#define otLogCritCoap(aInstance, aFormat, ...)
+#define otLogWarnCoap(aInstance, aFormat, ...)
+#define otLogInfoCoap(aInstance, aFormat, ...)
+#define otLogInfoCoapErr(aInstance, aError, aFormat, ...)
+#define otLogDebgCoap(aInstance, aFormat, ...)
+#endif
+
#endif // WINDOWS_LOGGING
/**
diff --git a/src/core/meshcop/announce_begin_client.cpp b/src/core/meshcop/announce_begin_client.cpp
index 7d7b5016b..8614d370a 100644
--- a/src/core/meshcop/announce_begin_client.cpp
+++ b/src/core/meshcop/announce_begin_client.cpp
@@ -87,7 +87,7 @@ ThreadError AnnounceBeginClient::SendRequest(uint32_t aChannelMask, uint8_t aCou
header.AppendUriPathOptions(OPENTHREAD_URI_ANNOUNCE_BEGIN);
header.SetPayloadMarker();
- VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(mNetif.GetCoapClient(), header)) != NULL,
+ VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(mNetif.GetCoap(), header)) != NULL,
error = kThreadError_NoBufs);
sessionId.Init();
@@ -111,7 +111,7 @@ ThreadError AnnounceBeginClient::SendRequest(uint32_t aChannelMask, uint8_t aCou
messageInfo.SetPeerPort(kCoapUdpPort);
messageInfo.SetInterfaceId(mNetif.GetInterfaceId());
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
otLogInfoMeshCoP(GetInstance(), "sent announce begin query");
diff --git a/src/core/meshcop/announce_begin_client.hpp b/src/core/meshcop/announce_begin_client.hpp
index 0349716b5..5d71faab2 100644
--- a/src/core/meshcop/announce_begin_client.hpp
+++ b/src/core/meshcop/announce_begin_client.hpp
@@ -35,7 +35,7 @@
#define ANNOUNCE_BEGIN_CLIENT_HPP_
#include "openthread-core-config.h"
-#include "coap/coap_client.hpp"
+#include "coap/coap.hpp"
#include "net/ip6_address.hpp"
#include "net/udp6.hpp"
diff --git a/src/core/meshcop/border_agent_proxy.cpp b/src/core/meshcop/border_agent_proxy.cpp
index 576256390..c35f10f8a 100644
--- a/src/core/meshcop/border_agent_proxy.cpp
+++ b/src/core/meshcop/border_agent_proxy.cpp
@@ -53,14 +53,12 @@
namespace ot {
namespace MeshCoP {
-BorderAgentProxy::BorderAgentProxy(const Ip6::Address &aMeshLocal16, Coap::Server &aCoapServer,
- Coap::Client &aCoapClient):
+BorderAgentProxy::BorderAgentProxy(const Ip6::Address &aMeshLocal16, Coap::Coap &aCoap):
mRelayReceive(OPENTHREAD_URI_RELAY_RX, &BorderAgentProxy::HandleRelayReceive, this),
mStreamHandler(NULL),
mContext(NULL),
mMeshLocal16(aMeshLocal16),
- mCoapServer(aCoapServer),
- mCoapClient(aCoapClient)
+ mCoap(aCoap)
{
}
@@ -70,7 +68,7 @@ ThreadError BorderAgentProxy::Start(otBorderAgentProxyStreamHandler aStreamHandl
VerifyOrExit(!mStreamHandler, error = kThreadError_Already);
- mCoapServer.AddResource(mRelayReceive);
+ mCoap.AddResource(mRelayReceive);
mStreamHandler = aStreamHandler;
mContext = aContext;
@@ -84,7 +82,7 @@ ThreadError BorderAgentProxy::Stop(void)
VerifyOrExit(mStreamHandler != NULL, error = kThreadError_Already);
- mCoapServer.RemoveResource(mRelayReceive);
+ mCoap.RemoveResource(mRelayReceive);
mStreamHandler = NULL;
@@ -157,11 +155,11 @@ ThreadError BorderAgentProxy::Send(Message &aMessage, uint16_t aLocator, uint16_
if (aPort == kCoapUdpPort)
{
// this is request to server, send with client
- error = mCoapClient.SendMessage(aMessage, messageInfo, BorderAgentProxy::HandleResponse, this);
+ error = mCoap.SendMessage(aMessage, messageInfo, BorderAgentProxy::HandleResponse, this);
}
else
{
- error = mCoapServer.SendMessage(aMessage, messageInfo);
+ error = mCoap.SendMessage(aMessage, messageInfo);
}
exit:
diff --git a/src/core/meshcop/border_agent_proxy.hpp b/src/core/meshcop/border_agent_proxy.hpp
index ebcfcc5d3..b67470ce6 100644
--- a/src/core/meshcop/border_agent_proxy.hpp
+++ b/src/core/meshcop/border_agent_proxy.hpp
@@ -37,8 +37,7 @@
#include
#include "openthread-core-config.h"
-#include "coap/coap_client.hpp"
-#include "coap/coap_server.hpp"
+#include "coap/coap.hpp"
namespace ot {
namespace MeshCoP {
@@ -50,11 +49,10 @@ 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.
+ * @param[in] aCoap A reference to the Management CoAP Service.
*
*/
- BorderAgentProxy(const Ip6::Address &aMeshLocal16, Coap::Server &aCoapServer, Coap::Client &aCoapClient);
+ BorderAgentProxy(const Ip6::Address &aMeshLocal16, Coap::Coap &aCoap);
/**
* This method enables the border agent proxy service.
@@ -114,8 +112,7 @@ private:
void *mContext;
const Ip6::Address &mMeshLocal16;
- Coap::Server &mCoapServer;
- Coap::Client &mCoapClient;
+ Coap::Coap &mCoap;
};
} // namespace MeshCoP
diff --git a/src/core/meshcop/commissioner.cpp b/src/core/meshcop/commissioner.cpp
index fd24079d4..007100402 100644
--- a/src/core/meshcop/commissioner.cpp
+++ b/src/core/meshcop/commissioner.cpp
@@ -91,16 +91,16 @@ otInstance *Commissioner::GetInstance(void)
void Commissioner::AddCoapResources(void)
{
- mNetif.GetCoapServer().AddResource(mRelayReceive);
- mNetif.GetCoapServer().AddResource(mDatasetChanged);
- mNetif.GetSecureCoapServer().AddResource(mJoinerFinalize);
+ mNetif.GetCoap().AddResource(mRelayReceive);
+ mNetif.GetCoap().AddResource(mDatasetChanged);
+ mNetif.GetCoapSecure().AddResource(mJoinerFinalize);
}
void Commissioner::RemoveCoapResources(void)
{
- mNetif.GetCoapServer().RemoveResource(mRelayReceive);
- mNetif.GetCoapServer().AddResource(mDatasetChanged);
- mNetif.GetSecureCoapServer().AddResource(mJoinerFinalize);
+ mNetif.GetCoap().RemoveResource(mRelayReceive);
+ mNetif.GetCoap().RemoveResource(mDatasetChanged);
+ mNetif.GetCoapSecure().RemoveResource(mJoinerFinalize);
}
ThreadError Commissioner::Start(void)
@@ -110,7 +110,7 @@ ThreadError Commissioner::Start(void)
otLogFuncEntry();
VerifyOrExit(mState == kCommissionerStateDisabled, error = kThreadError_InvalidState);
- SuccessOrExit(error = mNetif.GetSecureCoapServer().Start(SendRelayTransmit, this));
+ SuccessOrExit(error = mNetif.GetCoapSecure().Start(OPENTHREAD_CONFIG_JOINER_UDP_PORT, SendRelayTransmit, this));
mState = kCommissionerStatePetition;
mTransmitAttempts = 0;
@@ -129,7 +129,7 @@ ThreadError Commissioner::Stop(void)
otLogFuncEntry();
VerifyOrExit(mState != kCommissionerStateDisabled, error = kThreadError_InvalidState);
- mNetif.GetSecureCoapServer().Stop();
+ mNetif.GetCoapSecure().Stop();
mState = kCommissionerStateDisabled;
RemoveCoapResources();
@@ -420,8 +420,7 @@ ThreadError Commissioner::SendMgmtCommissionerGetRequest(const uint8_t *aTlvs,
header.SetPayloadMarker();
}
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapClient(), header)) != NULL,
- error = kThreadError_NoBufs);
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoap(), header)) != NULL, error = kThreadError_NoBufs);
if (aLength > 0)
{
@@ -434,8 +433,8 @@ ThreadError Commissioner::SendMgmtCommissionerGetRequest(const uint8_t *aTlvs,
messageInfo.SetSockAddr(mNetif.GetMle().GetMeshLocal16());
mNetif.GetMle().GetLeaderAloc(messageInfo.GetPeerAddr());
messageInfo.SetPeerPort(kCoapUdpPort);
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo,
- Commissioner::HandleMgmtCommissionerGetResponse, this));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo,
+ Commissioner::HandleMgmtCommissionerGetResponse, this));
otLogInfoMeshCoP(GetInstance(), "sent MGMT_COMMISSIONER_GET.req to leader");
@@ -488,8 +487,7 @@ ThreadError Commissioner::SendMgmtCommissionerSetRequest(const otCommissioningDa
header.AppendUriPathOptions(OPENTHREAD_URI_COMMISSIONER_SET);
header.SetPayloadMarker();
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapClient(), header)) != NULL,
- error = kThreadError_NoBufs);
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoap(), header)) != NULL, error = kThreadError_NoBufs);
if (aDataset.mIsLocatorSet)
{
@@ -538,8 +536,8 @@ ThreadError Commissioner::SendMgmtCommissionerSetRequest(const otCommissioningDa
messageInfo.SetSockAddr(mNetif.GetMle().GetMeshLocal16());
mNetif.GetMle().GetLeaderAloc(messageInfo.GetPeerAddr());
messageInfo.SetPeerPort(kCoapUdpPort);
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo,
- Commissioner::HandleMgmtCommissionerSetResponse, this));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo,
+ Commissioner::HandleMgmtCommissionerSetResponse, this));
otLogInfoMeshCoP(GetInstance(), "sent MGMT_COMMISSIONER_SET.req to leader");
@@ -594,8 +592,7 @@ ThreadError Commissioner::SendPetition(void)
header.AppendUriPathOptions(OPENTHREAD_URI_LEADER_PETITION);
header.SetPayloadMarker();
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapClient(), header)) != NULL,
- error = kThreadError_NoBufs);
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoap(), header)) != NULL, error = kThreadError_NoBufs);
commissionerId.Init();
commissionerId.SetCommissionerId("OpenThread Commissioner");
@@ -605,8 +602,8 @@ ThreadError Commissioner::SendPetition(void)
mNetif.GetMle().GetLeaderAloc(messageInfo.GetPeerAddr());
messageInfo.SetPeerPort(kCoapUdpPort);
messageInfo.SetSockAddr(mNetif.GetMle().GetMeshLocal16());
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo,
- Commissioner::HandleLeaderPetitionResponse, this));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo,
+ Commissioner::HandleLeaderPetitionResponse, this));
otLogInfoMeshCoP(GetInstance(), "sent petition");
@@ -695,8 +692,7 @@ ThreadError Commissioner::SendKeepAlive(void)
header.AppendUriPathOptions(OPENTHREAD_URI_LEADER_KEEP_ALIVE);
header.SetPayloadMarker();
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapClient(), header)) != NULL,
- error = kThreadError_NoBufs);
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoap(), header)) != NULL, error = kThreadError_NoBufs);
state.Init();
state.SetState(mState == kCommissionerStateActive ? StateTlv::kAccept : StateTlv::kReject);
@@ -709,8 +705,8 @@ ThreadError Commissioner::SendKeepAlive(void)
messageInfo.SetSockAddr(mNetif.GetMle().GetMeshLocal16());
mNetif.GetMle().GetLeaderAloc(messageInfo.GetPeerAddr());
messageInfo.SetPeerPort(kCoapUdpPort);
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo,
- Commissioner::HandleLeaderKeepAliveResponse, this));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo,
+ Commissioner::HandleLeaderKeepAliveResponse, this));
otLogInfoMeshCoP(GetInstance(), "sent keep alive");
@@ -803,7 +799,7 @@ void Commissioner::HandleRelayReceive(Coap::Header &aHeader, Message &aMessage,
SuccessOrExit(error = Tlv::GetValueOffset(aMessage, Tlv::kJoinerDtlsEncapsulation, offset, length));
VerifyOrExit(length <= aMessage.GetLength() - offset, error = kThreadError_Parse);
- if (!mNetif.GetSecureCoapServer().IsConnectionActive())
+ if (!mNetif.GetCoapSecure().IsConnectionActive())
{
memcpy(mJoinerIid, joinerIid.GetIid(), sizeof(mJoinerIid));
mJoinerIid[0] ^= 0x2;
@@ -818,8 +814,8 @@ void Commissioner::HandleRelayReceive(Coap::Header &aHeader, Message &aMessage,
if (mJoiners[i].mAny || !memcmp(&mJoiners[i].mExtAddress, mJoinerIid, sizeof(mJoiners[i].mExtAddress)))
{
- error = mNetif.GetSecureCoapServer().SetPsk(reinterpret_cast(mJoiners[i].mPsk),
- static_cast(strlen(mJoiners[i].mPsk)));
+ error = mNetif.GetCoapSecure().SetPsk(reinterpret_cast(mJoiners[i].mPsk),
+ static_cast(strlen(mJoiners[i].mPsk)));
SuccessOrExit(error);
otLogInfoMeshCoP(GetInstance(), "found joiner, starting new session");
enableJoiner = true;
@@ -848,7 +844,7 @@ void Commissioner::HandleRelayReceive(Coap::Header &aHeader, Message &aMessage,
joinerMessageInfo.GetPeerAddr().SetIid(mJoinerIid);
joinerMessageInfo.SetPeerPort(mJoinerPort);
- mNetif.GetSecureCoapServer().Receive(aMessage, joinerMessageInfo);
+ mNetif.GetCoapSecure().Receive(aMessage, joinerMessageInfo);
exit:
(void)aMessageInfo;
@@ -872,7 +868,7 @@ void Commissioner::HandleDatasetChanged(Coap::Header &aHeader, Message &aMessage
otLogInfoMeshCoP(GetInstance(), "received dataset changed");
(void)aMessage;
- SuccessOrExit(mNetif.GetCoapServer().SendEmptyAck(aHeader, aMessageInfo));
+ SuccessOrExit(mNetif.GetCoap().SendEmptyAck(aHeader, aMessageInfo));
otLogInfoMeshCoP(GetInstance(), "sent dataset changed acknowledgment");
@@ -937,7 +933,7 @@ void Commissioner::SendJoinFinalizeResponse(const Coap::Header &aRequestHeader,
responseHeader.SetDefaultResponseHeader(aRequestHeader);
responseHeader.SetPayloadMarker();
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetSecureCoapServer(), responseHeader)) != NULL,
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapSecure(), responseHeader)) != NULL,
error = kThreadError_NoBufs);
message->SetSubType(Message::kSubTypeJoinerFinalizeResponse);
@@ -958,7 +954,7 @@ void Commissioner::SendJoinFinalizeResponse(const Coap::Header &aRequestHeader,
message->GetLength() - responseHeader.GetLength());
#endif
- SuccessOrExit(error = mNetif.GetSecureCoapServer().SendMessage(*message, joinerMessageInfo));
+ SuccessOrExit(error = mNetif.GetCoapSecure().SendMessage(*message, joinerMessageInfo));
memcpy(extAddr.m8, mJoinerIid, sizeof(extAddr.m8));
extAddr.SetLocal(!extAddr.IsLocal());
@@ -1000,8 +996,7 @@ ThreadError Commissioner::SendRelayTransmit(Message &aMessage, const Ip6::Messag
header.AppendUriPathOptions(OPENTHREAD_URI_RELAY_TX);
header.SetPayloadMarker();
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapClient(), header)) != NULL,
- error = kThreadError_NoBufs);
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoap(), header)) != NULL, error = kThreadError_NoBufs);
udpPort.Init();
udpPort.SetUdpPort(mJoinerPort);
@@ -1035,7 +1030,7 @@ ThreadError Commissioner::SendRelayTransmit(Message &aMessage, const Ip6::Messag
messageInfo.SetPeerPort(kCoapUdpPort);
messageInfo.SetInterfaceId(mNetif.GetInterfaceId());
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
aMessage.Free();
diff --git a/src/core/meshcop/commissioner.hpp b/src/core/meshcop/commissioner.hpp
index 88eaedb16..6d6ac1443 100644
--- a/src/core/meshcop/commissioner.hpp
+++ b/src/core/meshcop/commissioner.hpp
@@ -37,9 +37,8 @@
#include
#include "openthread-core-config.h"
-#include "coap/coap_client.hpp"
-#include "coap/coap_server.hpp"
-#include "coap/secure_coap_server.hpp"
+#include "coap/coap.hpp"
+#include "coap/coap_secure.hpp"
#include "common/timer.hpp"
#include "mac/mac_frame.hpp"
#include "meshcop/announce_begin_client.hpp"
diff --git a/src/core/meshcop/dataset_manager.cpp b/src/core/meshcop/dataset_manager.cpp
index 43c3d1f48..fdf8188a7 100644
--- a/src/core/meshcop/dataset_manager.cpp
+++ b/src/core/meshcop/dataset_manager.cpp
@@ -317,15 +317,14 @@ ThreadError DatasetManager::Register(void)
pending->UpdateDelayTimer();
}
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapClient(), header)) != NULL,
- error = kThreadError_NoBufs);
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoap(), header)) != NULL, error = kThreadError_NoBufs);
SuccessOrExit(error = message->Append(mLocal.GetBytes(), mLocal.GetSize()));
messageInfo.SetSockAddr(mNetif.GetMle().GetMeshLocal16());
mNetif.GetMle().GetLeaderAloc(messageInfo.GetPeerAddr());
messageInfo.SetPeerPort(kCoapUdpPort);
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
otLogInfoMeshCoP(GetInstance(), "sent dataset to leader");
@@ -602,8 +601,7 @@ ThreadError DatasetManager::SendSetRequest(const otOperationalDataset &aDataset,
header.AppendUriPathOptions(mUriSet);
header.SetPayloadMarker();
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapClient(), header)) != NULL,
- error = kThreadError_NoBufs);
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoap(), header)) != NULL, error = kThreadError_NoBufs);
#if OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
bool isCommissioner;
@@ -737,7 +735,7 @@ ThreadError DatasetManager::SendSetRequest(const otOperationalDataset &aDataset,
messageInfo.SetSockAddr(mNetif.GetMle().GetMeshLocal16());
mNetif.GetMle().GetLeaderAloc(messageInfo.GetPeerAddr());
messageInfo.SetPeerPort(kCoapUdpPort);
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
otLogInfoMeshCoP(GetInstance(), "sent dataset set request to leader");
@@ -769,8 +767,7 @@ ThreadError DatasetManager::SendGetRequest(const uint8_t *aTlvTypes, const uint8
header.SetPayloadMarker();
}
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapClient(), header)) != NULL,
- error = kThreadError_NoBufs);
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoap(), header)) != NULL, error = kThreadError_NoBufs);
if (aLength > 0)
@@ -792,7 +789,7 @@ ThreadError DatasetManager::SendGetRequest(const uint8_t *aTlvTypes, const uint8
messageInfo.SetSockAddr(mNetif.GetMle().GetMeshLocal16());
messageInfo.SetPeerPort(kCoapUdpPort);
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
otLogInfoMeshCoP(GetInstance(), "sent dataset get request");
@@ -817,14 +814,13 @@ void DatasetManager::SendSetResponse(const Coap::Header &aRequestHeader, const I
responseHeader.SetDefaultResponseHeader(aRequestHeader);
responseHeader.SetPayloadMarker();
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapServer(), responseHeader)) != NULL,
- error = kThreadError_NoBufs);
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoap(), responseHeader)) != NULL, error = kThreadError_NoBufs);
state.Init();
state.SetState(aState);
SuccessOrExit(error = message->Append(&state, sizeof(state)));
- SuccessOrExit(error = mNetif.GetCoapServer().SendMessage(*message, aMessageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, aMessageInfo));
otLogInfoMeshCoP(GetInstance(), "sent dataset set response");
@@ -850,8 +846,7 @@ void DatasetManager::SendGetResponse(const Coap::Header &aRequestHeader, const I
responseHeader.SetDefaultResponseHeader(aRequestHeader);
responseHeader.SetPayloadMarker();
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapServer(), responseHeader)) != NULL,
- error = kThreadError_NoBufs);
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoap(), responseHeader)) != NULL, error = kThreadError_NoBufs);
if (aLength == 0)
{
@@ -892,7 +887,7 @@ void DatasetManager::SendGetResponse(const Coap::Header &aRequestHeader, const I
message->SetLength(message->GetLength() - 1);
}
- SuccessOrExit(error = mNetif.GetCoapServer().SendMessage(*message, aMessageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, aMessageInfo));
otLogInfoMeshCoP(GetInstance(), "sent dataset get response");
@@ -908,7 +903,7 @@ ActiveDatasetBase::ActiveDatasetBase(ThreadNetif &aThreadNetif):
DatasetManager(aThreadNetif, Tlv::kActiveTimestamp, OPENTHREAD_URI_ACTIVE_SET, OPENTHREAD_URI_ACTIVE_GET),
mResourceGet(OPENTHREAD_URI_ACTIVE_GET, &ActiveDatasetBase::HandleGet, this)
{
- mNetif.GetCoapServer().AddResource(mResourceGet);
+ mNetif.GetCoap().AddResource(mResourceGet);
}
ThreadError ActiveDatasetBase::Restore(void)
@@ -997,7 +992,7 @@ PendingDatasetBase::PendingDatasetBase(ThreadNetif &aThreadNetif):
mNetworkTime(0),
mResourceGet(OPENTHREAD_URI_PENDING_GET, &PendingDatasetBase::HandleGet, this)
{
- mNetif.GetCoapServer().AddResource(mResourceGet);
+ mNetif.GetCoap().AddResource(mResourceGet);
}
ThreadError PendingDatasetBase::Restore(void)
diff --git a/src/core/meshcop/dataset_manager.hpp b/src/core/meshcop/dataset_manager.hpp
index 252758b0f..2f835b930 100644
--- a/src/core/meshcop/dataset_manager.hpp
+++ b/src/core/meshcop/dataset_manager.hpp
@@ -37,7 +37,7 @@
#include
-#include "coap/coap_server.hpp"
+#include "coap/coap.hpp"
#include "common/timer.hpp"
#include "meshcop/dataset.hpp"
#include "net/udp6.hpp"
diff --git a/src/core/meshcop/dataset_manager_ftd.cpp b/src/core/meshcop/dataset_manager_ftd.cpp
index 4ffebfeb5..f8ab04413 100644
--- a/src/core/meshcop/dataset_manager_ftd.cpp
+++ b/src/core/meshcop/dataset_manager_ftd.cpp
@@ -188,12 +188,12 @@ void ActiveDataset::StartLeader(void)
mLocal.Store();
mNetwork = mLocal;
- mNetif.GetCoapServer().AddResource(mResourceSet);
+ mNetif.GetCoap().AddResource(mResourceSet);
}
void ActiveDataset::StopLeader(void)
{
- mNetif.GetCoapServer().RemoveResource(mResourceSet);
+ mNetif.GetCoap().RemoveResource(mResourceSet);
}
void ActiveDataset::HandleSet(void *aContext, otCoapHeader *aHeader, otMessage *aMessage,
@@ -226,12 +226,12 @@ void PendingDataset::StartLeader(void)
mNetwork = mLocal;
ResetDelayTimer(kFlagNetworkUpdated);
- mNetif.GetCoapServer().AddResource(mResourceSet);
+ mNetif.GetCoap().AddResource(mResourceSet);
}
void PendingDataset::StopLeader(void)
{
- mNetif.GetCoapServer().RemoveResource(mResourceSet);
+ mNetif.GetCoap().RemoveResource(mResourceSet);
}
void PendingDataset::HandleSet(void *aContext, otCoapHeader *aHeader, otMessage *aMessage,
diff --git a/src/core/meshcop/dataset_manager_ftd.hpp b/src/core/meshcop/dataset_manager_ftd.hpp
index f5316fa71..2c7a76a16 100644
--- a/src/core/meshcop/dataset_manager_ftd.hpp
+++ b/src/core/meshcop/dataset_manager_ftd.hpp
@@ -37,7 +37,7 @@
#include
-#include "coap/coap_server.hpp"
+#include "coap/coap.hpp"
namespace ot {
diff --git a/src/core/meshcop/energy_scan_client.cpp b/src/core/meshcop/energy_scan_client.cpp
index 7f0b31ae1..2f44ede44 100644
--- a/src/core/meshcop/energy_scan_client.cpp
+++ b/src/core/meshcop/energy_scan_client.cpp
@@ -66,7 +66,7 @@ EnergyScanClient::EnergyScanClient(ThreadNetif &aThreadNetif) :
{
mContext = NULL;
mCallback = NULL;
- mNetif.GetCoapServer().AddResource(mEnergyScan);
+ mNetif.GetCoap().AddResource(mEnergyScan);
}
otInstance *EnergyScanClient::GetInstance(void)
@@ -96,7 +96,7 @@ ThreadError EnergyScanClient::SendQuery(uint32_t aChannelMask, uint8_t aCount, u
header.AppendUriPathOptions(OPENTHREAD_URI_ENERGY_SCAN);
header.SetPayloadMarker();
- VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(mNetif.GetCoapClient(), header)) != NULL,
+ VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(mNetif.GetCoap(), header)) != NULL,
error = kThreadError_NoBufs);
sessionId.Init();
@@ -123,7 +123,7 @@ ThreadError EnergyScanClient::SendQuery(uint32_t aChannelMask, uint8_t aCount, u
messageInfo.SetPeerAddr(aAddress);
messageInfo.SetPeerPort(kCoapUdpPort);
messageInfo.SetInterfaceId(mNetif.GetInterfaceId());
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
otLogInfoMeshCoP(GetInstance(), "sent energy scan query");
@@ -176,7 +176,7 @@ void EnergyScanClient::HandleReport(Coap::Header &aHeader, Message &aMessage, co
mCallback(channelMask.GetMask(), energyList.list, energyList.tlv.GetLength(), mContext);
}
- SuccessOrExit(mNetif.GetCoapServer().SendEmptyAck(aHeader, responseInfo));
+ SuccessOrExit(mNetif.GetCoap().SendEmptyAck(aHeader, responseInfo));
otLogInfoMeshCoP(GetInstance(), "sent energy scan report response");
diff --git a/src/core/meshcop/energy_scan_client.hpp b/src/core/meshcop/energy_scan_client.hpp
index 46af62d5f..1e8d9ad4b 100644
--- a/src/core/meshcop/energy_scan_client.hpp
+++ b/src/core/meshcop/energy_scan_client.hpp
@@ -37,8 +37,7 @@
#include
#include "openthread-core-config.h"
-#include "coap/coap_client.hpp"
-#include "coap/coap_server.hpp"
+#include "coap/coap.hpp"
#include "net/ip6_address.hpp"
#include "net/udp6.hpp"
diff --git a/src/core/meshcop/joiner.cpp b/src/core/meshcop/joiner.cpp
index bcd35b6e4..c9c4a340d 100644
--- a/src/core/meshcop/joiner.cpp
+++ b/src/core/meshcop/joiner.cpp
@@ -81,7 +81,7 @@ Joiner::Joiner(ThreadNetif &aNetif):
mJoinerEntrust(OPENTHREAD_URI_JOINER_ENTRUST, &Joiner::HandleJoinerEntrust, this),
mNetif(aNetif)
{
- mNetif.GetCoapServer().AddResource(mJoinerEntrust);
+ mNetif.GetCoap().AddResource(mJoinerEntrust);
}
otInstance *Joiner::GetInstance(void)
@@ -116,10 +116,14 @@ ThreadError Joiner::Start(const char *aPSKd, const char *aProvisioningUrl,
mCcitt = ccitt.Get();
mAnsi = ansi.Get();
- error = mNetif.GetSecureCoapClient().GetDtls().SetPsk(reinterpret_cast(aPSKd),
- static_cast(strlen(aPSKd)));
+ error = mNetif.GetCoapSecure().Start(OPENTHREAD_CONFIG_JOINER_UDP_PORT);
SuccessOrExit(error);
- error = mNetif.GetSecureCoapClient().GetDtls().mProvisioningUrl.SetProvisioningUrl(aProvisioningUrl);
+
+ error = mNetif.GetCoapSecure().GetDtls().SetPsk(reinterpret_cast(aPSKd),
+ static_cast(strlen(aPSKd)));
+ SuccessOrExit(error);
+
+ error = mNetif.GetCoapSecure().GetDtls().mProvisioningUrl.SetProvisioningUrl(aProvisioningUrl);
SuccessOrExit(error);
mJoinerRouterPanId = Mac::kPanIdBroadcast;
@@ -152,8 +156,8 @@ void Joiner::Close(void)
{
otLogFuncEntry();
- mNetif.GetSecureCoapClient().Disconnect();
- mNetif.GetIp6Filter().RemoveUnsecurePort(mNetif.GetSecureCoapClient().GetPort());
+ mNetif.GetCoapSecure().Disconnect();
+ mNetif.GetIp6Filter().RemoveUnsecurePort(mNetif.GetCoapSecure().GetPort());
otLogFuncExit();
}
@@ -162,6 +166,8 @@ void Joiner::Complete(ThreadError aError)
{
mState = kStateIdle;
+ mNetif.GetCoapSecure().Stop();
+
if (mCallback)
{
otJoinerCallback callback = mCallback;
@@ -216,14 +222,14 @@ void Joiner::HandleDiscoverResult(otActiveScanResult *aResult)
mNetif.GetMac().SetPanId(mJoinerRouterPanId);
mNetif.GetMac().SetChannel(mJoinerRouterChannel);
- mNetif.GetIp6Filter().AddUnsecurePort(mNetif.GetSecureCoapClient().GetPort());
+ mNetif.GetIp6Filter().AddUnsecurePort(mNetif.GetCoapSecure().GetPort());
messageInfo.GetPeerAddr().mFields.m16[0] = HostSwap16(0xfe80);
messageInfo.GetPeerAddr().SetIid(mJoinerRouter);
messageInfo.mPeerPort = mJoinerUdpPort;
messageInfo.mInterfaceId = OT_NETIF_INTERFACE_ID_THREAD;
- mNetif.GetSecureCoapClient().Connect(messageInfo, Joiner::HandleSecureCoapClientConnect, this);
+ mNetif.GetCoapSecure().Connect(messageInfo, Joiner::HandleSecureCoapClientConnect, this);
mState = kStateConnect;
}
else
@@ -281,7 +287,7 @@ void Joiner::SendJoinerFinalize(void)
header.AppendUriPathOptions(OPENTHREAD_URI_JOINER_FINALIZE);
header.SetPayloadMarker();
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetSecureCoapClient(), header)) != NULL,
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapSecure(), header)) != NULL,
error = kThreadError_NoBufs);
stateTlv.Init();
@@ -315,10 +321,10 @@ void Joiner::SendJoinerFinalize(void)
SuccessOrExit(error = message->Append(&vendorDataTlv, vendorDataTlv.GetSize()));
}
- if (mNetif.GetSecureCoapClient().GetDtls().mProvisioningUrl.GetLength() > 0)
+ if (mNetif.GetCoapSecure().GetDtls().mProvisioningUrl.GetLength() > 0)
{
- SuccessOrExit(error = message->Append(&mNetif.GetSecureCoapClient().GetDtls().mProvisioningUrl,
- mNetif.GetSecureCoapClient().GetDtls().mProvisioningUrl.GetSize()));
+ SuccessOrExit(error = message->Append(&mNetif.GetCoapSecure().GetDtls().mProvisioningUrl,
+ mNetif.GetCoapSecure().GetDtls().mProvisioningUrl.GetSize()));
}
#if OPENTHREAD_ENABLE_CERT_LOG
@@ -329,7 +335,7 @@ void Joiner::SendJoinerFinalize(void)
message->GetLength() - header.GetLength());
#endif
- mNetif.GetSecureCoapClient().SendMessage(*message, Joiner::HandleJoinerFinalizeResponse, this);
+ mNetif.GetCoapSecure().SendMessage(*message, Joiner::HandleJoinerFinalizeResponse, this);
otLogInfoMeshCoP(GetInstance(), "Sent joiner finalize");
@@ -460,12 +466,11 @@ void Joiner::SendJoinerEntrustResponse(const Coap::Header &aRequestHeader,
responseHeader.SetDefaultResponseHeader(aRequestHeader);
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapServer(), responseHeader)) != NULL,
- error = kThreadError_NoBufs);
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoap(), responseHeader)) != NULL, error = kThreadError_NoBufs);
message->SetSubType(Message::kSubTypeJoinerEntrust);
memset(&responseInfo.mSockAddr, 0, sizeof(responseInfo.mSockAddr));
- SuccessOrExit(error = mNetif.GetCoapServer().SendMessage(*message, responseInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, responseInfo));
mState = kStateJoined;
diff --git a/src/core/meshcop/joiner.hpp b/src/core/meshcop/joiner.hpp
index 752f76172..b3a064045 100644
--- a/src/core/meshcop/joiner.hpp
+++ b/src/core/meshcop/joiner.hpp
@@ -36,9 +36,9 @@
#include
+#include "coap/coap.hpp"
#include "coap/coap_header.hpp"
-#include "coap/coap_server.hpp"
-#include "coap/secure_coap_client.hpp"
+#include "coap/coap_secure.hpp"
#include "common/crc16.hpp"
#include "common/message.hpp"
#include "meshcop/dtls.hpp"
diff --git a/src/core/meshcop/joiner_router.cpp b/src/core/meshcop/joiner_router.cpp
index 30a394c58..9a1149542 100644
--- a/src/core/meshcop/joiner_router.cpp
+++ b/src/core/meshcop/joiner_router.cpp
@@ -70,7 +70,7 @@ JoinerRouter::JoinerRouter(ThreadNetif &aNetif):
mExpectJoinEntRsp(false)
{
mSocket.GetSockName().mPort = OPENTHREAD_CONFIG_JOINER_UDP_PORT;
- mNetif.GetCoapServer().AddResource(mRelayTransmit);
+ mNetif.GetCoap().AddResource(mRelayTransmit);
mNetifCallback.Set(HandleNetifStateChanged, this);
mNetif.RegisterCallback(mNetifCallback);
}
@@ -183,8 +183,7 @@ void JoinerRouter::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &a
header.AppendUriPathOptions(OPENTHREAD_URI_RELAY_RX);
header.SetPayloadMarker();
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapClient(), header)) != NULL,
- error = kThreadError_NoBufs);
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoap(), header)) != NULL, error = kThreadError_NoBufs);
udpPort.Init();
udpPort.SetUdpPort(aMessageInfo.GetPeerPort());
@@ -223,7 +222,7 @@ void JoinerRouter::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &a
messageInfo.GetPeerAddr().mFields.m16[7] = HostSwap16(borderAgentRloc);
messageInfo.SetPeerPort(kCoapUdpPort);
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
otLogInfoMeshCoP(GetInstance(), "Sent relay rx");
@@ -342,8 +341,7 @@ ThreadError JoinerRouter::DelaySendingJoinerEntrust(const Ip6::MessageInfo &aMes
header.AppendUriPathOptions(OPENTHREAD_URI_JOINER_ENTRUST);
header.SetPayloadMarker();
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapClient(), header)) != NULL,
- error = kThreadError_NoBufs);
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoap(), header)) != NULL, error = kThreadError_NoBufs);
message->SetSubType(Message::kSubTypeJoinerEntrust);
masterKey.Init();
@@ -492,11 +490,11 @@ ThreadError JoinerRouter::SendJoinerEntrust(Message &aMessage, const Ip6::Messag
{
ThreadError error;
- mNetif.GetCoapClient().AbortTransaction(&JoinerRouter::HandleJoinerEntrustResponse, this);
+ mNetif.GetCoap().AbortTransaction(&JoinerRouter::HandleJoinerEntrustResponse, this);
otLogInfoMeshCoP(GetInstance(), "Sending JOIN_ENT.ntf");
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(aMessage, aMessageInfo,
- &JoinerRouter::HandleJoinerEntrustResponse, this));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(aMessage, aMessageInfo,
+ &JoinerRouter::HandleJoinerEntrustResponse, this));
otLogInfoMeshCoP(GetInstance(), "Sent joiner entrust length = %d", aMessage.GetLength());
otLogCertMeshCoP(GetInstance(), "[THCI] direction=send | type=JOIN_ENT.ntf");
diff --git a/src/core/meshcop/joiner_router.hpp b/src/core/meshcop/joiner_router.hpp
index 9da044be8..2986f1bf4 100644
--- a/src/core/meshcop/joiner_router.hpp
+++ b/src/core/meshcop/joiner_router.hpp
@@ -36,10 +36,8 @@
#include
-#include "coap/coap_base.hpp"
-#include "coap/coap_client.hpp"
+#include "coap/coap.hpp"
#include "coap/coap_header.hpp"
-#include "coap/coap_server.hpp"
#include "common/message.hpp"
#include "common/timer.hpp"
#include "mac/mac_frame.hpp"
diff --git a/src/core/meshcop/leader.cpp b/src/core/meshcop/leader.cpp
index 3eb745f3e..a7d60509a 100644
--- a/src/core/meshcop/leader.cpp
+++ b/src/core/meshcop/leader.cpp
@@ -67,8 +67,8 @@ Leader::Leader(ThreadNetif &aThreadNetif):
mSessionId(0xffff),
mNetif(aThreadNetif)
{
- mNetif.GetCoapServer().AddResource(mPetition);
- mNetif.GetCoapServer().AddResource(mKeepAlive);
+ mNetif.GetCoap().AddResource(mPetition);
+ mNetif.GetCoap().AddResource(mKeepAlive);
}
otInstance *Leader::GetInstance(void)
@@ -131,8 +131,7 @@ ThreadError Leader::SendPetitionResponse(const Coap::Header &aRequestHeader, con
responseHeader.SetDefaultResponseHeader(aRequestHeader);
responseHeader.SetPayloadMarker();
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapServer(), responseHeader)) != NULL,
- error = kThreadError_NoBufs);
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoap(), responseHeader)) != NULL, error = kThreadError_NoBufs);
state.Init();
state.SetState(aState);
@@ -151,7 +150,7 @@ ThreadError Leader::SendPetitionResponse(const Coap::Header &aRequestHeader, con
SuccessOrExit(error = message->Append(&sessionId, sizeof(sessionId)));
}
- SuccessOrExit(error = mNetif.GetCoapServer().SendMessage(*message, aMessageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, aMessageInfo));
otLogInfoMeshCoP(GetInstance(), "sent petition response");
@@ -221,14 +220,13 @@ ThreadError Leader::SendKeepAliveResponse(const Coap::Header &aRequestHeader, co
responseHeader.SetDefaultResponseHeader(aRequestHeader);
responseHeader.SetPayloadMarker();
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapServer(), responseHeader)) != NULL,
- error = kThreadError_NoBufs);
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoap(), responseHeader)) != NULL, error = kThreadError_NoBufs);
state.Init();
state.SetState(aState);
SuccessOrExit(error = message->Append(&state, sizeof(state)));
- SuccessOrExit(error = mNetif.GetCoapServer().SendMessage(*message, aMessageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, aMessageInfo));
otLogInfoMeshCoP(GetInstance(), "sent keep alive response");
@@ -253,13 +251,12 @@ ThreadError Leader::SendDatasetChanged(const Ip6::Address &aAddress)
header.SetToken(Coap::Header::kDefaultTokenLength);
header.AppendUriPathOptions(OPENTHREAD_URI_DATASET_CHANGED);
- VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoapClient(), header)) != NULL,
- error = kThreadError_NoBufs);
+ VerifyOrExit((message = NewMeshCoPMessage(mNetif.GetCoap(), header)) != NULL, error = kThreadError_NoBufs);
messageInfo.SetSockAddr(mNetif.GetMle().GetMeshLocal16());
messageInfo.SetPeerAddr(aAddress);
messageInfo.SetPeerPort(kCoapUdpPort);
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
otLogInfoMeshCoP(GetInstance(), "sent dataset changed");
diff --git a/src/core/meshcop/leader.hpp b/src/core/meshcop/leader.hpp
index 1b54909dd..f2dcb17d1 100644
--- a/src/core/meshcop/leader.hpp
+++ b/src/core/meshcop/leader.hpp
@@ -34,8 +34,7 @@
#ifndef MESHCOP_LEADER_HPP_
#define MESHCOP_LEADER_HPP_
-#include "coap/coap_client.hpp"
-#include "coap/coap_server.hpp"
+#include "coap/coap.hpp"
#include "common/timer.hpp"
#include "meshcop/meshcop_tlvs.hpp"
#include "net/udp6.hpp"
diff --git a/src/core/meshcop/meshcop.hpp b/src/core/meshcop/meshcop.hpp
index 999f80c54..cbd5e2ca6 100644
--- a/src/core/meshcop/meshcop.hpp
+++ b/src/core/meshcop/meshcop.hpp
@@ -35,7 +35,7 @@
#ifndef MESHCOP_HPP_
#define MESHCOP_HPP_
-#include "coap/coap_base.hpp"
+#include "coap/coap.hpp"
#include "common/message.hpp"
namespace ot {
@@ -50,9 +50,9 @@ enum
* This function create Message for MeshCoP
*
*/
-inline Message *NewMeshCoPMessage(Coap::CoapBase &aCoapBase, const Coap::Header &aHeader)
+inline Message *NewMeshCoPMessage(Coap::Coap &aCoap, const Coap::Header &aHeader)
{
- return aCoapBase.NewMessage(aHeader, kMeshCoPMessagePriority);
+ return aCoap.NewMessage(aHeader, kMeshCoPMessagePriority);
}
diff --git a/src/core/meshcop/panid_query_client.cpp b/src/core/meshcop/panid_query_client.cpp
index 06fe5397b..b3b671b3d 100644
--- a/src/core/meshcop/panid_query_client.cpp
+++ b/src/core/meshcop/panid_query_client.cpp
@@ -62,7 +62,7 @@ PanIdQueryClient::PanIdQueryClient(ThreadNetif &aThreadNetif) :
mPanIdQuery(OPENTHREAD_URI_PANID_CONFLICT, &PanIdQueryClient::HandleConflict, this),
mNetif(aThreadNetif)
{
- mNetif.GetCoapServer().AddResource(mPanIdQuery);
+ mNetif.GetCoap().AddResource(mPanIdQuery);
}
otInstance *PanIdQueryClient::GetInstance(void)
@@ -89,7 +89,7 @@ ThreadError PanIdQueryClient::SendQuery(uint16_t aPanId, uint32_t aChannelMask,
header.AppendUriPathOptions(OPENTHREAD_URI_PANID_QUERY);
header.SetPayloadMarker();
- VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(mNetif.GetCoapClient(), header)) != NULL,
+ VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(mNetif.GetCoap(), header)) != NULL,
error = kThreadError_NoBufs);
sessionId.Init();
@@ -108,7 +108,7 @@ ThreadError PanIdQueryClient::SendQuery(uint16_t aPanId, uint32_t aChannelMask,
messageInfo.SetPeerAddr(aAddress);
messageInfo.SetPeerPort(kCoapUdpPort);
messageInfo.SetInterfaceId(mNetif.GetInterfaceId());
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
otLogInfoMeshCoP(GetInstance(), "sent panid query");
@@ -155,7 +155,7 @@ void PanIdQueryClient::HandleConflict(Coap::Header &aHeader, Message &aMessage,
mCallback(panId.GetPanId(), channelMask.GetMask(), mContext);
}
- SuccessOrExit(mNetif.GetCoapServer().SendEmptyAck(aHeader, responseInfo));
+ SuccessOrExit(mNetif.GetCoap().SendEmptyAck(aHeader, responseInfo));
otLogInfoMeshCoP(GetInstance(), "sent panid query conflict response");
diff --git a/src/core/meshcop/panid_query_client.hpp b/src/core/meshcop/panid_query_client.hpp
index 62cf16420..966e04b8f 100644
--- a/src/core/meshcop/panid_query_client.hpp
+++ b/src/core/meshcop/panid_query_client.hpp
@@ -37,8 +37,7 @@
#include
#include "openthread-core-config.h"
-#include "coap/coap_client.hpp"
-#include "coap/coap_server.hpp"
+#include "coap/coap.hpp"
#include "net/ip6_address.hpp"
#include "net/udp6.hpp"
diff --git a/src/core/openthread-core-default-config.h b/src/core/openthread-core-default-config.h
index 5847aac89..a0fc30e9f 100644
--- a/src/core/openthread-core-default-config.h
+++ b/src/core/openthread-core-default-config.h
@@ -549,6 +549,16 @@
#define OPENTHREAD_CONFIG_LOG_PLATFORM 0
#endif // OPENTHREAD_CONFIG_LOG_PLATFORM
+/**
+ * @def OPENTHREAD_CONFIG_LOG_COAP
+ *
+ * Define to enable COAP logging.
+ *
+ */
+#ifndef OPENTHREAD_CONFIG_LOG_COAP
+#define OPENTHREAD_CONFIG_LOG_COAP 1
+#endif // OPENTHREAD_CONFIG_LOG_COAP
+
/**
* @def OPENTHREAD_CONFIG_LOG_PREPEND_LEVEL
*
diff --git a/src/core/openthread-instance.h b/src/core/openthread-instance.h
index aaf928b79..9d3e0f332 100644
--- a/src/core/openthread-instance.h
+++ b/src/core/openthread-instance.h
@@ -53,7 +53,7 @@
#include "api/link_raw.hpp"
#endif
-#include "coap/coap_server.hpp"
+#include "coap/coap.hpp"
#include "crypto/mbedtls.hpp"
#include "net/ip6.hpp"
#include "thread/thread_netif.hpp"
@@ -93,7 +93,7 @@ typedef struct otInstance
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
#if OPENTHREAD_ENABLE_APPLICATION_COAP
- ot::Coap::Server mApplicationCoapServer;
+ ot::Coap::Coap mApplicationCoap;
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP
#if OPENTHREAD_CONFIG_ENABLE_DYNAMIC_LOG_LEVEL
diff --git a/src/core/thread/address_resolver.cpp b/src/core/thread/address_resolver.cpp
index 36db989b3..a782a95c1 100644
--- a/src/core/thread/address_resolver.cpp
+++ b/src/core/thread/address_resolver.cpp
@@ -71,9 +71,9 @@ AddressResolver::AddressResolver(ThreadNetif &aThreadNetif) :
{
Clear();
- mNetif.GetCoapServer().AddResource(mAddressError);
- mNetif.GetCoapServer().AddResource(mAddressQuery);
- mNetif.GetCoapServer().AddResource(mAddressNotification);
+ mNetif.GetCoap().AddResource(mAddressError);
+ mNetif.GetCoap().AddResource(mAddressQuery);
+ mNetif.GetCoap().AddResource(mAddressNotification);
mNetif.GetIp6().mIcmp.RegisterHandler(mIcmpHandler);
}
@@ -247,7 +247,7 @@ ThreadError AddressResolver::SendAddressQuery(const Ip6::Address &aEid)
header.AppendUriPathOptions(OPENTHREAD_URI_ADDRESS_QUERY);
header.SetPayloadMarker();
- VerifyOrExit((message = mNetif.GetCoapClient().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
+ VerifyOrExit((message = mNetif.GetCoap().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
targetTlv.Init();
targetTlv.SetTarget(aEid);
@@ -259,7 +259,7 @@ ThreadError AddressResolver::SendAddressQuery(const Ip6::Address &aEid)
messageInfo.SetPeerPort(kCoapUdpPort);
messageInfo.SetInterfaceId(mNetif.GetInterfaceId());
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
otLogInfoArp(GetInstance(), "Sent address query");
@@ -355,7 +355,7 @@ void AddressResolver::HandleAddressNotification(Coap::Header &aHeader, Message &
mCache[i].mState = Cache::kStateCached;
MarkCacheEntryAsUsed(mCache[i]);
- if (mNetif.GetCoapServer().SendEmptyAck(aHeader, aMessageInfo) == kThreadError_None)
+ if (mNetif.GetCoap().SendEmptyAck(aHeader, aMessageInfo) == kThreadError_None)
{
otLogInfoArp(GetInstance(), "Sent address notification acknowledgment");
}
@@ -382,7 +382,7 @@ ThreadError AddressResolver::SendAddressError(const ThreadTargetTlv &aTarget, co
header.AppendUriPathOptions(OPENTHREAD_URI_ADDRESS_ERROR);
header.SetPayloadMarker();
- VerifyOrExit((message = mNetif.GetCoapClient().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
+ VerifyOrExit((message = mNetif.GetCoap().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
SuccessOrExit(error = message->Append(&aTarget, sizeof(aTarget)));
SuccessOrExit(error = message->Append(&aEid, sizeof(aEid)));
@@ -401,7 +401,7 @@ ThreadError AddressResolver::SendAddressError(const ThreadTargetTlv &aTarget, co
messageInfo.SetPeerPort(kCoapUdpPort);
messageInfo.SetInterfaceId(mNetif.GetInterfaceId());
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
otLogInfoArp(GetInstance(), "Sent address error");
@@ -441,7 +441,7 @@ void AddressResolver::HandleAddressError(Coap::Header &aHeader, Message &aMessag
if (aHeader.IsConfirmable() && !aMessageInfo.GetSockAddr().IsMulticast())
{
- if (mNetif.GetCoapServer().SendEmptyAck(aHeader, aMessageInfo) == kThreadError_None)
+ if (mNetif.GetCoap().SendEmptyAck(aHeader, aMessageInfo) == kThreadError_None)
{
otLogInfoArp(GetInstance(), "Sent address error notification acknowledgment");
}
@@ -578,7 +578,7 @@ void AddressResolver::SendAddressQueryResponse(const ThreadTargetTlv &aTargetTlv
header.AppendUriPathOptions(OPENTHREAD_URI_ADDRESS_NOTIFY);
header.SetPayloadMarker();
- VerifyOrExit((message = mNetif.GetCoapClient().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
+ VerifyOrExit((message = mNetif.GetCoap().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
SuccessOrExit(error = message->Append(&aTargetTlv, sizeof(aTargetTlv)));
SuccessOrExit(error = message->Append(&aMlIidTlv, sizeof(aMlIidTlv)));
@@ -596,7 +596,7 @@ void AddressResolver::SendAddressQueryResponse(const ThreadTargetTlv &aTargetTlv
messageInfo.SetSockAddr(mNetif.GetMle().GetMeshLocal16());
messageInfo.SetPeerPort(kCoapUdpPort);
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
otLogInfoArp(GetInstance(), "Sent address notification");
diff --git a/src/core/thread/address_resolver.hpp b/src/core/thread/address_resolver.hpp
index 170bfbb48..a5d86b1e7 100644
--- a/src/core/thread/address_resolver.hpp
+++ b/src/core/thread/address_resolver.hpp
@@ -37,8 +37,7 @@
#include
#include "openthread-core-config.h"
-#include "coap/coap_client.hpp"
-#include "coap/coap_server.hpp"
+#include "coap/coap.hpp"
#include "common/timer.hpp"
#include "mac/mac.hpp"
#include "net/icmp6.hpp"
diff --git a/src/core/thread/announce_begin_server.cpp b/src/core/thread/announce_begin_server.cpp
index e0a7e6b46..f0bf62c71 100644
--- a/src/core/thread/announce_begin_server.cpp
+++ b/src/core/thread/announce_begin_server.cpp
@@ -64,7 +64,7 @@ AnnounceBeginServer::AnnounceBeginServer(ThreadNetif &aThreadNetif) :
mAnnounceBegin(OPENTHREAD_URI_ANNOUNCE_BEGIN, &AnnounceBeginServer::HandleRequest, this),
mNetif(aThreadNetif)
{
- mNetif.GetCoapServer().AddResource(mAnnounceBegin);
+ mNetif.GetCoap().AddResource(mAnnounceBegin);
}
otInstance *AnnounceBeginServer::GetInstance(void)
@@ -127,7 +127,7 @@ void AnnounceBeginServer::HandleRequest(Coap::Header &aHeader, Message &aMessage
if (aHeader.IsConfirmable() && !aMessageInfo.GetSockAddr().IsMulticast())
{
- SuccessOrExit(mNetif.GetCoapServer().SendEmptyAck(aHeader, responseInfo));
+ SuccessOrExit(mNetif.GetCoap().SendEmptyAck(aHeader, responseInfo));
otLogInfoMeshCoP(GetInstance(), "sent announce begin response");
}
diff --git a/src/core/thread/announce_begin_server.hpp b/src/core/thread/announce_begin_server.hpp
index 71c213aa7..a5c33d438 100644
--- a/src/core/thread/announce_begin_server.hpp
+++ b/src/core/thread/announce_begin_server.hpp
@@ -37,8 +37,7 @@
#include
#include "openthread-core-config.h"
-#include "coap/coap_client.hpp"
-#include "coap/coap_server.hpp"
+#include "coap/coap.hpp"
#include "common/timer.hpp"
#include "net/ip6_address.hpp"
diff --git a/src/core/thread/energy_scan_server.cpp b/src/core/thread/energy_scan_server.cpp
index 0263e87b3..c51d7b326 100644
--- a/src/core/thread/energy_scan_server.cpp
+++ b/src/core/thread/energy_scan_server.cpp
@@ -69,7 +69,7 @@ EnergyScanServer::EnergyScanServer(ThreadNetif &aThreadNetif) :
mNetifCallback.Set(&EnergyScanServer::HandleNetifStateChanged, this);
mNetif.RegisterCallback(mNetifCallback);
- mNetif.GetCoapServer().AddResource(mEnergyScan);
+ mNetif.GetCoap().AddResource(mEnergyScan);
}
otInstance *EnergyScanServer::GetInstance(void)
@@ -120,7 +120,7 @@ void EnergyScanServer::HandleRequest(Coap::Header &aHeader, Message &aMessage, c
if (aHeader.IsConfirmable() && !aMessageInfo.GetSockAddr().IsMulticast())
{
- SuccessOrExit(mNetif.GetCoapServer().SendEmptyAck(aHeader, responseInfo));
+ SuccessOrExit(mNetif.GetCoap().SendEmptyAck(aHeader, responseInfo));
otLogInfoMeshCoP(GetInstance(), "sent energy scan query response");
}
@@ -204,7 +204,7 @@ ThreadError EnergyScanServer::SendReport(void)
header.AppendUriPathOptions(OPENTHREAD_URI_ENERGY_REPORT);
header.SetPayloadMarker();
- VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(mNetif.GetCoapClient(), header)) != NULL,
+ VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(mNetif.GetCoap(), header)) != NULL,
error = kThreadError_NoBufs);
channelMask.Init();
@@ -219,7 +219,7 @@ ThreadError EnergyScanServer::SendReport(void)
messageInfo.SetSockAddr(mNetif.GetMle().GetMeshLocal16());
messageInfo.SetPeerAddr(mCommissioner);
messageInfo.SetPeerPort(kCoapUdpPort);
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
otLogInfoMeshCoP(GetInstance(), "sent scan results");
diff --git a/src/core/thread/energy_scan_server.hpp b/src/core/thread/energy_scan_server.hpp
index a1bfe94cc..15817cbcc 100644
--- a/src/core/thread/energy_scan_server.hpp
+++ b/src/core/thread/energy_scan_server.hpp
@@ -37,8 +37,7 @@
#include
#include "openthread-core-config.h"
-#include "coap/coap_client.hpp"
-#include "coap/coap_server.hpp"
+#include "coap/coap.hpp"
#include "common/timer.hpp"
#include "net/ip6_address.hpp"
#include "net/udp6.hpp"
diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp
index 9237aefc2..145bc7a9f 100644
--- a/src/core/thread/mle_router.cpp
+++ b/src/core/thread/mle_router.cpp
@@ -323,8 +323,8 @@ exit:
void MleRouter::StopLeader(void)
{
- mNetif.GetCoapServer().RemoveResource(mAddressSolicit);
- mNetif.GetCoapServer().RemoveResource(mAddressRelease);
+ mNetif.GetCoap().RemoveResource(mAddressSolicit);
+ mNetif.GetCoap().RemoveResource(mAddressRelease);
mNetif.GetActiveDataset().StopLeader();
mNetif.GetPendingDataset().StopLeader();
mAdvertiseTimer.Stop();
@@ -473,8 +473,8 @@ ThreadError MleRouter::SetStateLeader(uint16_t aRloc16)
mNetif.GetNetworkDataLeader().Start();
mNetif.GetActiveDataset().StartLeader();
mNetif.GetPendingDataset().StartLeader();
- mNetif.GetCoapServer().AddResource(mAddressSolicit);
- mNetif.GetCoapServer().AddResource(mAddressRelease);
+ mNetif.GetCoap().AddResource(mAddressSolicit);
+ mNetif.GetCoap().AddResource(mAddressRelease);
mNetif.GetIp6().SetForwardingEnabled(true);
mNetif.GetIp6().mMpl.SetTimerExpirations(kMplRouterDataMessageTimerExpirations);
mNetif.GetMac().SetBeaconEnabled(true);
@@ -3802,7 +3802,7 @@ ThreadError MleRouter::SendAddressSolicit(ThreadStatusTlv::Status aStatus)
header.AppendUriPathOptions(OPENTHREAD_URI_ADDRESS_SOLICIT);
header.SetPayloadMarker();
- VerifyOrExit((message = mNetif.GetCoapClient().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
+ VerifyOrExit((message = mNetif.GetCoap().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
macAddr64Tlv.Init();
macAddr64Tlv.SetMacAddr(*mNetif.GetMac().GetExtAddress());
@@ -3823,8 +3823,8 @@ ThreadError MleRouter::SendAddressSolicit(ThreadStatusTlv::Status aStatus)
messageInfo.SetSockAddr(GetMeshLocal16());
messageInfo.SetPeerPort(kCoapUdpPort);
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo,
- &MleRouter::HandleAddressSolicitResponse, this));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo,
+ &MleRouter::HandleAddressSolicitResponse, this));
otLogInfoMle(GetInstance(), "Sent address solicit to %04x", HostSwap16(messageInfo.GetPeerAddr().mFields.m16[7]));
@@ -3852,7 +3852,7 @@ ThreadError MleRouter::SendAddressRelease(void)
header.AppendUriPathOptions(OPENTHREAD_URI_ADDRESS_RELEASE);
header.SetPayloadMarker();
- VerifyOrExit((message = mNetif.GetCoapClient().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
+ VerifyOrExit((message = mNetif.GetCoap().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
rlocTlv.Init();
rlocTlv.SetRloc16(GetRloc16(mRouterId));
@@ -3865,7 +3865,7 @@ ThreadError MleRouter::SendAddressRelease(void)
messageInfo.SetSockAddr(GetMeshLocal16());
SuccessOrExit(error = GetLeaderAddress(messageInfo.GetPeerAddr()));
messageInfo.SetPeerPort(kCoapUdpPort);
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
otLogInfoMle(GetInstance(), "Sent address release");
@@ -4130,7 +4130,7 @@ void MleRouter::SendAddressSolicitResponse(const Coap::Header &aRequestHeader, u
responseHeader.SetDefaultResponseHeader(aRequestHeader);
responseHeader.SetPayloadMarker();
- VerifyOrExit((message = mNetif.GetCoapServer().NewMessage(responseHeader)) != NULL, error = kThreadError_NoBufs);
+ VerifyOrExit((message = mNetif.GetCoap().NewMessage(responseHeader)) != NULL, error = kThreadError_NoBufs);
statusTlv.Init();
statusTlv.SetStatus(!IsRouterIdValid(aRouterId) ? statusTlv.kNoAddressAvailable : statusTlv.kSuccess);
@@ -4157,7 +4157,7 @@ void MleRouter::SendAddressSolicitResponse(const Coap::Header &aRequestHeader, u
SuccessOrExit(error = message->Append(&routerMaskTlv, sizeof(routerMaskTlv)));
}
- SuccessOrExit(error = mNetif.GetCoapServer().SendMessage(*message, aMessageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, aMessageInfo));
otLogInfoMle(GetInstance(), "Sent address reply");
@@ -4204,7 +4204,7 @@ void MleRouter::HandleAddressRelease(Coap::Header &aHeader, Message &aMessage,
ReleaseRouterId(routerId);
- SuccessOrExit(mNetif.GetCoapServer().SendEmptyAck(aHeader, aMessageInfo));
+ SuccessOrExit(mNetif.GetCoap().SendEmptyAck(aHeader, aMessageInfo));
otLogInfoMle(GetInstance(), "Sent address release response");
diff --git a/src/core/thread/mle_router_ftd.hpp b/src/core/thread/mle_router_ftd.hpp
index 8f459b1ef..1f61a070a 100644
--- a/src/core/thread/mle_router_ftd.hpp
+++ b/src/core/thread/mle_router_ftd.hpp
@@ -36,9 +36,8 @@
#include "utils/wrap_string.h"
-#include "coap/coap_client.hpp"
+#include "coap/coap.hpp"
#include "coap/coap_header.hpp"
-#include "coap/coap_server.hpp"
#include "common/timer.hpp"
#include "common/trickle_timer.hpp"
#include "mac/mac_frame.hpp"
diff --git a/src/core/thread/network_data.cpp b/src/core/thread/network_data.cpp
index 7cac26c60..3c3cc40c4 100644
--- a/src/core/thread/network_data.cpp
+++ b/src/core/thread/network_data.cpp
@@ -622,7 +622,7 @@ ThreadError NetworkData::SendServerDataNotification(uint16_t aRloc16)
header.AppendUriPathOptions(OPENTHREAD_URI_SERVER_DATA);
header.SetPayloadMarker();
- VerifyOrExit((message = mNetif.GetCoapClient().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
+ VerifyOrExit((message = mNetif.GetCoap().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
if (mLocal)
{
@@ -644,7 +644,7 @@ ThreadError NetworkData::SendServerDataNotification(uint16_t aRloc16)
mNetif.GetMle().GetLeaderAloc(messageInfo.GetPeerAddr());
messageInfo.SetSockAddr(mNetif.GetMle().GetMeshLocal16());
messageInfo.SetPeerPort(kCoapUdpPort);
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
if (mLocal)
{
diff --git a/src/core/thread/network_data.hpp b/src/core/thread/network_data.hpp
index 6777e3819..572a57f7c 100644
--- a/src/core/thread/network_data.hpp
+++ b/src/core/thread/network_data.hpp
@@ -36,7 +36,7 @@
#include
-#include "coap/coap_client.hpp"
+#include "coap/coap.hpp"
#include "net/udp6.hpp"
#include "thread/lowpan.hpp"
#include "thread/mle_router.hpp"
diff --git a/src/core/thread/network_data_leader.hpp b/src/core/thread/network_data_leader.hpp
index e09f18d78..1c2f75b24 100644
--- a/src/core/thread/network_data_leader.hpp
+++ b/src/core/thread/network_data_leader.hpp
@@ -36,7 +36,7 @@
#include "utils/wrap_stdint.h"
-#include "coap/coap_server.hpp"
+#include "coap/coap.hpp"
#include "common/timer.hpp"
#include "net/ip6_address.hpp"
#include "thread/mle_router.hpp"
diff --git a/src/core/thread/network_data_leader_ftd.cpp b/src/core/thread/network_data_leader_ftd.cpp
index d7f8d9059..287ab4d54 100644
--- a/src/core/thread/network_data_leader_ftd.cpp
+++ b/src/core/thread/network_data_leader_ftd.cpp
@@ -86,16 +86,16 @@ void Leader::Reset(void)
void Leader::Start(void)
{
- mNetif.GetCoapServer().AddResource(mServerData);
- mNetif.GetCoapServer().AddResource(mCommissioningDataGet);
- mNetif.GetCoapServer().AddResource(mCommissioningDataSet);
+ mNetif.GetCoap().AddResource(mServerData);
+ mNetif.GetCoap().AddResource(mCommissioningDataGet);
+ mNetif.GetCoap().AddResource(mCommissioningDataSet);
}
void Leader::Stop(void)
{
- mNetif.GetCoapServer().RemoveResource(mServerData);
- mNetif.GetCoapServer().RemoveResource(mCommissioningDataGet);
- mNetif.GetCoapServer().RemoveResource(mCommissioningDataSet);
+ mNetif.GetCoap().RemoveResource(mServerData);
+ mNetif.GetCoap().RemoveResource(mCommissioningDataGet);
+ mNetif.GetCoap().RemoveResource(mCommissioningDataSet);
}
void Leader::IncrementVersion(void)
@@ -177,7 +177,7 @@ void Leader::HandleServerData(Coap::Header &aHeader, Message &aMessage,
networkData.GetTlvs(), networkData.GetLength());
}
- SuccessOrExit(mNetif.GetCoapServer().SendEmptyAck(aHeader, aMessageInfo));
+ SuccessOrExit(mNetif.GetCoap().SendEmptyAck(aHeader, aMessageInfo));
otLogInfoNetData(GetInstance(), "Sent network data registration acknowledgment");
@@ -324,7 +324,7 @@ void Leader::SendCommissioningGetResponse(const Coap::Header &aRequestHeader, co
responseHeader.SetDefaultResponseHeader(aRequestHeader);
responseHeader.SetPayloadMarker();
- VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(mNetif.GetCoapServer(), responseHeader)) != NULL,
+ VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(mNetif.GetCoap(), responseHeader)) != NULL,
error = kThreadError_NoBufs);
for (NetworkDataTlv *cur = reinterpret_cast(mTlvs);
@@ -368,7 +368,7 @@ void Leader::SendCommissioningGetResponse(const Coap::Header &aRequestHeader, co
message->SetLength(message->GetLength() - 1);
}
- SuccessOrExit(error = mNetif.GetCoapServer().SendMessage(*message, aMessageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, aMessageInfo));
otLogInfoMeshCoP(GetInstance(), "sent commissioning dataset get response");
@@ -391,14 +391,14 @@ void Leader::SendCommissioningSetResponse(const Coap::Header &aRequestHeader, co
responseHeader.SetDefaultResponseHeader(aRequestHeader);
responseHeader.SetPayloadMarker();
- VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(mNetif.GetCoapServer(), responseHeader)) != NULL,
+ VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(mNetif.GetCoap(), responseHeader)) != NULL,
error = kThreadError_NoBufs);
state.Init();
state.SetState(aState);
SuccessOrExit(error = message->Append(&state, sizeof(state)));
- SuccessOrExit(error = mNetif.GetCoapServer().SendMessage(*message, aMessageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, aMessageInfo));
otLogInfoMeshCoP(GetInstance(), "sent commissioning dataset set response");
diff --git a/src/core/thread/network_data_leader_ftd.hpp b/src/core/thread/network_data_leader_ftd.hpp
index ff1de7282..576302749 100644
--- a/src/core/thread/network_data_leader_ftd.hpp
+++ b/src/core/thread/network_data_leader_ftd.hpp
@@ -36,7 +36,7 @@
#include "utils/wrap_stdint.h"
-#include "coap/coap_server.hpp"
+#include "coap/coap.hpp"
#include "common/timer.hpp"
#include "net/ip6_address.hpp"
#include "thread/mle_router.hpp"
diff --git a/src/core/thread/network_diagnostic.cpp b/src/core/thread/network_diagnostic.cpp
index 867bc75ab..d8c67b0ee 100644
--- a/src/core/thread/network_diagnostic.cpp
+++ b/src/core/thread/network_diagnostic.cpp
@@ -74,10 +74,10 @@ NetworkDiagnostic::NetworkDiagnostic(ThreadNetif &aThreadNetif) :
mReceiveDiagnosticGetCallback(NULL),
mReceiveDiagnosticGetCallbackContext(NULL)
{
- mNetif.GetCoapServer().AddResource(mDiagnosticGetRequest);
- mNetif.GetCoapServer().AddResource(mDiagnosticGetQuery);
- mNetif.GetCoapServer().AddResource(mDiagnosticGetAnswer);
- mNetif.GetCoapServer().AddResource(mDiagnosticReset);
+ mNetif.GetCoap().AddResource(mDiagnosticGetRequest);
+ mNetif.GetCoap().AddResource(mDiagnosticGetQuery);
+ mNetif.GetCoap().AddResource(mDiagnosticGetAnswer);
+ mNetif.GetCoap().AddResource(mDiagnosticReset);
}
otInstance *NetworkDiagnostic::GetInstance(void)
@@ -120,7 +120,7 @@ ThreadError NetworkDiagnostic::SendDiagnosticGet(const Ip6::Address &aDestinatio
header.SetPayloadMarker();
}
- VerifyOrExit((message = mNetif.GetCoapClient().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
+ VerifyOrExit((message = mNetif.GetCoap().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
SuccessOrExit(error = message->Append(aTlvTypes, aCount));
@@ -129,7 +129,7 @@ ThreadError NetworkDiagnostic::SendDiagnosticGet(const Ip6::Address &aDestinatio
messageInfo.SetPeerPort(kCoapUdpPort);
messageInfo.SetInterfaceId(mNetif.GetInterfaceId());
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo, handler, this));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo, handler, this));
otLogInfoNetDiag(GetInstance(), "Sent diagnostic get");
@@ -191,7 +191,7 @@ void NetworkDiagnostic::HandleDiagnosticGetAnswer(Coap::Header &aHeader, Message
mReceiveDiagnosticGetCallback(&aMessage, &aMessageInfo, mReceiveDiagnosticGetCallbackContext);
}
- SuccessOrExit(mNetif.GetCoapServer().SendEmptyAck(aHeader, aMessageInfo));
+ SuccessOrExit(mNetif.GetCoap().SendEmptyAck(aHeader, aMessageInfo));
otLogInfoNetDiag(GetInstance(), "Sent diagnostic answer acknowledgment");
@@ -458,7 +458,7 @@ void NetworkDiagnostic::HandleDiagnosticGetQuery(Coap::Header &aHeader, Message
// DIAG_GET.qry may be sent as a confirmable message.
if (aHeader.GetType() == kCoapTypeConfirmable)
{
- if (mNetif.GetCoapServer().SendEmptyAck(aHeader, aMessageInfo) == kThreadError_None)
+ if (mNetif.GetCoap().SendEmptyAck(aHeader, aMessageInfo) == kThreadError_None)
{
otLogInfoNetDiag(GetInstance(), "Sent diagnostic get query acknowledgment");
}
@@ -473,7 +473,7 @@ void NetworkDiagnostic::HandleDiagnosticGetQuery(Coap::Header &aHeader, Message
header.SetPayloadMarker();
}
- VerifyOrExit((message = mNetif.GetCoapClient().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
+ VerifyOrExit((message = mNetif.GetCoap().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
messageInfo.SetPeerAddr(aMessageInfo.GetPeerAddr());
messageInfo.SetSockAddr(mNetif.GetMle().GetMeshLocal16());
@@ -482,7 +482,7 @@ void NetworkDiagnostic::HandleDiagnosticGetQuery(Coap::Header &aHeader, Message
SuccessOrExit(error = FillRequestedTlvs(aMessage, *message, networkDiagnosticTlv));
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo, NULL, this));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo, NULL, this));
otLogInfoNetDiag(GetInstance(), "Sent diagnostic get answer");
@@ -526,7 +526,7 @@ void NetworkDiagnostic::HandleDiagnosticGetRequest(Coap::Header &aHeader, Messag
header.SetDefaultResponseHeader(aHeader);
header.SetPayloadMarker();
- VerifyOrExit((message = mNetif.GetCoapServer().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
+ VerifyOrExit((message = mNetif.GetCoap().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
SuccessOrExit(error = FillRequestedTlvs(aMessage, *message, networkDiagnosticTlv));
@@ -536,7 +536,7 @@ void NetworkDiagnostic::HandleDiagnosticGetRequest(Coap::Header &aHeader, Messag
message->SetLength(header.GetLength() - 1);
}
- SuccessOrExit(error = mNetif.GetCoapServer().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
otLogInfoNetDiag(GetInstance(), "Sent diagnostic get response");
@@ -565,7 +565,7 @@ ThreadError NetworkDiagnostic::SendDiagnosticReset(const Ip6::Address &aDestinat
header.SetPayloadMarker();
}
- VerifyOrExit((message = mNetif.GetCoapClient().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
+ VerifyOrExit((message = mNetif.GetCoap().NewMessage(header)) != NULL, error = kThreadError_NoBufs);
SuccessOrExit(error = message->Append(aTlvTypes, aCount));
@@ -574,7 +574,7 @@ ThreadError NetworkDiagnostic::SendDiagnosticReset(const Ip6::Address &aDestinat
messageInfo.SetPeerPort(kCoapUdpPort);
messageInfo.SetInterfaceId(mNetif.GetInterfaceId());
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
otLogInfoNetDiag(GetInstance(), "Sent network diagnostic reset");
@@ -634,7 +634,7 @@ void NetworkDiagnostic::HandleDiagnosticReset(Coap::Header &aHeader, Message &aM
}
}
- SuccessOrExit(mNetif.GetCoapServer().SendEmptyAck(aHeader, aMessageInfo));
+ SuccessOrExit(mNetif.GetCoap().SendEmptyAck(aHeader, aMessageInfo));
otLogInfoNetDiag(GetInstance(), "Sent diagnostic reset acknowledgment");
diff --git a/src/core/thread/network_diagnostic.hpp b/src/core/thread/network_diagnostic.hpp
index b87a54318..e1bfc6d9f 100644
--- a/src/core/thread/network_diagnostic.hpp
+++ b/src/core/thread/network_diagnostic.hpp
@@ -37,8 +37,7 @@
#include
#include "openthread-core-config.h"
-#include "coap/coap_client.hpp"
-#include "coap/coap_server.hpp"
+#include "coap/coap.hpp"
#include "net/udp6.hpp"
namespace ot {
diff --git a/src/core/thread/panid_query_server.cpp b/src/core/thread/panid_query_server.cpp
index 8bda4eca8..d42b5715a 100644
--- a/src/core/thread/panid_query_server.cpp
+++ b/src/core/thread/panid_query_server.cpp
@@ -61,7 +61,7 @@ PanIdQueryServer::PanIdQueryServer(ThreadNetif &aThreadNetif) :
mPanIdQuery(OPENTHREAD_URI_PANID_QUERY, &PanIdQueryServer::HandleQuery, this),
mNetif(aThreadNetif)
{
- mNetif.GetCoapServer().AddResource(mPanIdQuery);
+ mNetif.GetCoap().AddResource(mPanIdQuery);
}
otInstance *PanIdQueryServer::GetInstance()
@@ -98,7 +98,7 @@ void PanIdQueryServer::HandleQuery(Coap::Header &aHeader, Message &aMessage, con
if (aHeader.IsConfirmable() && !aMessageInfo.GetSockAddr().IsMulticast())
{
- SuccessOrExit(mNetif.GetCoapServer().SendEmptyAck(aHeader, responseInfo));
+ SuccessOrExit(mNetif.GetCoap().SendEmptyAck(aHeader, responseInfo));
otLogInfoMeshCoP(GetInstance(), "sent panid query response");
}
@@ -144,7 +144,7 @@ ThreadError PanIdQueryServer::SendConflict(void)
header.AppendUriPathOptions(OPENTHREAD_URI_PANID_CONFLICT);
header.SetPayloadMarker();
- VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(mNetif.GetCoapClient(), header)) != NULL,
+ VerifyOrExit((message = MeshCoP::NewMeshCoPMessage(mNetif.GetCoap(), header)) != NULL,
error = kThreadError_NoBufs);
channelMask.Init();
@@ -158,7 +158,7 @@ ThreadError PanIdQueryServer::SendConflict(void)
messageInfo.SetSockAddr(mNetif.GetMle().GetMeshLocal16());
messageInfo.SetPeerAddr(mCommissioner);
messageInfo.SetPeerPort(kCoapUdpPort);
- SuccessOrExit(error = mNetif.GetCoapClient().SendMessage(*message, messageInfo));
+ SuccessOrExit(error = mNetif.GetCoap().SendMessage(*message, messageInfo));
otLogInfoMeshCoP(GetInstance(), "sent panid conflict");
diff --git a/src/core/thread/panid_query_server.hpp b/src/core/thread/panid_query_server.hpp
index 0ea11a1ac..721ab6407 100644
--- a/src/core/thread/panid_query_server.hpp
+++ b/src/core/thread/panid_query_server.hpp
@@ -37,8 +37,7 @@
#include
#include "openthread-core-config.h"
-#include "coap/coap_client.hpp"
-#include "coap/coap_server.hpp"
+#include "coap/coap.hpp"
#include "common/timer.hpp"
#include "net/ip6_address.hpp"
#include "net/udp6.hpp"
diff --git a/src/core/thread/thread_netif.cpp b/src/core/thread/thread_netif.cpp
index b95c3c865..4eadc1fdd 100644
--- a/src/core/thread/thread_netif.cpp
+++ b/src/core/thread/thread_netif.cpp
@@ -65,8 +65,7 @@ static const otMasterKey kThreadMasterKey =
ThreadNetif::ThreadNetif(Ip6::Ip6 &aIp6):
Netif(aIp6, OT_NETIF_INTERFACE_ID_THREAD),
- mCoapServer(*this, kCoapUdpPort),
- mCoapClient(*this),
+ mCoap(*this),
#if OPENTHREAD_ENABLE_DHCP6_CLIENT
mDhcp6Client(*this),
#endif // OPENTHREAD_ENABLE_DHCP6_CLIENT
@@ -89,14 +88,13 @@ ThreadNetif::ThreadNetif(Ip6::Ip6 &aIp6):
mNetworkDiagnostic(*this),
#endif
#if OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
- mSecureCoapServer(*this, OPENTHREAD_CONFIG_JOINER_UDP_PORT),
mCommissioner(*this),
#endif // OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
#if OPENTHREAD_ENABLE_DTLS
mDtls(*this),
+ mCoapSecure(*this),
#endif
#if OPENTHREAD_ENABLE_JOINER
- mSecureCoapClient(*this),
mJoiner(*this),
#endif // OPENTHREAD_ENABLE_JOINER
#if OPENTHREAD_ENABLE_JAM_DETECTION
@@ -104,7 +102,7 @@ ThreadNetif::ThreadNetif(Ip6::Ip6 &aIp6):
#endif // OPENTHREAD_ENABLE_JAM_DETECTTION
#if OPENTHREAD_FTD
#if OPENTHREAD_ENABLE_BORDER_AGENT_PROXY
- mBorderAgentProxy(mMleRouter.GetMeshLocal16(), mCoapServer, mCoapClient),
+ mBorderAgentProxy(mMleRouter.GetMeshLocal16(), mCoap),
#endif // OPENTHREAD_ENABLE_BORDER_AGENT_PROXY
mJoinerRouter(*this),
mLeader(*this),
@@ -118,7 +116,7 @@ ThreadNetif::ThreadNetif(Ip6::Ip6 &aIp6):
{
mKeyManager.SetMasterKey(kThreadMasterKey);
- mCoapServer.SetInterceptor(&ThreadNetif::TmfFilter);
+ mCoap.SetInterceptor(&ThreadNetif::TmfFilter);
}
ThreadError ThreadNetif::Up(void)
@@ -127,11 +125,7 @@ ThreadError ThreadNetif::Up(void)
{
mIp6.AddNetif(*this);
mMeshForwarder.Start();
- mCoapServer.Start();
- mCoapClient.Start();
-#if OPENTHREAD_ENABLE_JOINER
- mSecureCoapClient.Start();
-#endif
+ mCoap.Start(kCoapUdpPort);
#if OPENTHREAD_ENABLE_DNS_CLIENT
mDnsClient.Start();
#endif
@@ -145,11 +139,7 @@ ThreadError ThreadNetif::Up(void)
ThreadError ThreadNetif::Down(void)
{
- mCoapServer.Stop();
- mCoapClient.Stop();
-#if OPENTHREAD_ENABLE_JOINER
- mSecureCoapClient.Stop();
-#endif
+ mCoap.Stop();
#if OPENTHREAD_ENABLE_DNS_CLIENT
mDnsClient.Stop();
#endif
diff --git a/src/core/thread/thread_netif.hpp b/src/core/thread/thread_netif.hpp
index 44f2ed0b0..1dfe219ba 100644
--- a/src/core/thread/thread_netif.hpp
+++ b/src/core/thread/thread_netif.hpp
@@ -42,10 +42,8 @@
#include
-#include "coap/coap_client.hpp"
-#include "coap/coap_server.hpp"
-#include "coap/secure_coap_client.hpp"
-#include "coap/secure_coap_server.hpp"
+#include "coap/coap.hpp"
+#include "coap/coap_secure.hpp"
#include "mac/mac.hpp"
#if OPENTHREAD_ENABLE_BORDER_AGENT_PROXY && OPENTHREAD_FTD
@@ -205,20 +203,12 @@ public:
#endif // OPENTHREAD_ENABLE_DNS_CLIENT
/**
- * This method returns a reference to the CoAP server object.
+ * This method returns a reference to the CoAP object.
*
- * @returns A reference to the CoAP server object.
+ * @returns A reference to the CoAP object.
*
*/
- Coap::Server &GetCoapServer(void) { return mCoapServer; }
-
- /**
- * This method returns a reference to the CoAP client object.
- *
- * @returns A reference to the CoAP client object.
- *
- */
- Coap::Client &GetCoapClient(void) { return mCoapClient; }
+ Coap::Coap &GetCoap(void) { return mCoap; }
/**
* This method returns a reference to the IPv6 filter object.
@@ -342,14 +332,6 @@ public:
*
*/
MeshCoP::Commissioner &GetCommissioner(void) { return mCommissioner; }
-
- /**
- * This method returns a reference to the secure CoAP server object.
- *
- * @returns A reference to the secure CoAP server object.
- *
- */
- Coap::SecureServer &GetSecureCoapServer(void) { return mSecureCoapServer; }
#endif // OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
#if OPENTHREAD_ENABLE_DTLS
@@ -360,6 +342,14 @@ public:
*
*/
MeshCoP::Dtls &GetDtls(void) { return mDtls; }
+
+ /**
+ * This method returns a reference to the secure CoAP object.
+ *
+ * @returns A reference to the secure CoAP object.
+ *
+ */
+ Coap::CoapSecure &GetCoapSecure(void) { return mCoapSecure; }
#endif // OPENTHREAD_ENABLE_DTLS
#if OPENTHREAD_ENABLE_JOINER
@@ -370,14 +360,6 @@ public:
*
*/
MeshCoP::Joiner &GetJoiner(void) { return mJoiner; }
-
- /**
- * This method returns a reference to the secure CoAP client object.
- *
- * @returns A reference to the secure CoAP client object.
- *
- */
- Coap::SecureClient &GetSecureCoapClient(void) { return mSecureCoapClient; }
#endif // OPENTHREAD_ENABLE_JOINER
#if OPENTHREAD_ENABLE_JAM_DETECTION
@@ -427,8 +409,7 @@ public:
private:
static ThreadError TmfFilter(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
- Coap::Server mCoapServer;
- Coap::Client mCoapClient;
+ Coap::Coap mCoap;
#if OPENTHREAD_ENABLE_DHCP6_CLIENT
Dhcp6::Dhcp6Client mDhcp6Client;
#endif // OPENTHREAD_ENABLE_DHCP6_CLIENT
@@ -454,16 +435,15 @@ private:
bool mIsUp;
#if OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
- Coap::SecureServer mSecureCoapServer;
MeshCoP::Commissioner mCommissioner;
#endif // OPENTHREAD_ENABLE_COMMISSIONER
#if OPENTHREAD_ENABLE_DTLS
MeshCoP::Dtls mDtls;
+ Coap::CoapSecure mCoapSecure;
#endif// OPENTHREAD_ENABLE_DTLS
#if OPENTHREAD_ENABLE_JOINER
- Coap::SecureClient mSecureCoapClient;
MeshCoP::Joiner mJoiner;
#endif // OPENTHREAD_ENABLE_JOINER
diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp
index 5c9bc9d4e..1594be019 100644
--- a/src/ncp/ncp_base.cpp
+++ b/src/ncp/ncp_base.cpp
@@ -3318,8 +3318,8 @@ ThreadError NcpBase::GetPropertyHandler_MSG_BUFFER_COUNTERS(uint8_t header, spin
bufferInfo.mMleBuffers,
bufferInfo.mArpMessages,
bufferInfo.mArpBuffers,
- bufferInfo.mCoapClientMessages,
- bufferInfo.mCoapClientBuffers
+ bufferInfo.mCoapMessages,
+ bufferInfo.mCoapBuffers
));
SuccessOrExit(errorCode = OutboundFrameSend());
diff --git a/src/ncp/spinel.h b/src/ncp/spinel.h
index b3c513b39..731770da1 100644
--- a/src/ncp/spinel.h
+++ b/src/ncp/spinel.h
@@ -1165,8 +1165,8 @@ typedef enum
* `S`, (MleBuffers) The number of buffers in the MLE send queue.
* `S`, (ArpMessages) The number of messages in the ARP send queue.
* `S`, (ArpBuffers) The number of buffers in the ARP send queue.
- * `S`, (CoapClientMessages) The number of messages in the CoAP client send queue.
- * `S`, (CoapClientBuffers) The number of buffers in the CoAP client send queue.
+ * `S`, (CoapMessages) The number of messages in the CoAP send queue.
+ * `S`, (CoapBuffers) The number of buffers in the CoAP send queue.
*/
SPINEL_PROP_MSG_BUFFER_COUNTERS = SPINEL_PROP_CNTR__BEGIN + 400,