Line data Source code
1 : /* 2 : * Copyright (c) 2024 Project CHIP Authors 3 : * All rights reserved. 4 : * 5 : * Licensed under the Apache License, Version 2.0 (the "License"); 6 : * you may not use this file except in compliance with the License. 7 : * You may obtain a copy of the License at 8 : * 9 : * http://www.apache.org/licenses/LICENSE-2.0 10 : * 11 : * Unless required by applicable law or agreed to in writing, software 12 : * distributed under the License is distributed on an "AS IS" BASIS, 13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 : * See the License for the specific language governing permissions and 15 : * limitations under the License. 16 : */ 17 : 18 : #include "FabricScopedPreEncodedValue.h" 19 : #include <lib/core/TLVReader.h> 20 : #include <lib/support/CodeUtils.h> 21 : 22 : #include <optional> 23 : 24 : namespace chip { 25 : namespace app { 26 : namespace DataModel { 27 : 28 4 : FabricScopedPreEncodedValue::FabricScopedPreEncodedValue(const ByteSpan & aData) : mData(aData) {} 29 : 30 3 : CHIP_ERROR FabricScopedPreEncodedValue::EncodeForRead(TLV::TLVWriter & aWriter, TLV::Tag aTag, FabricIndex aFabricIndex) const 31 : { 32 : TLV::TLVReader reader; 33 3 : reader.Init(mData); 34 : 35 3 : ReturnErrorOnFailure(reader.Next()); 36 : 37 3 : return aWriter.CopyElement(aTag, reader); 38 : } 39 : 40 6 : FabricIndex FabricScopedPreEncodedValue::GetFabricIndex() const 41 : { 42 : TLV::TLVReader reader; 43 6 : reader.Init(mData); 44 6 : CHIP_ERROR err = reader.Next(); 45 6 : if (err != CHIP_NO_ERROR) 46 : { 47 0 : return kUndefinedFabricIndex; 48 : } 49 : 50 : // We must have a struct here. 51 6 : if (reader.GetType() != TLV::kTLVType_Structure) 52 : { 53 0 : return kUndefinedFabricIndex; 54 : } 55 : 56 : TLV::TLVType structType; 57 6 : err = reader.EnterContainer(structType); 58 6 : if (err != CHIP_NO_ERROR) 59 : { 60 0 : return kUndefinedFabricIndex; 61 : } 62 : 63 : // Now look for a single field with the right tag. 64 6 : std::optional<FabricIndex> foundFabricIndex; 65 6 : constexpr TLV::Tag kFabricIndexTag = TLV::ContextTag(254); 66 18 : while ((err = reader.Next()) == CHIP_NO_ERROR) 67 : { 68 12 : if (reader.GetTag() != kFabricIndexTag) 69 : { 70 6 : continue; 71 : } 72 : 73 6 : if (foundFabricIndex.has_value()) 74 : { 75 : // Two fabric indices? Just give up. Note that this will lead to 76 : // errors encoding our value. 77 0 : return kUndefinedFabricIndex; 78 : } 79 : 80 6 : err = reader.Get(foundFabricIndex.emplace()); 81 6 : if (err != CHIP_NO_ERROR) 82 : { 83 0 : return kUndefinedFabricIndex; 84 : } 85 : } 86 : 87 6 : if (err != CHIP_ERROR_END_OF_TLV) 88 : { 89 0 : return kUndefinedFabricIndex; 90 : } 91 : 92 6 : err = reader.ExitContainer(structType); 93 6 : if (err != CHIP_NO_ERROR) 94 : { 95 0 : return kUndefinedFabricIndex; 96 : } 97 : 98 6 : return foundFabricIndex.value_or(kUndefinedFabricIndex); 99 : } 100 : 101 : } // namespace DataModel 102 : } // namespace app 103 : } // namespace chip