Line data Source code
1 : /**
2 : *
3 : * Copyright (c) 2020 Project CHIP Authors
4 : * Copyright (c) 2016-2017 Nest Labs, Inc.
5 : *
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 Status Information Block in Interaction Model
21 : *
22 : */
23 :
24 : #pragma once
25 :
26 : #include "StructBuilder.h"
27 : #include "StructParser.h"
28 :
29 : #include <app/AppConfig.h>
30 : #include <app/util/basic-types.h>
31 : #include <lib/core/CHIPCore.h>
32 : #include <lib/core/Optional.h>
33 : #include <lib/core/TLV.h>
34 : #include <lib/support/CodeUtils.h>
35 : #include <lib/support/logging/CHIPLogging.h>
36 : #include <protocols/interaction_model/Constants.h>
37 : #include <protocols/interaction_model/StatusCode.h>
38 : #include <protocols/secure_channel/Constants.h>
39 :
40 : namespace chip {
41 : namespace app {
42 : struct StatusIB
43 : {
44 8231 : StatusIB() = default;
45 6 : explicit StatusIB(Protocols::InteractionModel::Status imStatus) : mStatus(imStatus) {}
46 :
47 : explicit StatusIB(Protocols::InteractionModel::Status imStatus, ClusterStatus clusterStatus) :
48 : mStatus(imStatus), mClusterStatus(clusterStatus)
49 : {}
50 :
51 105 : explicit StatusIB(const Protocols::InteractionModel::ClusterStatusCode & statusCode) : mStatus(statusCode.GetStatus())
52 : {
53 : // NOTE: Cluster-specific codes are only valid on SUCCESS/FAILURE IM status (7.10.7. Status Codes)
54 105 : chip::Optional<ClusterStatus> clusterStatus = statusCode.GetClusterSpecificCode();
55 105 : if (clusterStatus.HasValue())
56 : {
57 2 : mStatus = statusCode.IsSuccess() ? Protocols::InteractionModel::Status::Success
58 : : Protocols::InteractionModel::Status::Failure;
59 2 : mClusterStatus = clusterStatus;
60 : }
61 105 : }
62 :
63 55 : explicit StatusIB(CHIP_ERROR error) : StatusIB(Protocols::InteractionModel::ClusterStatusCode(error)) {}
64 :
65 : enum class Tag : uint8_t
66 : {
67 : kStatus = 0,
68 : kClusterStatus = 1,
69 : };
70 :
71 : class Parser : public StructParser
72 : {
73 : public:
74 : #if CHIP_CONFIG_IM_PRETTY_PRINT
75 : CHIP_ERROR PrettyPrint() const;
76 : #endif // CHIP_CONFIG_IM_PRETTY_PRINT
77 : /**
78 : * Decode the StatusIB
79 : *
80 : * @return CHIP_ERROR codes returned by chip::TLV objects. CHIP_END_OF_TLV if either
81 : * element is missing. CHIP_ERROR_WRONG_TLV_TYPE if the elements are of the wrong
82 : * type.
83 : */
84 : CHIP_ERROR DecodeStatusIB(StatusIB & aStatusIB) const;
85 : };
86 :
87 : class Builder : public StructBuilder
88 : {
89 : public:
90 : /**
91 : * Write the StatusIB into TLV and close the container
92 : *
93 : * @return CHIP_ERROR codes returned by chip::TLV objects. CHIP_END_OF_TLV if either
94 : * element is missing. CHIP_ERROR_WRONG_TLV_TYPE if the elements are of the wrong
95 : * type.
96 : */
97 : StatusIB::Builder & EncodeStatusIB(const StatusIB & aStatusIB);
98 : };
99 :
100 : /**
101 : * Encapsulate a StatusIB in a CHIP_ERROR. This can be done for any
102 : * StatusIB, but will treat all success codes (including cluster-specific
103 : * ones) as CHIP_NO_ERROR. The resulting CHIP_ERROR will either be
104 : * CHIP_NO_ERROR or test true for IsIMStatus().
105 : */
106 : CHIP_ERROR ToChipError() const;
107 :
108 : /**
109 : * Test whether this status is a success.
110 : */
111 2487 : bool IsSuccess() const { return mStatus == Protocols::InteractionModel::Status::Success; }
112 :
113 : /**
114 : * Test whether this status is a failure.
115 : */
116 : bool IsFailure() const { return !IsSuccess(); }
117 :
118 : /**
119 : * Register the StatusIB error formatter.
120 : */
121 : static void RegisterErrorFormatter();
122 :
123 : Protocols::InteractionModel::Status mStatus = Protocols::InteractionModel::Status::Success;
124 : Optional<ClusterStatus> mClusterStatus = Optional<ClusterStatus>::Missing();
125 :
126 : }; // struct StatusIB
127 :
128 : constexpr bool operator==(const StatusIB & one, const StatusIB & two)
129 : {
130 : return one.mStatus == two.mStatus && one.mClusterStatus == two.mClusterStatus;
131 : }
132 :
133 : constexpr bool operator!=(const StatusIB & one, const StatusIB & two)
134 : {
135 : return !(one == two);
136 : }
137 :
138 : }; // namespace app
139 : }; // namespace chip
|