| /* |
| * |
| * Copyright (c) 2015-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 |
| * |
| * @brief |
| * Definitions for the abstract ProfileDatabase auxiliary class. |
| * |
| * This file contains definitions for the abstract ProfileDatabase |
| * auxiliary class, which is intended to make the construction of |
| * WDM-based applications more straightforward by providing a template |
| * and filling common infrastructure. Also provided is a set of helper |
| * functions for wrangling WDM-related TLV. |
| */ |
| |
| #ifndef _WEAVE_DATA_MANAGEMENT_PROFILE_DATABASE_LEGACY_H |
| #define _WEAVE_DATA_MANAGEMENT_PROFILE_DATABASE_LEGACY_H |
| |
| #include <Weave/Profiles/data-management/Legacy/WdmManagedNamespace.h> |
| |
| #include <Weave/Profiles/data-management/DataManagement.h> |
| |
| namespace nl { |
| namespace Weave { |
| namespace Profiles { |
| namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Legacy) { |
| |
| /** |
| * @brief |
| * Start writing a path list. |
| * |
| * Write the TLV for the beginning of a WDM path list, e.g. as |
| * the primary argument of a ViewRequest(). |
| * |
| * @param [in] aWriter A reference to a TLV writer |
| * with which to start writing. |
| * |
| * @return #WEAVE_NO_ERROR On success. Otherwise return a |
| * #WEAVE_ERROR reflecting an inability to start a container. |
| */ |
| |
| static inline WEAVE_ERROR StartPathList(nl::Weave::TLV::TLVWriter &aWriter) |
| { |
| nl::Weave::TLV::TLVType pathListContainer; |
| |
| return aWriter.StartContainer(nl::Weave::TLV::ProfileTag(kWeaveProfile_WDM, kTag_WDMPathList), |
| nl::Weave::TLV::kTLVType_Array, pathListContainer); |
| }; |
| |
| |
| /** |
| * @brief |
| * Start writing a data list. |
| * |
| * Write the TLV for the beginning of a WDM data list, e.g. as |
| * the primary argument of an UpdateRequest(). |
| * |
| * @param [in] aWriter A reference to a TLV writer |
| * with which to start writing. |
| * |
| * @return #WEAVE_NO_ERROR On success. Otherwise return a |
| * #WEAVE_ERROR reflecting an inability to start a container. |
| */ |
| |
| static inline WEAVE_ERROR StartDataList(nl::Weave::TLV::TLVWriter &aWriter) |
| { |
| nl::Weave::TLV::TLVType dataListContainer; |
| |
| return aWriter.StartContainer(nl::Weave::TLV::ProfileTag(kWeaveProfile_WDM, kTag_WDMDataList), |
| nl::Weave::TLV::kTLVType_Array, dataListContainer); |
| }; |
| |
| /** |
| * @brief |
| * Start writing a data list to a given ReferencedTLVData object. |
| * |
| * Write the TLV for the beginning of a WDM data list. In this |
| * case, we assume that we're writing out the data list to a |
| * referenced TLV data structure. The writer is assumed to be |
| * uninitialized - or, in any case, will be initialized to point |
| * to the given object. |
| * |
| * @param [out] aDataList A reference to a |
| * ReferencedTLVData object that |
| * is to be the target of the |
| * writer and eventually contain |
| * the data of interest. |
| * |
| * @param [in] aWriter A reference to a TLV writer |
| * with which to start writing. |
| * |
| * @return #WEAVE_NO_ERROR On success. Otherwise return a |
| * #WEAVE_ERROR reflecting an inability to start a container. |
| */ |
| |
| static inline WEAVE_ERROR StartDataList(ReferencedTLVData &aDataList, nl::Weave::TLV::TLVWriter &aWriter) |
| { |
| aWriter.Init(aDataList.theData, aDataList.theMaxLength); |
| |
| return StartDataList(aWriter); |
| }; |
| |
| /** |
| * @brief |
| * Finish writing a path list or data list. |
| * |
| * Write the TLV for the end of a WDM path or data list. Also, |
| * finalize the writer. |
| * |
| * @param [in,out] aWriter A reference to a TLV writer |
| * with which to write the end of |
| * the list. |
| * |
| * @return #WEAVE_NO_ERROR On success. Otherwise return a |
| * #WEAVE_ERROR reflecting an inability to end a container. |
| */ |
| |
| static inline WEAVE_ERROR EndList(nl::Weave::TLV::TLVWriter &aWriter) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| /* |
| * in the normal case, which is what these convenience methods |
| * are attempting to address, both the path list and data list |
| * appear as the only elements of a top-level TLV |
| * structure. thus, the outer container type is always |
| * "structure". |
| */ |
| |
| err = aWriter.EndContainer(nl::Weave::TLV::kTLVType_Structure); |
| if (err == WEAVE_NO_ERROR) |
| { |
| err = aWriter.Finalize(); |
| } |
| |
| return err; |
| }; |
| |
| /** |
| * @brief |
| * Finish writing a path list or data list. |
| * |
| * Write the TLV for the end of a WDM path or data list. Also, |
| * finalize the writer. In this case, the ReferencedTLVData object |
| * to which the TLV is being written is passed in and modified to |
| * reflect the amount of data written. |
| * |
| * @param [in,out] aList A reference to the |
| * ReferenceTLVData object to |
| * which the list was being |
| * written. |
| * |
| * @param [in] aWriter A reference to a TLV writer |
| * with which to write the end of |
| * the list. |
| * |
| * @return #WEAVE_NO_ERROR On success. Otherwise return a |
| * #WEAVE_ERROR reflecting an inability to end a container. |
| */ |
| |
| static inline WEAVE_ERROR EndList(ReferencedTLVData &aList, nl::Weave::TLV::TLVWriter &aWriter) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| |
| err = EndList(aWriter); |
| |
| aList.theLength = aWriter.GetLengthWritten(); |
| |
| return err; |
| }; |
| |
| /** |
| * @brief |
| * Start writing a data list element. |
| * |
| * Write the TLV for the beginning of a WDM data list element. |
| * |
| * @param [in] aWriter A reference to a TLV writer |
| * with which to start writing. |
| * |
| * @return #WEAVE_NO_ERROR On success. Otherwise return a |
| * #WEAVE_ERROR reflecting an inability to start a container. |
| */ |
| |
| static inline WEAVE_ERROR StartDataListElement(nl::Weave::TLV::TLVWriter &aWriter) |
| { |
| nl::Weave::TLV::TLVType itemContainer; |
| |
| return aWriter.StartContainer(nl::Weave::TLV::AnonymousTag, nl::Weave::TLV::kTLVType_Structure, itemContainer); |
| }; |
| |
| /** |
| * @brief |
| * Finish writing a data list element. |
| * |
| * Write the TLV for the end of a WDM data list element. Note this |
| * this automatically passes in a type of kTLVType_Array to the |
| * EndContainer() call assuming that we are always closing a list |
| * item. |
| * |
| * @param [in] aWriter A reference to a TLV writer |
| * with which to write the end of |
| * the item. |
| * |
| * @return #WEAVE_NO_ERROR On success. Otherwise return a |
| * #WEAVE_ERROR reflecting an inability to end a container. |
| */ |
| |
| static inline WEAVE_ERROR EndDataListElement(nl::Weave::TLV::TLVWriter &aWriter) |
| { |
| /* |
| * obviously, the outer container of a list element is a |
| * "list", i.e. an array. |
| */ |
| |
| return aWriter.EndContainer(nl::Weave::TLV::kTLVType_Array); |
| }; |
| |
| bool CheckWDMTag(uint32_t aTagNum, nl::Weave::TLV::TLVReader &aReader); |
| |
| /** |
| * @brief |
| * Validate that a TLV element being read has the expected WDM |
| * tag. |
| * |
| * @param [in] aTagNum The 32-bit tag number of the |
| * expected WDM tag. |
| * |
| * @param [in] aReader A TLV reader positioned at the |
| * element to be validated. |
| * |
| * @return #WEAVE_NO_ERROR On success. Otherwise |
| * #WEAVE_ERROR_INVALID_TLV_TAG if the tag does not match the |
| * given tag number when interpreted as a WDM tag. |
| */ |
| |
| static inline WEAVE_ERROR ValidateWDMTag(uint32_t aTagNum, nl::Weave::TLV::TLVReader &aReader) |
| { |
| WEAVE_ERROR err; |
| |
| if (CheckWDMTag(aTagNum, aReader)) |
| err = WEAVE_NO_ERROR; |
| |
| else |
| err = WEAVE_ERROR_INVALID_TLV_TAG; |
| |
| return err; |
| }; |
| |
| /** |
| * @brief |
| * Check that a TLV element being read has the expected TLV |
| * type. |
| * |
| * Check a given TLV type against |
| * the element type at the head of a TLV reader. |
| * |
| * @sa WeaveTLVTypes.h |
| * |
| * @param [in] aType The TLVType to be checked |
| * against a specific element |
| * |
| * @param [in] aReader A reference to a TLV reader |
| * positioned at the element to |
| * be checked |
| * |
| * @return true iff the TLVType of the element and aType match. |
| */ |
| |
| static inline bool CheckTLVType(nl::Weave::TLV::TLVType aType, nl::Weave::TLV::TLVReader &aReader) |
| { |
| nl::Weave::TLV::TLVType type = aReader.GetType(); |
| |
| return type == aType; |
| }; |
| |
| /** |
| * @brief |
| * Validate that a TLV element being read has the expected TLV |
| * type. |
| * |
| * Check a given TLV type against |
| * the element type at the head of a TLV reader and return an |
| * error if there is no match. |
| * |
| * @sa WeaveTLVTypes.h |
| * |
| * @param [in] aType The TLVType to be validated |
| * against a specific element. |
| * |
| * @param [in] aReader A reference to a TLV reader |
| * positioned at the element to |
| * be validated. |
| * |
| * @return #WEAVE_NO_ERROR if there is a match or |
| * #WEAVE_ERROR_WRONG_TLV_TYPE if not. |
| */ |
| |
| inline WEAVE_ERROR ValidateTLVType(nl::Weave::TLV::TLVType aType, nl::Weave::TLV::TLVReader &aReader) |
| { |
| WEAVE_ERROR err; |
| |
| if (CheckTLVType(aType, aReader)) |
| err = WEAVE_NO_ERROR; |
| |
| else |
| err = WEAVE_ERROR_WRONG_TLV_TYPE; |
| |
| return err; |
| }; |
| |
| WEAVE_ERROR OpenPathList(ReferencedTLVData &aPathList, nl::Weave::TLV::TLVReader &aReader); |
| |
| WEAVE_ERROR OpenDataList(ReferencedTLVData &aDataList, nl::Weave::TLV::TLVReader &aReader); |
| |
| WEAVE_ERROR OpenDataListElement(nl::Weave::TLV::TLVReader &aReader, nl::Weave::TLV::TLVReader &aPathReader, uint64_t &aVersion); |
| |
| /** |
| * @brief |
| * Stop reading a WDM path or data list. |
| * |
| * This method assumes that the list in question is the topmost |
| * TLV element and so passes kTLVType_Sructure to ExitContainer(). |
| * |
| * @param [in,out] aReader A TLV reader positioned in |
| * a WDM path or data list. |
| * |
| * @return #WEAVE_NO_ERROR On success. Otherwise return a |
| * #WEAVE_ERROR reflecting an inability to exit a container. |
| */ |
| |
| inline WEAVE_ERROR CloseList(nl::Weave::TLV::TLVReader &aReader) |
| { |
| return aReader.ExitContainer(nl::Weave::TLV::kTLVType_Structure); |
| }; |
| |
| /** |
| * @brief |
| * Stop reading a WDM data list element. |
| * |
| * This method assumes that the element in question is part of a |
| * WDM data list and so passes kTLVType_Array to ExitContainer(). |
| * |
| * @param [in,out] aReader A TLV reader positioned in |
| * a WDM data list element. |
| * |
| * @return #WEAVE_NO_ERROR On success. Otherwise return a |
| * #WEAVE_ERROR reflecting an inability to exit a container. |
| */ |
| |
| inline WEAVE_ERROR CloseDataListElement(nl::Weave::TLV::TLVReader &aReader) |
| { |
| return aReader.ExitContainer(nl::Weave::TLV::kTLVType_Array); |
| }; |
| |
| /* |
| * it also turns out that we have to support a range of instance |
| * identifiers. we make the assumption that, at least in an |
| * embedded context, they are all binary encodings. so, that means |
| * that for all the numeric ones we can probably get away with |
| * using a uint64 - since that will be the normal case anyway - |
| * and for longer values we can use the TLV byte array. |
| * |
| * what this means, sadly, is that all the "convenience" methods |
| * below that take or extract an instance ID have to account for |
| * both types. |
| */ |
| |
| WEAVE_ERROR EncodePath(nl::Weave::TLV::TLVWriter &aWriter, |
| const uint64_t &aTag, |
| uint32_t aProfileId, |
| const uint64_t &aInstanceId, |
| uint16_t aPathLen, |
| ...); |
| |
| WEAVE_ERROR EncodePath(nl::Weave::TLV::TLVWriter &aWriter, |
| const uint64_t &aTag, |
| uint32_t aProfileId, |
| const uint32_t aInstanceIdLen, |
| const uint8_t *aInstanceId, |
| uint16_t aPathLen, |
| ...); |
| |
| WEAVE_ERROR EncodePath(nl::Weave::TLV::TLVWriter &aWriter, |
| const uint64_t &aTag, |
| uint32_t aProfileId, |
| const char *aInstanceId, |
| uint16_t aPathLen, |
| ...); |
| |
| /* |
| * and for compatibility with Topaz, actually with older versions |
| * of the Service that were in use under Topaz 1.0, we need these |
| * versions. |
| */ |
| |
| WEAVE_ERROR EncodeDeprecatedPath(nl::Weave::TLV::TLVWriter &aWriter, |
| const uint64_t &aTag, |
| uint32_t aProfileId, |
| const uint64_t &aInstanceId, |
| uint16_t aPathLen, |
| ...); |
| |
| WEAVE_ERROR EncodeDeprecatedPath(nl::Weave::TLV::TLVWriter &aWriter, |
| const uint64_t &aTag, |
| uint32_t aProfileId, |
| const char *aInstanceId, |
| uint16_t aPathLen, |
| ...); |
| |
| /** |
| * @class ProfileDatabase |
| * |
| * @brief |
| * The abstract ProfileDatabase auxiliary class. |
| * |
| * WDM separates the protocol implementation from the data |
| * management implementation and, at least in principle, leaves |
| * most of the latter to the application developer. All of the |
| * interesting calls in WDM and all of the abstract methods that |
| * the profile developer is required to implement take TLV-encoded |
| * path lists or data lists. This puts a burden on profile |
| * developers and, in practice, will cause a lot of code |
| * duplication as developer after developer writes the same code |
| * for packing and unpacking TLV and so on. To ease things a bit |
| * we provide a kind of "data management toolkit". |
| * |
| * This auxiliary class provides support for storing and retrieving data |
| * provided that the necessary concrete ProfileData sub-classes have been |
| * supplied and added to the LookupProfileData() method below. |
| */ |
| |
| class ProfileDatabase |
| { |
| public: |
| |
| /** |
| * @class ProfileData |
| * |
| * @brief |
| * The abstract ProfileData auxiliary inner class. |
| * |
| * ProfileDatabase sub-class implementers should implement |
| * sub-classes of this auxiliary inner class as well. The |
| * function of ProfileData objects is to provide hooks |
| * whereby concrete data may be stored, given a its |
| * representation as TLV and retrieved as a TLV |
| * representation given a TLV-encoded list of paths. |
| */ |
| |
| class ProfileData |
| { |
| public: |
| ProfileData(void); |
| |
| virtual ~ProfileData(void); |
| |
| virtual WEAVE_ERROR Store(nl::Weave::TLV::TLVReader &aPathReader, uint64_t aVersion, nl::Weave::TLV::TLVReader &aDataReader); |
| |
| /** |
| * @brief |
| * Store a data item based on its tag. |
| * |
| * @note |
| * ProfileDatabase subclass implementers must supply a |
| * concrete implementation of this method in order to |
| * store a particular kind of data under a known tag. |
| * |
| * @param [in] aTag A reference to the |
| * fully-qualified 64-bit |
| * TLV tag under which |
| * the data should be |
| * stored. |
| * |
| * @param [in] aDataReader A TLV reader |
| * positioned at the data |
| * item to be stored. |
| * |
| * @return #WEAVE_NO_ERROR on success, otherwise return |
| * a #WEAVE_ERROR reflecting an inability either to |
| * recognize the tag or to store the data. |
| */ |
| |
| virtual WEAVE_ERROR StoreItem(const uint64_t &aTag, nl::Weave::TLV::TLVReader &aDataReader) = 0; |
| |
| /** |
| * @brief |
| * Write out a data item given a residual WDM path. |
| * |
| * ProfileDatabase subclass implementers must provide a |
| * concrete implementation for this method in every case |
| * where the individual elements of a ProfileData subclass |
| * object are accessible under particular tags. |
| * |
| * @param [in] aPathReader A reference to a TLV |
| * reader positioned in a |
| * WDM path after the |
| * profile information, |
| * i.e. at the 'residual' |
| * path elements if any. |
| * |
| * @param [in] aDataWriter A reference to a TLV |
| * writer used to write |
| * out the data indicated |
| * by the residual path. |
| * |
| * @return #WEAVE_NO_ERROR On success. Otherwise return a |
| * #WEAVE_ERROR reflecting an inability to recognize a |
| * residual tag or else to write the corresponding data. |
| */ |
| |
| virtual WEAVE_ERROR Retrieve(nl::Weave::TLV::TLVReader &aPathReader, nl::Weave::TLV::TLVWriter &aDataWriter) = 0; |
| |
| /* |
| * data members: |
| */ |
| |
| /** |
| * @brief |
| * Profile data version. |
| * |
| * The version given here in the ProfileData object |
| * applies to the whole profile data set for a particular |
| * instance. |
| */ |
| |
| uint64_t mVersion; |
| |
| }; |
| |
| WEAVE_ERROR Store(ReferencedTLVData &aDataList); |
| |
| WEAVE_ERROR Retrieve(ReferencedTLVData &aPathList, ReferencedTLVData &aDataList); |
| |
| WEAVE_ERROR Retrieve(ReferencedTLVData &aPathList, nl::Weave::TLV::TLVWriter &aWriter); |
| |
| WEAVE_ERROR LookupProfileData(nl::Weave::TLV::TLVReader &aPathReader, ProfileData **aProfileData); |
| |
| WEAVE_ERROR LookupDataFromProfileDescriptor(nl::Weave::TLV::TLVReader &aDescReader, ProfileData **aProfileData); |
| |
| /** |
| * @brief |
| * Look up a ProfileData object. |
| * |
| * Look up a specific ProfileData object given a profile ID |
| * and an (optional) instance ID< provided as a TLV reader. |
| * |
| * @param [in] aProfileId The 32-bit profile number |
| * of the profile of interest. |
| * |
| * @param [in] aInstanceIdRdr A pointer to a TLV reader |
| * positioned at the instance |
| * identifier data. If not |
| * instance identifier was |
| * provided then this shall |
| * be NULL. |
| * |
| * @param [out] aResult A pointer, intended to return a |
| * pointer to the ProfileData object |
| * of interest. |
| * |
| * @return #WEAVE_NO_ERROR On success. Otherwise return a |
| * #WEAVE_ERROR reflecting an inability to find a ProfileData |
| * object. |
| */ |
| |
| virtual WEAVE_ERROR LookupProfileData(uint32_t aProfileId, nl::Weave::TLV::TLVReader *aInstanceIdRdr, ProfileData **aResult) = 0; |
| |
| protected: |
| |
| WEAVE_ERROR StoreInternal(nl::Weave::TLV::TLVReader &aPathReader, uint64_t aVersion, nl::Weave::TLV::TLVReader &aDataReader); |
| }; |
| |
| }; // WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Legacy) |
| }; // Profiles |
| }; // Weave |
| }; // nl |
| |
| #endif // _WEAVE_DATA_MANAGEMENT_PROFILE_DATABASE_LEGACY_H |