diff --git a/etc/visual-studio/libopenthread.vcxproj b/etc/visual-studio/libopenthread.vcxproj
index 8c52e33ed..9013c15f8 100644
--- a/etc/visual-studio/libopenthread.vcxproj
+++ b/etc/visual-studio/libopenthread.vcxproj
@@ -79,6 +79,7 @@
+
diff --git a/etc/visual-studio/libopenthread.vcxproj.filters b/etc/visual-studio/libopenthread.vcxproj.filters
index db7e58b1d..deb8bf5c2 100644
--- a/etc/visual-studio/libopenthread.vcxproj.filters
+++ b/etc/visual-studio/libopenthread.vcxproj.filters
@@ -201,6 +201,9 @@
Source Files\thread
+
+ Source Files\thread
+
Source Files\meshcop
diff --git a/etc/visual-studio/libopenthread_k.vcxproj b/etc/visual-studio/libopenthread_k.vcxproj
index 60c367a66..869db620f 100644
--- a/etc/visual-studio/libopenthread_k.vcxproj
+++ b/etc/visual-studio/libopenthread_k.vcxproj
@@ -87,6 +87,7 @@
+
diff --git a/etc/visual-studio/libopenthread_k.vcxproj.filters b/etc/visual-studio/libopenthread_k.vcxproj.filters
index 58430a0a9..8e67620ff 100644
--- a/etc/visual-studio/libopenthread_k.vcxproj.filters
+++ b/etc/visual-studio/libopenthread_k.vcxproj.filters
@@ -201,6 +201,9 @@
Source Files\thread
+
+ Source Files\thread
+
Source Files\meshcop
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index f2e21f318..b785cb252 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -141,6 +141,7 @@ libopenthread_ftd_a_CPPFLAGS = \
libopenthread_ftd_a_SOURCES = \
$(SOURCES_COMMON) \
+ meshcop/dataset_manager_ftd.cpp \
meshcop/joiner_router.cpp \
meshcop/leader.cpp \
thread/address_resolver.cpp \
@@ -196,6 +197,8 @@ noinst_HEADERS = \
meshcop/commissioner.hpp \
meshcop/dataset.hpp \
meshcop/dataset_manager.hpp \
+ meshcop/dataset_manager_ftd.hpp \
+ meshcop/dataset_manager_mtd.hpp \
meshcop/dtls.hpp \
meshcop/energy_scan_client.hpp \
meshcop/joiner.hpp \
diff --git a/src/core/meshcop/dataset_manager.cpp b/src/core/meshcop/dataset_manager.cpp
index b25e0c535..8d5d67f96 100644
--- a/src/core/meshcop/dataset_manager.cpp
+++ b/src/core/meshcop/dataset_manager.cpp
@@ -272,7 +272,7 @@ ThreadError DatasetManager::Register(void)
if (strcmp(mUriSet, OPENTHREAD_URI_PENDING_SET) == 0)
{
- PendingDataset *pending = static_cast(this);
+ PendingDatasetBase *pending = static_cast(this);
pending->UpdateDelayTimer();
}
@@ -796,15 +796,12 @@ exit:
}
}
-ActiveDataset::ActiveDataset(ThreadNetif &aThreadNetif):
- DatasetManager(aThreadNetif, Tlv::kActiveTimestamp, OPENTHREAD_URI_ACTIVE_SET, OPENTHREAD_URI_ACTIVE_GET),
- mResourceGet(OPENTHREAD_URI_ACTIVE_GET, &ActiveDataset::HandleGet, this),
- mResourceSet(OPENTHREAD_URI_ACTIVE_SET, &ActiveDataset::HandleSet, this)
+ActiveDatasetBase::ActiveDatasetBase(ThreadNetif &aThreadNetif):
+ DatasetManager(aThreadNetif, Tlv::kActiveTimestamp, OPENTHREAD_URI_ACTIVE_SET, OPENTHREAD_URI_ACTIVE_GET)
{
- mCoapServer.AddResource(mResourceGet);
}
-ThreadError ActiveDataset::Restore(void)
+ThreadError ActiveDatasetBase::Restore(void)
{
ThreadError error = kThreadError_None;
@@ -815,74 +812,7 @@ exit:
return error;
}
-void ActiveDataset::StartLeader(void)
-{
- if (mLocal.GetTimestamp() == NULL)
- {
- otOperationalDataset dataset;
-
- memset(&dataset, 0, sizeof(dataset));
-
- // Active Timestamp
- dataset.mActiveTimestamp = 0;
- dataset.mIsActiveTimestampSet = true;
-
- // Channel
- dataset.mChannel = mNetif.GetMac().GetChannel();
- dataset.mIsChannelSet = true;
-
- // channelMask
- dataset.mChannelMaskPage0 = kPhySupportedChannelMask;
- dataset.mIsChannelMaskPage0Set = true;
-
- // Extended PAN ID
- memcpy(dataset.mExtendedPanId.m8, mNetif.GetMac().GetExtendedPanId(), sizeof(dataset.mExtendedPanId));
- dataset.mIsExtendedPanIdSet = true;
-
- // Mesh-Local Prefix
- memcpy(dataset.mMeshLocalPrefix.m8, mNetif.GetMle().GetMeshLocalPrefix(), sizeof(dataset.mMeshLocalPrefix));
- dataset.mIsMeshLocalPrefixSet = true;
-
- // Master Key
- const uint8_t *key;
- uint8_t keyLength;
- key = mNetif.GetKeyManager().GetMasterKey(&keyLength);
- memcpy(dataset.mMasterKey.m8, key, keyLength);
- dataset.mIsMasterKeySet = true;
-
- // Network Name
- const char *name;
- name = mNetif.GetMac().GetNetworkName();
- memcpy(dataset.mNetworkName.m8, name, strlen(name));
- dataset.mIsNetworkNameSet = true;
-
- // Pan ID
- dataset.mPanId = mNetif.GetMac().GetPanId();
- dataset.mIsPanIdSet = true;
-
- // PSKc
- memset(dataset.mPSKc.m8, 0, OT_PSKC_MAX_SIZE);
- dataset.mIsPSKcSet = true;
-
- // Security Policy
- dataset.mSecurityPolicy.mRotationTime = static_cast(mNetif.GetKeyManager().GetKeyRotation());
- dataset.mSecurityPolicy.mFlags = mNetif.GetKeyManager().GetSecurityPolicyFlags();
- dataset.mIsSecurityPolicySet = true;
-
- mLocal.Set(dataset);
- }
-
- mLocal.Store();
- mNetwork = mLocal;
- mCoapServer.AddResource(mResourceSet);
-}
-
-void ActiveDataset::StopLeader(void)
-{
- mCoapServer.RemoveResource(mResourceSet);
-}
-
-ThreadError ActiveDataset::Clear(bool aOnlyClearNetwork)
+ThreadError ActiveDatasetBase::Clear(bool aOnlyClearNetwork)
{
ThreadError error = kThreadError_None;
uint8_t flags;
@@ -893,7 +823,7 @@ exit:
return error;
}
-ThreadError ActiveDataset::Set(const otOperationalDataset &aDataset)
+ThreadError ActiveDatasetBase::Set(const otOperationalDataset &aDataset)
{
ThreadError error = kThreadError_None;
uint8_t flags;
@@ -905,7 +835,7 @@ exit:
return error;
}
-ThreadError ActiveDataset::Set(const Dataset &aDataset)
+ThreadError ActiveDatasetBase::Set(const Dataset &aDataset)
{
ThreadError error = kThreadError_None;
@@ -922,8 +852,8 @@ exit:
return error;
}
-ThreadError ActiveDataset::Set(const Timestamp &aTimestamp, const Message &aMessage,
- uint16_t aOffset, uint8_t aLength)
+ThreadError ActiveDatasetBase::Set(const Timestamp &aTimestamp, const Message &aMessage,
+ uint16_t aOffset, uint8_t aLength)
{
ThreadError error = kThreadError_None;
uint8_t flags;
@@ -935,46 +865,13 @@ exit:
return error;
}
-void ActiveDataset::HandleGet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
- const otMessageInfo *aMessageInfo)
-{
- static_cast(aContext)->HandleGet(
- *static_cast(aHeader), *static_cast(aMessage),
- *static_cast(aMessageInfo));
-}
-
-void ActiveDataset::HandleGet(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
-{
- DatasetManager::Get(aHeader, aMessage, aMessageInfo);
-}
-
-void ActiveDataset::HandleSet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
- const otMessageInfo *aMessageInfo)
-{
- static_cast(aContext)->HandleSet(
- *static_cast(aHeader), *static_cast(aMessage),
- *static_cast(aMessageInfo));
-}
-
-void ActiveDataset::HandleSet(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
-{
- SuccessOrExit(DatasetManager::Set(aHeader, aMessage, aMessageInfo));
- ApplyConfiguration();
-
-exit:
- return;
-}
-
-PendingDataset::PendingDataset(ThreadNetif &aThreadNetif):
+PendingDatasetBase::PendingDatasetBase(ThreadNetif &aThreadNetif):
DatasetManager(aThreadNetif, Tlv::kPendingTimestamp, OPENTHREAD_URI_PENDING_SET, OPENTHREAD_URI_PENDING_GET),
- mResourceGet(OPENTHREAD_URI_PENDING_GET, &PendingDataset::HandleGet, this),
- mResourceSet(OPENTHREAD_URI_PENDING_SET, &PendingDataset::HandleSet, this),
- mTimer(aThreadNetif.GetIp6().mTimerScheduler, &PendingDataset::HandleTimer, this)
+ mTimer(aThreadNetif.GetIp6().mTimerScheduler, &PendingDatasetBase::HandleTimer, this)
{
- mCoapServer.AddResource(mResourceGet);
}
-ThreadError PendingDataset::Restore(void)
+ThreadError PendingDatasetBase::Restore(void)
{
ThreadError error = kThreadError_None;
@@ -986,22 +883,7 @@ exit:
return error;
}
-void PendingDataset::StartLeader(void)
-{
- UpdateDelayTimer(mLocal, mLocalTime);
- mLocal.Store();
- mNetwork = mLocal;
- ResetDelayTimer(kFlagNetworkUpdated);
-
- mCoapServer.AddResource(mResourceSet);
-}
-
-void PendingDataset::StopLeader(void)
-{
- mCoapServer.RemoveResource(mResourceSet);
-}
-
-ThreadError PendingDataset::Clear(bool aOnlyClearNetwork)
+ThreadError PendingDatasetBase::Clear(bool aOnlyClearNetwork)
{
ThreadError error = kThreadError_None;
uint8_t flags;
@@ -1013,7 +895,7 @@ exit:
return error;
}
-ThreadError PendingDataset::Set(const otOperationalDataset &aDataset)
+ThreadError PendingDatasetBase::Set(const otOperationalDataset &aDataset)
{
ThreadError error = kThreadError_None;
uint8_t flags;
@@ -1025,7 +907,7 @@ exit:
return error;
}
-ThreadError PendingDataset::Set(const Dataset &aDataset)
+ThreadError PendingDatasetBase::Set(const Dataset &aDataset)
{
ThreadError error = kThreadError_None;
@@ -1036,8 +918,8 @@ exit:
return error;
}
-ThreadError PendingDataset::Set(const Timestamp &aTimestamp, const Message &aMessage,
- uint16_t aOffset, uint8_t aLength)
+ThreadError PendingDatasetBase::Set(const Timestamp &aTimestamp, const Message &aMessage,
+ uint16_t aOffset, uint8_t aLength)
{
ThreadError error = kThreadError_None;
uint8_t flags;
@@ -1049,37 +931,7 @@ exit:
return error;
}
-void PendingDataset::HandleGet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
- const otMessageInfo *aMessageInfo)
-{
- static_cast(aContext)->HandleGet(
- *static_cast(aHeader), *static_cast(aMessage),
- *static_cast(aMessageInfo));
-}
-
-void PendingDataset::HandleGet(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
-{
- DatasetManager::Get(aHeader, aMessage, aMessageInfo);
-}
-
-void PendingDataset::HandleSet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
- const otMessageInfo *aMessageInfo)
-{
- static_cast(aContext)->HandleSet(
- *static_cast(aHeader), *static_cast(aMessage),
- *static_cast(aMessageInfo));
-}
-
-void PendingDataset::HandleSet(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
-{
- SuccessOrExit(DatasetManager::Set(aHeader, aMessage, aMessageInfo));
- ResetDelayTimer(kFlagLocalUpdated | kFlagNetworkUpdated);
-
-exit:
- return;
-}
-
-void PendingDataset::ResetDelayTimer(uint8_t aFlags)
+void PendingDatasetBase::ResetDelayTimer(uint8_t aFlags)
{
DelayTimerTlv *delayTimer;
@@ -1108,13 +960,13 @@ void PendingDataset::ResetDelayTimer(uint8_t aFlags)
}
}
-void PendingDataset::UpdateDelayTimer(void)
+void PendingDatasetBase::UpdateDelayTimer(void)
{
UpdateDelayTimer(mLocal, mLocalTime);
UpdateDelayTimer(mNetwork, mNetworkTime);
}
-void PendingDataset::UpdateDelayTimer(Dataset &aDataset, uint32_t &aStartTime)
+void PendingDatasetBase::UpdateDelayTimer(Dataset &aDataset, uint32_t &aStartTime)
{
DelayTimerTlv *delayTimer;
uint32_t now = Timer::GetNow();
@@ -1144,12 +996,12 @@ exit:
return;
}
-void PendingDataset::HandleTimer(void *aContext)
+void PendingDatasetBase::HandleTimer(void *aContext)
{
- static_cast(aContext)->HandleTimer();
+ static_cast(aContext)->HandleTimer();
}
-void PendingDataset::HandleTimer(void)
+void PendingDatasetBase::HandleTimer(void)
{
DelayTimerTlv *delayTimer;
@@ -1164,7 +1016,7 @@ void PendingDataset::HandleTimer(void)
Clear(false);
}
-void PendingDataset::ApplyActiveDataset(const Timestamp &aTimestamp, Message &aMessage)
+void PendingDatasetBase::ApplyActiveDataset(const Timestamp &aTimestamp, Message &aMessage)
{
uint16_t offset = aMessage.GetOffset();
DelayTimerTlv delayTimer;
@@ -1203,7 +1055,7 @@ exit:
{}
}
-void PendingDataset::HandleNetworkUpdate(uint8_t &aFlags)
+void PendingDatasetBase::HandleNetworkUpdate(uint8_t &aFlags)
{
DatasetManager::HandleNetworkUpdate(aFlags);
}
diff --git a/src/core/meshcop/dataset_manager.hpp b/src/core/meshcop/dataset_manager.hpp
index f642fb952..cc8c5a113 100644
--- a/src/core/meshcop/dataset_manager.hpp
+++ b/src/core/meshcop/dataset_manager.hpp
@@ -112,17 +112,13 @@ private:
const char *mUriGet;
};
-class ActiveDataset: public DatasetManager
+class ActiveDatasetBase: public DatasetManager
{
public:
- ActiveDataset(ThreadNetif &aThreadNetif);
+ ActiveDatasetBase(ThreadNetif &aThreadNetif);
ThreadError Restore(void);
- void StartLeader(void);
-
- void StopLeader(void);
-
ThreadError Clear(bool aOnlyClearNetwork);
ThreadError Set(const otOperationalDataset &aDataset);
@@ -130,31 +126,15 @@ public:
ThreadError Set(const Dataset &aDataset);
ThreadError Set(const Timestamp &aTimestamp, const Message &aMessage, uint16_t aOffset, uint8_t aLength);
-
-private:
- static void HandleGet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
- const otMessageInfo *aMessageInfo);
- void HandleGet(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
-
- static void HandleSet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
- const otMessageInfo *aMessageInfo);
- void HandleSet(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
-
- Coap::Resource mResourceGet;
- Coap::Resource mResourceSet;
};
-class PendingDataset: public DatasetManager
+class PendingDatasetBase: public DatasetManager
{
public:
- PendingDataset(ThreadNetif &aThreadNetif);
+ PendingDatasetBase(ThreadNetif &aThreadNetif);
ThreadError Restore(void);
- void StartLeader(void);
-
- void StopLeader(void);
-
ThreadError Clear(bool aOnlyClearNetwork);
ThreadError Set(const otOperationalDataset &aDataset);
@@ -167,15 +147,7 @@ public:
void ApplyActiveDataset(const Timestamp &aTimestamp, Message &aMessage);
-private:
- static void HandleGet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
- const otMessageInfo *aMessageInfo);
- void HandleGet(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
-
- static void HandleSet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
- const otMessageInfo *aMessageInfo);
- void HandleSet(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
-
+protected:
static void HandleTimer(void *aContext);
void HandleTimer(void);
@@ -184,9 +156,6 @@ private:
void HandleNetworkUpdate(uint8_t &aFlags);
- Coap::Resource mResourceGet;
- Coap::Resource mResourceSet;
-
Timer mTimer;
uint32_t mLocalTime;
uint32_t mNetworkTime;
@@ -195,4 +164,10 @@ private:
} // namespace MeshCoP
} // namespace Thread
+#ifdef OPENTHREAD_MTD
+#include "dataset_manager_mtd.hpp"
+#else
+#include "dataset_manager_ftd.hpp"
+#endif
+
#endif // MESHCOP_DATASET_MANAGER_HPP_
diff --git a/src/core/meshcop/dataset_manager_ftd.cpp b/src/core/meshcop/dataset_manager_ftd.cpp
new file mode 100644
index 000000000..4a74b9617
--- /dev/null
+++ b/src/core/meshcop/dataset_manager_ftd.cpp
@@ -0,0 +1,219 @@
+/*
+ * 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 MeshCoP Datasets manager to process commands.
+ *
+ */
+
+#define WPP_NAME "dataset_manager.tmh"
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace Thread {
+namespace MeshCoP {
+
+ActiveDataset::ActiveDataset(ThreadNetif &aThreadNetif):
+ ActiveDatasetBase(aThreadNetif),
+ mResourceGet(OPENTHREAD_URI_ACTIVE_GET, &ActiveDataset::HandleGet, this),
+ mResourceSet(OPENTHREAD_URI_ACTIVE_SET, &ActiveDataset::HandleSet, this)
+{
+ mCoapServer.AddResource(mResourceGet);
+}
+
+void ActiveDataset::StartLeader(void)
+{
+ if (mLocal.GetTimestamp() == NULL)
+ {
+ otOperationalDataset dataset;
+
+ memset(&dataset, 0, sizeof(dataset));
+
+ // Active Timestamp
+ dataset.mActiveTimestamp = 0;
+ dataset.mIsActiveTimestampSet = true;
+
+ // Channel
+ dataset.mChannel = mNetif.GetMac().GetChannel();
+ dataset.mIsChannelSet = true;
+
+ // channelMask
+ dataset.mChannelMaskPage0 = kPhySupportedChannelMask;
+ dataset.mIsChannelMaskPage0Set = true;
+
+ // Extended PAN ID
+ memcpy(dataset.mExtendedPanId.m8, mNetif.GetMac().GetExtendedPanId(), sizeof(dataset.mExtendedPanId));
+ dataset.mIsExtendedPanIdSet = true;
+
+ // Mesh-Local Prefix
+ memcpy(dataset.mMeshLocalPrefix.m8, mNetif.GetMle().GetMeshLocalPrefix(), sizeof(dataset.mMeshLocalPrefix));
+ dataset.mIsMeshLocalPrefixSet = true;
+
+ // Master Key
+ const uint8_t *key;
+ uint8_t keyLength;
+ key = mNetif.GetKeyManager().GetMasterKey(&keyLength);
+ memcpy(dataset.mMasterKey.m8, key, keyLength);
+ dataset.mIsMasterKeySet = true;
+
+ // Network Name
+ const char *name;
+ name = mNetif.GetMac().GetNetworkName();
+ memcpy(dataset.mNetworkName.m8, name, strlen(name));
+ dataset.mIsNetworkNameSet = true;
+
+ // Pan ID
+ dataset.mPanId = mNetif.GetMac().GetPanId();
+ dataset.mIsPanIdSet = true;
+
+ // PSKc
+ memset(dataset.mPSKc.m8, 0, OT_PSKC_MAX_SIZE);
+ dataset.mIsPSKcSet = true;
+
+ // Security Policy
+ dataset.mSecurityPolicy.mRotationTime = static_cast(mNetif.GetKeyManager().GetKeyRotation());
+ dataset.mSecurityPolicy.mFlags = mNetif.GetKeyManager().GetSecurityPolicyFlags();
+ dataset.mIsSecurityPolicySet = true;
+
+ mLocal.Set(dataset);
+ }
+
+ mLocal.Store();
+ mNetwork = mLocal;
+ mCoapServer.AddResource(mResourceSet);
+}
+
+void ActiveDataset::StopLeader(void)
+{
+ mCoapServer.RemoveResource(mResourceSet);
+}
+
+void ActiveDataset::HandleGet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
+ const otMessageInfo *aMessageInfo)
+{
+ static_cast(aContext)->HandleGet(
+ *static_cast(aHeader), *static_cast(aMessage),
+ *static_cast(aMessageInfo));
+}
+
+void ActiveDataset::HandleGet(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+{
+ DatasetManager::Get(aHeader, aMessage, aMessageInfo);
+}
+
+void ActiveDataset::HandleSet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
+ const otMessageInfo *aMessageInfo)
+{
+ static_cast(aContext)->HandleSet(
+ *static_cast(aHeader), *static_cast(aMessage),
+ *static_cast(aMessageInfo));
+}
+
+void ActiveDataset::HandleSet(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+{
+ SuccessOrExit(DatasetManager::Set(aHeader, aMessage, aMessageInfo));
+ ApplyConfiguration();
+
+exit:
+ return;
+}
+
+PendingDataset::PendingDataset(ThreadNetif &aThreadNetif):
+ PendingDatasetBase(aThreadNetif),
+ mResourceGet(OPENTHREAD_URI_PENDING_GET, &PendingDataset::HandleGet, this),
+ mResourceSet(OPENTHREAD_URI_PENDING_SET, &PendingDataset::HandleSet, this)
+{
+ mCoapServer.AddResource(mResourceGet);
+}
+
+void PendingDataset::StartLeader(void)
+{
+ UpdateDelayTimer(mLocal, mLocalTime);
+ mLocal.Store();
+ mNetwork = mLocal;
+ ResetDelayTimer(kFlagNetworkUpdated);
+
+ mCoapServer.AddResource(mResourceSet);
+}
+
+void PendingDataset::StopLeader(void)
+{
+ mCoapServer.RemoveResource(mResourceSet);
+}
+
+void PendingDataset::HandleGet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
+ const otMessageInfo *aMessageInfo)
+{
+ static_cast(aContext)->HandleGet(
+ *static_cast(aHeader), *static_cast(aMessage),
+ *static_cast(aMessageInfo));
+}
+
+void PendingDataset::HandleGet(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+{
+ DatasetManager::Get(aHeader, aMessage, aMessageInfo);
+}
+
+void PendingDataset::HandleSet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
+ const otMessageInfo *aMessageInfo)
+{
+ static_cast(aContext)->HandleSet(
+ *static_cast(aHeader), *static_cast(aMessage),
+ *static_cast(aMessageInfo));
+}
+
+void PendingDataset::HandleSet(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
+{
+ SuccessOrExit(DatasetManager::Set(aHeader, aMessage, aMessageInfo));
+ ResetDelayTimer(kFlagLocalUpdated | kFlagNetworkUpdated);
+
+exit:
+ return;
+}
+
+} // namespace MeshCoP
+} // namespace Thread
diff --git a/src/core/meshcop/dataset_manager_ftd.hpp b/src/core/meshcop/dataset_manager_ftd.hpp
new file mode 100644
index 000000000..c14b5ae47
--- /dev/null
+++ b/src/core/meshcop/dataset_manager_ftd.hpp
@@ -0,0 +1,95 @@
+/*
+ * 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 includes definitions for managing MeshCoP Datasets.
+ *
+ */
+
+#ifndef MESHCOP_DATASET_MANAGER_FTD_HPP_
+#define MESHCOP_DATASET_MANAGER_FTD_HPP_
+
+#include
+
+#include
+
+namespace Thread {
+
+class ThreadNetif;
+
+namespace MeshCoP {
+
+class ActiveDataset: public ActiveDatasetBase
+{
+public:
+ ActiveDataset(ThreadNetif &aThreadNetif);
+
+ void StartLeader(void);
+
+ void StopLeader(void);
+
+private:
+ static void HandleGet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
+ const otMessageInfo *aMessageInfo);
+ void HandleGet(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+
+ static void HandleSet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
+ const otMessageInfo *aMessageInfo);
+ void HandleSet(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+
+ Coap::Resource mResourceGet;
+ Coap::Resource mResourceSet;
+};
+
+class PendingDataset: public PendingDatasetBase
+{
+public:
+ PendingDataset(ThreadNetif &aThreadNetif);
+
+ void StartLeader(void);
+
+ void StopLeader(void);
+
+private:
+ static void HandleGet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
+ const otMessageInfo *aMessageInfo);
+ void HandleGet(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+
+ static void HandleSet(void *aContext, otCoapHeader *aHeader, otMessage aMessage,
+ const otMessageInfo *aMessageInfo);
+ void HandleSet(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+
+ Coap::Resource mResourceGet;
+ Coap::Resource mResourceSet;
+};
+
+} // namespace MeshCoP
+} // namespace Thread
+
+#endif // MESHCOP_DATASET_MANAGER_HPP_
diff --git a/src/core/meshcop/dataset_manager_mtd.hpp b/src/core/meshcop/dataset_manager_mtd.hpp
new file mode 100644
index 000000000..1cc1400a0
--- /dev/null
+++ b/src/core/meshcop/dataset_manager_mtd.hpp
@@ -0,0 +1,69 @@
+/*
+ * 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 includes definitions for managing MeshCoP Datasets.
+ *
+ */
+
+#ifndef MESHCOP_DATASET_MANAGER_MTD_HPP_
+#define MESHCOP_DATASET_MANAGER_MTD_HPP_
+
+#include
+
+namespace Thread {
+
+class ThreadNetif;
+
+namespace MeshCoP {
+
+class ActiveDataset: public ActiveDatasetBase
+{
+public:
+ ActiveDataset(ThreadNetif &aThreadNetif) : ActiveDatasetBase(aThreadNetif) { }
+
+ void StartLeader(void) { }
+
+ void StopLeader(void) { }
+};
+
+class PendingDataset: public PendingDatasetBase
+{
+public:
+ PendingDataset(ThreadNetif &aThreadNetif) : PendingDatasetBase(aThreadNetif) { }
+
+ void StartLeader(void) { }
+
+ void StopLeader(void) { }
+};
+
+} // namespace MeshCoP
+} // namespace Thread
+
+#endif // MESHCOP_DATASET_MANAGER_HPP_