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