| /* |
| * |
| * Copyright (c) 2020 Google LLC. |
| * 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 |
| * Generic trait data sinks. |
| * WARNING: This is experimental feature for Weave Data Management Client |
| */ |
| |
| #ifndef __STDC_FORMAT_MACROS |
| #define __STDC_FORMAT_MACROS |
| #endif |
| |
| #ifndef __STDC_LIMIT_MACROS |
| #define __STDC_LIMIT_MACROS |
| #endif |
| |
| #include <stdint.h> |
| #include <inttypes.h> |
| #include <stdlib.h> |
| #include <stdint.h> |
| #include <errno.h> |
| #include <time.h> |
| #include <string> |
| |
| #include <Weave/Core/WeaveCore.h> |
| |
| #if WEAVE_CONFIG_DATA_MANAGEMENT_CLIENT_EXPERIMENTAL |
| #include <Weave/Support/Base64.h> |
| #include <Weave/Support/CodeUtils.h> |
| #include <Weave/Core/WeaveEncoding.h> |
| #include <Weave/Profiles/WeaveProfiles.h> |
| #include <Weave/Profiles/common/CommonProfile.h> |
| #include <Weave/Profiles/data-management/DataManagement.h> |
| #include <Weave/Profiles/data-management/Current/WdmManagedNamespace.h> |
| #include <Weave/Support/logging/WeaveLogging.h> |
| #include <Weave/Support/ErrorStr.h> |
| #include <Weave/Support/TimeUtils.h> |
| #include <Weave/DeviceManager/WeaveDataManagementClient.h> |
| #include <Weave/DeviceManager/TraitSchemaDirectory.h> |
| #include <Weave/Profiles/data-management/Current/GenericTraitCatalogImpl.h> |
| #include <Weave/Profiles/data-management/Current/GenericTraitCatalogImpl.ipp> |
| |
| 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; |
| using namespace ::nl::Weave::TLV; |
| using namespace Schema::Weave::Common; |
| |
| class GenericTraitUpdatableDataSink; |
| class WdmClient; |
| |
| GenericTraitUpdatableDataSink::GenericTraitUpdatableDataSink( |
| const nl::Weave::Profiles::DataManagement::TraitSchemaEngine * apEngine, WdmClient * apWdmClient) : |
| TraitUpdatableDataSink(apEngine) |
| { |
| mpWdmClient = apWdmClient; |
| } |
| |
| GenericTraitUpdatableDataSink::~GenericTraitUpdatableDataSink() |
| { |
| Clear(); |
| } |
| |
| void GenericTraitUpdatableDataSink::Clear(void) |
| { |
| SubscriptionClient * pSubscriptionClient = GetSubscriptionClient(); |
| if (pSubscriptionClient != NULL) |
| { |
| pSubscriptionClient->DiscardUpdates(); |
| } |
| ClearVersion(); |
| |
| for (auto itr = mPathTlvDataMap.begin(); itr != mPathTlvDataMap.end(); ++itr) |
| { |
| if (NULL != itr->second) |
| { |
| PacketBuffer::Free(itr->second); |
| itr->second = NULL; |
| } |
| } |
| |
| mPathTlvDataMap.clear(); |
| } |
| |
| void GenericTraitUpdatableDataSink::UpdateTLVDataMap(PropertyPathHandle aPropertyPathHandle, PacketBuffer * apMsgBuf) |
| { |
| auto it = mPathTlvDataMap.find(aPropertyPathHandle); |
| if (it != mPathTlvDataMap.end() && NULL != it->second) |
| { |
| PacketBuffer::Free(it->second); |
| } |
| mPathTlvDataMap[aPropertyPathHandle] = apMsgBuf; |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::LocateTraitHandle(void * apContext, |
| const TraitCatalogBase<TraitDataSink> * const apCatalog, |
| TraitDataHandle & aHandle) |
| { |
| GenericTraitUpdatableDataSink * pGenericTraitUpdatableDataSink = static_cast<GenericTraitUpdatableDataSink *>(apContext); |
| return apCatalog->Locate(pGenericTraitUpdatableDataSink, aHandle); |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::RefreshData(void * appReqState, DMCompleteFunct onComplete, DMErrorFunct onError) |
| { |
| ClearVersion(); |
| mpWdmClient->RefreshData(appReqState, this, onComplete, onError, LocateTraitHandle); |
| return WEAVE_NO_ERROR; |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::SetData(const char * apPath, int64_t aValue, bool aIsConditional) |
| { |
| return Set(apPath, aValue, aIsConditional); |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::SetData(const char * apPath, uint64_t aValue, bool aIsConditional) |
| { |
| return Set(apPath, aValue, aIsConditional); |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::SetData(const char * apPath, double aValue, bool aIsConditional) |
| { |
| return Set(apPath, aValue, aIsConditional); |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::SetBoolean(const char * apPath, bool aValue, bool aIsConditional) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| nl::Weave::TLV::TLVWriter writer; |
| PropertyPathHandle propertyPathHandle = kNullPropertyPathHandle; |
| PacketBuffer * pMsgBuf = PacketBuffer::New(); |
| VerifyOrExit(NULL != pMsgBuf, err = WEAVE_ERROR_NO_MEMORY); |
| |
| VerifyOrExit(GetSubscriptionClient() != NULL, err = WEAVE_ERROR_INCORRECT_STATE); |
| |
| Lock(GetSubscriptionClient()); |
| |
| err = GetSchemaEngine()->MapPathToHandle(apPath, propertyPathHandle); |
| SuccessOrExit(err); |
| |
| writer.Init(pMsgBuf); |
| |
| err = writer.PutBoolean(AnonymousTag, aValue); |
| SuccessOrExit(err); |
| |
| err = writer.Finalize(); |
| SuccessOrExit(err); |
| |
| #if WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| err = DebugPrettyPrint(pMsgBuf); |
| SuccessOrExit(err); |
| #endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| |
| UpdateTLVDataMap(propertyPathHandle, pMsgBuf); |
| pMsgBuf = NULL; |
| err = SetUpdated(GetSubscriptionClient(), propertyPathHandle, aIsConditional); |
| Unlock(GetSubscriptionClient()); |
| |
| WeaveLogDetail(DataManagement, "<set updated> in 0x%08x", propertyPathHandle); |
| |
| exit: |
| WeaveLogFunctError(err); |
| |
| if (NULL != pMsgBuf) |
| { |
| PacketBuffer::Free(pMsgBuf); |
| pMsgBuf = NULL; |
| } |
| return err; |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::SetString(const char * apPath, const char * aValue, bool aIsConditional) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| nl::Weave::TLV::TLVWriter writer; |
| PropertyPathHandle propertyPathHandle = kNullPropertyPathHandle; |
| PacketBuffer * pMsgBuf = PacketBuffer::New(); |
| VerifyOrExit(NULL != pMsgBuf, err = WEAVE_ERROR_NO_MEMORY); |
| |
| VerifyOrExit(GetSubscriptionClient() != NULL, err = WEAVE_ERROR_INCORRECT_STATE); |
| |
| Lock(GetSubscriptionClient()); |
| |
| err = GetSchemaEngine()->MapPathToHandle(apPath, propertyPathHandle); |
| SuccessOrExit(err); |
| |
| writer.Init(pMsgBuf); |
| |
| err = writer.PutString(AnonymousTag, aValue); |
| SuccessOrExit(err); |
| |
| err = writer.Finalize(); |
| SuccessOrExit(err); |
| |
| #if WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| err = DebugPrettyPrint(pMsgBuf); |
| SuccessOrExit(err); |
| #endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| |
| UpdateTLVDataMap(propertyPathHandle, pMsgBuf); |
| pMsgBuf = NULL; |
| err = SetUpdated(GetSubscriptionClient(), propertyPathHandle, aIsConditional); |
| Unlock(GetSubscriptionClient()); |
| |
| WeaveLogDetail(DataManagement, "<set updated> in 0x%08x", propertyPathHandle); |
| |
| exit: |
| WeaveLogFunctError(err); |
| |
| if (NULL != pMsgBuf) |
| { |
| PacketBuffer::Free(pMsgBuf); |
| pMsgBuf = NULL; |
| } |
| |
| return err; |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::SetBytes(const char * apPath, const uint8_t * dataBuf, size_t dataLen, |
| bool aIsConditional) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| nl::Weave::TLV::TLVWriter writer; |
| nl::Weave::TLV::TLVReader reader; |
| PropertyPathHandle propertyPathHandle = kNullPropertyPathHandle; |
| PacketBuffer * pMsgBuf = PacketBuffer::New(); |
| VerifyOrExit(NULL != pMsgBuf, err = WEAVE_ERROR_NO_MEMORY); |
| |
| VerifyOrExit(GetSubscriptionClient() != NULL, err = WEAVE_ERROR_INCORRECT_STATE); |
| |
| Lock(GetSubscriptionClient()); |
| |
| err = GetSchemaEngine()->MapPathToHandle(apPath, propertyPathHandle); |
| SuccessOrExit(err); |
| |
| writer.Init(pMsgBuf); |
| |
| reader.Init(dataBuf, dataLen); |
| reader.Next(); |
| writer.CopyElement(AnonymousTag, reader); |
| |
| err = writer.Finalize(); |
| SuccessOrExit(err); |
| |
| #if WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| err = DebugPrettyPrint(pMsgBuf); |
| SuccessOrExit(err); |
| #endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| |
| UpdateTLVDataMap(propertyPathHandle, pMsgBuf); |
| pMsgBuf = NULL; |
| err = SetUpdated(GetSubscriptionClient(), propertyPathHandle, aIsConditional); |
| Unlock(GetSubscriptionClient()); |
| |
| WeaveLogDetail(DataManagement, "<set updated> in 0x%08x", propertyPathHandle); |
| |
| exit: |
| WeaveLogFunctError(err); |
| |
| if (NULL != pMsgBuf) |
| { |
| PacketBuffer::Free(pMsgBuf); |
| pMsgBuf = NULL; |
| } |
| |
| return err; |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::SetTLVBytes(const char * apPath, const uint8_t * dataBuf, size_t dataLen, |
| bool aIsConditional) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| TLVReader reader; |
| PropertyPathHandle propertyPathHandle = kNullPropertyPathHandle; |
| TraitSchemaEngine::ISetDataDelegate * setDataDelegate = NULL; |
| |
| VerifyOrExit(GetSubscriptionClient() != NULL, err = WEAVE_ERROR_INCORRECT_STATE); |
| Lock(GetSubscriptionClient()); |
| |
| err = GetSchemaEngine()->MapPathToHandle(apPath, propertyPathHandle); |
| SuccessOrExit(err); |
| |
| reader.Init(dataBuf, dataLen); |
| err = reader.Next(); |
| SuccessOrExit(err); |
| |
| setDataDelegate = static_cast<TraitSchemaEngine::ISetDataDelegate *>(this); |
| err = GetSchemaEngine()->StoreData(propertyPathHandle, reader, setDataDelegate, NULL); |
| SuccessOrExit(err); |
| |
| err = SetUpdated(GetSubscriptionClient(), propertyPathHandle, aIsConditional); |
| |
| Unlock(GetSubscriptionClient()); |
| WeaveLogDetail(DataManagement, "<set updated> in 0x%08x", propertyPathHandle); |
| |
| exit: |
| WeaveLogFunctError(err); |
| |
| return err; |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::SetNull(const char * apPath, bool aIsConditional) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| nl::Weave::TLV::TLVWriter writer; |
| PropertyPathHandle propertyPathHandle = kNullPropertyPathHandle; |
| PacketBuffer * pMsgBuf = PacketBuffer::New(); |
| VerifyOrExit(NULL != pMsgBuf, err = WEAVE_ERROR_NO_MEMORY); |
| |
| VerifyOrExit(GetSubscriptionClient() != NULL, err = WEAVE_ERROR_INCORRECT_STATE); |
| |
| Lock(GetSubscriptionClient()); |
| |
| err = GetSchemaEngine()->MapPathToHandle(apPath, propertyPathHandle); |
| SuccessOrExit(err); |
| |
| writer.Init(pMsgBuf); |
| |
| err = writer.PutNull(AnonymousTag); |
| SuccessOrExit(err); |
| |
| err = writer.Finalize(); |
| SuccessOrExit(err); |
| |
| #if WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| err = DebugPrettyPrint(pMsgBuf); |
| SuccessOrExit(err); |
| #endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| |
| UpdateTLVDataMap(propertyPathHandle, pMsgBuf); |
| pMsgBuf = NULL; |
| err = SetUpdated(GetSubscriptionClient(), propertyPathHandle, aIsConditional); |
| Unlock(GetSubscriptionClient()); |
| |
| WeaveLogDetail(DataManagement, "<set updated> in 0x%08x", propertyPathHandle); |
| |
| exit: |
| WeaveLogFunctError(err); |
| |
| if (NULL != pMsgBuf) |
| { |
| PacketBuffer::Free(pMsgBuf); |
| pMsgBuf = NULL; |
| } |
| |
| return err; |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::SetStringArray(const char * apPath, const std::vector<std::string> & aValueVector, |
| bool aIsConditional) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| nl::Weave::TLV::TLVWriter writer; |
| PropertyPathHandle propertyPathHandle = kNullPropertyPathHandle; |
| TLVType OuterContainerType; |
| PacketBuffer * pMsgBuf = PacketBuffer::New(); |
| VerifyOrExit(NULL != pMsgBuf, err = WEAVE_ERROR_NO_MEMORY); |
| |
| VerifyOrExit(GetSubscriptionClient() != NULL, err = WEAVE_ERROR_INCORRECT_STATE); |
| |
| Lock(GetSubscriptionClient()); |
| |
| err = GetSchemaEngine()->MapPathToHandle(apPath, propertyPathHandle); |
| SuccessOrExit(err); |
| |
| writer.Init(pMsgBuf); |
| |
| err = writer.StartContainer(AnonymousTag, kTLVType_Array, OuterContainerType); |
| SuccessOrExit(err); |
| |
| for (uint8_t i = 0; i < aValueVector.size(); ++i) |
| { |
| err = writer.PutString(AnonymousTag, aValueVector[i].c_str()); |
| SuccessOrExit(err); |
| } |
| |
| err = writer.EndContainer(OuterContainerType); |
| SuccessOrExit(err); |
| |
| err = writer.Finalize(); |
| SuccessOrExit(err); |
| |
| #if WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| err = DebugPrettyPrint(pMsgBuf); |
| SuccessOrExit(err); |
| #endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| |
| UpdateTLVDataMap(propertyPathHandle, pMsgBuf); |
| pMsgBuf = NULL; |
| err = SetUpdated(GetSubscriptionClient(), propertyPathHandle, aIsConditional); |
| Unlock(GetSubscriptionClient()); |
| |
| WeaveLogDetail(DataManagement, "<set updated> in 0x%08x", propertyPathHandle); |
| |
| exit: |
| WeaveLogFunctError(err); |
| |
| if (NULL != pMsgBuf) |
| { |
| PacketBuffer::Free(pMsgBuf); |
| pMsgBuf = NULL; |
| } |
| |
| return err; |
| } |
| |
| template <class T> |
| WEAVE_ERROR GenericTraitUpdatableDataSink::Set(const char * apPath, T aValue, bool aIsConditional) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| nl::Weave::TLV::TLVWriter writer; |
| PropertyPathHandle propertyPathHandle = kNullPropertyPathHandle; |
| PacketBuffer * pMsgBuf = PacketBuffer::New(); |
| VerifyOrExit(NULL != pMsgBuf, err = WEAVE_ERROR_NO_MEMORY); |
| |
| VerifyOrExit(GetSubscriptionClient() != NULL, err = WEAVE_ERROR_INCORRECT_STATE); |
| |
| Lock(GetSubscriptionClient()); |
| |
| err = GetSchemaEngine()->MapPathToHandle(apPath, propertyPathHandle); |
| SuccessOrExit(err); |
| |
| writer.Init(pMsgBuf); |
| |
| err = writer.Put(AnonymousTag, aValue); |
| SuccessOrExit(err); |
| |
| err = writer.Finalize(); |
| SuccessOrExit(err); |
| |
| #if WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| err = DebugPrettyPrint(pMsgBuf); |
| SuccessOrExit(err); |
| #endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| |
| UpdateTLVDataMap(propertyPathHandle, pMsgBuf); |
| pMsgBuf = NULL; |
| |
| err = SetUpdated(GetSubscriptionClient(), propertyPathHandle, aIsConditional); |
| Unlock(GetSubscriptionClient()); |
| |
| WeaveLogDetail(DataManagement, "<set updated> in 0x%08x", propertyPathHandle); |
| |
| exit: |
| WeaveLogFunctError(err); |
| |
| if (NULL != pMsgBuf) |
| { |
| PacketBuffer::Free(pMsgBuf); |
| pMsgBuf = NULL; |
| } |
| |
| return err; |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::GetData(const char * apPath, int64_t & aValue) |
| { |
| return Get(apPath, aValue); |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::GetData(const char * apPath, uint64_t & aValue) |
| { |
| return Get(apPath, aValue); |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::GetData(const char * apPath, double & aValue) |
| { |
| return Get(apPath, aValue); |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::GetBoolean(const char * apPath, bool & aValue) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| nl::Weave::TLV::TLVReader reader; |
| PacketBuffer * pMsgBuf = NULL; |
| PropertyPathHandle propertyPathHandle = kNullPropertyPathHandle; |
| ; |
| std::map<PropertyPathHandle, PacketBuffer *>::iterator it; |
| |
| err = GetSchemaEngine()->MapPathToHandle(apPath, propertyPathHandle); |
| SuccessOrExit(err); |
| |
| it = mPathTlvDataMap.find(propertyPathHandle); |
| VerifyOrExit(it != mPathTlvDataMap.end(), err = WEAVE_ERROR_INVALID_TLV_TAG); |
| |
| pMsgBuf = mPathTlvDataMap[propertyPathHandle]; |
| |
| #if WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| err = DebugPrettyPrint(pMsgBuf); |
| SuccessOrExit(err); |
| #endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| |
| reader.Init(pMsgBuf); |
| err = reader.Next(); |
| SuccessOrExit(err); |
| |
| err = reader.Get(aValue); |
| SuccessOrExit(err); |
| |
| exit: |
| WeaveLogFunctError(err); |
| return err; |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::GetString(const char * apPath, BytesData * apBytesData) |
| { |
| return GetBytes(apPath, apBytesData); |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::GetBytes(const char * apPath, BytesData * apBytesData) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| nl::Weave::TLV::TLVReader reader; |
| PacketBuffer * pMsgBuf = NULL; |
| PropertyPathHandle propertyPathHandle = kNullPropertyPathHandle; |
| ; |
| std::map<PropertyPathHandle, PacketBuffer *>::iterator it; |
| |
| err = GetSchemaEngine()->MapPathToHandle(apPath, propertyPathHandle); |
| SuccessOrExit(err); |
| |
| it = mPathTlvDataMap.find(propertyPathHandle); |
| VerifyOrExit(it != mPathTlvDataMap.end(), err = WEAVE_ERROR_INVALID_TLV_TAG); |
| |
| pMsgBuf = mPathTlvDataMap[propertyPathHandle]; |
| |
| #if WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| err = DebugPrettyPrint(pMsgBuf); |
| SuccessOrExit(err); |
| #endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| |
| reader.Init(pMsgBuf); |
| err = reader.Next(); |
| SuccessOrExit(err); |
| |
| apBytesData->mDataLen = reader.GetLength(); |
| err = reader.GetDataPtr(apBytesData->mpDataBuf); |
| SuccessOrExit(err); |
| |
| exit: |
| WeaveLogFunctError(err); |
| return err; |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::GetTLVBytes(const char * apPath, BytesData * apBytesData) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| TraitSchemaEngine::IGetDataDelegate * getDataDelegate = NULL; |
| TLVType dummyContainerType; |
| nl::Weave::TLV::TLVWriter writer; |
| PropertyPathHandle propertyPathHandle = kNullPropertyPathHandle; |
| |
| PacketBuffer * pMsgBuf = PacketBuffer::New(); |
| VerifyOrExit(NULL != pMsgBuf, err = WEAVE_ERROR_NO_MEMORY); |
| |
| VerifyOrExit(NULL != apBytesData, err = WEAVE_ERROR_INVALID_ARGUMENT); |
| |
| err = GetSchemaEngine()->MapPathToHandle(apPath, propertyPathHandle); |
| SuccessOrExit(err); |
| |
| writer.Init(pMsgBuf); |
| |
| getDataDelegate = static_cast<TraitSchemaEngine::IGetDataDelegate *>(this); |
| err = GetSchemaEngine()->RetrieveData(propertyPathHandle, AnonymousTag, writer, getDataDelegate); |
| SuccessOrExit(err); |
| |
| err = writer.Finalize(); |
| SuccessOrExit(err); |
| |
| #if WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| err = DebugPrettyPrint(pMsgBuf); |
| SuccessOrExit(err); |
| #endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| |
| apBytesData->mpDataBuf = pMsgBuf->Start(); |
| apBytesData->mDataLen = pMsgBuf->DataLength(); |
| apBytesData->mpMsgBuf = pMsgBuf; |
| pMsgBuf = NULL; |
| |
| exit: |
| WeaveLogFunctError(err); |
| |
| if (NULL != pMsgBuf) |
| { |
| PacketBuffer::Free(pMsgBuf); |
| pMsgBuf = NULL; |
| } |
| return err; |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::IsNull(const char * apPath, bool & aIsNull) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| nl::Weave::TLV::TLVReader reader; |
| PacketBuffer * pMsgBuf = NULL; |
| PropertyPathHandle propertyPathHandle = kNullPropertyPathHandle; |
| ; |
| std::map<PropertyPathHandle, PacketBuffer *>::iterator it; |
| |
| err = GetSchemaEngine()->MapPathToHandle(apPath, propertyPathHandle); |
| SuccessOrExit(err); |
| |
| it = mPathTlvDataMap.find(propertyPathHandle); |
| VerifyOrExit(it != mPathTlvDataMap.end(), err = WEAVE_ERROR_INVALID_TLV_TAG); |
| |
| pMsgBuf = mPathTlvDataMap[propertyPathHandle]; |
| |
| #if WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| err = DebugPrettyPrint(pMsgBuf); |
| SuccessOrExit(err); |
| #endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| |
| reader.Init(pMsgBuf); |
| err = reader.Next(); |
| SuccessOrExit(err); |
| |
| if (reader.GetType() == kTLVElementType_Null) |
| { |
| aIsNull = true; |
| } |
| else |
| { |
| aIsNull = false; |
| } |
| |
| exit: |
| WeaveLogFunctError(err); |
| return err; |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::GetStringArray(const char * apPath, std::vector<std::string> & aValueVector) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| nl::Weave::TLV::TLVReader reader; |
| PacketBuffer * pMsgBuf = NULL; |
| PropertyPathHandle propertyPathHandle = kNullPropertyPathHandle; |
| ; |
| TLVType OuterContainerType; |
| std::map<PropertyPathHandle, PacketBuffer *>::iterator it; |
| |
| err = GetSchemaEngine()->MapPathToHandle(apPath, propertyPathHandle); |
| SuccessOrExit(err); |
| |
| it = mPathTlvDataMap.find(propertyPathHandle); |
| VerifyOrExit(it != mPathTlvDataMap.end(), err = WEAVE_ERROR_INVALID_TLV_TAG); |
| |
| pMsgBuf = mPathTlvDataMap[propertyPathHandle]; |
| |
| #if WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| err = DebugPrettyPrint(pMsgBuf); |
| SuccessOrExit(err); |
| #endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| |
| reader.Init(pMsgBuf); |
| err = reader.Next(); |
| SuccessOrExit(err); |
| |
| err = reader.EnterContainer(OuterContainerType); |
| SuccessOrExit(err); |
| |
| while (WEAVE_NO_ERROR == (err = reader.Next())) |
| { |
| int length = reader.GetLength(); |
| const uint8_t * pDataBuf = NULL; |
| err = reader.GetDataPtr(pDataBuf); |
| SuccessOrExit(err); |
| std::string val((char *) pDataBuf, length); |
| aValueVector.push_back(val); |
| } |
| |
| // if we have exhausted this container |
| if (WEAVE_END_OF_TLV == err) |
| { |
| err = WEAVE_NO_ERROR; |
| } |
| |
| err = reader.ExitContainer(OuterContainerType); |
| SuccessOrExit(err); |
| |
| exit: |
| WeaveLogFunctError(err); |
| return err; |
| } |
| |
| template <class T> |
| WEAVE_ERROR GenericTraitUpdatableDataSink::Get(const char * apPath, T & aValue) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| nl::Weave::TLV::TLVReader reader; |
| PacketBuffer * pMsgBuf = NULL; |
| PropertyPathHandle propertyPathHandle = kNullPropertyPathHandle; |
| std::map<PropertyPathHandle, PacketBuffer *>::iterator it; |
| |
| err = GetSchemaEngine()->MapPathToHandle(apPath, propertyPathHandle); |
| SuccessOrExit(err); |
| |
| it = mPathTlvDataMap.find(propertyPathHandle); |
| VerifyOrExit(it != mPathTlvDataMap.end(), err = WEAVE_ERROR_INVALID_TLV_TAG); |
| |
| pMsgBuf = mPathTlvDataMap[propertyPathHandle]; |
| |
| #if WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| err = DebugPrettyPrint(pMsgBuf); |
| SuccessOrExit(err); |
| #endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| |
| reader.Init(pMsgBuf); |
| err = reader.Next(); |
| SuccessOrExit(err); |
| |
| err = reader.Get(aValue); |
| SuccessOrExit(err); |
| |
| exit: |
| WeaveLogFunctError(err); |
| return err; |
| } |
| |
| WEAVE_ERROR |
| GenericTraitUpdatableDataSink::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader & aReader) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| nl::Weave::TLV::TLVWriter writer; |
| PacketBuffer * pMsgBuf = PacketBuffer::New(); |
| VerifyOrExit(NULL != pMsgBuf, err = WEAVE_ERROR_NO_MEMORY); |
| |
| writer.Init(pMsgBuf); |
| |
| err = writer.CopyElement(AnonymousTag, aReader); |
| SuccessOrExit(err); |
| |
| err = writer.Finalize(); |
| SuccessOrExit(err); |
| |
| UpdateTLVDataMap(aLeafHandle, pMsgBuf); |
| #if WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| err = DebugPrettyPrint(pMsgBuf); |
| SuccessOrExit(err); |
| #endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| pMsgBuf = NULL; |
| |
| exit: |
| WeaveLogFunctError(err); |
| |
| if (NULL != pMsgBuf) |
| { |
| PacketBuffer::Free(pMsgBuf); |
| pMsgBuf = NULL; |
| } |
| |
| return err; |
| } |
| |
| WEAVE_ERROR |
| GenericTraitUpdatableDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter & aWriter) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| nl::Weave::TLV::TLVReader reader; |
| PacketBuffer * pMsgBuf = NULL; |
| |
| std::map<PropertyPathHandle, PacketBuffer *>::iterator it = mPathTlvDataMap.find(aLeafHandle); |
| |
| VerifyOrExit(it != mPathTlvDataMap.end(), err = WEAVE_ERROR_INVALID_TLV_TAG); |
| |
| pMsgBuf = mPathTlvDataMap[aLeafHandle]; |
| |
| #if WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| err = DebugPrettyPrint(pMsgBuf); |
| SuccessOrExit(err); |
| #endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| |
| reader.Init(pMsgBuf); |
| err = reader.Next(); |
| SuccessOrExit(err); |
| err = aWriter.CopyElement(aTagToWrite, reader); |
| SuccessOrExit(err); |
| |
| exit: |
| WeaveLogFunctError(err); |
| return err; |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t & aContext, |
| PropertyDictionaryKey & aKey) |
| { |
| return WEAVE_END_OF_INPUT; |
| } |
| |
| #if WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| void GenericTraitUpdatableDataSink::TLVPrettyPrinter(const char * aFormat, ...) |
| { |
| va_list args; |
| |
| va_start(args, aFormat); |
| |
| vprintf(aFormat, args); |
| |
| va_end(args); |
| } |
| |
| WEAVE_ERROR GenericTraitUpdatableDataSink::DebugPrettyPrint(PacketBuffer * apMsgBuf) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| nl::Weave::TLV::TLVReader reader; |
| reader.Init(apMsgBuf); |
| err = reader.Next(); |
| SuccessOrExit(err); |
| nl::Weave::TLV::Debug::Dump(reader, TLVPrettyPrinter); |
| |
| exit: |
| if (WEAVE_NO_ERROR != err) |
| { |
| WeaveLogProgress(DataManagement, "DebugPrettyPrint fails with err %d", err); |
| } |
| |
| return err; |
| } |
| #endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK |
| |
| const nl::Weave::ExchangeContext::Timeout kResponseTimeoutMsec = 15000; |
| |
| WdmClient::WdmClient() : |
| mpAppState(NULL), mpPublisherPathList(NULL), mpSubscriptionClient(NULL), mpMsgLayer(NULL), mpContext(NULL), mpAppReqState(NULL) |
| { |
| State = kState_NotInitialized; |
| } |
| |
| void WdmClient::Close(void) |
| { |
| if (mpSubscriptionClient != NULL) |
| { |
| mpSubscriptionClient->DiscardUpdates(); |
| mpSubscriptionClient->Free(); |
| mpSubscriptionClient = NULL; |
| } |
| |
| mSinkCatalog.Iterate(ClearDataSink, this); |
| |
| mSinkCatalog.Clear(); |
| if (mpPublisherPathList != NULL) |
| { |
| delete[] mpPublisherPathList; |
| mpPublisherPathList = NULL; |
| } |
| |
| mpAppState = NULL; |
| mpContext = NULL; |
| mpMsgLayer = NULL; |
| mpAppReqState = NULL; |
| mOnError = NULL; |
| |
| State = kState_NotInitialized; |
| ClearOpState(); |
| } |
| |
| void WdmClient::ClearDataSink(void * aTraitInstance, TraitDataHandle aHandle, void * aContext) |
| { |
| GenericTraitUpdatableDataSink * pGenericTraitUpdatableDataSink = NULL; |
| if (aTraitInstance != NULL) |
| { |
| pGenericTraitUpdatableDataSink = static_cast<GenericTraitUpdatableDataSink *>(aTraitInstance); |
| delete pGenericTraitUpdatableDataSink; |
| pGenericTraitUpdatableDataSink = NULL; |
| } |
| } |
| |
| void WdmClient::ClearDataSinkVersion(void * aTraitInstance, TraitDataHandle aHandle, void * aContext) |
| { |
| GenericTraitUpdatableDataSink * pGenericTraitUpdatableDataSink = NULL; |
| if (aTraitInstance != NULL) |
| { |
| pGenericTraitUpdatableDataSink = static_cast<GenericTraitUpdatableDataSink *>(aTraitInstance); |
| pGenericTraitUpdatableDataSink->ClearVersion(); |
| } |
| } |
| |
| void WdmClient::ClientEventCallback(void * const aAppState, SubscriptionClient::EventID aEvent, |
| const SubscriptionClient::InEventParam & aInParam, |
| SubscriptionClient::OutEventParam & aOutParam) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| WdmClient * const pWdmClient = reinterpret_cast<WdmClient *>(aAppState); |
| |
| OpState savedOpState = pWdmClient->mOpState; |
| WeaveLogDetail(DataManagement, "WDM ClientEventCallback: current op is, %d", savedOpState); |
| |
| switch (aEvent) |
| { |
| case SubscriptionClient::kEvent_OnExchangeStart: |
| WeaveLogDetail(DataManagement, "Client->kEvent_OnExchangeStart"); |
| break; |
| case SubscriptionClient::kEvent_OnSubscribeRequestPrepareNeeded: |
| WeaveLogDetail(DataManagement, "Client->kEvent_OnSubscribeRequestPrepareNeeded"); |
| VerifyOrExit(kOpState_RefreshData == savedOpState, err = WEAVE_ERROR_INCORRECT_STATE); |
| { |
| uint16_t pathListLen = 0; |
| uint16_t traitListLen = 0; |
| TraitDataHandle handle; |
| bool needSubscribeSpecificTrait = false; |
| |
| if (pWdmClient->mGetDataHandle != NULL && pWdmClient->mpContext != NULL) |
| { |
| err = pWdmClient->mGetDataHandle(pWdmClient->mpContext, &pWdmClient->mSinkCatalog, handle); |
| SuccessOrExit(err); |
| traitListLen = 1; |
| needSubscribeSpecificTrait = true; |
| } |
| else |
| { |
| traitListLen = pWdmClient->mSinkCatalog.Size(); |
| VerifyOrExit(traitListLen != 0, err = WEAVE_ERROR_INVALID_LIST_LENGTH); |
| } |
| WeaveLogDetail(DataManagement, "prepare to subscribe %d trait data sink", traitListLen); |
| |
| if (pWdmClient->mpPublisherPathList == NULL) |
| { |
| delete[] pWdmClient->mpPublisherPathList; |
| } |
| |
| pWdmClient->mpPublisherPathList = new TraitPath[traitListLen]; |
| |
| if (needSubscribeSpecificTrait) |
| { |
| pathListLen = 1; |
| err = pWdmClient->mSinkCatalog.PrepareSubscriptionSpecificPathList(pWdmClient->mpPublisherPathList, traitListLen, |
| handle); |
| } |
| else |
| { |
| err = pWdmClient->mSinkCatalog.PrepareSubscriptionPathList(pWdmClient->mpPublisherPathList, traitListLen, |
| pathListLen); |
| } |
| SuccessOrExit(err); |
| |
| aOutParam.mSubscribeRequestPrepareNeeded.mPathList = pWdmClient->mpPublisherPathList; |
| aOutParam.mSubscribeRequestPrepareNeeded.mPathListSize = pathListLen; |
| aOutParam.mSubscribeRequestPrepareNeeded.mNeedAllEvents = false; |
| aOutParam.mSubscribeRequestPrepareNeeded.mLastObservedEventList = NULL; |
| aOutParam.mSubscribeRequestPrepareNeeded.mLastObservedEventListSize = 0; |
| aOutParam.mSubscribeRequestPrepareNeeded.mTimeoutSecMin = 30; |
| aOutParam.mSubscribeRequestPrepareNeeded.mTimeoutSecMax = 120; |
| } |
| break; |
| |
| case SubscriptionClient::kEvent_OnSubscriptionEstablished: |
| WeaveLogDetail(DataManagement, "Client->kEvent_OnSubscriptionEstablished"); |
| pWdmClient->mpSubscriptionClient->AbortSubscription(); |
| VerifyOrExit(kOpState_RefreshData == pWdmClient->mOpState, err = WEAVE_ERROR_INCORRECT_STATE); |
| pWdmClient->mOnComplete.General(pWdmClient->mpContext, pWdmClient->mpAppReqState); |
| pWdmClient->mpContext = NULL; |
| pWdmClient->ClearOpState(); |
| break; |
| case SubscriptionClient::kEvent_OnNotificationRequest: |
| WeaveLogDetail(DataManagement, "Client->kEvent_OnNotificationRequest"); |
| VerifyOrExit(kOpState_RefreshData == pWdmClient->mOpState, err = WEAVE_ERROR_INCORRECT_STATE); |
| break; |
| case SubscriptionClient::kEvent_OnNotificationProcessed: |
| WeaveLogDetail(DataManagement, "Client->kEvent_OnNotificationProcessed"); |
| VerifyOrExit(kOpState_RefreshData == pWdmClient->mOpState, err = WEAVE_ERROR_INCORRECT_STATE); |
| break; |
| case SubscriptionClient::kEvent_OnSubscriptionTerminated: |
| WeaveLogDetail(DataManagement, "Client->kEvent_OnSubscriptionTerminated. Reason: %u, peer = 0x%" PRIX64 "\n", |
| aInParam.mSubscriptionTerminated.mReason, aInParam.mSubscriptionTerminated.mClient->GetPeerNodeId()); |
| pWdmClient->mpSubscriptionClient->AbortSubscription(); |
| err = WEAVE_ERROR_INCORRECT_STATE; |
| break; |
| case SubscriptionClient::kEvent_OnUpdateComplete: |
| if ((aInParam.mUpdateComplete.mReason == WEAVE_NO_ERROR) && |
| (nl::Weave::Profiles::kWeaveProfile_Common == aInParam.mUpdateComplete.mStatusProfileId) && |
| (nl::Weave::Profiles::Common::kStatus_Success == aInParam.mUpdateComplete.mStatusCode)) |
| { |
| WeaveLogDetail(DataManagement, "Update: path result: success"); |
| } |
| else |
| { |
| WeaveLogDetail(DataManagement, "Update: path failed: %s, %s, tdh %" PRIu16 ", will %sretry, discard failed change", |
| ErrorStr(aInParam.mUpdateComplete.mReason), |
| nl::StatusReportStr(aInParam.mUpdateComplete.mStatusProfileId, aInParam.mUpdateComplete.mStatusCode), |
| aInParam.mUpdateComplete.mTraitDataHandle, aInParam.mUpdateComplete.mWillRetry ? "" : "not "); |
| } |
| |
| break; |
| case SubscriptionClient::kEvent_OnNoMorePendingUpdates: |
| //TODO: notify application with all status for updated paths |
| WeaveLogDetail(DataManagement, "Update: no more pending updates"); |
| VerifyOrExit(kOpState_FlushUpdate == savedOpState, err = WEAVE_ERROR_INCORRECT_STATE); |
| pWdmClient->mpSubscriptionClient->DiscardUpdates(); |
| pWdmClient->mOnComplete.General(pWdmClient->mpContext, pWdmClient->mpAppReqState); |
| pWdmClient->mpContext = NULL; |
| pWdmClient->ClearOpState(); |
| break; |
| |
| default: |
| SubscriptionClient::DefaultEventHandler(aEvent, aInParam, aOutParam); |
| break; |
| } |
| |
| exit: |
| if (WEAVE_NO_ERROR != err) |
| { |
| WeaveLogError(DataManagement, "WDM ClientEventCallback failure: err = %d", err); |
| pWdmClient->mOnError(pWdmClient->mpContext, pWdmClient->mpAppReqState, err, NULL); |
| pWdmClient->mpContext = NULL; |
| pWdmClient->ClearOpState(); |
| } |
| |
| return; |
| } |
| |
| WEAVE_ERROR WdmClient::Init(WeaveMessageLayer * apMsgLayer, Binding * apBinding) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| mpMsgLayer = apMsgLayer; |
| |
| VerifyOrExit(State == kState_NotInitialized, err = WEAVE_ERROR_INCORRECT_STATE); |
| |
| if (mpSubscriptionClient == NULL) |
| { |
| err = SubscriptionEngine::GetInstance()->NewClient( |
| &mpSubscriptionClient, apBinding, this, ClientEventCallback, &mSinkCatalog, |
| kResponseTimeoutMsec * 2); // max num of msec between subscribe request and subscribe response |
| SuccessOrExit(err); |
| } |
| |
| mpSubscriptionClient->EnableResubscribe(NULL); |
| |
| State = kState_Initialized; |
| mpContext = NULL; |
| ClearOpState(); |
| |
| exit: |
| return WEAVE_NO_ERROR; |
| } |
| |
| void WdmClient::SetNodeId(uint64_t aNodeId) |
| { |
| mSinkCatalog.SetNodeId(aNodeId); |
| } |
| |
| WEAVE_ERROR WdmClient::NewDataSink(const ResourceIdentifier & aResourceId, uint32_t aProfileId, uint64_t aInstanceId, |
| const char * apPath, GenericTraitUpdatableDataSink *& apGenericTraitUpdatableDataSink) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| PropertyPathHandle handle = kNullPropertyPathHandle; |
| |
| const TraitSchemaEngine * pEngine = TraitSchemaDirectory::GetTraitSchemaEngine(aProfileId); |
| VerifyOrExit(pEngine != NULL, err = WEAVE_ERROR_INCORRECT_STATE); |
| |
| VerifyOrExit(mpSubscriptionClient != NULL, err = WEAVE_ERROR_INCORRECT_STATE); |
| |
| VerifyOrExit(WEAVE_NO_ERROR != GetDataSink(aResourceId, aProfileId, aInstanceId, apGenericTraitUpdatableDataSink), |
| WeaveLogDetail(DataManagement, "Trait exist")); |
| |
| apGenericTraitUpdatableDataSink = new GenericTraitUpdatableDataSink(pEngine, this); |
| VerifyOrExit(apGenericTraitUpdatableDataSink != NULL, err = WEAVE_ERROR_NO_MEMORY); |
| |
| if (apPath == NULL) |
| { |
| handle = kRootPropertyPathHandle; |
| } |
| else |
| { |
| apGenericTraitUpdatableDataSink->GetSchemaEngine()->MapPathToHandle(apPath, handle); |
| } |
| |
| err = SubscribePublisherTrait(aResourceId, aInstanceId, handle, apGenericTraitUpdatableDataSink); |
| SuccessOrExit(err); |
| |
| apGenericTraitUpdatableDataSink->SetSubscriptionClient(mpSubscriptionClient); |
| |
| exit: |
| return err; |
| } |
| |
| WEAVE_ERROR WdmClient::GetDataSink(const ResourceIdentifier & aResourceId, uint32_t aProfileId, uint64_t aInstanceId, |
| GenericTraitUpdatableDataSink *& apGenericTraitUpdatableDataSink) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| TraitDataSink * dataSink = NULL; |
| |
| err = mSinkCatalog.Locate(aProfileId, aInstanceId, aResourceId, &dataSink); |
| SuccessOrExit(err); |
| |
| apGenericTraitUpdatableDataSink = static_cast<GenericTraitUpdatableDataSink *>(dataSink); |
| |
| exit: |
| return err; |
| } |
| |
| WEAVE_ERROR WdmClient::FlushUpdate(void * apAppReqState, DMCompleteFunct onComplete, DMErrorFunct onError) |
| { |
| VerifyOrExit(mOpState == kOpState_Idle, WeaveLogError(DataManagement, "FlushUpdate with OpState %d", mOpState)); |
| |
| mpAppReqState = apAppReqState; |
| mOnComplete.General = onComplete; |
| mOnError = onError; |
| mOpState = kOpState_FlushUpdate; |
| mpContext = this; |
| mpSubscriptionClient->FlushUpdate(true); |
| |
| exit: |
| return WEAVE_NO_ERROR; |
| } |
| |
| WEAVE_ERROR WdmClient::RefreshData(void * apAppReqState, DMCompleteFunct onComplete, DMErrorFunct onError, |
| GetDataHandleFunct getDataHandleCb) |
| { |
| VerifyOrExit(mpSubscriptionClient != NULL, WeaveLogError(DataManagement, "mpSubscriptionClient is NULL")); |
| |
| mSinkCatalog.Iterate(ClearDataSinkVersion, this); |
| |
| RefreshData(apAppReqState, this, onComplete, onError, getDataHandleCb); |
| |
| exit: |
| return WEAVE_NO_ERROR; |
| } |
| |
| WEAVE_ERROR WdmClient::RefreshData(void * apAppReqState, void * apContext, DMCompleteFunct onComplete, DMErrorFunct onError, |
| GetDataHandleFunct getDataHandleCb) |
| { |
| VerifyOrExit(mOpState == kOpState_Idle, WeaveLogError(DataManagement, "RefreshData with OpState %d", mOpState)); |
| |
| mpAppReqState = apAppReqState; |
| mOnComplete.General = onComplete; |
| mOnError = onError; |
| mOpState = kOpState_RefreshData; |
| mGetDataHandle = getDataHandleCb; |
| mpContext = apContext; |
| |
| mpSubscriptionClient->InitiateSubscription(); |
| |
| exit: |
| return WEAVE_NO_ERROR; |
| } |
| |
| void WdmClient::ClearOpState() |
| { |
| mOpState = kOpState_Idle; |
| } |
| |
| WEAVE_ERROR WdmClient::SubscribePublisherTrait(const ResourceIdentifier & aResourceId, const uint64_t & aInstanceId, |
| PropertyPathHandle aBasePathHandle, TraitDataSink * apDataSink) |
| { |
| TraitDataHandle traitHandle; |
| return mSinkCatalog.Add(aResourceId, aInstanceId, aBasePathHandle, apDataSink, traitHandle); |
| } |
| |
| WEAVE_ERROR WdmClient::UnsubscribePublisherTrait(TraitDataSink * apDataSink) |
| { |
| return mSinkCatalog.Remove(apDataSink); |
| } |
| |
| } // namespace DeviceManager |
| } // namespace Weave |
| } // namespace nl |
| #endif // WEAVE_CONFIG_DATA_MANAGEMENT_CLIENT_EXPERIMENTAL |