Line data Source code
1 : /** 2 : * 3 : * Copyright (c) 2020 Project CHIP Authors 4 : * Copyright (c) 2016-2017 Nest Labs, Inc. 5 : * 6 : * Licensed under the Apache License, Version 2.0 (the "License"); 7 : * you may not use this file except in compliance with the License. 8 : * You may obtain a copy of the License at 9 : * 10 : * http://www.apache.org/licenses/LICENSE-2.0 11 : * 12 : * Unless required by applicable law or agreed to in writing, software 13 : * distributed under the License is distributed on an "AS IS" BASIS, 14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 : * See the License for the specific language governing permissions and 16 : * limitations under the License. 17 : */ 18 : /** 19 : * @file 20 : * This file defines parser in CHIP interaction model 21 : * 22 : */ 23 : 24 : #pragma once 25 : 26 : #include <app/data-model/Nullable.h> 27 : #include <app/util/basic-types.h> 28 : #include <lib/core/CHIPCore.h> 29 : #include <lib/core/TLV.h> 30 : #include <lib/support/CodeUtils.h> 31 : #include <lib/support/logging/CHIPLogging.h> 32 : 33 : namespace chip { 34 : namespace app { 35 : class Parser 36 : { 37 : public: 38 : /** 39 : * @brief Initialize the Builder object with TLVReader and ContainerType 40 : * 41 : * @param [in] aReader TLVReader 42 : * @param [in] aOuterContainerType outer container type 43 : * 44 : */ 45 : void Init(const chip::TLV::TLVReader & aReader, chip::TLV::TLVType aOuterContainerType); 46 : 47 : /** 48 : * @brief Initialize a TLVReader to point to the beginning of any tagged element in this request 49 : * 50 : * @param [in] aTagToFind Tag to find in the request 51 : * @param [out] apReader A pointer to TLVReader, which will be initialized at the specified TLV element 52 : * on success 53 : * 54 : * @return #CHIP_NO_ERROR on success 55 : */ 56 : CHIP_ERROR GetReaderOnTag(const TLV::Tag aTagToFind, TLV::TLVReader * const apReader) const; 57 : 58 : /** 59 : * @brief Get the TLV Reader 60 : * 61 : * @param [in] apReader A pointer to a TLVReader 62 : * 63 : */ 64 : void GetReader(chip::TLV::TLVReader * const apReader); 65 : 66 : /** 67 : * @brief Iterate to next element 68 : * 69 : * @return #CHIP_NO_ERROR on success 70 : */ 71 : CHIP_ERROR Next(); 72 : 73 : protected: 74 : chip::TLV::TLVReader mReader; 75 : chip::TLV::TLVType mOuterContainerType; 76 : Parser(); 77 : 78 : /** 79 : * Gets a unsigned integer value with the given tag, the value is not touched when the tag is not found in the TLV. 80 : * 81 : * @return #CHIP_NO_ERROR on success 82 : * #CHIP_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types 83 : * #CHIP_END_OF_TLV if there is no such element 84 : */ 85 : template <typename T> 86 72456 : CHIP_ERROR GetUnsignedInteger(const uint8_t aContextTag, T * const apLValue) const 87 : { 88 72456 : return GetSimpleValue(aContextTag, chip::TLV::kTLVType_UnsignedInteger, apLValue); 89 : }; 90 : 91 : /** 92 : * Gets a unsigned integer or null value with the given tag, the value is not touched when the tag is not found in the TLV. 93 : * 94 : * @return #CHIP_NO_ERROR on success 95 : * #CHIP_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types and is 96 : * not null 97 : * #CHIP_END_OF_TLV if there is no such element 98 : */ 99 : template <typename T> 100 8676 : CHIP_ERROR GetNullableUnsignedInteger(const uint8_t aContextTag, DataModel::Nullable<T> * const apLValue) const 101 : { 102 8676 : return GetSimpleNullableValue(aContextTag, chip::TLV::kTLVType_UnsignedInteger, apLValue); 103 : }; 104 : 105 : /** 106 : * Gets a scalar value with the given tag, the value is not touched when the tag is not found in the TLV. 107 : * 108 : * @return #CHIP_NO_ERROR on success 109 : * #CHIP_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types 110 : * #CHIP_END_OF_TLV if there is no such element 111 : */ 112 : template <typename T> 113 83058 : CHIP_ERROR GetSimpleValue(const uint8_t aContextTag, const chip::TLV::TLVType aTLVType, T * const apLValue) const 114 : { 115 83058 : CHIP_ERROR err = CHIP_NO_ERROR; 116 : chip::TLV::TLVReader reader; 117 : 118 83058 : err = mReader.FindElementWithTag(chip::TLV::ContextTag(aContextTag), reader); 119 83058 : SuccessOrExit(err); 120 : 121 69479 : *apLValue = 0; 122 : 123 69479 : VerifyOrExit(aTLVType == reader.GetType(), err = CHIP_ERROR_WRONG_TLV_TYPE); 124 : 125 69479 : err = reader.Get(*apLValue); 126 69479 : SuccessOrExit(err); 127 : 128 83058 : exit: 129 83058 : ChipLogIfFalse((CHIP_NO_ERROR == err) || (CHIP_END_OF_TLV == err)); 130 : 131 83058 : return err; 132 : }; 133 : 134 : /** 135 : * Gets a scalar value with the given tag, the value is not touched when the tag is not found in the TLV. 136 : * 137 : * @return #CHIP_NO_ERROR on success 138 : * #CHIP_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types 139 : * #CHIP_END_OF_TLV if there is no such element 140 : */ 141 : template <typename T> 142 8676 : CHIP_ERROR GetSimpleNullableValue(const uint8_t aContextTag, const chip::TLV::TLVType aTLVType, 143 : DataModel::Nullable<T> * const apLValue) const 144 : { 145 8676 : CHIP_ERROR err = CHIP_NO_ERROR; 146 : chip::TLV::TLVReader reader; 147 : 148 8676 : err = mReader.FindElementWithTag(chip::TLV::ContextTag(aContextTag), reader); 149 8676 : SuccessOrExit(err); 150 : 151 4404 : apLValue->SetNull(); 152 : 153 4404 : VerifyOrExit(aTLVType == reader.GetType() || TLV::TLVType::kTLVType_Null == reader.GetType(), 154 : err = CHIP_ERROR_WRONG_TLV_TYPE); 155 : 156 4404 : if (reader.GetType() == aTLVType) 157 : { 158 : T value; 159 0 : err = reader.Get(value); 160 0 : SuccessOrExit(err); 161 0 : apLValue->SetNonNull(value); 162 : } 163 : 164 4404 : exit: 165 8676 : ChipLogIfFalse((CHIP_NO_ERROR == err) || (CHIP_END_OF_TLV == err)); 166 : 167 8676 : return err; 168 : }; 169 : }; 170 : } // namespace app 171 : } // namespace chip