Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / app / MessageDef / AttributeStatusElement.cpp
1 /**
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    Copyright (c) 2018 Google LLC.
5  *    Copyright (c) 2016-2017 Nest Labs, Inc.
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 AttributeStatusElement parser and builder in CHIP interaction model
21  *
22  */
23
24 #include "AttributeStatusElement.h"
25
26 #include "MessageDefHelper.h"
27
28 #include <inttypes.h>
29 #include <stdarg.h>
30 #include <stdio.h>
31
32 using namespace chip;
33 using namespace chip::TLV;
34
35 namespace chip {
36 namespace app {
37 CHIP_ERROR AttributeStatusElement::Builder::Init(chip::TLV::TLVWriter * const apWriter)
38 {
39     return InitAnonymousStructure(apWriter);
40 }
41
42 AttributePath::Builder & AttributeStatusElement::Builder::CreateAttributePathBuilder()
43 {
44     // skip if error has already been set
45     VerifyOrExit(CHIP_NO_ERROR == mError, mAttributePathBuilder.ResetError(mError));
46
47     mError = mAttributePathBuilder.Init(mpWriter, kCsTag_AttributePath);
48
49 exit:
50     ChipLogFunctError(mError);
51     return mAttributePathBuilder;
52 }
53
54 StatusElement::Builder & AttributeStatusElement::Builder::CreateStatusElementBuilder()
55 {
56     // skip if error has already been set
57     VerifyOrExit(CHIP_NO_ERROR == mError, mStatusElementBuilder.ResetError(mError));
58
59     mError = mStatusElementBuilder.Init(mpWriter, kCsTag_StatusElement);
60
61 exit:
62     ChipLogFunctError(mError);
63     return mStatusElementBuilder;
64 }
65
66 AttributeStatusElement::Builder & AttributeStatusElement::Builder::EndOfAttributeStatusElement()
67 {
68     EndOfContainer();
69     return *this;
70 }
71
72 CHIP_ERROR AttributeStatusElement::Parser::Init(const chip::TLV::TLVReader & aReader)
73 {
74     CHIP_ERROR err = CHIP_NO_ERROR;
75
76     // make a copy of the reader here
77     mReader.Init(aReader);
78     VerifyOrExit(chip::TLV::kTLVType_Structure == mReader.GetType(), err = CHIP_ERROR_WRONG_TLV_TYPE);
79
80     // This is just a dummy, as we're not going to exit this container ever
81     chip::TLV::TLVType OuterContainerType;
82     err = mReader.EnterContainer(OuterContainerType);
83
84 exit:
85     ChipLogFunctError(err);
86     return err;
87 }
88
89 #if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK
90 CHIP_ERROR AttributeStatusElement::Parser::CheckSchemaValidity() const
91 {
92     CHIP_ERROR err           = CHIP_NO_ERROR;
93     uint16_t TagPresenceMask = 0;
94     chip::TLV::TLVReader reader;
95
96     PRETTY_PRINT("AttributeStatusElement =");
97     PRETTY_PRINT("{");
98
99     // make a copy of the reader
100     reader.Init(mReader);
101
102     while (CHIP_NO_ERROR == (err = reader.Next()))
103     {
104         VerifyOrExit(chip::TLV::IsContextTag(reader.GetTag()), err = CHIP_ERROR_INVALID_TLV_TAG);
105         switch (chip::TLV::TagNumFromTag(reader.GetTag()))
106         {
107         case kCsTag_AttributePath:
108             VerifyOrExit(!(TagPresenceMask & (1 << kCsTag_AttributePath)), err = CHIP_ERROR_INVALID_TLV_TAG);
109             TagPresenceMask |= (1 << kCsTag_AttributePath);
110             {
111                 AttributePath::Parser path;
112                 err = path.Init(reader);
113                 SuccessOrExit(err);
114
115                 PRETTY_PRINT_INCDEPTH();
116                 err = path.CheckSchemaValidity();
117                 SuccessOrExit(err);
118                 PRETTY_PRINT_DECDEPTH();
119             }
120             break;
121         case kCsTag_StatusElement:
122             VerifyOrExit(!(TagPresenceMask & (1 << kCsTag_StatusElement)), err = CHIP_ERROR_INVALID_TLV_TAG);
123             TagPresenceMask |= (1 << kCsTag_StatusElement);
124             {
125                 StatusElement::Parser status;
126                 err = status.Init(reader);
127                 SuccessOrExit(err);
128
129                 PRETTY_PRINT_INCDEPTH();
130                 err = status.CheckSchemaValidity();
131                 SuccessOrExit(err);
132                 PRETTY_PRINT_DECDEPTH();
133             }
134             break;
135         default:
136             ExitNow(err = CHIP_ERROR_INVALID_TLV_TAG);
137         }
138     }
139
140     PRETTY_PRINT("},");
141     PRETTY_PRINT("");
142
143     // if we have exhausted this container
144     if (CHIP_END_OF_TLV == err)
145     {
146         // check for required fields:
147         const uint16_t RequiredFields = (1 << kCsTag_AttributePath) | (1 << kCsTag_StatusElement);
148
149         if ((TagPresenceMask & RequiredFields) == RequiredFields)
150         {
151             err = CHIP_NO_ERROR;
152         }
153         else
154         {
155             err = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_STATUS_ELEMENT;
156         }
157     }
158
159 exit:
160     ChipLogFunctError(err);
161
162     return err;
163 }
164 #endif // CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK
165
166 CHIP_ERROR AttributeStatusElement::Parser::GetAttributePath(AttributePath::Parser * const apAttributePath) const
167 {
168     CHIP_ERROR err = CHIP_NO_ERROR;
169     chip::TLV::TLVReader reader;
170
171     err = mReader.FindElementWithTag(chip::TLV::ContextTag(kCsTag_AttributePath), reader);
172     SuccessOrExit(err);
173
174     VerifyOrExit(chip::TLV::kTLVType_List == reader.GetType(), err = CHIP_ERROR_WRONG_TLV_TYPE);
175
176     err = apAttributePath->Init(reader);
177     SuccessOrExit(err);
178
179 exit:
180     ChipLogIfFalse((CHIP_NO_ERROR == err) || (CHIP_END_OF_TLV == err));
181
182     return err;
183 }
184
185 CHIP_ERROR AttributeStatusElement::Parser::GetStatusElement(StatusElement::Parser * const apStatusElement) const
186 {
187     CHIP_ERROR err = CHIP_NO_ERROR;
188     chip::TLV::TLVReader reader;
189
190     err = mReader.FindElementWithTag(chip::TLV::ContextTag(kCsTag_StatusElement), reader);
191     SuccessOrExit(err);
192
193     VerifyOrExit(chip::TLV::kTLVType_Array == reader.GetType(), err = CHIP_ERROR_WRONG_TLV_TYPE);
194
195     err = apStatusElement->Init(reader);
196     SuccessOrExit(err);
197
198 exit:
199     ChipLogIfFalse((CHIP_NO_ERROR == err) || (CHIP_END_OF_TLV == err));
200
201     return err;
202 }
203 }; // namespace app
204 }; // namespace chip