| /* |
| * |
| * 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/bulk-data-transfer/Development/BDXManagedNamespace.hpp> |
| #include <Weave/Profiles/data-management/Current/WdmManagedNamespace.h> |
| |
| #include <Weave/Support/CodeUtils.h> |
| #include <Weave/Profiles/security/ApplicationKeysTrait.h> |
| #include <Weave/Profiles/security/ApplicationKeysStructSchema.h> |
| #include "ToolCommon.h" |
| #include "MockSinkTraits.h" |
| #include <schema/weave/common/DayOfWeekEnum.h> |
| |
| using namespace ::nl::Weave; |
| using namespace ::nl::Weave::TLV; |
| using namespace ::nl::Weave::Profiles::DataManagement; |
| using namespace ::nl::Weave::Profiles::Security::AppKeys; |
| |
| using namespace Weave::Trait::Locale; |
| using namespace Weave::Trait::Security; |
| using namespace Schema::Weave::Trait::Auth; |
| using namespace Schema::Weave::Trait::Auth::ApplicationKeysTrait; |
| using namespace Schema::Nest::Test::Trait; |
| 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); |
| } |
| |
| MockTraitDataSink::MockTraitDataSink(const TraitSchemaEngine * aEngine) |
| : TraitDataSink(aEngine) |
| { |
| } |
| |
| #if WEAVE_CONFIG_ENABLE_WDM_UPDATE |
| MockTraitUpdatableDataSink::MockTraitUpdatableDataSink(const TraitSchemaEngine * aEngine) |
| : TraitUpdatableDataSink(aEngine) |
| { |
| } |
| #endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE |
| |
| WEAVE_ERROR |
| MockTraitDataSourceDelegate::GetData(PropertyPathHandle aHandle, |
| uint64_t aTagToWrite, |
| nl::Weave::TLV::TLVWriter &aWriter, |
| bool &aIsNull, |
| bool &aIsPresent) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| aIsNull = false; |
| aIsPresent = true; |
| err = GetLeafData(aHandle, aTagToWrite, aWriter); |
| |
| return err; |
| } |
| |
| LocaleSettingsTraitDataSink::LocaleSettingsTraitDataSink() |
| : MockTraitDataSink(&LocaleSettingsTrait::TraitSchema) |
| { |
| memset(mLocale, 0, sizeof(mLocale)); |
| } |
| |
| WEAVE_ERROR |
| LocaleSettingsTraitDataSink::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 |
| LocaleSettingsTraitDataSink::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 LocaleSettingsTraitDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey) |
| { |
| return WEAVE_END_OF_INPUT; |
| } |
| |
| LocaleCapabilitiesTraitDataSink::LocaleCapabilitiesTraitDataSink() |
| : MockTraitDataSink(&LocaleCapabilitiesTrait::TraitSchema), |
| mNumLocales(0) |
| { |
| memset(mLocales, 0, sizeof(mLocales)); |
| } |
| |
| WEAVE_ERROR |
| LocaleCapabilitiesTraitDataSink::OnEvent(uint16_t aType, void *aInParam) |
| { |
| WeaveLogDetail(DataManagement, "LocaleCapabilitiesTraitDataSink::OnEvent event: %u", aType); |
| return WEAVE_NO_ERROR; |
| } |
| |
| WEAVE_ERROR |
| LocaleCapabilitiesTraitDataSink::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| char next_locale[kMaxNumOfCharsPerLocale]; |
| |
| if (LocaleCapabilitiesTrait::kPropertyHandle_available_locales == aLeafHandle) |
| { |
| nl::Weave::TLV::TLVType OuterContainerType; |
| |
| // clear all locales |
| mNumLocales = 0; |
| |
| VerifyOrExit(aReader.GetType() == nl::Weave::TLV::kTLVType_Array, err = WEAVE_ERROR_WRONG_TLV_TYPE); |
| |
| err = aReader.EnterContainer(OuterContainerType); |
| SuccessOrExit(err); |
| |
| while (WEAVE_NO_ERROR == (err = aReader.Next())) |
| { |
| VerifyOrExit(nl::Weave::TLV::kTLVType_UTF8String == aReader.GetType(), err = WEAVE_ERROR_WRONG_TLV_TYPE); |
| VerifyOrExit(nl::Weave::TLV::AnonymousTag == aReader.GetTag(), err = WEAVE_ERROR_INVALID_TLV_TAG); |
| |
| err = aReader.GetString(next_locale, kMaxNumOfCharsPerLocale); |
| SuccessOrExit(err); |
| if (strncmp(next_locale, mLocales[mNumLocales], MAX_LOCALE_SIZE) != 0) |
| { |
| WeaveLogDetail(DataManagement, "<< locale[%u] is changed from [%s] to [%s]", mNumLocales, mLocales[mNumLocales], next_locale); |
| memcpy(mLocales[mNumLocales], next_locale, MAX_LOCALE_SIZE); |
| } |
| |
| WeaveLogDetail(DataManagement, "<< locale[%u] = [%s]", mNumLocales, mLocales[mNumLocales]); |
| |
| ++mNumLocales; |
| |
| if (kMaxNumOfLocals == mNumLocales) |
| { |
| WeaveLogDetail(DataManagement, "Cannot handle more than %d locales, skip", kMaxNumOfLocals); |
| break; |
| } |
| } |
| |
| // Note that ExitContainer internally skip all unread elements till the end of current container |
| err = aReader.ExitContainer(OuterContainerType); |
| SuccessOrExit(err); |
| } |
| else |
| { |
| WeaveLogDetail(DataManagement, "<< UNKNOWN!"); |
| ExitNow(err = WEAVE_ERROR_INVALID_TLV_TAG); |
| } |
| |
| exit: |
| return err; |
| } |
| |
| WEAVE_ERROR |
| LocaleCapabilitiesTraitDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| if (LocaleCapabilitiesTrait::kPropertyHandle_available_locales == aLeafHandle) { |
| nl::Weave::TLV::TLVType OuterContainerType; |
| |
| err = aWriter.StartContainer(aTagToWrite, nl::Weave::TLV::kTLVType_Array, OuterContainerType); |
| SuccessOrExit(err); |
| |
| for (uint8_t i = 0; i < mNumLocales; ++i) { |
| err = aWriter.PutString(nl::Weave::TLV::AnonymousTag, mLocales[i]); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> locale[%u] = [%s]", i, mLocales[i]); |
| } |
| |
| err = aWriter.EndContainer(OuterContainerType); |
| SuccessOrExit(err); |
| } |
| else { |
| WeaveLogDetail(DataManagement, ">> UNKNOWN!"); |
| ExitNow(err = WEAVE_ERROR_INVALID_TLV_TAG); |
| } |
| |
| exit: |
| WeaveLogFunctError(err); |
| |
| return err; |
| } |
| |
| WEAVE_ERROR LocaleCapabilitiesTraitDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey) |
| { |
| return WEAVE_END_OF_INPUT; |
| } |
| |
| BoltLockSettingTraitDataSink::BoltLockSettingTraitDataSink() |
| : MockTraitDataSink(&BoltLockSettingTrait::TraitSchema) |
| { |
| mAutoRelockOn = false; |
| mAutoRelockDuration = 0; |
| } |
| |
| WEAVE_ERROR |
| BoltLockSettingTraitDataSink::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| switch (aLeafHandle) { |
| case BoltLockSettingTrait::kPropertyHandle_auto_relock_on: |
| bool next_autoRelockOn; |
| err = aReader.Get(next_autoRelockOn); |
| SuccessOrExit(err); |
| if (next_autoRelockOn != mAutoRelockOn) |
| { |
| WeaveLogDetail(DataManagement, "<< auto_relock_on is changed from %s to %s", mAutoRelockOn ? "true" : "false", next_autoRelockOn ? "true" : "false"); |
| mAutoRelockOn = next_autoRelockOn; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< auto_relock_on = %s", mAutoRelockOn ? "true" : "false"); |
| break; |
| |
| case BoltLockSettingTrait::kPropertyHandle_auto_relock_duration: |
| uint32_t aAutoRelockDuration; |
| err = aReader.Get(aAutoRelockDuration); |
| SuccessOrExit(err); |
| if (aAutoRelockDuration != mAutoRelockDuration) |
| { |
| WeaveLogDetail(DataManagement, "<< auto_relock_duration is changed from %u to %u", mAutoRelockDuration, aAutoRelockDuration); |
| mAutoRelockDuration = aAutoRelockDuration; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< auto_relock_duration = %u", mAutoRelockDuration); |
| break; |
| |
| default: |
| WeaveLogDetail(DataManagement, "<< UNKNOWN!"); |
| err = WEAVE_ERROR_TLV_TAG_NOT_FOUND; |
| } |
| |
| exit: |
| return err; |
| } |
| |
| WEAVE_ERROR |
| BoltLockSettingTraitDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| switch (aLeafHandle) { |
| case BoltLockSettingTrait::kPropertyHandle_auto_relock_on: |
| err = aWriter.PutBoolean(aTagToWrite, mAutoRelockOn); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> auto_relock_on = %s", mAutoRelockOn ? "true" : "false"); |
| break; |
| |
| case BoltLockSettingTrait::kPropertyHandle_auto_relock_duration: |
| err = aWriter.Put(aTagToWrite, mAutoRelockDuration); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> auto_relock_duration = %u", mAutoRelockDuration); |
| break; |
| |
| default: |
| WeaveLogDetail(DataManagement, ">> UNKNOWN!"); |
| ExitNow(err = WEAVE_ERROR_TLV_TAG_NOT_FOUND); |
| } |
| |
| exit: |
| WeaveLogFunctError(err); |
| return err; |
| } |
| |
| WEAVE_ERROR BoltLockSettingTraitDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey) |
| { |
| return WEAVE_END_OF_INPUT; |
| } |
| |
| TestATraitDataSink::TestATraitDataSink() |
| : MockTraitDataSink(&TestATrait::TraitSchema) |
| { |
| taa = TestATrait::ENUM_A_VALUE_1; |
| tab = TestCommon::COMMON_ENUM_A_VALUE_1; |
| tac = 0; |
| tad.saA = 0; |
| tad.saB = false; |
| |
| for (size_t i = 0; i < (sizeof(tae) / sizeof(tae[0])); i++) { |
| tae[i] = 0; |
| } |
| for (size_t i = 0; i < sizeof(nullified_path) / sizeof(nullified_path[0]); i++) |
| { |
| nullified_path[i] = false; |
| } |
| } |
| |
| TestATraitDataSink::TestATraitDataSink(bool aAcceptsSublessNotifies) |
| : MockTraitDataSink(&TestATrait::TraitSchema) |
| { |
| TestATraitDataSink(); |
| |
| #if WDM_ENABLE_SUBSCRIPTIONLESS_NOTIFICATION |
| SetAcceptsSubscriptionlessNotifications(aAcceptsSublessNotifies); |
| #endif // WDM_ENABLE_SUBSCRIPTIONLESS_NOTIFICATION |
| } |
| |
| WEAVE_ERROR |
| TestATraitDataSink::OnEvent(uint16_t aType, void *aInParam) |
| { |
| InEventParam *inParam = static_cast<InEventParam *>(aInParam); |
| PropertyPathHandle handle; |
| PropertyDictionaryKey key; |
| |
| switch (aType) { |
| case kEventDictionaryReplaceBegin: |
| case kEventDictionaryReplaceEnd: |
| case kEventDictionaryItemModifyBegin: |
| case kEventDictionaryItemModifyEnd: |
| WeaveLogDetail(DataManagement, "TestATraitDataSink::OnEvent event: %u (handle: %08x)", aType, *(PropertyPathHandle *)aInParam); |
| break; |
| |
| default: |
| WeaveLogDetail(DataManagement, "TestATraitDataSink::OnEvent event: %u", aType); |
| } |
| |
| switch (aType) { |
| case kEventDictionaryReplaceBegin: |
| handle = inParam->mDictionaryItemModifyBegin.mTargetHandle; |
| |
| if (handle == TestATrait::kPropertyHandle_TaI) { |
| WeaveLogDetail(DataManagement, "Clearing out dictionary tai..."); |
| tai_map.clear(); |
| } |
| else if (handle == TestATrait::kPropertyHandle_TaJ) { |
| WeaveLogDetail(DataManagement, "Clearing out dictionary taj..."); |
| taj_map.clear(); |
| } |
| else { |
| WeaveLogDetail(DataManagement, "Unknown dictionary!"); |
| } |
| |
| break; |
| |
| case kEventDictionaryItemDelete: |
| handle = inParam->mDictionaryItemDelete.mTargetHandle; |
| key = GetPropertyDictionaryKey(handle); |
| |
| if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaI_Value) { |
| WeaveLogDetail(DataManagement, "Deleting key %u from tai...", key); |
| tai_map.erase(key); |
| } |
| else if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaJ_Value) { |
| WeaveLogDetail(DataManagement, "Deleting key %u from taj...", key); |
| taj_map.erase(key); |
| } |
| |
| break; |
| |
| case kEventDictionaryItemModifyBegin: |
| handle = inParam->mDictionaryItemModifyBegin.mTargetHandle; |
| key = GetPropertyDictionaryKey(handle); |
| |
| if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaI_Value) { |
| if (tai_map.find(key) == tai_map.end()) { |
| WeaveLogDetail(DataManagement, "Staging new key %u for tai...", key); |
| memset(&tai_stageditem, 0, sizeof(tai_stageditem)); |
| } |
| else { |
| WeaveLogDetail(DataManagement, "Modifying key %u in tai...", key); |
| tai_stageditem = tai_map[key]; |
| } |
| } |
| else if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaJ_Value) { |
| if (taj_map.find(key) == taj_map.end()) { |
| WeaveLogDetail(DataManagement, "Staging new key %u for taj...", key); |
| memset(&taj_stageditem, 0, sizeof(taj_stageditem)); |
| } |
| else { |
| WeaveLogDetail(DataManagement, "Modifying key %u in taj...", key); |
| taj_stageditem = taj_map[key]; |
| } |
| } |
| |
| break; |
| |
| case kEventDictionaryItemModifyEnd: |
| handle = inParam->mDictionaryItemModifyEnd.mTargetHandle; |
| key = GetPropertyDictionaryKey(handle); |
| |
| if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaI_Value) { |
| if (tai_map.find(key) == tai_map.end()) { |
| WeaveLogDetail(DataManagement, "Adding key %u to tai...", key); |
| } |
| |
| tai_map[key] = tai_stageditem; |
| } |
| else if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaJ_Value) { |
| if (taj_map.find(key) == taj_map.end()) { |
| WeaveLogDetail(DataManagement, "Adding key %u to taj...", key); |
| } |
| |
| taj_map[key] = taj_stageditem; |
| } |
| |
| break; |
| } |
| |
| return WEAVE_NO_ERROR; |
| } |
| |
| void TestATraitDataSink::SetNullifiedPath(PropertyPathHandle aHandle, bool isNull) |
| { |
| if (aHandle <= TestATrait::kPropertyHandle_TaJ_Value_SaB) |
| { |
| if (nullified_path[aHandle - TraitSchemaEngine::kHandleTableOffset] != isNull) |
| { |
| nullified_path[aHandle - TraitSchemaEngine::kHandleTableOffset] = isNull; |
| } |
| } |
| } |
| |
| |
| WEAVE_ERROR |
| TestATraitDataSink::SetData(PropertyPathHandle aHandle, TLVReader &aReader, bool aIsNull) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| if (aIsNull && !mSchemaEngine->IsNullable(aHandle)) |
| { |
| WeaveLogDetail(DataManagement, "<< Non-nullable handle %d received a NULL", aHandle); |
| |
| #if TDM_DISABLE_STRICT_SCHEMA_COMPLIANCE == 0 |
| ExitNow(err = WEAVE_ERROR_INVALID_TLV_ELEMENT); |
| #endif |
| } |
| |
| SetNullifiedPath(aHandle, aIsNull); |
| |
| if ((!aIsNull) && (mSchemaEngine->IsLeaf(aHandle))) |
| { |
| err = SetLeafData(aHandle, aReader); |
| // set the parent handles to non-null |
| while (aHandle != kRootPropertyPathHandle) |
| { |
| SetNullifiedPath(aHandle, aIsNull); |
| aHandle = mSchemaEngine->GetParent(aHandle); |
| } |
| } |
| |
| #if TDM_DISABLE_STRICT_SCHEMA_COMPLIANCE == 0 |
| exit: |
| #endif |
| return err; |
| } |
| |
| WEAVE_ERROR |
| TestATraitDataSink::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| switch (GetPropertySchemaHandle(aLeafHandle)) { |
| case TestATrait::kPropertyHandle_TaA: |
| err = aReader.Get(taa); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_a = %u", taa); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaB: |
| err = aReader.Get(tab); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_b = %u", tab); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaC: |
| uint32_t next_tac; |
| err = aReader.Get(next_tac); |
| SuccessOrExit(err); |
| if (next_tac != tac) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_c is changed from %u to %u", tac, next_tac); |
| tac = next_tac; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_c = %u", tac); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaD_SaA: |
| uint32_t next_tad_saa; |
| err = aReader.Get(next_tad_saa); |
| SuccessOrExit(err); |
| if (next_tad_saa != tad.saA) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_d.sa_a is changed from %u to %u", tad.saA, next_tad_saa); |
| tad.saA = next_tad_saa; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_d.sa_a = %u", tad.saA); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaD_SaB: |
| bool next_tad_sab; |
| err = aReader.Get(next_tad_sab); |
| SuccessOrExit(err); |
| if (next_tad_sab != tad.saB) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_d.sa_b is changed from %u to %u", tad.saB, next_tad_sab); |
| tad.saB = next_tad_sab; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_d.sa_b = %u", tad.saB); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaE: |
| { |
| TLVType outerType; |
| uint32_t i = 0; |
| |
| err = aReader.EnterContainer(outerType); |
| SuccessOrExit(err); |
| |
| while (((err = aReader.Next()) == WEAVE_NO_ERROR) && (i < (sizeof(tae) / sizeof(tae[0])))) { |
| uint32_t next_tae; |
| err = aReader.Get(next_tae); |
| SuccessOrExit(err); |
| if (tae[i] != next_tae) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_e[%u] is changed from %u to %u", i, tae[i], next_tae); |
| tae[i] = next_tae; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_e[%u] = %u", i, tae[i]); |
| i++; |
| } |
| |
| err = aReader.ExitContainer(outerType); |
| break; |
| } |
| |
| case TestATrait::kPropertyHandle_TaG: |
| { |
| if (aReader.GetType() == kTLVType_UTF8String) |
| { |
| err = aReader.GetString(tag_string, sizeof(tag_string)); |
| SuccessOrExit(err); |
| |
| tag_use_ref = false; |
| |
| WeaveLogDetail(DataManagement, "<< ta_g string = %s", tag_string); |
| } |
| else |
| { |
| err = aReader.Get(tag_ref); |
| SuccessOrExit(err); |
| |
| tag_use_ref = true; |
| |
| WeaveLogDetail(DataManagement, "<< ta_g ref = %u", tag_ref); |
| } |
| } |
| break; |
| |
| case TestATrait::kPropertyHandle_TaK: |
| err = aReader.GetBytes(&tak[0], sizeof(tak)); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_k %d bytes", sizeof(tak)); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaL: |
| err = aReader.Get(tal); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_l = %x", tal); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaM: |
| err = aReader.Get(tam_resourceid); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_m = %" PRIx64 , tam_resourceid); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaN: |
| err = aReader.GetBytes(&tan[0], sizeof(tan)); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_n %d bytes", sizeof(tan)); |
| DumpMemory(&tan[0], sizeof(tan), "WEAVE:DMG: << ta_n ", 16); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaO: |
| err = aReader.Get(tao); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_o = %d", tao); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaP: |
| int64_t next_tap; |
| err = aReader.Get(next_tap); |
| SuccessOrExit(err); |
| |
| if (next_tap != tap) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_p is changed from %d to %d", tap, next_tap); |
| tap = next_tap; |
| } |
| WeaveLogDetail(DataManagement, "<< ta_p = %d", tap); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaQ: |
| err = aReader.Get(taq); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_q %" PRId64 , taq); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaR: |
| err = aReader.Get(tar); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_r %u", tar); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaS: |
| err = aReader.Get(tas); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_s %u", tas); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaT: |
| err = aReader.Get(tat); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_t %u", tat); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaU: |
| err = aReader.Get(tau); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_u %d", tau); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaV: |
| err = aReader.Get(tav); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_v %u", tav); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaW: |
| err = aReader.GetString(&taw[0], sizeof(taw)); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_w %s", taw); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaX: |
| err = aReader.Get(tax); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_x %d", tax); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaI_Value: |
| err = aReader.Get(tai_stageditem); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< tai[%u] = %u", GetPropertyDictionaryKey(aLeafHandle), tai_stageditem); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaJ_Value_SaA: |
| err = aReader.Get(taj_stageditem.saA); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< taj[%u].sa_a = %u", GetPropertyDictionaryKey(aLeafHandle), taj_stageditem.saA); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaJ_Value_SaB: |
| err = aReader.Get(taj_stageditem.saB); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< taj[%u].sa_b = %u", GetPropertyDictionaryKey(aLeafHandle), taj_stageditem.saB); |
| break; |
| |
| default: |
| WeaveLogDetail(DataManagement, "<< UNKNOWN!"); |
| } |
| |
| exit: |
| return err; |
| } |
| |
| template <typename T> |
| WEAVE_ERROR GetNextDictionaryItemKeyHelper(std::map<uint16_t, T> *aMap, typename std::map<uint16_t, T>::iterator &it, uintptr_t &aContext, PropertyDictionaryKey &aKey) |
| { |
| if (aContext == 0) { |
| it = aMap->begin(); |
| } |
| else { |
| it++; |
| } |
| |
| aContext = (uintptr_t)⁢ |
| if (it == aMap->end()) { |
| return WEAVE_END_OF_INPUT; |
| } |
| else { |
| aKey = it->first; |
| } |
| |
| return WEAVE_NO_ERROR; |
| } |
| |
| WEAVE_ERROR TestATraitDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey) |
| { |
| static std::map<uint16_t, uint32_t>::iterator tai_iter; |
| static std::map<uint16_t, TestATrait::StructA>::iterator taj_iter; |
| |
| if (aDictionaryHandle == TestATrait::kPropertyHandle_TaI) { |
| return GetNextDictionaryItemKeyHelper(&tai_map, tai_iter, aContext, aKey); |
| } |
| else if (aDictionaryHandle == TestATrait::kPropertyHandle_TaJ) { |
| return GetNextDictionaryItemKeyHelper(&taj_map, taj_iter, aContext, aKey); |
| } |
| |
| return WEAVE_ERROR_INVALID_ARGUMENT; |
| } |
| |
| WEAVE_ERROR TestATraitDataSink::GetData(PropertyPathHandle aHandle, |
| uint64_t aTagToWrite, |
| TLVWriter &aWriter, |
| bool &aIsNull, |
| bool &aIsPresent) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| if (mSchemaEngine->IsNullable(aHandle)) |
| { |
| aIsNull = nullified_path[GetPropertySchemaHandle(aHandle) - TraitSchemaEngine::kHandleTableOffset]; |
| } |
| else |
| { |
| aIsNull = false; |
| } |
| |
| aIsPresent = true; |
| |
| // TDM will handle writing null |
| if ((!aIsNull) && (aIsPresent) && (mSchemaEngine->IsLeaf(aHandle))) |
| { |
| err = GetLeafData(aHandle, aTagToWrite, aWriter); |
| } |
| |
| return err; |
| } |
| |
| |
| |
| WEAVE_ERROR TestATraitDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| switch (GetPropertySchemaHandle(aLeafHandle)) { |
| case TestATrait::kPropertyHandle_TaA: |
| err = aWriter.Put(aTagToWrite, taa); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_a = %u", taa); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaB: |
| err = aWriter.Put(aTagToWrite, tab); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_b = %u", tab); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaC: |
| err = aWriter.Put(aTagToWrite, tac); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_c = %u", tac); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaD_SaA: |
| err = aWriter.Put(aTagToWrite, tad.saA); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_d.sa_a = %u", tad.saA); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaD_SaB: |
| err = aWriter.PutBoolean(aTagToWrite, tad.saB); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_d.sa_b = %s", tad.saB ? "true" : "false"); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaE: |
| { |
| TLVType outerType; |
| |
| err = aWriter.StartContainer(aTagToWrite, kTLVType_Array, outerType); |
| SuccessOrExit(err); |
| |
| for (size_t i = 0; i < (sizeof(tae) / sizeof(tae[0])); i++) { |
| err = aWriter.Put(AnonymousTag, tae[i]); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_e[%u] = %u", i, tae[i]); |
| } |
| |
| err = aWriter.EndContainer(outerType); |
| break; |
| } |
| |
| case TestATrait::kPropertyHandle_TaG: |
| { |
| if (tag_use_ref) |
| { |
| err = aWriter.Put(aTagToWrite, tag_ref); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_g ref = %u", tag_ref); |
| } |
| else |
| { |
| err = aWriter.PutString(aTagToWrite, tag_string); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_g string = %s", tag_string); |
| } |
| } |
| break; |
| |
| case TestATrait::kPropertyHandle_TaH: |
| // maybe TODO |
| break; |
| |
| case TestATrait::kPropertyHandle_TaK: |
| err = aWriter.PutBytes(aTagToWrite, tak, sizeof(tak)); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_k %d bytes", sizeof(tak)); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaL: |
| err = aWriter.Put(aTagToWrite, tal); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_l = %x", tal); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaM: |
| err = aWriter.Put(aTagToWrite, tam_resourceid); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_m = %" PRIx64 , tam_resourceid); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaN: |
| err = aWriter.PutBytes(aTagToWrite, tan, sizeof(tan)); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_n %d bytes", sizeof(tan)); |
| DumpMemory(&tan[0], sizeof(tan), "WEAVE:DMG: >> ta_n ", 16); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaO: |
| err = aWriter.Put(aTagToWrite, tao); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_o %u", tao); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaP: |
| err = aWriter.Put(aTagToWrite, tap); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_p %" PRId64 , tap); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaQ: |
| err = aWriter.Put(aTagToWrite, taq); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_q %" PRId64 , taq); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaR: |
| err = aWriter.Put(aTagToWrite, tar); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_r %u", tar); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaS: |
| err = aWriter.Put(aTagToWrite, tas); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_s %u", tas); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaT: |
| err = aWriter.Put(aTagToWrite, tat); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_t %u", tat); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaU: |
| err = aWriter.Put(aTagToWrite, tau); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_u %d", tau); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaV: |
| err = aWriter.PutBoolean(aTagToWrite, tav); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_v %u", tav); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaW: |
| err = aWriter.PutString(aTagToWrite, taw); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_w %s", taw); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaX: |
| err = aWriter.Put(aTagToWrite, tax); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_x %d", tax); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaI_Value: |
| { |
| PropertyDictionaryKey key = GetPropertyDictionaryKey(aLeafHandle); |
| |
| err = aWriter.Put(aTagToWrite, tai_map[key]); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_i[%u] = %u", key, tai_map[key]); |
| break; |
| } |
| |
| case TestATrait::kPropertyHandle_TaJ_Value_SaA: |
| { |
| PropertyDictionaryKey key = GetPropertyDictionaryKey(aLeafHandle); |
| |
| err = aWriter.Put(aTagToWrite, taj_map[key].saA); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_j[%u].sa_a = %u", key, taj_map[key].saA); |
| break; |
| } |
| |
| |
| case TestATrait::kPropertyHandle_TaJ_Value_SaB: |
| { |
| PropertyDictionaryKey key = GetPropertyDictionaryKey(aLeafHandle); |
| |
| err = aWriter.PutBoolean(aTagToWrite, taj_map[key].saB); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_j[%u].sa_b = %u", key, taj_map[key].saB); |
| break; |
| } |
| |
| default: |
| WeaveLogDetail(DataManagement, ">> TestATrait UNKNOWN! %08x", aLeafHandle); |
| } |
| |
| exit: |
| WeaveLogFunctError(err); |
| return err; |
| } |
| |
| WEAVE_ERROR TestBTraitDataSink::GetData(PropertyPathHandle aHandle, |
| uint64_t aTagToWrite, |
| TLVWriter &aWriter, |
| bool &aIsNull, |
| bool &aIsPresent) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| if (mSchemaEngine->IsNullable(aHandle)) |
| { |
| aIsNull = nullified_path[GetPropertySchemaHandle(aHandle) - TraitSchemaEngine::kHandleTableOffset]; |
| } |
| else |
| { |
| aIsNull = false; |
| } |
| |
| aIsPresent = true; |
| |
| // TDM will handle writing null |
| if ((!aIsNull) && (aIsPresent) && (mSchemaEngine->IsLeaf(aHandle))) |
| { |
| err = GetLeafData(aHandle, aTagToWrite, aWriter); |
| } |
| |
| return err; |
| } |
| |
| WEAVE_ERROR TestBTraitDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| switch (aLeafHandle) { |
| // |
| // TestATrait |
| // |
| |
| case TestBTrait::kPropertyHandle_TaA: |
| err = aWriter.Put(aTagToWrite, taa); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_a = %u", taa); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaB: |
| err = aWriter.Put(aTagToWrite, tab); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_b = %u", tab); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaC: |
| err = aWriter.Put(aTagToWrite, tac); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_c = %u", tac); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaD_SaA: |
| err = aWriter.Put(aTagToWrite, tad_saa); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_d.sa_a = %u", tad_saa); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaD_SaB: |
| err = aWriter.PutBoolean(aTagToWrite, tad_sab); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_d.sa_b = %s", tad_sab ? "true" : "false"); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaP: |
| err = aWriter.Put(aTagToWrite, tap); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_p = %d", tap); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaE: |
| { |
| TLVType outerType; |
| |
| err = aWriter.StartContainer(aTagToWrite, kTLVType_Array, outerType); |
| SuccessOrExit(err); |
| |
| for (size_t i = 0; i < (sizeof(tae) / sizeof(tae[0])); i++) { |
| err = aWriter.Put(AnonymousTag, tae[i]); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_e[%u] = %u", i, tae[i]); |
| } |
| |
| err = aWriter.EndContainer(outerType); |
| break; |
| } |
| |
| // |
| // TestBTrait |
| // |
| |
| case TestBTrait::kPropertyHandle_TbA: |
| err = aWriter.Put(aTagToWrite, tba); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> tb_a = %u", tba); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbB_SbA: |
| err = aWriter.PutString(aTagToWrite, tbb_sba); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> tb_b.sb_a = \"%s\"", tbb_sba); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbB_SbB: |
| err = aWriter.Put(aTagToWrite, tbb_sbb); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> tb_b.sb_b = %u", tbb_sbb); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbC_SaA: |
| err = aWriter.Put(aTagToWrite, tbc_saa); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> tb_c.sa_a = %u", tbc_saa); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbC_SaB: |
| err = aWriter.PutBoolean(aTagToWrite, tbc_sab); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> tb_c.sa_b = %s", tbc_sab ? "true" : "false"); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbC_SeaC: |
| err = aWriter.PutString(aTagToWrite, tbc_seac); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> tb_c.sea_c = %s", tbc_seac); |
| break; |
| |
| default: |
| WeaveLogDetail(DataManagement, ">> UNKNOWN!"); |
| } |
| |
| exit: |
| WeaveLogFunctError(err); |
| return err; |
| } |
| |
| WEAVE_ERROR TestBTraitDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey) |
| { |
| return WEAVE_END_OF_INPUT; |
| } |
| |
| TestBTraitDataSink::TestBTraitDataSink() |
| : MockTraitDataSink(&TestBTrait::TraitSchema) |
| { |
| taa = TestATrait::ENUM_A_VALUE_1; |
| tab = TestCommon::COMMON_ENUM_A_VALUE_1; |
| tac = 0; |
| tad_saa = 0; |
| tad_sab = false; |
| |
| for (size_t i = 0; i < (sizeof(tae) / sizeof(tae[0])); i++) { |
| tae[i] = 0; |
| } |
| |
| strcpy(tai, ""); |
| |
| tba = 0; |
| strcpy(tbb_sba, ""); |
| tbb_sbb = 0; |
| |
| tbc_saa = 0; |
| tbc_sab = false; |
| strcpy(tbc_seac, ""); |
| |
| for (size_t i = 0; i < sizeof(nullified_path) / sizeof(nullified_path[0]); i++) |
| { |
| nullified_path[i] = false; |
| } |
| } |
| |
| void TestBTraitDataSink::SetNullifiedPath(PropertyPathHandle aHandle, bool isNull) |
| { |
| if (aHandle <= TestBTrait::kPropertyHandle_TaJ_Value_SaB) |
| { |
| if (nullified_path[aHandle - TraitSchemaEngine::kHandleTableOffset] != isNull) |
| { |
| nullified_path[aHandle - TraitSchemaEngine::kHandleTableOffset] = isNull; |
| } |
| } |
| } |
| |
| |
| WEAVE_ERROR |
| TestBTraitDataSink::SetData(PropertyPathHandle aHandle, TLVReader &aReader, bool aIsNull) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| if (aIsNull && !mSchemaEngine->IsNullable(aHandle)) |
| { |
| WeaveLogDetail(DataManagement, "<< Non-nullable handle %d received a NULL", aHandle); |
| |
| #if TDM_DISABLE_STRICT_SCHEMA_COMPLIANCE == 0 |
| ExitNow(err = WEAVE_ERROR_INVALID_TLV_ELEMENT); |
| #endif |
| } |
| |
| SetNullifiedPath(aHandle, aIsNull); |
| |
| if ((!aIsNull) && (mSchemaEngine->IsLeaf(aHandle))) |
| { |
| err = SetLeafData(aHandle, aReader); |
| // set the parent handles to non-null |
| while (aHandle != kRootPropertyPathHandle) |
| { |
| SetNullifiedPath(aHandle, aIsNull); |
| aHandle = mSchemaEngine->GetParent(aHandle); |
| } |
| } |
| |
| return err; |
| } |
| |
| WEAVE_ERROR |
| TestBTraitDataSink::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| switch (aLeafHandle) { |
| // |
| // TestATrait |
| // |
| |
| case TestBTrait::kPropertyHandle_TaA: |
| int32_t next_taa; |
| err = aReader.Get(next_taa); |
| SuccessOrExit(err); |
| if (next_taa != taa) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_a is changed from %u to %u", taa, next_taa); |
| taa = next_taa; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_a = %u", taa); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaB: |
| int32_t next_tab; |
| err = aReader.Get(next_tab); |
| SuccessOrExit(err); |
| if (next_tab != tab) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_b is changed from %u to %u", tab, next_tab); |
| tab = next_tab; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_b = %u", tab); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaC: |
| uint32_t next_tac; |
| err = aReader.Get(next_tac); |
| SuccessOrExit(err); |
| if (next_tac != tac) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_c is changed from %u to %u", tac, next_tac); |
| tac = next_tac; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_c = %u", tac); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaD_SaA: |
| uint32_t next_tad_saa; |
| err = aReader.Get(next_tad_saa); |
| SuccessOrExit(err); |
| if (next_tad_saa != tad_saa) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_d.sa_a is changed from %u to %u", tad_saa, next_tad_saa); |
| tad_saa = next_tad_saa; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_d.sa_a = %u", tad_saa); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaD_SaB: |
| bool next_tad_sab; |
| err = aReader.Get(next_tad_sab); |
| SuccessOrExit(err); |
| if (next_tad_sab != tad_sab) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_d.sa_b is changed from %u to %u", tad_sab, next_tad_sab); |
| tad_sab = next_tad_sab; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_d.sa_b = %u", tad_sab); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaE: |
| { |
| TLVType outerType; |
| uint32_t i = 0; |
| |
| err = aReader.EnterContainer(outerType); |
| SuccessOrExit(err); |
| |
| while (((err = aReader.Next()) == WEAVE_NO_ERROR) && (i < (sizeof(tae) / sizeof(tae[0])))) { |
| uint32_t next_tae; |
| err = aReader.Get(next_tae); |
| SuccessOrExit(err); |
| if (tae[i] != next_tae) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_e[%u] is changed from %u to %u", i, tae[i], next_tae); |
| tae[i] = next_tae; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_e[%u] = %u", i, tae[i]); |
| i++; |
| } |
| |
| err = aReader.ExitContainer(outerType); |
| break; |
| } |
| |
| case TestBTrait::kPropertyHandle_TaP: |
| err = aReader.Get(tap); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_p = %" PRId64, tap); |
| break; |
| |
| // |
| // TestBTrait |
| // |
| |
| case TestBTrait::kPropertyHandle_TbA: |
| uint32_t next_tba; |
| err = aReader.Get(next_tba); |
| SuccessOrExit(err); |
| if (tba != next_tba) |
| { |
| WeaveLogDetail(DataManagement, "<< tb_a is changed from %u to %u", tba, next_tba); |
| tba = next_tba; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< tb_a = %u", tba); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbB_SbA: |
| char next_tbb_sba[MAX_ARRAY_LEN]; |
| err = aReader.GetString(next_tbb_sba, MAX_ARRAY_SIZE); |
| SuccessOrExit(err); |
| if (strncmp(tbb_sba, next_tbb_sba, MAX_ARRAY_SIZE)) |
| { |
| WeaveLogDetail(DataManagement, "<< tb_b.sb_a is changed from %s to %s", tbb_sba, next_tbb_sba); |
| memcpy(tbb_sba, next_tbb_sba, MAX_ARRAY_SIZE); |
| } |
| |
| WeaveLogDetail(DataManagement, "<< tb_b.sb_a = %s", tbb_sba); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbB_SbB: |
| uint32_t next_tbb_sbb; |
| err = aReader.Get(next_tbb_sbb); |
| SuccessOrExit(err); |
| if (tbb_sbb != next_tbb_sbb) |
| { |
| WeaveLogDetail(DataManagement, "<< tb_b.sb_b is changed from %u to %u", tbb_sbb, next_tbb_sbb); |
| tbb_sbb = next_tbb_sbb; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< tb_b.sb_b = %u", tbb_sbb); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbC_SaA: |
| uint32_t next_tbc_saa; |
| err = aReader.Get(next_tbc_saa); |
| SuccessOrExit(err); |
| if (tbc_saa != next_tbc_saa) |
| { |
| WeaveLogDetail(DataManagement, "<< tb_c.sa_a is changed from %u to %u", tbc_saa, next_tbc_saa); |
| tbc_saa = next_tbc_saa; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< tb_c.sa_a = %u", tbc_saa); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbC_SaB: |
| bool next_tbc_sab; |
| err = aReader.Get(next_tbc_sab); |
| SuccessOrExit(err); |
| if (tbc_sab != next_tbc_sab) |
| { |
| WeaveLogDetail(DataManagement, "<< tb_c.sa_b is changed from %u to %u", tbc_sab, next_tbc_sab); |
| tbc_sab = next_tbc_sab; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< tb_c.sa_b = %u", tbc_sab); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbC_SeaC: |
| char next_tbc_seac[MAX_ARRAY_LEN]; |
| err = aReader.GetString(next_tbc_seac, MAX_ARRAY_SIZE); |
| SuccessOrExit(err); |
| if (strncmp(tbc_seac, next_tbc_seac, MAX_ARRAY_SIZE)) |
| { |
| WeaveLogDetail(DataManagement, "<< tb_c.sea_c is changed from \"%s\" to \"%s\"", tbc_seac, next_tbc_seac); |
| memcpy(tbc_seac, next_tbc_seac, MAX_ARRAY_SIZE); |
| } |
| |
| WeaveLogDetail(DataManagement, "<< tb_c.sea_c = \"%s\"", tbc_seac); |
| break; |
| |
| default: |
| WeaveLogDetail(DataManagement, "<< TestBTrait UNKNOWN! %08x", aLeafHandle); |
| } |
| |
| exit: |
| return err; |
| } |
| |
| TestApplicationKeysTraitDataSink::TestApplicationKeysTraitDataSink(void) |
| { |
| } |
| |
| enum |
| { |
| #if WEAVE_CONFIG_MAX_APPLICATION_EPOCH_KEYS > WEAVE_CONFIG_MAX_APPLICATION_GROUPS |
| kMaxGroupKeysOfATypeCount = WEAVE_CONFIG_MAX_APPLICATION_EPOCH_KEYS, |
| #else |
| kMaxGroupKeysOfATypeCount = WEAVE_CONFIG_MAX_APPLICATION_GROUPS, |
| #endif |
| }; |
| |
| WEAVE_ERROR TestApplicationKeysTraitDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| TLVType outerContainerType; |
| uint32_t keyType; |
| uint32_t keyIds[kMaxGroupKeysOfATypeCount]; |
| uint8_t keyCount; |
| WeaveGroupKey groupKey; |
| |
| VerifyOrExit(GroupKeyStore != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT); |
| |
| if (ApplicationKeysTrait::kPropertyHandle_EpochKeys == aLeafHandle) |
| { |
| keyType = WeaveKeyId::kType_AppEpochKey; |
| } |
| else if (ApplicationKeysTrait::kPropertyHandle_MasterKeys == aLeafHandle) |
| { |
| keyType = WeaveKeyId::kType_AppGroupMasterKey; |
| } |
| else |
| { |
| ExitNow(err = WEAVE_ERROR_INVALID_TLV_TAG); |
| } |
| |
| err = aWriter.StartContainer(aTagToWrite, kTLVType_Array, outerContainerType); |
| SuccessOrExit(err); |
| |
| err = GroupKeyStore->EnumerateGroupKeys(keyType, keyIds, sizeof(keyIds) / sizeof(keyIds[0]), keyCount); |
| SuccessOrExit(err); |
| |
| for (int i = 0; i < keyCount; ++i) |
| { |
| err = GroupKeyStore->GetGroupKey(keyIds[i], groupKey); |
| SuccessOrExit(err); |
| |
| TLVType containerType2; |
| |
| err = aWriter.StartContainer(AnonymousTag, kTLVType_Structure, containerType2); |
| SuccessOrExit(err); |
| |
| if (keyType == WeaveKeyId::kType_AppEpochKey) |
| { |
| const uint32_t epochKeyNumber = WeaveKeyId::GetEpochKeyNumber(groupKey.KeyId); |
| err = aWriter.Put(ContextTag(kTag_EpochKey_KeyId), epochKeyNumber); |
| SuccessOrExit(err); |
| |
| err = aWriter.Put(ContextTag(kTag_EpochKey_StartTime), (static_cast<int64_t>(groupKey.StartTime) * 1000)); |
| SuccessOrExit(err); |
| |
| err = aWriter.PutBytes(ContextTag(kTag_EpochKey_Key), groupKey.Key, groupKey.KeyLen); |
| SuccessOrExit(err); |
| |
| err = aWriter.EndContainer(containerType2); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> GroupEpochKeyId = %08" PRIX32, groupKey.KeyId); |
| } |
| // If master group key. |
| else |
| { |
| err = aWriter.Put(ContextTag(kTag_ApplicationGroup_GlobalId), groupKey.GlobalId); |
| SuccessOrExit(err); |
| |
| const uint32_t appGroupLocalNumber = WeaveKeyId::GetAppGroupLocalNumber(groupKey.KeyId); |
| err = aWriter.Put(ContextTag(kTag_ApplicationGroup_ShortId), appGroupLocalNumber); |
| SuccessOrExit(err); |
| |
| err = aWriter.PutBytes(ContextTag(kTag_ApplicationGroup_Key), groupKey.Key, groupKey.KeyLen); |
| SuccessOrExit(err); |
| |
| err = aWriter.EndContainer(containerType2); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> GroupMasterKeyId = %08" PRIX32, groupKey.KeyId); |
| } |
| } |
| |
| err = aWriter.EndContainer(outerContainerType); |
| SuccessOrExit(err); |
| |
| exit: |
| |
| WeaveLogFunctError(err); |
| |
| return err; |
| } |
| |
| WEAVE_ERROR TestApplicationKeysTraitDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey) |
| { |
| return WEAVE_END_OF_INPUT; |
| } |
| |
| #if WEAVE_CONFIG_ENABLE_WDM_UPDATE |
| 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(SubscriptionClient * apSubClient, |
| bool aIsConditional, |
| MockWdmNodeOptions::WdmUpdateMutation aMutation) |
| { |
| 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; |
| |
| Lock(apSubClient); |
| |
| MOCK_strlcpy(mLocale, locales[whichLocale], sizeof(mLocale)); |
| whichLocale = (whichLocale + 1) % (sizeof(locales)/sizeof(locales[0])); |
| |
| // This trait instance only supports the OneLeaf and Root mutations. |
| |
| switch (aMutation) |
| { |
| case MockWdmNodeOptions::kMutation_Root: |
| pathHandle = LocaleSettingsTrait::kPropertyHandle_Root; |
| break; |
| |
| case MockWdmNodeOptions::kMutation_OneLeaf: |
| default: |
| aMutation = MockWdmNodeOptions::kMutation_OneLeaf; |
| pathHandle = LocaleSettingsTrait::kPropertyHandle_active_locale; |
| break; |
| } |
| |
| WeaveLogDetail(DataManagement, "<set updated> in 0x%08x", pathHandle); |
| |
| err = SetUpdated(apSubClient, pathHandle, aIsConditional); |
| SuccessOrExit(err); |
| |
| exit: |
| WeaveLogDetail(DataManagement, "LocaleSettingsTrait mutated %s with error %d", MockWdmNodeOptions::GetMutationStrings()[aMutation], err); |
| |
| Unlock(apSubClient); |
| |
| return err; |
| } |
| |
| WEAVE_ERROR LocaleSettingsTraitUpdatableDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey) |
| { |
| return WEAVE_END_OF_INPUT; |
| } |
| |
| WEAVE_ERROR TestATraitUpdatableDataSink::Mutate(SubscriptionClient * apSubClient, |
| bool aIsConditional, |
| MockWdmNodeOptions::WdmUpdateMutation aMutation) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| Lock(apSubClient); |
| |
| WeaveLogDetail(DataManagement, |
| "TestATraitUpdatableDataSink: mTraitTestSet: %" PRIu32 ", mTestCounter: %" PRIu32 "", |
| mTraitTestSet, mTestCounter); |
| |
| switch (aMutation) |
| { |
| case MockWdmNodeOptions::kMutation_OneLeaf: |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaP, aIsConditional); |
| SuccessOrExit(err); |
| |
| tap++; |
| |
| break; |
| |
| case MockWdmNodeOptions::kMutation_SameLevelLeaves: |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaP, aIsConditional); |
| SuccessOrExit(err); |
| |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaC, aIsConditional); |
| SuccessOrExit(err); |
| |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaR, aIsConditional); |
| SuccessOrExit(err); |
| |
| tap++; |
| tac++; |
| tar++; |
| |
| break; |
| |
| case MockWdmNodeOptions::kMutation_DiffLevelLeaves: |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaD_SaB, aIsConditional); |
| SuccessOrExit(err); |
| |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaA, aIsConditional); |
| SuccessOrExit(err); |
| |
| if (taa == TestATrait::ENUM_A_VALUE_1) { |
| taa = TestATrait::ENUM_A_VALUE_2; |
| } |
| else { |
| taa = TestATrait::ENUM_A_VALUE_1; |
| } |
| |
| tad.saB = !tad.saB; |
| |
| break; |
| |
| case MockWdmNodeOptions::kMutation_WholeDictionary: |
| { |
| uint32_t seed = 0; |
| |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaI, aIsConditional); |
| SuccessOrExit(err); |
| |
| if (tai_map[0] == seed) |
| { |
| // Just make sure we change the data |
| seed = 100; |
| } |
| |
| tai_map.clear(); |
| for (uint16_t i = 0; i < 10; i++) { |
| tai_map[i] = { (uint32_t)i + seed }; |
| } |
| |
| break; |
| } |
| |
| case MockWdmNodeOptions::kMutation_WholeLargeDictionary: |
| { |
| uint32_t seed = 0; |
| |
| // Add a leaf as well before the dictionary to prevent a regression; if the whole process |
| // fails while encoding partial dictionaries, a retry will succeed only if the update context |
| // has been reset properly; the reason is that if the dictionary encoder has left |
| // stale state in the update context, the encoding of the leaf fails immediately. |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaP, aIsConditional); |
| SuccessOrExit(err); |
| |
| tap++; |
| |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaI, aIsConditional); |
| SuccessOrExit(err); |
| |
| if (tai_map[0] == seed) |
| { |
| // Just make sure we change the data |
| seed = 100; |
| } |
| |
| tai_map.clear(); |
| for (uint16_t i = 0; i < 800; i++) { |
| tai_map[i] = { (uint32_t)i + 1 }; |
| } |
| |
| break; |
| } |
| |
| case MockWdmNodeOptions::kMutation_FewDictionaryItems: |
| err = SetUpdated(apSubClient, CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaI_Value, 4), aIsConditional); |
| SuccessOrExit(err); |
| |
| err = SetUpdated(apSubClient, CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaI_Value, 5), aIsConditional); |
| SuccessOrExit(err); |
| |
| err = SetUpdated(apSubClient, CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaI_Value, 6), aIsConditional); |
| SuccessOrExit(err); |
| |
| err = SetUpdated(apSubClient, CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaI_Value, 7), aIsConditional); |
| SuccessOrExit(err); |
| |
| tai_map[4] = { 4 }; |
| tai_map[5] = { 5 }; |
| tai_map[6] = { 6 }; |
| tai_map[7] = { 7 }; |
| |
| break; |
| |
| case MockWdmNodeOptions::kMutation_ManyDictionaryItems: |
| for (size_t i = 0; i < 60; i++) |
| { |
| err = SetUpdated(apSubClient, CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaI_Value, i), aIsConditional); |
| SuccessOrExit(err); |
| |
| tai_map[i] = { static_cast<uint32_t>(i) }; |
| } |
| |
| break; |
| |
| case MockWdmNodeOptions::kMutation_WholeDictionaryAndLeaf: |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaI, aIsConditional); |
| SuccessOrExit(err); |
| |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaP, aIsConditional); |
| SuccessOrExit(err); |
| |
| tai_map.clear(); |
| for (uint16_t i = 0; i < 10; i++) { |
| tai_map[i] = { static_cast<uint32_t>(i) + 1 }; |
| } |
| |
| tap++; |
| |
| break; |
| |
| case MockWdmNodeOptions::kMutation_OneStructure: |
| |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaD, aIsConditional); |
| SuccessOrExit(err); |
| |
| tad.saA = mTestCounter; |
| tad.saB = !tad.saB; |
| |
| break; |
| |
| case MockWdmNodeOptions::kMutation_OneLeafOneStructure: |
| |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaP, aIsConditional); |
| SuccessOrExit(err); |
| |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaD, aIsConditional); |
| SuccessOrExit(err); |
| |
| tap++; |
| |
| tad.saA = mTestCounter; |
| tad.saB = !tad.saB; |
| |
| break; |
| |
| case MockWdmNodeOptions::kMutation_Root: |
| { |
| |
| Schema::Nest::Test::Trait::TestATrait::StructA tmpTajItem; |
| |
| // Root and some more subpaths |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaD_SaA, aIsConditional); |
| SuccessOrExit(err); |
| |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaA, aIsConditional); |
| SuccessOrExit(err); |
| |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaD, aIsConditional); |
| SuccessOrExit(err); |
| |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaI, aIsConditional); |
| SuccessOrExit(err); |
| |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_Root, aIsConditional); |
| SuccessOrExit(err); |
| |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_TaD, aIsConditional); |
| SuccessOrExit(err); |
| |
| tai_map.clear(); |
| // test_weave_wdm_next_service_update_10_cond_Root_multi_traits.py depends on |
| // the number of items added the to the dictionaries here |
| for (uint16_t i = 0; i < 85; i++) { |
| tai_map[i] = { ((uint32_t)i + 1)*10 + 7 }; |
| } |
| |
| taj_map.clear(); |
| tmpTajItem.saB = tad.saB; |
| tmpTajItem.saA = 0; |
| if (tmpTajItem.saB) |
| { |
| tmpTajItem.saA++; |
| } |
| for (uint16_t i = 0; i < 10; i++) { |
| tmpTajItem.saA++; |
| taj_map[i] = tmpTajItem; |
| } |
| |
| if (taa == TestATrait::ENUM_A_VALUE_1) { |
| taa = TestATrait::ENUM_A_VALUE_2; |
| } |
| else { |
| taa = TestATrait::ENUM_A_VALUE_1; |
| } |
| |
| tad.saB = !tad.saB; |
| |
| break; |
| } |
| |
| case MockWdmNodeOptions::kMutation_RootWithLargeDictionary: |
| |
| err = SetUpdated(apSubClient, TestATrait::kPropertyHandle_Root, aIsConditional); |
| SuccessOrExit(err); |
| |
| tai_map.clear(); |
| for (uint16_t i = 0; i < 800; i++) { |
| tai_map[i] = { ((uint32_t)i + 1)*10 + 3 }; |
| } |
| |
| tad.saB = !tad.saB; |
| |
| break; |
| |
| default: |
| WeaveDie(); |
| break; |
| } |
| |
| mTestCounter++; |
| |
| exit: |
| |
| WeaveLogDetail(DataManagement, "TestATrait mutated %s with error %d", MockWdmNodeOptions::GetMutationStrings()[aMutation], err); |
| |
| Unlock(apSubClient); |
| |
| return err; |
| } |
| |
| TestATraitUpdatableDataSink::TestATraitUpdatableDataSink() |
| : MockTraitUpdatableDataSink(&TestATrait::TraitSchema) |
| { |
| taa = TestATrait::ENUM_A_VALUE_1; |
| tab = TestCommon::COMMON_ENUM_A_VALUE_1; |
| tac = 0; |
| tad.saA = 0; |
| tad.saB = false; |
| |
| for (size_t i = 0; i < (sizeof(tae) / sizeof(tae[0])); i++) { |
| tae[i] = 0; |
| } |
| for (size_t i = 0; i < sizeof(nullified_path) / sizeof(nullified_path[0]); i++) |
| { |
| nullified_path[i] = false; |
| } |
| } |
| |
| WEAVE_ERROR |
| TestATraitUpdatableDataSink::OnEvent(uint16_t aType, void *aInParam) |
| { |
| InEventParam *inParam = static_cast<InEventParam *>(aInParam); |
| PropertyPathHandle handle; |
| PropertyDictionaryKey key; |
| |
| switch (aType) { |
| case kEventDictionaryReplaceBegin: |
| case kEventDictionaryReplaceEnd: |
| case kEventDictionaryItemModifyBegin: |
| case kEventDictionaryItemModifyEnd: |
| WeaveLogDetail(DataManagement, "TestATraitUpdatableDataSink::OnEvent event: %u (handle: %08x)", aType, *(PropertyPathHandle *)aInParam); |
| break; |
| |
| default: |
| WeaveLogDetail(DataManagement, "TestATraitUpdatableDataSink::OnEvent event: %u", aType); |
| } |
| |
| switch (aType) { |
| case kEventDictionaryReplaceBegin: |
| handle = inParam->mDictionaryItemModifyBegin.mTargetHandle; |
| |
| if (handle == TestATrait::kPropertyHandle_TaI) { |
| WeaveLogDetail(DataManagement, "Clearing out dictionary tai..."); |
| tai_map.clear(); |
| } |
| else if (handle == TestATrait::kPropertyHandle_TaJ) { |
| WeaveLogDetail(DataManagement, "Clearing out dictionary taj..."); |
| taj_map.clear(); |
| } |
| else { |
| WeaveLogDetail(DataManagement, "Unknown dictionary!"); |
| } |
| |
| break; |
| |
| case kEventDictionaryItemDelete: |
| handle = inParam->mDictionaryItemDelete.mTargetHandle; |
| key = GetPropertyDictionaryKey(handle); |
| |
| if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaI_Value) { |
| WeaveLogDetail(DataManagement, "Deleting key %u from tai...", key); |
| tai_map.erase(key); |
| } |
| else if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaJ_Value) { |
| WeaveLogDetail(DataManagement, "Deleting key %u from taj...", key); |
| taj_map.erase(key); |
| } |
| |
| break; |
| |
| case kEventDictionaryItemModifyBegin: |
| handle = inParam->mDictionaryItemModifyBegin.mTargetHandle; |
| key = GetPropertyDictionaryKey(handle); |
| |
| if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaI_Value) { |
| if (tai_map.find(key) == tai_map.end()) { |
| WeaveLogDetail(DataManagement, "Staging new key %u for tai...", key); |
| memset(&tai_stageditem, 0, sizeof(tai_stageditem)); |
| } |
| else { |
| WeaveLogDetail(DataManagement, "Modifying key %u in tai...", key); |
| tai_stageditem = tai_map[key]; |
| } |
| } |
| else if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaJ_Value) { |
| if (taj_map.find(key) == taj_map.end()) { |
| WeaveLogDetail(DataManagement, "Staging new key %u for taj...", key); |
| memset(&taj_stageditem, 0, sizeof(taj_stageditem)); |
| } |
| else { |
| WeaveLogDetail(DataManagement, "Modifying key %u in taj...", key); |
| taj_stageditem = taj_map[key]; |
| } |
| } |
| |
| break; |
| |
| case kEventDictionaryItemModifyEnd: |
| handle = inParam->mDictionaryItemModifyEnd.mTargetHandle; |
| key = GetPropertyDictionaryKey(handle); |
| |
| if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaI_Value) { |
| if (tai_map.find(key) == tai_map.end()) { |
| WeaveLogDetail(DataManagement, "Adding key %u to tai...", key); |
| } |
| |
| tai_map[key] = tai_stageditem; |
| } |
| else if (GetPropertySchemaHandle(handle) == TestATrait::kPropertyHandle_TaJ_Value) { |
| if (taj_map.find(key) == taj_map.end()) { |
| WeaveLogDetail(DataManagement, "Adding key %u to taj...", key); |
| } |
| |
| taj_map[key] = taj_stageditem; |
| } |
| |
| break; |
| } |
| |
| return WEAVE_NO_ERROR; |
| } |
| |
| void TestATraitUpdatableDataSink::SetNullifiedPath(PropertyPathHandle aHandle, bool isNull) |
| { |
| if (aHandle <= TestATrait::kPropertyHandle_TaJ_Value_SaB) |
| { |
| if (nullified_path[aHandle - TraitSchemaEngine::kHandleTableOffset] != isNull) |
| { |
| nullified_path[aHandle - TraitSchemaEngine::kHandleTableOffset] = isNull; |
| } |
| } |
| } |
| |
| |
| WEAVE_ERROR |
| TestATraitUpdatableDataSink::SetData(PropertyPathHandle aHandle, TLVReader &aReader, bool aIsNull) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| if (aIsNull && !mSchemaEngine->IsNullable(aHandle)) |
| { |
| WeaveLogDetail(DataManagement, "<< Non-nullable handle %d received a NULL", aHandle); |
| |
| #if TDM_DISABLE_STRICT_SCHEMA_COMPLIANCE == 0 |
| ExitNow(err = WEAVE_ERROR_INVALID_TLV_ELEMENT); |
| #endif |
| } |
| |
| SetNullifiedPath(aHandle, aIsNull); |
| |
| if ((!aIsNull) && (mSchemaEngine->IsLeaf(aHandle))) |
| { |
| err = SetLeafData(aHandle, aReader); |
| // set the parent handles to non-null |
| while (aHandle != kRootPropertyPathHandle) |
| { |
| SetNullifiedPath(aHandle, aIsNull); |
| aHandle = mSchemaEngine->GetParent(aHandle); |
| } |
| } |
| |
| #if TDM_DISABLE_STRICT_SCHEMA_COMPLIANCE == 0 |
| exit: |
| #endif |
| return err; |
| } |
| |
| WEAVE_ERROR |
| TestATraitUpdatableDataSink::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| switch (GetPropertySchemaHandle(aLeafHandle)) { |
| case TestATrait::kPropertyHandle_TaA: |
| err = aReader.Get(taa); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_a = %u", taa); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaB: |
| err = aReader.Get(tab); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_b = %u", tab); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaC: |
| uint32_t next_tac; |
| err = aReader.Get(next_tac); |
| SuccessOrExit(err); |
| if (next_tac != tac) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_c is changed from %u to %u", tac, next_tac); |
| tac = next_tac; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_c = %u", tac); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaD_SaA: |
| uint32_t next_tad_saa; |
| err = aReader.Get(next_tad_saa); |
| SuccessOrExit(err); |
| if (next_tad_saa != tad.saA) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_d.sa_a is changed from %u to %u", tad.saA, next_tad_saa); |
| tad.saA = next_tad_saa; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_d.sa_a = %u", tad.saA); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaD_SaB: |
| bool next_tad_sab; |
| err = aReader.Get(next_tad_sab); |
| SuccessOrExit(err); |
| if (next_tad_sab != tad.saB) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_d.sa_b is changed from %u to %u", tad.saB, next_tad_sab); |
| tad.saB = next_tad_sab; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_d.sa_b = %u", tad.saB); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaE: |
| { |
| TLVType outerType; |
| uint32_t i = 0; |
| |
| err = aReader.EnterContainer(outerType); |
| SuccessOrExit(err); |
| |
| while (((err = aReader.Next()) == WEAVE_NO_ERROR) && (i < (sizeof(tae) / sizeof(tae[0])))) { |
| uint32_t next_tae; |
| err = aReader.Get(next_tae); |
| SuccessOrExit(err); |
| if (tae[i] != next_tae) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_e[%u] is changed from %u to %u", i, tae[i], next_tae); |
| tae[i] = next_tae; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_e[%u] = %u", i, tae[i]); |
| i++; |
| } |
| |
| err = aReader.ExitContainer(outerType); |
| break; |
| } |
| |
| case TestATrait::kPropertyHandle_TaG: |
| { |
| if (aReader.GetType() == kTLVType_UTF8String) |
| { |
| err = aReader.GetString(tag_string, sizeof(tag_string)); |
| SuccessOrExit(err); |
| |
| tag_use_ref = false; |
| |
| WeaveLogDetail(DataManagement, "<< ta_g string = %s", tag_string); |
| } |
| else |
| { |
| err = aReader.Get(tag_ref); |
| SuccessOrExit(err); |
| |
| tag_use_ref = true; |
| |
| WeaveLogDetail(DataManagement, "<< ta_g ref = %u", tag_ref); |
| } |
| } |
| break; |
| |
| case TestATrait::kPropertyHandle_TaK: |
| err = aReader.GetBytes(&tak[0], sizeof(tak)); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_k %d bytes", sizeof(tak)); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaL: |
| err = aReader.Get(tal); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_l = %x", tal); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaM: |
| err = aReader.Get(tam_resourceid); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_m = %" PRIx64 , tam_resourceid); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaN: |
| err = aReader.GetBytes(&tan[0], sizeof(tan)); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_n %d bytes", sizeof(tan)); |
| DumpMemory(&tan[0], sizeof(tan), "WEAVE:DMG: << ta_n ", 16); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaO: |
| err = aReader.Get(tao); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_o = %d", tao); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaP: |
| int64_t next_tap; |
| err = aReader.Get(next_tap); |
| SuccessOrExit(err); |
| |
| if (next_tap != tap) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_p is changed from %d to %d", tap, next_tap); |
| tap = next_tap; |
| } |
| WeaveLogDetail(DataManagement, "<< ta_p = %d", tap); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaQ: |
| err = aReader.Get(taq); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_q %" PRId64 , taq); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaR: |
| err = aReader.Get(tar); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_r %u", tar); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaS: |
| err = aReader.Get(tas); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_s %u", tas); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaT: |
| err = aReader.Get(tat); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_t %u", tat); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaU: |
| err = aReader.Get(tau); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_u %d", tau); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaV: |
| err = aReader.Get(tav); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_v %u", tav); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaW: |
| err = aReader.GetString(&taw[0], sizeof(taw)); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_w %s", taw); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaX: |
| err = aReader.Get(tax); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_x %d", tax); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaI_Value: |
| err = aReader.Get(tai_stageditem); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< tai[%u] = %u", GetPropertyDictionaryKey(aLeafHandle), tai_stageditem); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaJ_Value_SaA: |
| err = aReader.Get(taj_stageditem.saA); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< taj[%u].sa_a = %u", GetPropertyDictionaryKey(aLeafHandle), taj_stageditem.saA); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaJ_Value_SaB: |
| err = aReader.Get(taj_stageditem.saB); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< taj[%u].sa_b = %u", GetPropertyDictionaryKey(aLeafHandle), taj_stageditem.saB); |
| break; |
| |
| default: |
| WeaveLogDetail(DataManagement, "<< UNKNOWN!"); |
| } |
| |
| exit: |
| return err; |
| } |
| |
| WEAVE_ERROR TestATraitUpdatableDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey) |
| { |
| static std::map<uint16_t, uint32_t>::iterator tai_iter; |
| static std::map<uint16_t, TestATrait::StructA>::iterator taj_iter; |
| |
| if (aDictionaryHandle == TestATrait::kPropertyHandle_TaI) { |
| return GetNextDictionaryItemKeyHelper(&tai_map, tai_iter, aContext, aKey); |
| } |
| else if (aDictionaryHandle == TestATrait::kPropertyHandle_TaJ) { |
| return GetNextDictionaryItemKeyHelper(&taj_map, taj_iter, aContext, aKey); |
| } |
| |
| return WEAVE_ERROR_INVALID_ARGUMENT; |
| } |
| |
| WEAVE_ERROR TestATraitUpdatableDataSink::GetData(PropertyPathHandle aHandle, |
| uint64_t aTagToWrite, |
| TLVWriter &aWriter, |
| bool &aIsNull, |
| bool &aIsPresent) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| if (mSchemaEngine->IsNullable(aHandle)) |
| { |
| aIsNull = nullified_path[GetPropertySchemaHandle(aHandle) - TraitSchemaEngine::kHandleTableOffset]; |
| } |
| else |
| { |
| aIsNull = false; |
| } |
| |
| aIsPresent = true; |
| |
| // TDM will handle writing null |
| if ((!aIsNull) && (aIsPresent) && (mSchemaEngine->IsLeaf(aHandle))) |
| { |
| err = GetLeafData(aHandle, aTagToWrite, aWriter); |
| } |
| |
| return err; |
| } |
| |
| |
| |
| WEAVE_ERROR TestATraitUpdatableDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| switch (GetPropertySchemaHandle(aLeafHandle)) { |
| case TestATrait::kPropertyHandle_TaA: |
| err = aWriter.Put(aTagToWrite, taa); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_a = %u", taa); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaB: |
| err = aWriter.Put(aTagToWrite, tab); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_b = %u", tab); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaC: |
| err = aWriter.Put(aTagToWrite, tac); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_c = %u", tac); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaD_SaA: |
| err = aWriter.Put(aTagToWrite, tad.saA); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_d.sa_a = %u", tad.saA); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaD_SaB: |
| err = aWriter.PutBoolean(aTagToWrite, tad.saB); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_d.sa_b = %s", tad.saB ? "true" : "false"); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaE: |
| { |
| TLVType outerType; |
| |
| err = aWriter.StartContainer(aTagToWrite, kTLVType_Array, outerType); |
| SuccessOrExit(err); |
| |
| for (size_t i = 0; i < (sizeof(tae) / sizeof(tae[0])); i++) { |
| err = aWriter.Put(AnonymousTag, tae[i]); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_e[%u] = %u", i, tae[i]); |
| } |
| |
| err = aWriter.EndContainer(outerType); |
| break; |
| } |
| |
| case TestATrait::kPropertyHandle_TaG: |
| { |
| if (tag_use_ref) |
| { |
| err = aWriter.Put(aTagToWrite, tag_ref); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_g ref = %u", tag_ref); |
| } |
| else |
| { |
| err = aWriter.PutString(aTagToWrite, tag_string); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_g string = %s", tag_string); |
| } |
| } |
| break; |
| |
| case TestATrait::kPropertyHandle_TaH: |
| // maybe TODO |
| break; |
| |
| case TestATrait::kPropertyHandle_TaK: |
| err = aWriter.PutBytes(aTagToWrite, tak, sizeof(tak)); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_k %d bytes", sizeof(tak)); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaL: |
| err = aWriter.Put(aTagToWrite, tal); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_l = %x", tal); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaM: |
| err = aWriter.Put(aTagToWrite, tam_resourceid); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_m = %" PRIx64 , tam_resourceid); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaN: |
| err = aWriter.PutBytes(aTagToWrite, tan, sizeof(tan)); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_n %d bytes", sizeof(tan)); |
| DumpMemory(&tan[0], sizeof(tan), "WEAVE:DMG: >> ta_n ", 16); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaO: |
| err = aWriter.Put(aTagToWrite, tao); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_o %u", tao); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaP: |
| err = aWriter.Put(aTagToWrite, tap); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_p %" PRId64 , tap); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaQ: |
| err = aWriter.Put(aTagToWrite, taq); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_q %" PRId64 , taq); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaR: |
| err = aWriter.Put(aTagToWrite, tar); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_r %u", tar); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaS: |
| err = aWriter.Put(aTagToWrite, tas); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_s %u", tas); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaT: |
| err = aWriter.Put(aTagToWrite, tat); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_t %u", tat); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaU: |
| err = aWriter.Put(aTagToWrite, tau); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_u %d", tau); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaV: |
| err = aWriter.PutBoolean(aTagToWrite, tav); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_v %u", tav); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaW: |
| err = aWriter.PutString(aTagToWrite, taw); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_w %s", taw); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaX: |
| err = aWriter.Put(aTagToWrite, tax); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_x %d", tax); |
| break; |
| |
| case TestATrait::kPropertyHandle_TaI_Value: |
| { |
| PropertyDictionaryKey key = GetPropertyDictionaryKey(aLeafHandle); |
| |
| err = aWriter.Put(aTagToWrite, tai_map[key]); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_i[%u] = %u", key, tai_map[key]); |
| break; |
| } |
| |
| case TestATrait::kPropertyHandle_TaJ_Value_SaA: |
| { |
| PropertyDictionaryKey key = GetPropertyDictionaryKey(aLeafHandle); |
| |
| err = aWriter.Put(aTagToWrite, taj_map[key].saA); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_j[%u].sa_a = %u", key, taj_map[key].saA); |
| break; |
| } |
| |
| |
| case TestATrait::kPropertyHandle_TaJ_Value_SaB: |
| { |
| PropertyDictionaryKey key = GetPropertyDictionaryKey(aLeafHandle); |
| |
| err = aWriter.PutBoolean(aTagToWrite, taj_map[key].saB); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_j[%u].sa_b = %u", key, taj_map[key].saB); |
| break; |
| } |
| |
| default: |
| WeaveLogDetail(DataManagement, ">> TestATrait UNKNOWN! %08x", aLeafHandle); |
| } |
| |
| exit: |
| WeaveLogFunctError(err); |
| return err; |
| } |
| |
| TestBTraitUpdatableDataSink::TestBTraitUpdatableDataSink() |
| : MockTraitUpdatableDataSink(&TestBTrait::TraitSchema) |
| { |
| taa = TestATrait::ENUM_A_VALUE_1; |
| tab = TestCommon::COMMON_ENUM_A_VALUE_1; |
| tac = 0; |
| tad_saa = 0; |
| tad_sab = false; |
| |
| for (size_t i = 0; i < (sizeof(tae) / sizeof(tae[0])); i++) { |
| tae[i] = 0; |
| } |
| |
| strcpy(tai, ""); |
| |
| tba = 0; |
| strcpy(tbb_sba, ""); |
| tbb_sbb = 0; |
| |
| tbc_saa = 0; |
| tbc_sab = false; |
| strcpy(tbc_seac, ""); |
| |
| for (size_t i = 0; i < sizeof(nullified_path) / sizeof(nullified_path[0]); i++) |
| { |
| nullified_path[i] = false; |
| } |
| } |
| |
| WEAVE_ERROR TestBTraitUpdatableDataSink::Mutate(SubscriptionClient * apSubClient, |
| bool aIsConditional, |
| MockWdmNodeOptions::WdmUpdateMutation aMutation) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| static int testNum = 0; |
| const int numTests = 3; |
| |
| Lock(apSubClient); |
| |
| switch (aMutation) |
| { |
| case MockWdmNodeOptions::kMutation_OneLeafOneStructure: |
| |
| err = SetUpdated(apSubClient, TestBTrait::kPropertyHandle_TbB_SbB, aIsConditional); |
| SuccessOrExit(err); |
| |
| err = SetUpdated(apSubClient, TestBTrait::kPropertyHandle_TaA, aIsConditional); |
| SuccessOrExit(err); |
| |
| if (taa == TestATrait::ENUM_A_VALUE_1) { |
| taa = TestATrait::ENUM_A_VALUE_2; |
| } |
| else { |
| taa = TestATrait::ENUM_A_VALUE_1; |
| } |
| |
| tbb_sbb++; |
| |
| break; |
| |
| case MockWdmNodeOptions::kMutation_DiffLevelLeaves: |
| |
| err = SetUpdated(apSubClient, TestBTrait::kPropertyHandle_TaC, aIsConditional); |
| SuccessOrExit(err); |
| |
| err = SetUpdated(apSubClient, TestBTrait::kPropertyHandle_TaP, aIsConditional); |
| SuccessOrExit(err); |
| |
| err = SetUpdated(apSubClient, TestBTrait::kPropertyHandle_TbC_SaB, aIsConditional); |
| SuccessOrExit(err); |
| |
| tap++; |
| tac++; |
| tbc_sab = !tbc_sab; |
| |
| break; |
| |
| case MockWdmNodeOptions::kMutation_OneLeaf: |
| default: |
| aMutation = MockWdmNodeOptions::kMutation_OneLeaf; |
| |
| err = SetUpdated(apSubClient, TestBTrait::kPropertyHandle_TaP, aIsConditional); |
| SuccessOrExit(err); |
| |
| tap++; |
| break; |
| } |
| |
| testNum = (testNum +1) % numTests; |
| |
| exit: |
| WeaveLogDetail(DataManagement, "TestBTrait mutated %s with error %d", MockWdmNodeOptions::GetMutationStrings()[aMutation], err); |
| |
| Unlock(apSubClient); |
| |
| return err; |
| } |
| |
| void TestBTraitUpdatableDataSink::SetNullifiedPath(PropertyPathHandle aHandle, bool isNull) |
| { |
| if (aHandle <= TestBTrait::kPropertyHandle_TaJ_Value_SaB) |
| { |
| if (nullified_path[aHandle - TraitSchemaEngine::kHandleTableOffset] != isNull) |
| { |
| nullified_path[aHandle - TraitSchemaEngine::kHandleTableOffset] = isNull; |
| } |
| } |
| } |
| |
| |
| WEAVE_ERROR |
| TestBTraitUpdatableDataSink::SetData(PropertyPathHandle aHandle, TLVReader &aReader, bool aIsNull) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| if (aIsNull && !mSchemaEngine->IsNullable(aHandle)) |
| { |
| WeaveLogDetail(DataManagement, "<< Non-nullable handle %d received a NULL", aHandle); |
| |
| #if TDM_DISABLE_STRICT_SCHEMA_COMPLIANCE == 0 |
| ExitNow(err = WEAVE_ERROR_INVALID_TLV_ELEMENT); |
| #endif |
| } |
| |
| SetNullifiedPath(aHandle, aIsNull); |
| |
| if ((!aIsNull) && (mSchemaEngine->IsLeaf(aHandle))) |
| { |
| err = SetLeafData(aHandle, aReader); |
| // set the parent handles to non-null |
| while (aHandle != kRootPropertyPathHandle) |
| { |
| SetNullifiedPath(aHandle, aIsNull); |
| aHandle = mSchemaEngine->GetParent(aHandle); |
| } |
| } |
| |
| return err; |
| } |
| |
| WEAVE_ERROR |
| TestBTraitUpdatableDataSink::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| switch (aLeafHandle) { |
| // |
| // TestATrait |
| // |
| |
| case TestBTrait::kPropertyHandle_TaA: |
| int32_t next_taa; |
| err = aReader.Get(next_taa); |
| SuccessOrExit(err); |
| if (next_taa != taa) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_a is changed from %u to %u", taa, next_taa); |
| taa = next_taa; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_a = %u", taa); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaB: |
| int32_t next_tab; |
| err = aReader.Get(next_tab); |
| SuccessOrExit(err); |
| if (next_tab != tab) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_b is changed from %u to %u", tab, next_tab); |
| tab = next_tab; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_b = %u", tab); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaC: |
| uint32_t next_tac; |
| err = aReader.Get(next_tac); |
| SuccessOrExit(err); |
| if (next_tac != tac) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_c is changed from %u to %u", tac, next_tac); |
| tac = next_tac; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_c = %u", tac); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaD_SaA: |
| uint32_t next_tad_saa; |
| err = aReader.Get(next_tad_saa); |
| SuccessOrExit(err); |
| if (next_tad_saa != tad_saa) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_d.sa_a is changed from %u to %u", tad_saa, next_tad_saa); |
| tad_saa = next_tad_saa; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_d.sa_a = %u", tad_saa); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaD_SaB: |
| bool next_tad_sab; |
| err = aReader.Get(next_tad_sab); |
| SuccessOrExit(err); |
| if (next_tad_sab != tad_sab) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_d.sa_b is changed from %u to %u", tad_sab, next_tad_sab); |
| tad_sab = next_tad_sab; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_d.sa_b = %u", tad_sab); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaE: |
| { |
| TLVType outerType; |
| uint32_t i = 0; |
| |
| err = aReader.EnterContainer(outerType); |
| SuccessOrExit(err); |
| |
| while (((err = aReader.Next()) == WEAVE_NO_ERROR) && (i < (sizeof(tae) / sizeof(tae[0])))) { |
| uint32_t next_tae; |
| err = aReader.Get(next_tae); |
| SuccessOrExit(err); |
| if (tae[i] != next_tae) |
| { |
| WeaveLogDetail(DataManagement, "<< ta_e[%u] is changed from %u to %u", i, tae[i], next_tae); |
| tae[i] = next_tae; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< ta_e[%u] = %u", i, tae[i]); |
| i++; |
| } |
| |
| err = aReader.ExitContainer(outerType); |
| break; |
| } |
| |
| case TestBTrait::kPropertyHandle_TaP: |
| err = aReader.Get(tap); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, "<< ta_p = %" PRId64, tap); |
| break; |
| |
| // |
| // TestBTrait |
| // |
| |
| case TestBTrait::kPropertyHandle_TbA: |
| uint32_t next_tba; |
| err = aReader.Get(next_tba); |
| SuccessOrExit(err); |
| if (tba != next_tba) |
| { |
| WeaveLogDetail(DataManagement, "<< tb_a is changed from %u to %u", tba, next_tba); |
| tba = next_tba; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< tb_a = %u", tba); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbB_SbA: |
| char next_tbb_sba[MAX_ARRAY_LEN]; |
| err = aReader.GetString(next_tbb_sba, MAX_ARRAY_SIZE); |
| SuccessOrExit(err); |
| if (strncmp(tbb_sba, next_tbb_sba, MAX_ARRAY_SIZE)) |
| { |
| WeaveLogDetail(DataManagement, "<< tb_b.sb_a is changed from %s to %s", tbb_sba, next_tbb_sba); |
| memcpy(tbb_sba, next_tbb_sba, MAX_ARRAY_SIZE); |
| } |
| |
| WeaveLogDetail(DataManagement, "<< tb_b.sb_a = %s", tbb_sba); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbB_SbB: |
| uint32_t next_tbb_sbb; |
| err = aReader.Get(next_tbb_sbb); |
| SuccessOrExit(err); |
| if (tbb_sbb != next_tbb_sbb) |
| { |
| WeaveLogDetail(DataManagement, "<< tb_b.sb_b is changed from %u to %u", tbb_sbb, next_tbb_sbb); |
| tbb_sbb = next_tbb_sbb; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< tb_b.sb_b = %u", tbb_sbb); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbC_SaA: |
| uint32_t next_tbc_saa; |
| err = aReader.Get(next_tbc_saa); |
| SuccessOrExit(err); |
| if (tbc_saa != next_tbc_saa) |
| { |
| WeaveLogDetail(DataManagement, "<< tb_c.sa_a is changed from %u to %u", tbc_saa, next_tbc_saa); |
| tbc_saa = next_tbc_saa; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< tb_c.sa_a = %u", tbc_saa); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbC_SaB: |
| bool next_tbc_sab; |
| err = aReader.Get(next_tbc_sab); |
| SuccessOrExit(err); |
| if (tbc_sab != next_tbc_sab) |
| { |
| WeaveLogDetail(DataManagement, "<< tb_c.sa_b is changed from %u to %u", tbc_sab, next_tbc_sab); |
| tbc_sab = next_tbc_sab; |
| } |
| |
| WeaveLogDetail(DataManagement, "<< tb_c.sa_b = %u", tbc_sab); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbC_SeaC: |
| char next_tbc_seac[MAX_ARRAY_LEN]; |
| err = aReader.GetString(next_tbc_seac, MAX_ARRAY_SIZE); |
| SuccessOrExit(err); |
| if (strncmp(tbc_seac, next_tbc_seac, MAX_ARRAY_SIZE)) |
| { |
| WeaveLogDetail(DataManagement, "<< tb_c.sea_c is changed from \"%s\" to \"%s\"", tbc_seac, next_tbc_seac); |
| memcpy(tbc_seac, next_tbc_seac, MAX_ARRAY_SIZE); |
| } |
| |
| WeaveLogDetail(DataManagement, "<< tb_c.sea_c = \"%s\"", tbc_seac); |
| break; |
| |
| default: |
| WeaveLogDetail(DataManagement, "<< TestBTrait UNKNOWN! %08x", aLeafHandle); |
| } |
| |
| exit: |
| return err; |
| } |
| |
| |
| WEAVE_ERROR TestBTraitUpdatableDataSink::GetData(PropertyPathHandle aHandle, |
| uint64_t aTagToWrite, |
| TLVWriter &aWriter, |
| bool &aIsNull, |
| bool &aIsPresent) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| if (mSchemaEngine->IsNullable(aHandle)) |
| { |
| aIsNull = nullified_path[GetPropertySchemaHandle(aHandle) - TraitSchemaEngine::kHandleTableOffset]; |
| } |
| else |
| { |
| aIsNull = false; |
| } |
| |
| aIsPresent = true; |
| |
| // TDM will handle writing null |
| if ((!aIsNull) && (aIsPresent) && (mSchemaEngine->IsLeaf(aHandle))) |
| { |
| err = GetLeafData(aHandle, aTagToWrite, aWriter); |
| } |
| |
| return err; |
| } |
| |
| WEAVE_ERROR TestBTraitUpdatableDataSink::GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, TLVWriter &aWriter) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| switch (aLeafHandle) { |
| // |
| // TestATrait |
| // |
| |
| case TestBTrait::kPropertyHandle_TaA: |
| err = aWriter.Put(aTagToWrite, taa); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_a = %u", taa); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaB: |
| err = aWriter.Put(aTagToWrite, tab); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_b = %u", tab); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaC: |
| err = aWriter.Put(aTagToWrite, tac); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_c = %u", tac); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaD_SaA: |
| err = aWriter.Put(aTagToWrite, tad_saa); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_d.sa_a = %u", tad_saa); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaD_SaB: |
| err = aWriter.PutBoolean(aTagToWrite, tad_sab); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_d.sa_b = %s", tad_sab ? "true" : "false"); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaP: |
| err = aWriter.Put(aTagToWrite, tap); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_p = %d", tap); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TaE: |
| { |
| TLVType outerType; |
| |
| err = aWriter.StartContainer(aTagToWrite, kTLVType_Array, outerType); |
| SuccessOrExit(err); |
| |
| for (size_t i = 0; i < (sizeof(tae) / sizeof(tae[0])); i++) { |
| err = aWriter.Put(AnonymousTag, tae[i]); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> ta_e[%u] = %u", i, tae[i]); |
| } |
| |
| err = aWriter.EndContainer(outerType); |
| break; |
| } |
| |
| // |
| // TestBTrait |
| // |
| |
| case TestBTrait::kPropertyHandle_TbA: |
| err = aWriter.Put(aTagToWrite, tba); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> tb_a = %u", tba); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbB_SbA: |
| err = aWriter.PutString(aTagToWrite, tbb_sba); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> tb_b.sb_a = \"%s\"", tbb_sba); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbB_SbB: |
| err = aWriter.Put(aTagToWrite, tbb_sbb); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> tb_b.sb_b = %u", tbb_sbb); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbC_SaA: |
| err = aWriter.Put(aTagToWrite, tbc_saa); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> tb_c.sa_a = %u", tbc_saa); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbC_SaB: |
| err = aWriter.PutBoolean(aTagToWrite, tbc_sab); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> tb_c.sa_b = %s", tbc_sab ? "true" : "false"); |
| break; |
| |
| case TestBTrait::kPropertyHandle_TbC_SeaC: |
| err = aWriter.PutString(aTagToWrite, tbc_seac); |
| SuccessOrExit(err); |
| |
| WeaveLogDetail(DataManagement, ">> tb_c.sea_c = %s", tbc_seac); |
| break; |
| |
| default: |
| WeaveLogDetail(DataManagement, ">> UNKNOWN!"); |
| } |
| |
| exit: |
| WeaveLogFunctError(err); |
| return err; |
| } |
| |
| WEAVE_ERROR TestBTraitUpdatableDataSink::GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey) |
| { |
| return WEAVE_END_OF_INPUT; |
| } |
| |
| #endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE |