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 3 : 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 6 : 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
|