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 41 : CHIP_ERROR InvokeRequestMessage::Parser::PrettyPrint() const
30 : {
31 41 : CHIP_ERROR err = CHIP_NO_ERROR;
32 41 : TLV::TLVReader reader;
33 :
34 41 : PRETTY_PRINT("InvokeRequestMessage =");
35 41 : PRETTY_PRINT("{");
36 :
37 : // make a copy of the reader
38 41 : reader.Init(mReader);
39 :
40 203 : while (CHIP_NO_ERROR == (err = reader.Next()))
41 : {
42 163 : if (!TLV::IsContextTag(reader.GetTag()))
43 : {
44 0 : continue;
45 : }
46 163 : uint32_t tagNum = TLV::TagNumFromTag(reader.GetTag());
47 163 : switch (tagNum)
48 : {
49 41 : case to_underlying(Tag::kSuppressResponse):
50 : #if CHIP_DETAIL_LOGGING
51 : {
52 : bool suppressResponse;
53 41 : ReturnErrorOnFailure(reader.Get(suppressResponse));
54 41 : PRETTY_PRINT("\tsuppressResponse = %s, ", suppressResponse ? "true" : "false");
55 : }
56 : #endif // CHIP_DETAIL_LOGGING
57 41 : break;
58 :
59 41 : case to_underlying(Tag::kTimedRequest):
60 : #if CHIP_DETAIL_LOGGING
61 : {
62 : bool timedRequest;
63 41 : ReturnErrorOnFailure(reader.Get(timedRequest));
64 41 : PRETTY_PRINT("\ttimedRequest = %s, ", timedRequest ? "true" : "false");
65 : }
66 : #endif // CHIP_DETAIL_LOGGING
67 41 : break;
68 41 : case to_underlying(Tag::kInvokeRequests): {
69 41 : InvokeRequests::Parser invokeRequests;
70 41 : ReturnErrorOnFailure(invokeRequests.Init(reader));
71 :
72 41 : PRETTY_PRINT_INCDEPTH();
73 41 : ReturnErrorOnFailure(invokeRequests.PrettyPrint());
74 40 : PRETTY_PRINT_DECDEPTH();
75 : }
76 40 : break;
77 40 : case Revision::kInteractionModelRevisionTag:
78 40 : ReturnErrorOnFailure(MessageParser::CheckInteractionModelRevision(reader));
79 40 : break;
80 0 : default:
81 0 : PRETTY_PRINT("Unknown tag num %" PRIu32, tagNum);
82 0 : break;
83 : }
84 : }
85 :
86 40 : PRETTY_PRINT("},");
87 40 : PRETTY_PRINT_BLANK_LINE();
88 :
89 40 : if (CHIP_END_OF_TLV == err)
90 : {
91 40 : err = CHIP_NO_ERROR;
92 : }
93 :
94 40 : ReturnErrorOnFailure(err);
95 40 : return reader.ExitContainer(mOuterContainerType);
96 : }
97 : #endif // CHIP_CONFIG_IM_PRETTY_PRINT
98 :
99 41 : CHIP_ERROR InvokeRequestMessage::Parser::GetSuppressResponse(bool * const apSuppressResponse) const
100 : {
101 41 : return GetSimpleValue(to_underlying(Tag::kSuppressResponse), TLV::kTLVType_Boolean, apSuppressResponse);
102 : }
103 :
104 41 : CHIP_ERROR InvokeRequestMessage::Parser::GetTimedRequest(bool * const apTimedRequest) const
105 : {
106 41 : return GetSimpleValue(to_underlying(Tag::kTimedRequest), TLV::kTLVType_Boolean, apTimedRequest);
107 : }
108 :
109 78 : CHIP_ERROR InvokeRequestMessage::Parser::GetInvokeRequests(InvokeRequests::Parser * const apInvokeRequests) const
110 : {
111 78 : TLV::TLVReader reader;
112 78 : ReturnErrorOnFailure(mReader.FindElementWithTag(TLV::ContextTag(Tag::kInvokeRequests), reader));
113 78 : return apInvokeRequests->Init(reader);
114 : }
115 :
116 40 : CHIP_ERROR InvokeRequestMessage::Builder::InitWithEndBufferReserved(TLV::TLVWriter * const apWriter)
117 : {
118 40 : ReturnErrorOnFailure(Init(apWriter));
119 40 : ReturnErrorOnFailure(GetWriter()->ReserveBuffer(GetSizeToEndInvokeRequestMessage()));
120 40 : mIsEndBufferReserved = true;
121 40 : return CHIP_NO_ERROR;
122 : }
123 :
124 44 : InvokeRequestMessage::Builder & InvokeRequestMessage::Builder::SuppressResponse(const bool aSuppressResponse)
125 : {
126 44 : if (mError == CHIP_NO_ERROR)
127 : {
128 44 : mError = mpWriter->PutBoolean(TLV::ContextTag(Tag::kSuppressResponse), aSuppressResponse);
129 : }
130 44 : return *this;
131 : }
132 :
133 44 : InvokeRequestMessage::Builder & InvokeRequestMessage::Builder::TimedRequest(const bool aTimedRequest)
134 : {
135 44 : if (mError == CHIP_NO_ERROR)
136 : {
137 44 : mError = mpWriter->PutBoolean(TLV::ContextTag(Tag::kTimedRequest), aTimedRequest);
138 : }
139 44 : return *this;
140 : }
141 :
142 45 : InvokeRequests::Builder & InvokeRequestMessage::Builder::CreateInvokeRequests(const bool aReserveEndBuffer)
143 : {
144 45 : if (mError == CHIP_NO_ERROR)
145 : {
146 45 : if (aReserveEndBuffer)
147 : {
148 39 : 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 45 : return mInvokeRequests;
156 : }
157 :
158 42 : 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 42 : ReturnErrorOnFailure(mError);
164 42 : if (mIsEndBufferReserved)
165 : {
166 36 : ReturnErrorOnFailure(GetWriter()->UnreserveBuffer(GetSizeToEndInvokeRequestMessage()));
167 36 : mIsEndBufferReserved = false;
168 : }
169 42 : if (mError == CHIP_NO_ERROR)
170 : {
171 42 : mError = MessageBuilder::EncodeInteractionModelRevision();
172 : }
173 42 : if (mError == CHIP_NO_ERROR)
174 : {
175 42 : EndOfContainer();
176 : }
177 42 : return GetError();
178 : }
179 :
180 76 : 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 76 : uint32_t kEncodeInteractionModelSize = 1 + 1 + 1;
185 76 : uint32_t kEndOfContainerSize = 1;
186 :
187 76 : return kEncodeInteractionModelSize + kEndOfContainerSize;
188 : }
189 : }; // namespace app
190 : }; // namespace chip
|