blob: e98a51fd29f8f7b3330b01fa012853ad26b1dcf2 [file] [log] [blame]
/*
*
* Copyright (c) 2014-2017 Nest Labs, Inc.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* This file implements a simple profile and Weave Data
* Management (WDM) profile database to go with it for testing
* purposes.
*
*/
#include <assert.h>
// This code tests the legacy version of Weave Data Management
#define WEAVE_CONFIG_DATA_MANAGEMENT_NAMESPACE kWeaveManagedNamespace_Legacy
#include "ToolCommon.h"
#include <Weave/Profiles/ProfileCommon.h>
#include <Weave/Profiles/data-management/DataManagement.h>
#include <Weave/Profiles/data-management/ProfileDatabase.h>
#include "TestProfile.h"
using namespace ::nl::Inet;
using namespace ::nl::Weave;
using namespace ::nl::Weave::TLV;
using namespace ::nl::Weave::Profiles;
using namespace ::nl::Weave::Profiles::Common;
using namespace ::nl::Weave::Profiles::DataManagement;
using namespace ::nl::Weave::Profiles::StatusReporting;
uint8_t LookupFailureMode(ReferencedTLVData &aPathList)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
uint8_t mode;
TLVReader rdr;
TLVType pathContainer;
TLVType profileContainer;
uint32_t profileId;
uint64_t instanceId;
err = OpenPathList(aPathList, rdr);
SuccessOrExit(err);
err = rdr.Next();
SuccessOrExit(err);
/*
* we assume only a single list element here, which is to say
* that if there's more than one element we ignore all but the
* first.
*/
err = rdr.EnterContainer(pathContainer);
SuccessOrExit(err);
/*
* the first element of a path under WDM should be a structure
* with 2 elements, one of which (the instance) is optional.
*/
err = rdr.Next();
SuccessOrExit(err);
ValidateTLVType(kTLVType_Structure, rdr);
SuccessOrExit(err);
err = ValidateWDMTag(kTag_WDMPathProfile, rdr);
SuccessOrExit(err);
/*
* parse the path profile and get the profile data object
*/
err = rdr.EnterContainer(profileContainer);
SuccessOrExit(err);
/*
* the first element here should be a profile ID
*/
err = rdr.Next();
SuccessOrExit(err);
err = ValidateTLVType(kTLVType_UnsignedInteger, rdr);
SuccessOrExit(err);
err = ValidateWDMTag(kTag_WDMPathProfileId, rdr);
SuccessOrExit(err);
err = rdr.Get(profileId);
SuccessOrExit(err);
/*
* and the second should be an instance
*/
err = rdr.Next();
SuccessOrExit(err);
err = ValidateWDMTag(kTag_WDMPathProfileInstance, rdr);
SuccessOrExit(err);
err = rdr.Get(instanceId);
SuccessOrExit(err);
rdr.ExitContainer(profileContainer);
rdr.ExitContainer(pathContainer);
CloseList(rdr);
/*
* OK. now we should have both the profile and instance ID in
* hand. figure out what we got.
*/
VerifyOrExit(profileId == kWeaveProfile_Fail, mode = kFailureMode_Invalid);
switch (instanceId)
{
case kFailureInstance_CloseConnection:
mode = kFailureMode_CloseConnection;
break;
case kFailureInstance_NoResponse:
mode = kFailureMode_NoResponse;
break;
default:
mode = kFailureMode_Invalid;
break;
}
exit:
if (err != WEAVE_NO_ERROR)
mode = kFailureMode_Invalid;
return mode;
}
TestProfileDB::TestData::TestData(void)
{
mIntegerItem = 0;
mPreviousIntegerItem = 0;
mInstanceId = kInstanceIdNotSpecified;
}
TestProfileDB::TestData::~TestData(void)
{
mIntegerItem = 0;
mPreviousIntegerItem = 0;
mInstanceId = kInstanceIdNotSpecified;
}
WEAVE_ERROR TestProfileDB::TestData::StoreItem(const uint64_t &aTag, TLVReader &aDataRdr)
{
WEAVE_ERROR err;
if (aTag == ContextTag(kTag_IntegerItem))
{
mPreviousIntegerItem = mIntegerItem;
err = aDataRdr.Get(mIntegerItem);
mVersion++;
}
else
err = WEAVE_ERROR_INVALID_TLV_TAG;
return err;
}
WEAVE_ERROR TestProfileDB::TestData::Retrieve(TLVReader &aPathRdr, TLVWriter &aDataWrtr)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
uint64_t tag;
err = aPathRdr.Next();
if (err == WEAVE_END_OF_TLV)
{
err = Retrieve(aDataWrtr);
SuccessOrExit(err);
}
else
{
tag = aPathRdr.GetTag();
/*
* in this case, the path contained an additional tag accessing
* a particular data item directly.
*/
// write the path
err = EncodePath(aDataWrtr,
ContextTag(kTag_WDMDataListElementPath),
kWeaveProfile_Test,
mInstanceId,
1,
tag);
SuccessOrExit(err);
// write the version
err = aDataWrtr.Put(ContextTag(kTag_WDMDataListElementVersion), mVersion);
SuccessOrExit(err);
// and the data item
err = aDataWrtr.Put(ContextTag(kTag_WDMDataListElementData), mIntegerItem);
}
exit:
return err;
}
WEAVE_ERROR TestProfileDB::TestData::Retrieve(TLVWriter &aDataWrtr)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
TLVType structure;
// write the path
err = EncodePath(aDataWrtr,
ContextTag(kTag_WDMDataListElementPath),
kWeaveProfile_Test,
mInstanceId,
0);
SuccessOrExit(err);
// write the version
err = aDataWrtr.Put(ContextTag(kTag_WDMDataListElementVersion), mVersion);
SuccessOrExit(err);
// and the whole structure
err = aDataWrtr.StartContainer(ContextTag(kTag_WDMDataListElementData), kTLVType_Structure, structure);
SuccessOrExit(err);
err = aDataWrtr.Put(ContextTag(kTag_IntegerItem), mIntegerItem);
SuccessOrExit(err);
err = aDataWrtr.EndContainer(structure);
SuccessOrExit(err);
exit:
return err;
}
WEAVE_ERROR TestProfileDB::LookupProfileData(uint32_t aProfileId, TLVReader *aInstanceIdReader, ProfileData **aResult)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
ProfileData *data = static_cast<ProfileData *>(&mTestData);
// we ignore the instance ID here
if (aProfileId == kWeaveProfile_Test)
{
*aResult = data;
}
else
{
*aResult = NULL;
err = WEAVE_ERROR_INVALID_PROFILE_ID;
}
return err;
}
void TestProfileDB::ChangeProfileData(void)
{
mTestData.mPreviousIntegerItem = mTestData.mIntegerItem;
mTestData.mIntegerItem = rand();
mTestData.mVersion++;
}
void TestProfileDB::RevertProfileData(void)
{
mTestData.mIntegerItem = mTestData.mPreviousIntegerItem;
mTestData.mVersion--;
}