Line data Source code
1 : /**
2 : *
3 : * Copyright (c) 2021 Project CHIP Authors
4 : * Licensed under the Apache License, Version 2.0 (the "License");
5 : * you may not use this file except in compliance with the License.
6 : * You may obtain a copy of the License at
7 : *
8 : * http://www.apache.org/licenses/LICENSE-2.0
9 : *
10 : * Unless required by applicable law or agreed to in writing, software
11 : * distributed under the License is distributed on an "AS IS" BASIS,
12 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : * See the License for the specific language governing permissions and
14 : * limitations under the License.
15 : */
16 :
17 : #include <inttypes.h>
18 : #include <stdarg.h>
19 : #include <stdio.h>
20 :
21 : #include "InvokeRequestMessage.h"
22 : #include "MessageDefHelper.h"
23 :
24 : #include <app/AppConfig.h>
25 :
26 : namespace chip {
27 : namespace app {
28 : #if CHIP_CONFIG_IM_PRETTY_PRINT
29 49 : CHIP_ERROR InvokeRequestMessage::Parser::PrettyPrint() const
30 : {
31 49 : CHIP_ERROR err = CHIP_NO_ERROR;
32 49 : TLV::TLVReader reader;
33 :
34 49 : PRETTY_PRINT("InvokeRequestMessage =");
35 49 : PRETTY_PRINT("{");
36 :
37 : // make a copy of the reader
38 49 : reader.Init(mReader);
39 :
40 243 : while (CHIP_NO_ERROR == (err = reader.Next()))
41 : {
42 195 : if (!TLV::IsContextTag(reader.GetTag()))
43 : {
44 0 : continue;
45 : }
46 195 : uint32_t tagNum = TLV::TagNumFromTag(reader.GetTag());
47 195 : switch (tagNum)
48 : {
49 49 : case to_underlying(Tag::kSuppressResponse):
50 : #if CHIP_DETAIL_LOGGING
51 : {
52 : bool suppressResponse;
53 49 : ReturnErrorOnFailure(reader.Get(suppressResponse));
54 49 : PRETTY_PRINT("\tsuppressResponse = %s, ", suppressResponse ? "true" : "false");
55 : }
56 : #endif // CHIP_DETAIL_LOGGING
57 49 : break;
58 :
59 49 : case to_underlying(Tag::kTimedRequest):
60 : #if CHIP_DETAIL_LOGGING
61 : {
62 : bool timedRequest;
63 49 : ReturnErrorOnFailure(reader.Get(timedRequest));
64 49 : PRETTY_PRINT("\ttimedRequest = %s, ", timedRequest ? "true" : "false");
65 : }
66 : #endif // CHIP_DETAIL_LOGGING
67 49 : break;
68 49 : case to_underlying(Tag::kInvokeRequests): {
69 49 : InvokeRequests::Parser invokeRequests;
70 49 : ReturnErrorOnFailure(invokeRequests.Init(reader));
71 :
72 49 : PRETTY_PRINT_INCDEPTH();
73 49 : ReturnErrorOnFailure(invokeRequests.PrettyPrint());
74 48 : PRETTY_PRINT_DECDEPTH();
75 : }
76 48 : break;
77 48 : case Revision::kInteractionModelRevisionTag:
78 48 : ReturnErrorOnFailure(MessageParser::CheckInteractionModelRevision(reader));
79 48 : break;
80 0 : default:
81 0 : PRETTY_PRINT("Unknown tag num %" PRIu32, tagNum);
82 0 : break;
83 : }
84 : }
85 :
86 48 : PRETTY_PRINT("},");
87 48 : PRETTY_PRINT_BLANK_LINE();
88 :
89 48 : if (CHIP_END_OF_TLV == err)
90 : {
91 48 : err = CHIP_NO_ERROR;
92 : }
93 :
94 48 : ReturnErrorOnFailure(err);
95 48 : return reader.ExitContainer(mOuterContainerType);
96 : }
97 : #endif // CHIP_CONFIG_IM_PRETTY_PRINT
98 :
99 49 : CHIP_ERROR InvokeRequestMessage::Parser::GetSuppressResponse(bool * const apSuppressResponse) const
100 : {
101 49 : return GetSimpleValue(to_underlying(Tag::kSuppressResponse), TLV::kTLVType_Boolean, apSuppressResponse);
102 : }
103 :
104 49 : CHIP_ERROR InvokeRequestMessage::Parser::GetTimedRequest(bool * const apTimedRequest) const
105 : {
106 49 : return GetSimpleValue(to_underlying(Tag::kTimedRequest), TLV::kTLVType_Boolean, apTimedRequest);
107 : }
108 :
109 94 : CHIP_ERROR InvokeRequestMessage::Parser::GetInvokeRequests(InvokeRequests::Parser * const apInvokeRequests) const
110 : {
111 94 : TLV::TLVReader reader;
112 94 : ReturnErrorOnFailure(mReader.FindElementWithTag(TLV::ContextTag(Tag::kInvokeRequests), reader));
113 94 : return apInvokeRequests->Init(reader);
114 : }
115 :
116 48 : CHIP_ERROR InvokeRequestMessage::Builder::InitWithEndBufferReserved(TLV::TLVWriter * const apWriter)
117 : {
118 48 : ReturnErrorOnFailure(Init(apWriter));
119 48 : ReturnErrorOnFailure(GetWriter()->ReserveBuffer(GetSizeToEndInvokeRequestMessage()));
120 48 : mIsEndBufferReserved = true;
121 48 : return CHIP_NO_ERROR;
122 : }
123 :
124 52 : InvokeRequestMessage::Builder & InvokeRequestMessage::Builder::SuppressResponse(const bool aSuppressResponse)
125 : {
126 52 : if (mError == CHIP_NO_ERROR)
127 : {
128 52 : mError = mpWriter->PutBoolean(TLV::ContextTag(Tag::kSuppressResponse), aSuppressResponse);
129 : }
130 52 : return *this;
131 : }
132 :
133 52 : InvokeRequestMessage::Builder & InvokeRequestMessage::Builder::TimedRequest(const bool aTimedRequest)
134 : {
135 52 : if (mError == CHIP_NO_ERROR)
136 : {
137 52 : mError = mpWriter->PutBoolean(TLV::ContextTag(Tag::kTimedRequest), aTimedRequest);
138 : }
139 52 : return *this;
140 : }
141 :
142 53 : InvokeRequests::Builder & InvokeRequestMessage::Builder::CreateInvokeRequests(const bool aReserveEndBuffer)
143 : {
144 53 : if (mError == CHIP_NO_ERROR)
145 : {
146 53 : if (aReserveEndBuffer)
147 : {
148 47 : mError = mInvokeRequests.InitWithEndBufferReserved(mpWriter, to_underlying(Tag::kInvokeRequests));
149 : }
150 : else
151 : {
152 6 : mError = mInvokeRequests.Init(mpWriter, to_underlying(Tag::kInvokeRequests));
153 : }
154 : }
155 53 : return mInvokeRequests;
156 : }
157 :
158 50 : CHIP_ERROR InvokeRequestMessage::Builder::EndOfInvokeRequestMessage()
159 : {
160 : // If any changes are made to how we end the invoke request message that involves how many
161 : // bytes are needed, a corresponding change to GetSizeToEndInvokeRequestMessage indicating
162 : // the new size that will be required.
163 50 : ReturnErrorOnFailure(mError);
164 50 : if (mIsEndBufferReserved)
165 : {
166 44 : ReturnErrorOnFailure(GetWriter()->UnreserveBuffer(GetSizeToEndInvokeRequestMessage()));
167 44 : mIsEndBufferReserved = false;
168 : }
169 50 : if (mError == CHIP_NO_ERROR)
170 : {
171 50 : mError = MessageBuilder::EncodeInteractionModelRevision();
172 : }
173 50 : if (mError == CHIP_NO_ERROR)
174 : {
175 50 : EndOfContainer();
176 : }
177 50 : return GetError();
178 : }
179 :
180 92 : uint32_t InvokeRequestMessage::Builder::GetSizeToEndInvokeRequestMessage()
181 : {
182 : // EncodeInteractionModelRevision() encodes a uint8_t with context tag 0xFF. This means 1 control byte,
183 : // 1 byte for the tag, 1 byte for the value.
184 92 : uint32_t kEncodeInteractionModelSize = 1 + 1 + 1;
185 92 : uint32_t kEndOfContainerSize = 1;
186 :
187 92 : return kEncodeInteractionModelSize + kEndOfContainerSize;
188 : }
189 : }; // namespace app
190 : }; // namespace chip
|