Line data Source code
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 ReportDataMessage parser and builder in CHIP interaction model 21 : * 22 : */ 23 : 24 : #include "ReportDataMessage.h" 25 : 26 : #include "MessageDefHelper.h" 27 : 28 : #include <inttypes.h> 29 : #include <stdarg.h> 30 : #include <stdio.h> 31 : 32 : #include <app/AppConfig.h> 33 : 34 : using namespace chip; 35 : 36 : namespace chip { 37 : namespace app { 38 : #if CHIP_CONFIG_IM_PRETTY_PRINT 39 1780 : CHIP_ERROR ReportDataMessage::Parser::PrettyPrint() const 40 : { 41 1780 : CHIP_ERROR err = CHIP_NO_ERROR; 42 : TLV::TLVReader reader; 43 1780 : AttributeReportIBs::Parser attributeReportIBs; 44 1780 : EventReportIBs::Parser eventReportIBs; 45 : 46 1780 : PRETTY_PRINT("ReportDataMessage ="); 47 1780 : PRETTY_PRINT("{"); 48 : 49 : // make a copy of the reader 50 1780 : reader.Init(mReader); 51 : 52 7190 : while (CHIP_NO_ERROR == (err = reader.Next())) 53 : { 54 5410 : if (!TLV::IsContextTag(reader.GetTag())) 55 : { 56 0 : continue; 57 : } 58 5410 : uint32_t tagNum = TLV::TagNumFromTag(reader.GetTag()); 59 5410 : switch (tagNum) 60 : { 61 632 : case to_underlying(Tag::kSuppressResponse): 62 632 : VerifyOrReturnError(TLV::kTLVType_Boolean == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); 63 : #if CHIP_DETAIL_LOGGING 64 : { 65 : bool SuppressResponse; 66 632 : ReturnErrorOnFailure(reader.Get(SuppressResponse)); 67 632 : PRETTY_PRINT("\tSuppressResponse = %s, ", SuppressResponse ? "true" : "false"); 68 : } 69 : #endif // CHIP_DETAIL_LOGGING 70 632 : break; 71 348 : case to_underlying(Tag::kSubscriptionId): 72 348 : VerifyOrReturnError(TLV::kTLVType_UnsignedInteger == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); 73 : #if CHIP_DETAIL_LOGGING 74 : { 75 : SubscriptionId subscriptionId; 76 348 : ReturnErrorOnFailure(reader.Get(subscriptionId)); 77 348 : PRETTY_PRINT("\tSubscriptionId = 0x%" PRIx32 ",", subscriptionId); 78 : } 79 : #endif // CHIP_DETAIL_LOGGING 80 348 : break; 81 1145 : case to_underlying(Tag::kAttributeReportIBs): 82 1145 : VerifyOrReturnError(TLV::kTLVType_Array == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); 83 : #if CHIP_DETAIL_LOGGING 84 : { 85 1145 : attributeReportIBs.Init(reader); 86 : 87 1145 : PRETTY_PRINT_INCDEPTH(); 88 1145 : ReturnErrorOnFailure(attributeReportIBs.PrettyPrint()); 89 1145 : PRETTY_PRINT_DECDEPTH(); 90 : } 91 : #endif // CHIP_DETAIL_LOGGING 92 1145 : break; 93 641 : case to_underlying(Tag::kEventReports): 94 641 : VerifyOrReturnError(TLV::kTLVType_Array == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); 95 : #if CHIP_DETAIL_LOGGING 96 : { 97 641 : eventReportIBs.Init(reader); 98 : 99 641 : PRETTY_PRINT_INCDEPTH(); 100 641 : ReturnErrorOnFailure(eventReportIBs.PrettyPrint()); 101 641 : PRETTY_PRINT_DECDEPTH(); 102 : } 103 : #endif // CHIP_DETAIL_LOGGING 104 641 : break; 105 864 : case to_underlying(Tag::kMoreChunkedMessages): 106 864 : VerifyOrReturnError(TLV::kTLVType_Boolean == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); 107 : #if CHIP_DETAIL_LOGGING 108 : { 109 : bool moreChunkedMessages; 110 864 : ReturnErrorOnFailure(reader.Get(moreChunkedMessages)); 111 864 : PRETTY_PRINT("\tMoreChunkedMessages = %s, ", moreChunkedMessages ? "true" : "false"); 112 : } 113 : #endif // CHIP_DETAIL_LOGGING 114 864 : break; 115 1780 : case kInteractionModelRevisionTag: 116 1780 : ReturnErrorOnFailure(MessageParser::CheckInteractionModelRevision(reader)); 117 1780 : break; 118 0 : default: 119 0 : PRETTY_PRINT("Unknown tag num %" PRIu32, tagNum); 120 0 : break; 121 : } 122 : } 123 : 124 1780 : PRETTY_PRINT("}"); 125 1780 : PRETTY_PRINT_BLANK_LINE(); 126 : // if we have exhausted this container 127 1780 : if (CHIP_END_OF_TLV == err) 128 : { 129 1780 : err = CHIP_NO_ERROR; 130 : } 131 1780 : ReturnErrorOnFailure(err); 132 1780 : return reader.ExitContainer(mOuterContainerType); 133 : } 134 : #endif // CHIP_CONFIG_IM_PRETTY_PRINT 135 : 136 1777 : CHIP_ERROR ReportDataMessage::Parser::GetSuppressResponse(bool * const apSuppressResponse) const 137 : { 138 1777 : return GetSimpleValue(to_underlying(Tag::kSuppressResponse), TLV::kTLVType_Boolean, apSuppressResponse); 139 : } 140 : 141 1862 : CHIP_ERROR ReportDataMessage::Parser::GetSubscriptionId(SubscriptionId * const apSubscriptionId) const 142 : { 143 1862 : return GetUnsignedInteger(to_underlying(Tag::kSubscriptionId), apSubscriptionId); 144 : } 145 : 146 1773 : CHIP_ERROR ReportDataMessage::Parser::GetAttributeReportIBs(AttributeReportIBs::Parser * const apAttributeReportIBs) const 147 : { 148 : TLV::TLVReader reader; 149 1773 : ReturnErrorOnFailure(mReader.FindElementWithTag(TLV::ContextTag(Tag::kAttributeReportIBs), reader)); 150 1142 : return apAttributeReportIBs->Init(reader); 151 : } 152 : 153 1773 : CHIP_ERROR ReportDataMessage::Parser::GetEventReports(EventReportIBs::Parser * const apEventReports) const 154 : { 155 : TLV::TLVReader reader; 156 1773 : ReturnErrorOnFailure(mReader.FindElementWithTag(TLV::ContextTag(Tag::kEventReports), reader)); 157 641 : return apEventReports->Init(reader); 158 : } 159 : 160 1773 : CHIP_ERROR ReportDataMessage::Parser::GetMoreChunkedMessages(bool * const apMoreChunkedMessages) const 161 : { 162 1773 : return GetSimpleValue(to_underlying(Tag::kMoreChunkedMessages), TLV::kTLVType_Boolean, apMoreChunkedMessages); 163 : } 164 : 165 648 : ReportDataMessage::Builder & ReportDataMessage::Builder::SuppressResponse(const bool aSuppressResponse) 166 : { 167 : // skip if error has already been set 168 648 : if (mError == CHIP_NO_ERROR) 169 : { 170 648 : mError = mpWriter->PutBoolean(TLV::ContextTag(Tag::kSuppressResponse), aSuppressResponse); 171 : } 172 648 : return *this; 173 : } 174 : 175 371 : ReportDataMessage::Builder & ReportDataMessage::Builder::SubscriptionId(const chip::SubscriptionId aSubscriptionId) 176 : { 177 : // skip if error has already been set 178 371 : if (mError == CHIP_NO_ERROR) 179 : { 180 371 : mError = mpWriter->Put(TLV::ContextTag(Tag::kSubscriptionId), aSubscriptionId); 181 : } 182 371 : return *this; 183 : } 184 : 185 1848 : AttributeReportIBs::Builder & ReportDataMessage::Builder::CreateAttributeReportIBs() 186 : { 187 : // skip if error has already been set 188 1848 : if (mError == CHIP_NO_ERROR) 189 : { 190 1848 : mError = mAttributeReportIBsBuilder.Init(mpWriter, to_underlying(Tag::kAttributeReportIBs)); 191 : } 192 1848 : return mAttributeReportIBsBuilder; 193 : } 194 : 195 864 : EventReportIBs::Builder & ReportDataMessage::Builder::CreateEventReports() 196 : { 197 : // skip if error has already been set 198 864 : if (mError == CHIP_NO_ERROR) 199 : { 200 864 : mError = mEventReportsBuilder.Init(mpWriter, to_underlying(Tag::kEventReports)); 201 : } 202 864 : return mEventReportsBuilder; 203 : } 204 : 205 874 : ReportDataMessage::Builder & ReportDataMessage::Builder::MoreChunkedMessages(const bool aMoreChunkedMessages) 206 : { 207 : // skip if error has already been set 208 874 : if (mError == CHIP_NO_ERROR) 209 : { 210 874 : mError = mpWriter->PutBoolean(TLV::ContextTag(Tag::kMoreChunkedMessages), aMoreChunkedMessages); 211 : } 212 874 : return *this; 213 : } 214 : 215 1821 : CHIP_ERROR ReportDataMessage::Builder::EndOfReportDataMessage() 216 : { 217 1821 : if (mError == CHIP_NO_ERROR) 218 : { 219 1821 : mError = MessageBuilder::EncodeInteractionModelRevision(); 220 : } 221 1821 : if (mError == CHIP_NO_ERROR) 222 : { 223 1821 : EndOfContainer(); 224 : } 225 1821 : return GetError(); 226 : } 227 : } // namespace app 228 : } // namespace chip