add wdm update in wdm

test instructions:
./boostrap
setup btvirt:
sudo ./build/x86_64-unknown-linux-gnu/third_party/bluez/repo/emulator/btvirt -L -l2
peripheral:
sudo ./output/x86_64-unknown-linux-gnu/bin/mock-device --enable-bluez-peripheral --peripheral-name N0003 --peripheral-address 00:AA:01:00:00:23 --wdm-simple-update-server --test-case 1 --total-count 0
central:
weave-device-mgr > ble-adapter-select 00:AA:01:01:00:24
weave-device-mgr > ble-scan-connect -t 120 00:AA:01:00:00:23
weave-device-mgr > connect -b -p TEST
weave-device-mgr (1 @ ::) > setup-dm-session
weave-device-mgr (1 @ ::) > set-active-locale US
weave-device-mgr (1 @ ::) > teardown-dm-session
diff --git a/src/device-manager/WeaveDeviceManager.cpp b/src/device-manager/WeaveDeviceManager.cpp
index ec1a6a8..23c422e 100644
--- a/src/device-manager/WeaveDeviceManager.cpp
+++ b/src/device-manager/WeaveDeviceManager.cpp
@@ -32,6 +32,8 @@
 #include <errno.h>
 #include <time.h>
 
+#include <Weave/Profiles/data-management/Current/WdmManagedNamespace.h>
+
 #include <Weave/Core/WeaveCore.h>
 #include <Weave/Support/Base64.h>
 #include <Weave/Support/CodeUtils.h>
@@ -42,8 +44,10 @@
 #include <Weave/Profiles/network-provisioning/NetworkProvisioning.h>
 #include <Weave/Profiles/service-provisioning/ServiceProvisioning.h>
 #include <Weave/Profiles/fabric-provisioning/FabricProvisioning.h>
+#include <Weave/Profiles/data-management/DataManagement.h>
 #include <Weave/Profiles/device-description/DeviceDescription.h>
 #include <Weave/Profiles/device-control/DeviceControl.h>
+#include <Weave/Profiles/locale/LocaleSettingsTrait.h>
 #include <Weave/Profiles/vendor/nestlabs/device-description/NestProductIdentifiers.hpp>
 #include <Weave/Profiles/security/WeaveSecurity.h>
 #include <Weave/Profiles/security/WeaveAccessToken.h>
@@ -58,12 +62,44 @@
 #include <Weave/Profiles/vendor/nestlabs/dropcam-legacy-pairing/DropcamLegacyPairing.h>
 
 namespace nl {
+    namespace Weave {
+        namespace Profiles {
+            namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) {
+
+            SubscriptionEngine * SubscriptionEngine::GetInstance()
+            {
+                static SubscriptionEngine *gSubscriptionEngine = NULL;
+                return gSubscriptionEngine;
+            }
+
+            namespace Platform {
+                // For unit tests, a dummy critical section is sufficient.
+                void CriticalSectionEnter()
+                {
+                    return;
+                }
+
+                void CriticalSectionExit()
+                {
+                    return;
+                }
+
+            } // Platform
+
+        } // WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current)
+    } // Profiles
+} // Weave
+} // nl
+
+namespace nl {
 namespace Weave {
 namespace DeviceManager {
 
 using namespace nl::Weave::Encoding;
 using namespace nl::Weave::Profiles;
+using namespace nl::Weave::Profiles::DataManagement;
 using namespace nl::Weave::Profiles::DeviceDescription;
+using namespace nl::Weave::Profiles::Locale;
 using namespace nl::Weave::Profiles::NetworkProvisioning;
 using namespace nl::Weave::Profiles::Security;
 using namespace nl::Weave::Profiles::ServiceProvisioning;
@@ -73,10 +109,13 @@
 using namespace nl::Weave::Profiles::Vendor::Nestlabs::Thermostat;
 using namespace nl::Weave::TLV;
 
+const nl::Weave::ExchangeContext::Timeout kResponseTimeoutMsec = 15000;
+
 static bool IsProductWildcard(uint16_t productId);
 
 static const uint32_t ENUMERATED_NODES_LIST_INITIAL_SIZE = 256;
 
+
 WeaveDeviceManager *WeaveDeviceManager::sListeningDeviceMgr = NULL;
 
 WeaveDeviceManager::WeaveDeviceManager()
@@ -5042,6 +5081,291 @@
     return WEAVE_NO_ERROR;
 }
 
+WeaveDeviceManager::WDMDMClient::WDMDMClient() :
+        mBuf(NULL),
+        mSinkCatalog(ResourceIdentifier(ResourceIdentifier::SELF_NODE_ID),
+                     mSinkCatalogStore, sizeof(mSinkCatalogStore) / sizeof(mSinkCatalogStore[0]))
+{
+    mPathList.Init(mStorage, ArraySize(mStorage));
+
+    mSinkCatalog.Add(0, &mLocaleSettingsTraitUpdatableDataSink, mTraitHandleSet[kLocaleSettingsSinkIndex]);
+
+    mLocaleSettingsTraitUpdatableDataSink.SetUpdateEncoder(&mEncoder);
+}
+
+WeaveDeviceManager::WDMDMClient::~WDMDMClient(void)
+{
+    mDeviceMgr = NULL;
+    mpBinding = NULL;
+    mDeviceId = kNodeIdNotSpecified ;
+}
+
+WEAVE_ERROR WeaveDeviceManager::WDMDMClient::Setup(WeaveDeviceManager *apDeviceMgr, WeaveExchangeManager *aExchangeMgr, uint64_t aDeviceId)
+{
+    WEAVE_ERROR err = WEAVE_NO_ERROR;
+    mDeviceMgr = apDeviceMgr;
+    mDeviceId = aDeviceId;
+    if (NULL == mpBinding)
+    {
+        mpBinding = aExchangeMgr->NewBinding(BindingEventCallback, this);
+        VerifyOrExit(NULL != mpBinding, err = WEAVE_ERROR_NO_MEMORY);
+
+        if (mpBinding->CanBePrepared())
+        {
+            err = mpBinding->RequestPrepare();
+            SuccessOrExit(err);
+        }
+    }
+exit:
+    return err;
+}
+
+void WeaveDeviceManager::WDMDMClient::TearDown()
+{
+    if (mBuf != NULL)
+    {
+        PacketBuffer::Free(mBuf);
+        mBuf = 0;
+    }
+}
+
+void WeaveDeviceManager::WDMDMClient::BindingEventCallback (void * const apAppState, const nl::Weave::Binding::EventType aEvent,
+                                                            const nl::Weave::Binding::InEventParam & aInParam, nl::Weave::Binding::OutEventParam & aOutParam)
+{
+
+    WEAVE_ERROR err = WEAVE_NO_ERROR;
+
+    WeaveLogDetail(DeviceManager, "%s: Event(%d)", __func__, aEvent);
+
+    WDMDMClient * const pWDMDMClient = reinterpret_cast<WDMDMClient *>(apAppState);
+
+    switch (aEvent)
+    {
+        case nl::Weave::Binding::kEvent_PrepareRequested:
+            WeaveLogDetail(DeviceManager, "kEvent_PrepareRequested");
+            err = pWDMDMClient->PrepareBinding(pWDMDMClient->mDeviceMgr->mDeviceCon);
+            SuccessOrExit(err);
+            break;
+
+        case nl::Weave::Binding::kEvent_PrepareFailed:
+            err = aInParam.PrepareFailed.Reason;
+            WeaveLogDetail(DeviceManager, "kEvent_PrepareFailed: reason");
+            break;
+
+        case nl::Weave::Binding::kEvent_BindingFailed:
+            err = aInParam.BindingFailed.Reason;
+            WeaveLogDetail(DeviceManager, "kEvent_BindingFailed: reason");
+            break;
+
+        case nl::Weave::Binding::kEvent_BindingReady:
+            WeaveLogDetail(DeviceManager, "kEvent_BindingReady");
+
+            WeaveLogProgress(DeviceManager, "%s", __PRETTY_FUNCTION__);
+
+            break;
+
+        case nl::Weave::Binding::kEvent_DefaultCheck:
+            WeaveLogDetail(DeviceManager, "kEvent_DefaultCheck");
+
+        default:
+            nl::Weave::Binding::DefaultEventHandler(apAppState, aEvent, aInParam, aOutParam);
+    }
+
+exit:
+    if (err != WEAVE_NO_ERROR)
+    {
+        WeaveLogDetail(DeviceManager, "error in BindingEventCallback");
+        pWDMDMClient->mpBinding->Release();
+        pWDMDMClient->mpBinding = NULL;
+    }
+
+    if (pWDMDMClient)
+    {
+        pWDMDMClient->mDeviceMgr->ClearOpState();
+        pWDMDMClient->mDeviceMgr->mOnComplete.General(pWDMDMClient->mDeviceMgr, pWDMDMClient->mDeviceMgr->mAppReqState);
+    }
+}
+
+void WeaveDeviceManager::WDMDMClient::UpdateEventCallback (void * const aAppState, UpdateClient::EventType aEvent, const UpdateClient::InEventParam & aInParam, UpdateClient::OutEventParam & aOutParam)
+{
+    WDMDMClient * const pWDMDMClient = reinterpret_cast<WDMDMClient *>(aAppState);
+
+    switch (aEvent)
+    {
+        case UpdateClient::kEvent_UpdateComplete:
+            WeaveLogDetail(DeviceManager, "Client->kEvent_UpdateComplete");
+            if ((aInParam.UpdateComplete.Reason == WEAVE_NO_ERROR) && (nl::Weave::Profiles::Common::kStatus_Success == aInParam.UpdateComplete.StatusReportPtr->mStatusCode))
+            {
+                WeaveLogDetail(DeviceManager, "Good Iteration, Update: path result: success");
+            }
+            else
+            {
+                WeaveLogDetail(DeviceManager, "Update: path failed: %s",
+                               ErrorStr(aInParam.UpdateComplete.Reason));
+            }
+            break;
+
+        default:
+            WeaveLogDetail(DeviceManager, "Unknown UpdateClient event: %d", aEvent);
+            break;
+    }
+
+    if (pWDMDMClient)
+    {
+        pWDMDMClient->mDeviceMgr->ClearOpState();
+        pWDMDMClient->mDeviceMgr->mOnComplete.General(pWDMDMClient->mDeviceMgr, pWDMDMClient->mDeviceMgr->mAppReqState);
+    }
+}
+
+void WeaveDeviceManager::WDMDMClient::InitEncoderContext(void)
+{
+    if (NULL == mBuf)
+    {
+        mBuf = PacketBuffer::New(0);
+        VerifyOrExit(mBuf != NULL, );
+    }
+
+    mBuf->SetDataLength(0);
+
+    mContext.mBuf = mBuf;
+    mContext.mMaxPayloadSize = mBuf->AvailableDataLength();
+    mContext.mUpdateRequestIndex = 7;
+    mContext.mExpiryTimeMicroSecond = 0;
+    mContext.mItemInProgress = 0;
+    mContext.mNextDictionaryElementPathHandle = kNullPropertyPathHandle;
+    mContext.mInProgressUpdateList = &mPathList;
+    mContext.mDataSinkCatalog = &mSinkCatalog;
+
+exit:
+    return;
+}
+
+WEAVE_ERROR WeaveDeviceManager::WDMDMClient::UpdateAndSendLeaf(void)
+{
+    WEAVE_ERROR err = WEAVE_NO_ERROR;
+
+    mTP = {
+            mTraitHandleSet[kLocaleSettingsSinkIndex],
+            CreatePropertyPathHandle(LocaleSettingsTrait::kPropertyHandle_active_locale)
+    };
+
+    err = mPathList.AddItem(mTP);
+    SuccessOrExit(err);
+
+    InitEncoderContext();
+
+    err = mEncoder.EncodeRequest(mContext);
+    SuccessOrExit(err);
+    err = mUpdateClient.SendUpdate(false, mBuf, true);
+    mBuf = NULL;
+    SuccessOrExit(err);
+
+exit:
+    if (NULL != mBuf)
+    {
+        PacketBuffer::Free(mBuf);
+        mBuf = NULL;
+    }
+
+    if (err == WEAVE_ERROR_BUFFER_TOO_SMALL)
+    {
+        WeaveLogDetail(DataManagement, "illegal oversized trait property is too big to fit in the packet");
+    }
+
+    return err;
+}
+
+WEAVE_ERROR WeaveDeviceManager::WDMDMClient::UpdateAndSendRoot(void)
+{
+    WEAVE_ERROR err = WEAVE_NO_ERROR;
+
+    mTP = {
+            mTraitHandleSet[kLocaleSettingsSinkIndex],
+            kRootPropertyPathHandle
+    };
+
+    err = mPathList.AddItem(mTP);
+    SuccessOrExit(err);
+
+    InitEncoderContext();
+
+    err = mEncoder.EncodeRequest(mContext);
+    SuccessOrExit(err);
+    err = mUpdateClient.SendUpdate(false, mBuf, true);
+    mBuf = NULL;
+    SuccessOrExit(err);
+
+exit:
+    if (NULL != mBuf)
+    {
+        PacketBuffer::Free(mBuf);
+        mBuf = NULL;
+    }
+
+    if (err == WEAVE_ERROR_BUFFER_TOO_SMALL)
+    {
+        WeaveLogDetail(DataManagement, "illegal oversized trait property is too big to fit in the packet");
+    }
+
+    return err;
+}
+
+WEAVE_ERROR WeaveDeviceManager::WDMDMClient::PrepareBinding(WeaveConnection *apDeviceCon)
+{
+    WEAVE_ERROR err = WEAVE_NO_ERROR;
+
+    //VerifyOrExit(apDeviceCon != NULL, err = WEAVE_ERROR_INCORRECT_STATE);
+
+//0x18B4300000000002ull
+    Binding::Configuration bindingConfig = mpBinding->BeginConfiguration()
+            .Target_NodeId(mDeviceId)
+            .Security_None()
+            .Transport_ExistingConnection(apDeviceCon)
+            .Exchange_ResponseTimeoutMsec(kResponseTimeoutMsec);
+    err = bindingConfig.PrepareBinding();
+    //SuccessOrExit(err);
+
+    return err;
+}
+
+WEAVE_ERROR WeaveDeviceManager::SetupDMSession(void* appReqState, CompleteFunct onComplete, ErrorFunct onError)
+{
+    uint64_t deviceId = kNodeIdNotSpecified;
+    GetDeviceId(deviceId);
+
+    mWDMDMClient.Setup(this, mExchangeMgr, deviceId);
+    //WeaveLogProgress(DeviceManager, "%s", __PRETTY_FUNCTION__);
+
+    return WEAVE_NO_ERROR;
+}
+
+WEAVE_ERROR WeaveDeviceManager::TearDownDMSession(void* appReqState, CompleteFunct onComplete, ErrorFunct onError)
+{
+    mWDMDMClient.TearDown();
+    WeaveLogProgress(DeviceManager, "%s", __PRETTY_FUNCTION__);
+
+    ClearOpState();
+    mOnComplete.General(this, mAppReqState);
+
+    return WEAVE_NO_ERROR;
+}
+
+WEAVE_ERROR WeaveDeviceManager::WDMDMClient::InitUpdateClient(void)
+{
+    mUpdateClient.Init(mpBinding, this, UpdateEventCallback);
+    mPathList.Clear();
+    return WEAVE_NO_ERROR;
+}
+
+WEAVE_ERROR WeaveDeviceManager::SetActiveLocale(void* appReqState, const char *aLocale, CompleteFunct onComplete, ErrorFunct onError)
+{
+    mWDMDMClient.InitUpdateClient();
+    mWDMDMClient.mLocaleSettingsTraitUpdatableDataSink.Mutate();
+    mWDMDMClient.UpdateAndSendLeaf();
+
+    return WEAVE_NO_ERROR;
+}
+
 bool IsProductWildcard(uint16_t productId)
 {
     return (productId >= kProductWildcardId_RangeStart && productId <= kProductWildcardId_RangeEnd);
diff --git a/src/device-manager/WeaveDeviceManager.h b/src/device-manager/WeaveDeviceManager.h
index 9633d87..33bd2b4 100644
--- a/src/device-manager/WeaveDeviceManager.h
+++ b/src/device-manager/WeaveDeviceManager.h
@@ -27,11 +27,16 @@
 #ifndef __WEAVEDEVICEMANAGER_H
 #define __WEAVEDEVICEMANAGER_H
 
+#include <Weave/Profiles/data-management/Current/WdmManagedNamespace.h>
+
 #include <Weave/Support/NLDLLUtil.h>
 #include <Weave/Core/WeaveCore.h>
 #include <Weave/Core/WeaveTLV.h>
 #include <Weave/Profiles/common/WeaveMessage.h>
+#include <Weave/Profiles/data-management/DataManagement.h>
 #include <Weave/Profiles/device-description/DeviceDescription.h>
+#include <Weave/Profiles/locale/LocaleProfile.hpp>
+#include <Weave/Profiles/locale/MockSinkTrait.h>
 #include <Weave/Profiles/network-provisioning/NetworkProvisioning.h>
 #include <Weave/Profiles/network-provisioning/NetworkInfo.h>
 #include <Weave/Profiles/security/WeaveSecurity.h>
@@ -48,6 +53,7 @@
 namespace DeviceManager {
 
 using namespace nl::Weave::Profiles;
+using namespace nl::Weave::Profiles::DataManagement;
 using namespace nl::Weave::Profiles::DeviceDescription;
 using namespace nl::Weave::Profiles::Vendor::Nestlabs::DropcamLegacyPairing;
 using namespace nl::Weave::Profiles::NetworkProvisioning;
@@ -100,7 +106,7 @@
     } State;                        // [READ-ONLY] Current state
 
     WeaveDeviceManager();
-
+    WeaveConnection *mDeviceCon;
     void *AppState;
 
     WEAVE_ERROR Init(WeaveExchangeManager *exchangeMsg, WeaveSecurityManager *securityMgr);
@@ -234,6 +240,13 @@
     WEAVE_ERROR StartSystemTest(void* appReqState, uint32_t profileId, uint32_t testId, CompleteFunct onComplete, ErrorFunct onError);
     WEAVE_ERROR StopSystemTest(void* appReqState, CompleteFunct onComplete, ErrorFunct onError);
 
+    // ----- Data Management -----
+    WEAVE_ERROR SetupDMSession(void* appReqState, CompleteFunct onComplete, ErrorFunct onError);
+    WEAVE_ERROR TearDownDMSession(void* appReqState, CompleteFunct onComplete, ErrorFunct onError);
+
+    // ----- Locale -----
+    WEAVE_ERROR SetActiveLocale(void* appReqState, const char *aLocale, CompleteFunct onComplete, ErrorFunct onError);
+
     // ---- Token Pairing ----
     WEAVE_ERROR PairToken(const uint8_t *pairingToken, uint32_t pairingTokenLen, void* appReqState, PairTokenCompleteFunct onComplete, ErrorFunct onError);
     WEAVE_ERROR UnpairToken(void* appReqState, UnpairTokenCompleteFunct onComplete, ErrorFunct onError);
@@ -297,7 +310,10 @@
         kOpState_UnpairToken                            = 41,
         kOpState_GetCameraAuthData                      = 42,
         kOpState_EnumerateDevices                       = 43,
-        kOpState_RemotePassiveRendezvousTimedOut        = 44
+        kOpState_RemotePassiveRendezvousTimedOut        = 44,
+        kOpState_SetupDMSession                         = 45,
+        kOpState_TearDownDMSession                      = 46,
+        kOpState_SetActiveLocale                        = 47,
     };
 
     enum ConnectionState
@@ -346,12 +362,77 @@
         kCertDecodeBufferSize = 1024
     };
 
+    class WDMDMClient
+    {
+    public:
+        WDMDMClient(void);
+
+        ~WDMDMClient(void);
+
+        WEAVE_ERROR Setup(WeaveDeviceManager *apDeviceMgr, WeaveExchangeManager *aExchangeMgr, uint64_t aDeviceId);
+
+        void TearDown();
+
+        WEAVE_ERROR InitUpdateClient(void);
+
+        WEAVE_ERROR UpdateAndSendLeaf(void);
+
+        WEAVE_ERROR UpdateAndSendRoot(void);
+
+        // The Trait instances
+        LocaleSettingsTraitUpdatableDataSink mLocaleSettingsTraitUpdatableDataSink;
+
+    private:
+        Binding * mpBinding;
+        UpdateClient mUpdateClient;
+        // The encoder
+        UpdateEncoder mEncoder;
+        UpdateEncoder::Context mContext;
+
+        // These are here for convenience
+        PacketBuffer *mBuf;
+        TraitPath mTP;
+
+        //
+        // The state usually held by the SubscriptionClient
+        //
+
+        // The list of path to encode
+        TraitPathStore mPathList;
+        TraitPathStore::Record mStorage[10];
+
+        // The catalog
+        SingleResourceSinkTraitCatalog mSinkCatalog;
+        SingleResourceSinkTraitCatalog::CatalogItem mSinkCatalogStore[9];
+
+        // The set of TraitDataHandles assigned by the catalog
+        // to the Trait instances
+        enum {
+            kLocaleSettingsSinkIndex,
+            kMaxNumTraitHandles,
+        };
+        TraitDataHandle mTraitHandleSet[kMaxNumTraitHandles];
+
+        void InitEncoderContext(void);
+
+        WEAVE_ERROR PrepareBinding(WeaveConnection *apDeviceCon);
+        static void BindingEventCallback(void * const apAppState, const nl::Weave::Binding::EventType aEvent,
+                                  const nl::Weave::Binding::InEventParam & aInParam,
+                                  nl::Weave::Binding::OutEventParam & aOutParam);
+
+        static void UpdateEventCallback (void * const aAppState, UpdateClient::EventType aEvent,
+                const UpdateClient::InEventParam & aInParam, UpdateClient::OutEventParam & aOutParam);
+    private:
+        WeaveDeviceManager *mDeviceMgr;
+        uint64_t mDeviceId;
+    };
+
     System::Layer* mSystemLayer;
     WeaveMessageLayer *mMessageLayer;
     WeaveExchangeManager *mExchangeMgr;
     WeaveSecurityManager *mSecurityMgr;
     ConnectionState mConState;
-    WeaveConnection *mDeviceCon;
+
     OpState mOpState;
     void *mAppReqState;
     union
@@ -422,6 +503,7 @@
     uint64_t *mEnumeratedNodes;
     uint32_t mEnumeratedNodesLen;
     uint32_t mEnumeratedNodesMaxLen;
+    WDMDMClient mWDMDMClient;
 
     // Use by static HandleConnectionReceived callback.
     static WeaveDeviceManager *sListeningDeviceMgr;
diff --git a/src/device-manager/python/WeaveDeviceManager-ScriptBinding.cpp b/src/device-manager/python/WeaveDeviceManager-ScriptBinding.cpp
index 0a4c5ae..ca01577 100644
--- a/src/device-manager/python/WeaveDeviceManager-ScriptBinding.cpp
+++ b/src/device-manager/python/WeaveDeviceManager-ScriptBinding.cpp
@@ -59,7 +59,7 @@
 using namespace nl::Weave;
 using namespace nl::Weave::DeviceManager;
 using namespace nl::Weave::Profiles::NetworkProvisioning;
-
+using namespace nl::Weave::Profiles::DataManagement;
 using DeviceDescription::IdentifyDeviceCriteria;
 
 extern "C" {
@@ -237,6 +237,9 @@
     NL_DLL_EXPORT WEAVE_ERROR nl_Weave_DeviceManager_ArmFailSafe(WeaveDeviceManager *devMgr, uint8_t armMode, uint32_t failSafeToken, CompleteFunct onComplete, ErrorFunct onError);
     NL_DLL_EXPORT WEAVE_ERROR nl_Weave_DeviceManager_DisarmFailSafe(WeaveDeviceManager *devMgr, CompleteFunct onComplete, ErrorFunct onError);
     NL_DLL_EXPORT WEAVE_ERROR nl_Weave_DeviceManager_ResetConfig(WeaveDeviceManager *devMgr, uint16_t resetFlags, CompleteFunct onComplete, ErrorFunct onError);
+    NL_DLL_EXPORT WEAVE_ERROR nl_Weave_DeviceManager_SetupDMSession(WeaveDeviceManager *devMgr, CompleteFunct onComplete, ErrorFunct onError);
+    NL_DLL_EXPORT WEAVE_ERROR nl_Weave_DeviceManager_TearDownDMSession(WeaveDeviceManager *devMgr, CompleteFunct onComplete, ErrorFunct onError);
+    NL_DLL_EXPORT WEAVE_ERROR nl_Weave_DeviceManager_SetActiveLocale(WeaveDeviceManager *devMgr, const char *aLocale, CompleteFunct onComplete, ErrorFunct onError);
     NL_DLL_EXPORT WEAVE_ERROR nl_Weave_DeviceManager_PairToken(WeaveDeviceManager *devMgr, const uint8_t *pairingToken, uint32_t pairingTokenLen, PairTokenCompleteFunct onComplete, ErrorFunct onError);
     NL_DLL_EXPORT WEAVE_ERROR nl_Weave_DeviceManager_UnpairToken(WeaveDeviceManager *devMgr, UnpairTokenCompleteFunct onComplete, ErrorFunct onError);
     NL_DLL_EXPORT WEAVE_ERROR nl_Weave_DeviceManager_StartSystemTest(WeaveDeviceManager *devMgr, uint32_t profileId, uint32_t testId, CompleteFunct onComplete, ErrorFunct onError);
@@ -1095,6 +1098,21 @@
     return devMgr->ResetConfig(resetFlags, NULL, onComplete, onError);
 }
 
+WEAVE_ERROR nl_Weave_DeviceManager_SetupDMSession(WeaveDeviceManager *devMgr, CompleteFunct onComplete, ErrorFunct onError)
+{
+    return devMgr->SetupDMSession(NULL, onComplete, onError);
+}
+
+WEAVE_ERROR nl_Weave_DeviceManager_TearDownDMSession(WeaveDeviceManager *devMgr, CompleteFunct onComplete, ErrorFunct onError)
+{
+    return devMgr->TearDownDMSession(NULL, onComplete, onError);
+}
+
+WEAVE_ERROR nl_Weave_DeviceManager_SetActiveLocale(WeaveDeviceManager *devMgr, const char *aLocale, CompleteFunct onComplete, ErrorFunct onError)
+{
+    return devMgr->SetActiveLocale(NULL, aLocale, onComplete, onError);
+}
+
 WEAVE_ERROR nl_Weave_DeviceManager_StartSystemTest(WeaveDeviceManager *devMgr, uint32_t profileId, uint32_t testId, CompleteFunct onComplete, ErrorFunct onError)
 {
     return devMgr->StartSystemTest(NULL, profileId, testId, onComplete, onError);
diff --git a/src/device-manager/python/WeaveDeviceMgr.py b/src/device-manager/python/WeaveDeviceMgr.py
index 450b5b9..0df5a82 100644
--- a/src/device-manager/python/WeaveDeviceMgr.py
+++ b/src/device-manager/python/WeaveDeviceMgr.py
@@ -1073,6 +1073,24 @@
             lambda: _dmLib.nl_Weave_DeviceManager_StopSystemTest(self.devMgr, self.cbHandleComplete, self.cbHandleError)
         )
 
+    def SetupDMSession(self):
+        self._CallDevMgrAsync(
+            lambda: _dmLib.nl_Weave_DeviceManager_SetupDMSession(self.devMgr, self.cbHandleComplete, self.cbHandleError)
+        )
+
+    def TearDownDMSession(self):
+        self._CallDevMgrAsync(
+            lambda: _dmLib.nl_Weave_DeviceManager_TearDownDMSession(self.devMgr, self.cbHandleComplete, self.cbHandleError)
+        )
+
+    def SetActiveLocale(self, locale):
+        if locale is not None and '\x00' in locale:
+            raise ValueError('Unexpected NUL character in locale')
+
+        self._CallDevMgrAsync(
+            lambda: _dmLib.nl_Weave_DeviceManager_SetActiveLocale(self.devMgr, locale, self.cbHandleComplete, self.cbHandleError)
+        )
+
     # ----- Private Members -----
     def _InitLib(self):
         global _dmLib
@@ -1300,6 +1318,15 @@
             _dmLib.nl_Weave_DeviceManager_StopSystemTest.argtypes = [ c_void_p, _CompleteFunct, _ErrorFunct ]
             _dmLib.nl_Weave_DeviceManager_StopSystemTest.restype = c_uint32
 
+            _dmLib.nl_Weave_DeviceManager_SetupDMSession.argtypes = [ c_void_p, _CompleteFunct, _ErrorFunct ]
+            _dmLib.nl_Weave_DeviceManager_SetupDMSession.restype = c_uint32
+
+            _dmLib.nl_Weave_DeviceManager_TearDownDMSession.argtypes = [ c_void_p, _CompleteFunct, _ErrorFunct ]
+            _dmLib.nl_Weave_DeviceManager_TearDownDMSession.restype = c_uint32
+
+            _dmLib.nl_Weave_DeviceManager_SetActiveLocale.argtypes = [ c_void_p, c_char_p, _CompleteFunct, _ErrorFunct ]
+            _dmLib.nl_Weave_DeviceManager_SetActiveLocale.restype = c_uint32
+
         res = _dmLib.nl_Weave_DeviceManager_Init()
         if (res != 0):
             raise self._ErrorToException(res)
diff --git a/src/device-manager/python/weave-device-mgr.py b/src/device-manager/python/weave-device-mgr.py
index 5843c79..cb2ff5d 100755
--- a/src/device-manager/python/weave-device-mgr.py
+++ b/src/device-manager/python/weave-device-mgr.py
@@ -269,6 +269,9 @@
         'ble-read',
         'start-system-test',
         'stop-system-test',
+        'setup-dm-session',
+        'teardown-dm-session',
+        'set-active-locale',
         'ble-scan-connect',
         'pair-token',
         'unpair-token',
@@ -2387,6 +2390,71 @@
 
         print "Stop system test complete"
 
+    def do_setupdmsession(self, line):
+        """
+          setup-dm-session
+
+          Setup Binding for weave data management
+        """
+
+        args = shlex.split(line)
+
+        if (len(args) != 0):
+            print "Usage:"
+            self.do_help('stop-system-test')
+            return
+
+        try:
+            self.devMgr.SetupDMSession()
+        except WeaveDeviceMgr.DeviceManagerException, ex:
+            print str(ex)
+            return
+
+        print "Setup weave data management binding complete"
+
+    def do_teardowndmsession(self, line):
+        """
+          teardown-dm-session
+
+          Teardown Binding for weave data management
+        """
+
+        args = shlex.split(line)
+
+        if (len(args) != 0):
+            print "Usage:"
+            self.do_help('stop-system-test')
+            return
+
+        try:
+            self.devMgr.TearDownDMSession()
+        except WeaveDeviceMgr.DeviceManagerException, ex:
+            print str(ex)
+            return
+
+        print "Teardown weave data management binding complete"
+
+    def do_setactivelocale(self, line):
+        """
+          set-active-locale <locale>
+          Set the device's active locale.
+        """
+
+        args = shlex.split(line)
+
+        if (len(args) != 1):
+            print "Usage:"
+            self.do_help('set-active-locale')
+            return
+
+        try:
+            self.devMgr.SetActiveLocale(args[0])
+        except WeaveDeviceMgr.DeviceManagerException, ex:
+            print str(ex)
+            return
+
+        print "Set active locale complete"
+
     def do_history(self, line):
         """
         history
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index 84a2835..7f64b9c 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -692,7 +692,8 @@
 nl_public_WeaveProfiles_locale_header_sources = \
 $(nl_public_WeaveProfiles_source_dirstem)/locale/LocaleProfile.hpp \
 $(nl_public_WeaveProfiles_source_dirstem)/locale/LocaleStatus.hpp \
-$(nl_public_WeaveProfiles_source_dirstem)/locale/LocaleTags.hpp \
+$(nl_public_WeaveProfiles_source_dirstem)/locale/LocaleSettingsTrait.h \
+$(nl_public_WeaveProfiles_source_dirstem)/locale/MockSinkTrait.h \
 $(NULL)
 
 nl_public_WeaveProfiles_network_provisioning_header_sources = \
diff --git a/src/lib/profiles/WeaveProfiles.am b/src/lib/profiles/WeaveProfiles.am
index 18fe494..09a7f1f 100644
--- a/src/lib/profiles/WeaveProfiles.am
+++ b/src/lib/profiles/WeaveProfiles.am
@@ -102,6 +102,8 @@
     @top_builddir@/src/lib/profiles/weave-tunneling/WeaveTunnelCommon.cpp               \
     @top_builddir@/src/lib/profiles/weave-tunneling/WeaveTunnelConnectionMgr.cpp        \
     @top_builddir@/src/lib/profiles/weave-tunneling/WeaveTunnelControl.cpp              \
+    @top_builddir@/src/lib/profiles/locale/LocaleSettingsTrait.cpp                      \
+    @top_builddir@/src/lib/profiles/locale/MockSinkTrait.cpp                            \
     $(NULL)
 
 if WEAVE_BUILD_LEGACY_WDM
diff --git a/src/lib/profiles/locale/LocaleProfile.hpp b/src/lib/profiles/locale/LocaleProfile.hpp
index eea1b4e..7656d49 100644
--- a/src/lib/profiles/locale/LocaleProfile.hpp
+++ b/src/lib/profiles/locale/LocaleProfile.hpp
@@ -26,8 +26,8 @@
 #define WEAVE_PROFILES_LOCALE_HPP
 
 #include "LocaleStatus.hpp"
-#include "LocaleTags.hpp"
-
+#include "LocaleSettingsTrait.h"
+#include "MockSinkTrait.h"
 /**
  *   @namespace nl::Weave::Profiles::Locale
  *
diff --git a/src/lib/profiles/locale/LocaleSettingsTrait.cpp b/src/lib/profiles/locale/LocaleSettingsTrait.cpp
new file mode 100644
index 0000000..ec93952
--- /dev/null
+++ b/src/lib/profiles/locale/LocaleSettingsTrait.cpp
@@ -0,0 +1,71 @@
+/*
+ *
+ *    Copyright (c) 2017 Nest Labs, Inc.
+ *    All rights reserved.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/**
+ *    @file
+ *      THIS FILE IS GENERATED. DO NOT MODIFY.
+ *
+ *      SOURCE PROTO: weave/trait/locale/locale_settings_trait.proto
+ *
+ */
+
+#include "LocaleSettingsTrait.h"
+
+using namespace nl::Weave::Profiles::DataManagement;
+
+namespace nl {
+
+    namespace Weave {
+
+        namespace Profiles {
+            namespace Locale {
+                namespace LocaleSettingsTrait {
+                    TraitSchemaEngine::PropertyInfo gSchemaMap[] = {
+                            /*  ParentHandle                ContextTag */
+                            {kPropertyHandle_Root, 1}
+                    };
+
+                    TraitSchemaEngine TraitSchema = {
+                            {
+                                    kWeaveProfileId,
+                                    gSchemaMap,
+                                    sizeof(gSchemaMap) / sizeof(gSchemaMap[0]),
+                                    1,
+#if (TDM_EXTENSION_SUPPORT) || (TDM_VERSIONING_SUPPORT)
+                                    2,
+#endif
+#if (TDM_DICTIONARY_SUPPORT)
+                                    NULL,
+#endif
+                                    NULL,
+                                    NULL,
+                                    NULL,
+                                    NULL,
+#if (TDM_EXTENSION_SUPPORT)
+                                    NULL,
+#endif
+#if (TDM_VERSIONING_SUPPORT)
+                                    NULL,
+#endif
+                            }
+                    };
+
+                }; // LocaleSettingsTrait
+            };
+}; // Locale
+}; // Trait
+}; // Weave
diff --git a/src/lib/profiles/locale/LocaleSettingsTrait.h b/src/lib/profiles/locale/LocaleSettingsTrait.h
new file mode 100644
index 0000000..f33c522
--- /dev/null
+++ b/src/lib/profiles/locale/LocaleSettingsTrait.h
@@ -0,0 +1,66 @@
+/*
+ *
+ *    Copyright (c) 2016-2017 Nest Labs, Inc.
+ *    All rights reserved.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+/**
+ *    @file
+ *      THIS FILE IS GENERATED. DO NOT MODIFY.
+ *
+ *      SOURCE PROTO: weave/trait/locale/locale_settings_trait.proto
+ *
+ */
+
+#ifndef _LOCALE_SETTINGS_TRAIT_H
+#define _LOCALE_SETTINGS_TRAIT_H
+
+// We want and assume the default managed namespace is Current and that is, explicitly, the managed namespace this code desires.
+#include <Weave/Profiles/data-management/TraitData.h>
+
+namespace nl {
+
+    namespace Weave {
+
+        namespace Profiles {
+            namespace Locale {
+                namespace LocaleSettingsTrait {
+                    extern nl::Weave::Profiles::DataManagement::TraitSchemaEngine TraitSchema;
+
+                    enum {
+                        kWeaveProfileId = 0x00000014
+                    };
+
+                    enum {
+                        kPropertyHandle_Root = 1,
+                        /*
+                         * Root =
+                         * {
+                         *       active_locale = 1 (string),
+                         */
+                                kPropertyHandle_active_locale = 2,
+
+                        /*
+                         * }
+                         *
+                         */
+                    };
+                }; // LocaleSettingsTrait
+            }
+} // Locale
+} // Trait
+} // Weave
+
+#endif // _LOCALE_SETTINGS_TRAIT_H
diff --git a/src/lib/profiles/locale/MockSinkTrait.cpp b/src/lib/profiles/locale/MockSinkTrait.cpp
new file mode 100644
index 0000000..c39852c
--- /dev/null
+++ b/src/lib/profiles/locale/MockSinkTrait.cpp
@@ -0,0 +1,151 @@
+/*
+ *
+ *    Copyright (c) 2018 Google LLC.
+ *    Copyright (c) 2016-2017 Nest Labs, Inc.
+ *    All rights reserved.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+/**
+ *    @file
+ *      Sample mock trait data sinks that implement the simple and complex mock traits.
+ */
+
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
+
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS
+#endif
+
+#include <stdint.h>
+#include <inttypes.h>
+
+// Note that the choice of namespace alias must be made up front for each and every compile unit
+// This is because many include paths could set the default alias to unintended target.
+
+#include <Weave/Profiles/data-management/Current/WdmManagedNamespace.h>
+
+#include <Weave/Support/CodeUtils.h>
+
+#include "MockSinkTrait.h"
+
+
+using namespace ::nl::Weave;
+using namespace ::nl::Weave::TLV;
+using namespace ::nl::Weave::Profiles::DataManagement;
+
+using namespace ::nl::Weave::Profiles::Locale;
+using namespace Schema::Weave::Common;
+
+static size_t MOCK_strlcpy(char * dst, const char * src, size_t size);
+
+static size_t MOCK_strlcpy(char * dst, const char * src, size_t size)
+{
+    // note that srtncpy doesn't NUL-terminate the destination if source is too long
+    strncpy(dst, src, size - 1);
+    // forcifully NUL-terminate the destination
+    dst[size - 1] = '\0';
+    // keep compatibility with common strlcpy definition
+    return strlen(src);
+}
+
+
+MockTraitUpdatableDataSink::MockTraitUpdatableDataSink(const TraitSchemaEngine * aEngine)
+        : TraitUpdatableDataSink(aEngine)
+{
+}
+
+LocaleSettingsTraitUpdatableDataSink::LocaleSettingsTraitUpdatableDataSink()
+        : MockTraitUpdatableDataSink(&LocaleSettingsTrait::TraitSchema)
+{
+    memset(mLocale, 0, sizeof(mLocale));
+}
+
+WEAVE_ERROR
+LocaleSettingsTraitUpdatableDataSink::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader)
+{
+    WEAVE_ERROR err = WEAVE_NO_ERROR;
+
+    switch (aLeafHandle) {
+        case LocaleSettingsTrait::kPropertyHandle_active_locale:
+            char next_locale[kMaxNumOfCharsPerLocale];
+            err = aReader.GetString(next_locale, MAX_LOCALE_SIZE);
+            SuccessOrExit(err);
+            if (strncmp(next_locale, mLocale, MAX_LOCALE_SIZE) != 0)
+            {
+                WeaveLogDetail(DataManagement, "<<  active_locale is changed from \"%s\" to \"%s\"", mLocale, next_locale);
+                memcpy(mLocale, next_locale, MAX_LOCALE_SIZE);
+            }
+
+            WeaveLogDetail(DataManagement, "<<  active_locale = \"%s\"", mLocale);
+            break;
+
+        default:
+            WeaveLogDetail(DataManagement, "<<  UNKNOWN!");
+            err = WEAVE_ERROR_TLV_TAG_NOT_FOUND;
+    }
+
+    exit:
+    return err;
+}
+
+WEAVE_ERROR
+LocaleSettingsTraitUpdatableDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter)
+{
+    WEAVE_ERROR err = WEAVE_NO_ERROR;
+
+    switch (aLeafHandle) {
+        case LocaleSettingsTrait::kPropertyHandle_active_locale:
+            err = aWriter.PutString(aTagToWrite, mLocale);
+            SuccessOrExit(err);
+
+            WeaveLogDetail(DataManagement, ">>  active_locale = \"%s\"", mLocale);
+            break;
+
+        default:
+            WeaveLogDetail(DataManagement, ">>  UNKNOWN!");
+            ExitNow(err = WEAVE_ERROR_TLV_TAG_NOT_FOUND);
+    }
+
+    exit:
+    WeaveLogFunctError(err);
+
+    return err;
+}
+
+WEAVE_ERROR LocaleSettingsTraitUpdatableDataSink::Mutate(void)
+{
+    WEAVE_ERROR err = WEAVE_NO_ERROR;
+    static unsigned int whichLocale = 0;
+    static const char * locales[] = { "en-US", "zh-TW", "ja-JP", "pl-PL", "zh-CN" };
+    PropertyPathHandle pathHandle = kNullPropertyPathHandle;
+
+    MOCK_strlcpy(mLocale, locales[whichLocale], sizeof(mLocale));
+    whichLocale = (whichLocale + 1) % (sizeof(locales)/sizeof(locales[0]));
+
+
+    pathHandle = LocaleSettingsTrait::kPropertyHandle_active_locale;
+
+
+    WeaveLogDetail(DataManagement, "<set updated> in 0x%08x", pathHandle);
+
+    return err;
+}
+
+WEAVE_ERROR LocaleSettingsTraitUpdatableDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey)
+{
+    return WEAVE_END_OF_INPUT;
+}
diff --git a/src/lib/profiles/locale/MockSinkTrait.h b/src/lib/profiles/locale/MockSinkTrait.h
new file mode 100644
index 0000000..b079f0a
--- /dev/null
+++ b/src/lib/profiles/locale/MockSinkTrait.h
@@ -0,0 +1,65 @@
+/*
+ *
+ *    Copyright (c) 2016-2017 Nest Labs, Inc.
+ *    All rights reserved.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+/**
+ *    @file
+ *      Sample mock trait data sinks that implement the simple and complex mock traits.
+ *
+ */
+
+#ifndef MOCK_TRAIT_SINKS_H_
+#define MOCK_TRAIT_SINKS_H_
+#define MAX_ARRAY_LEN 10
+#define MAX_ARRAY_SIZE sizeof(char) * MAX_ARRAY_LEN
+#define MAX_LOCALE_SIZE sizeof(char) * 24
+
+// We want and assume the default managed namespace is Current and that is, explicitly, the managed namespace this code desires.
+#include <Weave/Profiles/data-management/DataManagement.h>
+#include <Weave/Profiles/data-management/SubscriptionClient.h>
+
+#include "LocaleSettingsTrait.h"
+
+#include <map>
+
+using namespace ::nl::Weave::Profiles::DataManagement_Current;
+
+class MockTraitUpdatableDataSink : public nl::Weave::Profiles::DataManagement::TraitUpdatableDataSink
+{
+public:
+    MockTraitUpdatableDataSink(const nl::Weave::Profiles::DataManagement::TraitSchemaEngine * aEngine);
+    void ResetDataSink(void) { ClearVersion(); };
+};
+
+class LocaleSettingsTraitUpdatableDataSink : public MockTraitUpdatableDataSink
+{
+public:
+    LocaleSettingsTraitUpdatableDataSink();
+    WEAVE_ERROR Mutate(void);
+private:
+    WEAVE_ERROR SetLeafData(nl::Weave::Profiles::DataManagement::PropertyPathHandle aLeafHandle, nl::Weave::TLV::TLVReader &aReader) __OVERRIDE;
+    WEAVE_ERROR GetLeafData(nl::Weave::Profiles::DataManagement::PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, nl::Weave::TLV::TLVWriter &aWriter) __OVERRIDE;
+    WEAVE_ERROR GetNextDictionaryItemKey(nl::Weave::Profiles::DataManagement::PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, nl::Weave::Profiles::DataManagement::PropertyDictionaryKey &aKey) __OVERRIDE;
+
+    enum
+    {
+        kMaxNumOfCharsPerLocale = 24
+    };
+    char mLocale[kMaxNumOfCharsPerLocale];
+};
+
+#endif // MOCK_TRAIT_SINKS_H_
diff --git a/src/test-apps/MockWdmUpdateServer.cpp b/src/test-apps/MockWdmUpdateServer.cpp
index d23f95d..21761dd 100644
--- a/src/test-apps/MockWdmUpdateServer.cpp
+++ b/src/test-apps/MockWdmUpdateServer.cpp
@@ -117,19 +117,20 @@
     uint8_t * p;
     reader.Init(payload);
     DebugPrettyPrint(reader);
-
+    WeaveLogDetail(DataManagement, "Incoming Update Request1");
     PacketBuffer * msgBuf   = PacketBuffer::NewWithAvailableSize(statusReportLen);
     VerifyOrExit(NULL != msgBuf, err = WEAVE_ERROR_NO_MEMORY);
-
+    WeaveLogDetail(DataManagement, "Incoming Update Request2");
     p = msgBuf->Start();
     nl::Weave::Encoding::LittleEndian::Write32(p, nl::Weave::Profiles::kWeaveProfile_Common);
     nl::Weave::Encoding::LittleEndian::Write16(p, nl::Weave::Profiles::Common::kStatus_Success);
     msgBuf->SetDataLength(statusReportLen);
-
-    err = ec->SendMessage(nl::Weave::Profiles::kWeaveProfile_Common, nl::Weave::Profiles::Common::kMsgType_StatusReport, msgBuf, nl::Weave::ExchangeContext::kSendFlag_RequestAck);
+    WeaveLogDetail(DataManagement, "Incoming Update Request3");
+    err = ec->SendMessage(nl::Weave::Profiles::kWeaveProfile_Common, nl::Weave::Profiles::Common::kMsgType_StatusReport, msgBuf, nl::Weave::ExchangeContext::kSendFlag_NoAutoRequestAck);
     msgBuf = NULL;
+    WeaveLogError(DataManagement, "%s at %s:%d", nl::ErrorStr(err), __FILE__, __LINE__);
     SuccessOrExit(err);
-
+    WeaveLogDetail(DataManagement, "Incoming Update Request4");
 exit:
     WeaveLogFunctError(err);
 
diff --git a/src/test-apps/mock-device.cpp b/src/test-apps/mock-device.cpp
index 12601f1..acccd5c 100644
--- a/src/test-apps/mock-device.cpp
+++ b/src/test-apps/mock-device.cpp
@@ -106,6 +106,7 @@
 static void InitiateConnection(System::Layer* aSystemLayer, void* aAppState, System::Error aError);
 static void HandleConnectionComplete(WeaveConnection *con, WEAVE_ERROR conErr);
 static void HandleWdmCompleteTest();
+static void HandleError();
 
 #if CONFIG_BLE_PLATFORM_BLUEZ
 bool EnableWeaveBluezPeripheral = false;
@@ -773,6 +774,172 @@
 
 #endif // CONFIG_BLE_PLATFORM_BLUEZ
 
+    if (gTestWdmNextOptions.mEnableMockTimestampInitialCounter)
+    {
+        EnableMockEventTimestampInitialCounter();
+    }
+
+    InitializeEventLogging(&ExchangeMgr);
+
+    switch (gMockWdmNodeOptions.mWdmRoleInTest)
+    {
+        case 0:
+            break;
+
+    #if ENABLE_VIEW_TEST
+
+        case kToolOpt_WdmSimpleViewClient:
+                if (gMockWdmNodeOptions.mWdmPublisherNodeId != kAnyNodeId)
+                {
+                    err = MockWdmViewClient::GetInstance()->Init(&ExchangeMgr, gMockWdmNodeOptions.mTestCaseId);
+                    FAIL_ERROR(err, "MockWdmViewClient.Init failed");
+                    MockWdmViewClient::GetInstance()-> onCompleteTest = HandleWdmCompleteTest;
+                }
+                else
+                {
+                    err = WEAVE_ERROR_INVALID_ARGUMENT;
+                    FAIL_ERROR(err, "Simple View Client requires node ID to some publisher");
+                }
+
+                break;
+            case kToolOpt_WdmSimpleViewServer:
+                err = MockWdmViewServer::GetInstance()->Init(&ExchangeMgr, gMockWdmNodeOptions.mTestCaseId);
+                FAIL_ERROR(err, "MockWdmViewServer.Init failed");
+                break;
+    #endif // ENABLE_VIEW_TEST
+
+        case kToolOpt_WdmSimpleUpdateClient:
+            if (gMockWdmNodeOptions.mWdmPublisherNodeId != kAnyNodeId)
+            {
+                err = MockWdmUpdateClient::GetInstance()->Init(&ExchangeMgr, 0, gWeaveSecurityMode.SecurityMode, gGroupKeyEncOptions.GetEncKeyId());
+                FAIL_ERROR(err, "MockWdmUpdateClient.Init failed");
+                err = MockWdmUpdateClient::GetInstance()->StartTesting(gMockWdmNodeOptions.mWdmPublisherNodeId, gMockWdmNodeOptions.mWdmUseSubnetId);
+                FAIL_ERROR(err, "MockWdmUpdateClient.StartTesting failed");
+
+                MockWdmUpdateClient::GetInstance()-> onCompleteTest = HandleWdmCompleteTest;
+            }
+            else
+            {
+                err = WEAVE_ERROR_INVALID_ARGUMENT;
+                FAIL_ERROR(err, "Simple Update Client requires node ID to some publisher");
+            }
+            break;
+        case kToolOpt_WdmSimpleUpdateServer:
+            err = MockWdmUpdateServer::GetInstance()->Init(&ExchangeMgr, 0);
+            FAIL_ERROR(err, "MockWdmUpdateServer.Init failed");
+            break;
+
+        case kToolOpt_WdmInitMutualSubscription:
+        case kToolOpt_WdmSubscriptionClient:
+
+            if (gMockWdmNodeOptions.mWdmPublisherNodeId != kAnyNodeId)
+            {
+                err = MockWdmSubscriptionInitiator::GetInstance()->Init(&ExchangeMgr,
+                                                                        gGroupKeyEncOptions.GetEncKeyId(),
+                                                                        gWeaveSecurityMode.SecurityMode,
+                                                                        gMockWdmNodeOptions);
+                FAIL_ERROR(err, "MockWdmSubscriptionInitiator.Init failed");
+                MockWdmSubscriptionInitiator::GetInstance()->onCompleteTest = HandleWdmCompleteTest;
+                MockWdmSubscriptionInitiator::GetInstance()->onError = HandleError;
+
+            }
+            else
+            {
+                err = WEAVE_ERROR_INVALID_ARGUMENT;
+                FAIL_ERROR(err, "MockWdmSubscriptionInitiator requires node ID to some publisher");
+            }
+
+            break;
+        case kToolOpt_WdmRespMutualSubscription:
+        case kToolOpt_WdmSubscriptionPublisher:
+            if (gMockWdmNodeOptions.mEnableRetry)
+            {
+                err = WEAVE_ERROR_INVALID_ARGUMENT;
+                FAIL_ERROR(err, "MockWdmSubcriptionResponder is incompatible with --enable-retry");
+            }
+
+            err = MockWdmSubscriptionResponder::GetInstance()->Init(&ExchangeMgr,
+                                                                    gMockWdmNodeOptions);
+            FAIL_ERROR(err, "MockWdmSubscriptionResponder.Init failed");
+            MockWdmSubscriptionResponder::GetInstance()->onCompleteTest = HandleWdmCompleteTest;
+            MockWdmSubscriptionResponder::GetInstance()->onError = HandleError;
+            if (gTestWdmNextOptions.mClearDataSinkState)
+            {
+                MockWdmSubscriptionResponder::GetInstance()->ClearDataSinkState();
+            }
+            break;
+        default:
+            err = WEAVE_ERROR_INVALID_ARGUMENT;
+            FAIL_ERROR(err, "WdmRoleInTest is invalid");
+    };
+
+    for (uint32_t iteration = 1; iteration <= gTestWdmNextOptions.mTestIterations; iteration++) {
+
+        switch (gMockWdmNodeOptions.mWdmRoleInTest) {
+            case 0:
+                break;
+
+#if ENABLE_VIEW_TEST
+            case kToolOpt_WdmSimpleViewClient:
+            if (gTestWdmNextOptions.mClearDataSinkState)
+            {
+                MockWdmViewClient::GetInstance()->ClearDataSinkState();
+            }
+
+            err = MockWdmViewClient::GetInstance()->StartTesting(WdmPublisherNodeId, WdmUseSubnetId);
+            FAIL_ERROR(err, "MockWdmViewClient.StartTesting failed");
+            break;
+
+#endif
+            case kToolOpt_WdmInitMutualSubscription:
+            case kToolOpt_WdmSubscriptionClient:
+                if (gTestWdmNextOptions.mClearDataSinkState) {
+                    MockWdmSubscriptionInitiator::GetInstance()->ClearDataSinkState();
+                }
+                err = MockWdmSubscriptionInitiator::GetInstance()->StartTesting(gMockWdmNodeOptions.mWdmPublisherNodeId,
+                                                                                gMockWdmNodeOptions.mWdmUseSubnetId);
+                if (err != WEAVE_NO_ERROR) {
+                    printf("\nMockWdmSubscriptionInitiator.StartTesting failed: %s\n", ErrorStr(err));
+                    Done = true;
+                }
+                //FAIL_ERROR(err, "MockWdmSubscriptionInitiator.StartTesting failed");
+                break;
+            default:
+                printf("TestWdmNext server is ready\n");
+        };
+
+        switch (gMockWdmNodeOptions.mEventGeneratorType) {
+            case MockWdmNodeOptions::kGenerator_None:
+                gEventGenerator = NULL;
+                break;
+            case MockWdmNodeOptions::kGenerator_TestDebug:
+                gEventGenerator = GetTestDebugGenerator();
+                break;
+            case MockWdmNodeOptions::kGenerator_TestLiveness:
+                gEventGenerator = GetTestLivenessGenerator();
+                break;
+            case MockWdmNodeOptions::kGenerator_TestSecurity:
+                gEventGenerator = GetTestSecurityGenerator();
+                break;
+            case MockWdmNodeOptions::kGenerator_TestTelemetry:
+                gEventGenerator = GetTestTelemetryGenerator();
+                break;
+            case MockWdmNodeOptions::kGenerator_TestTrait:
+                gEventGenerator = GetTestTraitGenerator();
+                break;
+            case MockWdmNodeOptions::kGenerator_NumItems:
+            default:
+                gEventGenerator = NULL;
+                break;
+        }
+
+        if (gEventGenerator != NULL) {
+            printf("Starting Event Generator\n");
+            MockEventGenerator::GetInstance()->Init(&ExchangeMgr, gEventGenerator,
+                                                    gMockWdmNodeOptions.mTimeBetweenEvents, true);
+        }
+
+    }
     while (!Done)
     {
         struct timeval sleepTime;
@@ -1076,3 +1243,8 @@
         Done = true;
     }
 }
+
+static void HandleError()
+{
+    Done = true;
+}