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 82916 : CHIP_ERROR GetUnsignedInteger(const uint8_t aContextTag, T * const apLValue) const
87 : {
88 82916 : 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 9377 : CHIP_ERROR GetNullableUnsignedInteger(const uint8_t aContextTag, DataModel::Nullable<T> * const apLValue) const
101 : {
102 9377 : 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 93746 : CHIP_ERROR GetSimpleValue(const uint8_t aContextTag, const chip::TLV::TLVType aTLVType, T * const apLValue) const
114 : {
115 93746 : CHIP_ERROR err = CHIP_NO_ERROR;
116 93746 : chip::TLV::TLVReader reader;
117 :
118 93746 : err = mReader.FindElementWithTag(chip::TLV::ContextTag(aContextTag), reader);
119 93746 : SuccessOrExit(err);
120 :
121 79817 : *apLValue = 0;
122 :
123 79817 : VerifyOrExit(aTLVType == reader.GetType(), err = CHIP_ERROR_WRONG_TLV_TYPE);
124 :
125 79817 : err = reader.Get(*apLValue);
126 79817 : SuccessOrExit(err);
127 :
128 93746 : exit:
129 93746 : ChipLogIfFalse((CHIP_NO_ERROR == err) || (CHIP_END_OF_TLV == err));
130 :
131 93746 : 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 9377 : CHIP_ERROR GetSimpleNullableValue(const uint8_t aContextTag, const chip::TLV::TLVType aTLVType,
143 : DataModel::Nullable<T> * const apLValue) const
144 : {
145 9377 : CHIP_ERROR err = CHIP_NO_ERROR;
146 9377 : chip::TLV::TLVReader reader;
147 :
148 9377 : err = mReader.FindElementWithTag(chip::TLV::ContextTag(aContextTag), reader);
149 9377 : SuccessOrExit(err);
150 :
151 4420 : apLValue->SetNull();
152 :
153 4420 : VerifyOrExit(aTLVType == reader.GetType() || TLV::TLVType::kTLVType_Null == reader.GetType(),
154 : err = CHIP_ERROR_WRONG_TLV_TYPE);
155 :
156 4420 : 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 4420 : exit:
165 9377 : ChipLogIfFalse((CHIP_NO_ERROR == err) || (CHIP_END_OF_TLV == err));
166 :
167 9377 : return err;
168 : };
169 : };
170 : } // namespace app
171 : } // namespace chip
|