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 : #pragma once
18 :
19 : #include <lib/core/CHIPError.h>
20 : #include <lib/support/StringBuilder.h>
21 : #include <protocols/interaction_model/StatusCode.h>
22 :
23 : #include <variant>
24 :
25 : namespace chip {
26 : namespace app {
27 : namespace DataModel {
28 :
29 : /// An ActionReturnStatus encodes the result of a read/write/invoke.
30 : ///
31 : /// Generally such actions result in a StatusIB in the interaction model,
32 : /// which is a code (InteractionModel::Status) and may have an associated
33 : /// cluster-specific code.
34 : ///
35 : /// However some actions specifically may return additional information for
36 : /// chunking, hence the existence of this class:
37 : ///
38 : /// - encapsulates a ClusterStatusCode for an actual action result
39 : /// - encapsulates a underlying CHIP_ERROR for reporting purposes
40 : /// - has a way to check for "chunking needed" status.
41 : ///
42 : /// The class is directly constructible from statuses (non-exlicit) to make
43 : /// returning of values easy.
44 : class ActionReturnStatus
45 : {
46 : public:
47 : /// Provides storage for the c_str() call for the action status.
48 : struct StringStorage
49 : {
50 : // Generally size should be sufficient.
51 : // The longest status code from StatusCodeList is NO_UPSTREAM_SUBSCRIPTION(197)
52 : // so we need space for one of:
53 : // "NO_UPSTREAM_SUBSCRIPTION(197)\0" = 30 // explicit verbose status code
54 : // "FAILURE(1), Code 255\0") // cluster failure, verbose
55 : // "SUCCESS(0), Code 255\0") // cluster success, verbose
56 : // "Status<197>, Code 255\0") // Cluster failure, non-verbose
57 : //
58 : // CHIP_ERROR has its own (global/static!) storage
59 : chip::StringBuilder<32> formatBuffer;
60 : };
61 :
62 10443 : ActionReturnStatus(CHIP_ERROR error) : mReturnStatus(error) {}
63 43 : ActionReturnStatus(Protocols::InteractionModel::Status status) :
64 43 : mReturnStatus(Protocols::InteractionModel::ClusterStatusCode(status))
65 43 : {}
66 : ActionReturnStatus(Protocols::InteractionModel::ClusterStatusCode status) : mReturnStatus(status) {}
67 :
68 : /// Constructs a status code. Either returns the underlying code directly
69 : /// or converts the underlying CHIP_ERROR into a cluster status code.
70 : Protocols::InteractionModel::ClusterStatusCode GetStatusCode() const;
71 :
72 : /// Gets the underlying CHIP_ERROR if it exists, otherwise it will
73 : /// return a CHIP_ERROR corresponding to the underlying return status.
74 : ///
75 : /// Success statusess will result in CHIP_NO_ERROR (i.e. cluster specitic success codes are lost)
76 : CHIP_ERROR GetUnderlyingError() const;
77 :
78 : /// If this is a CHIP_NO_ERROR or a Status::Success
79 : bool IsSuccess() const;
80 :
81 : /// Considers if the underlying error is an error or not (CHIP_NO_ERROR is the only non-erro)
82 : /// or if the underlying statuscode is not an error (success and cluster specific successes
83 : /// are not an error).
84 4350 : bool IsError() const { return !IsSuccess(); }
85 :
86 : /// Checks if the underlying error is an out of space condition (i.e. something that
87 : /// chunking can handle by sending partial list data).
88 : ///
89 : /// Generally this is when the return is based on CHIP_ERROR_NO_MEMORY or CHIP_ERROR_BUFFER_TOO_SMALL
90 : bool IsOutOfSpaceEncodingResponse() const;
91 :
92 : // NOTE: operator== will treat a CHIP_GLOBAL_IM_ERROR and a raw cluster status as equal if the statuses match,
93 : // even though a CHIP_ERROR has some formatting info like file/line
94 : bool operator==(const ActionReturnStatus & other) const;
95 : bool operator!=(const ActionReturnStatus & other) const { return !(*this == other); }
96 :
97 : /// Get the formatted string of this status.
98 : ///
99 : /// May use `storage` for storying the actual underlying character string.
100 : const char * c_str(StringStorage & storage) const;
101 :
102 : private:
103 : std::variant<CHIP_ERROR, Protocols::InteractionModel::ClusterStatusCode> mReturnStatus;
104 : };
105 :
106 : } // namespace DataModel
107 : } // namespace app
108 : } // namespace chip
|