Coverage Report

Created: 2025-08-28 06:31

/src/connectedhomeip/src/app/data-model-provider/Provider.h
Line
Count
Source (jump to first uncovered line)
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/core/TLVReader.h>
21
#include <lib/core/TLVWriter.h>
22
23
#include <app/AttributeValueDecoder.h>
24
#include <app/AttributeValueEncoder.h>
25
#include <app/CommandHandler.h>
26
27
#include <app/data-model-provider/ActionReturnStatus.h>
28
#include <app/data-model-provider/Context.h>
29
#include <app/data-model-provider/OperationTypes.h>
30
#include <app/data-model-provider/ProviderMetadataTree.h>
31
32
namespace chip {
33
namespace app {
34
namespace DataModel {
35
36
/// Represents operations against a matter-defined data model.
37
///
38
/// Class is SINGLE-THREADED:
39
///   - operations are assumed to only be ever run in a single event-loop
40
///     thread or equivalent
41
///   - class is allowed to attempt to cache indexes/locations for faster
42
///     lookups of things (e.g during iterations)
43
class Provider : public ProviderMetadataTree
44
{
45
public:
46
    ~Provider() override = default;
47
48
    // `context` references  will be guaranteed valid until Shutdown is called()
49
1
    virtual CHIP_ERROR Startup(InteractionModelContext context) { return CHIP_NO_ERROR; }
50
0
    virtual CHIP_ERROR Shutdown() { return CHIP_NO_ERROR; }
51
52
    /// NOTE: this code is NOT required to handle `List` global attributes:
53
    ///       AcceptedCommandsList, GeneratedCommandsList OR AttributeList
54
    ///
55
    ///       Users of DataModel::Provider are expected to get these lists
56
    ///       from ProviderMetadataTree (in particular IM Reads of these
57
    ///       attributes will be automatically filled from metadata).
58
    ///
59
    /// When this is invoked, caller is expected to have already done some validations:
60
    ///    - `request.path` is a valid path inside the ProviderMetadataTree (an AttributeEntry exists)
61
    ///    - Attribute is readable according to the ProviderMetadataTree/AttributeEntry data
62
    ///    - Appropriate ACL checks done according to the attribute's AttributeEntry
63
    ///
64
    /// Return value notes:
65
    ///   ActionReturnStatus::IsOutOfSpaceEncodingResponse
66
    ///      - Indicates that list encoding had insufficient buffer space to encode elements.
67
    ///      - encoder::GetState().AllowPartialData() determines if these errors are permanent (no partial
68
    ///        data allowed) or further encoding can be retried (AllowPartialData true for list encoding)
69
    virtual ActionReturnStatus ReadAttribute(const ReadAttributeRequest & request, AttributeValueEncoder & encoder) = 0;
70
71
    /// Requests a write of an attribute.
72
    ///
73
    /// When this is invoked, caller is expected to have already done some validations:
74
    ///    - cluster `data version` has been checked for the incoming request if applicable
75
    ///    - validation of ACL/timed interaction flags/writability, if those checks are desired.
76
    ///    - `request.path` is a valid path inside the ProviderMetadataTree (an AttributeEntry exists)
77
    ///    - Attribute is writable according to the ProviderMetadataTree/AttributeEntry data
78
    ///    - Appropriate ACL checks done according to the attribute's AttributeEntry
79
    virtual ActionReturnStatus WriteAttribute(const WriteAttributeRequest & request, AttributeValueDecoder & decoder) = 0;
80
81
    ///   Indicates the start/end of a series of list operations. This function will be called either before the first
82
    ///   Write operation or after the last one of a series of consecutive attribute data of the same attribute.
83
    ///
84
    ///   1) This function will be called if the client tries to set a nullable list attribute to null.
85
    ///   2) This function will only be called at the beginning and end of a series of consecutive attribute data
86
    ///   blocks for the same attribute, no matter what list operations those data blocks represent.
87
    ///   3) The opType argument indicates the type of notification (Start, Failure, Success).
88
    virtual void ListAttributeWriteNotification(const ConcreteAttributePath & aPath, ListWriteOperation opType) = 0;
89
90
    /// `handler` is used to send back the reply.
91
    ///    - returning `std::nullopt` means that return value was placed in handler directly.
92
    ///      This includes cases where command handling and value return will be done asynchronously.
93
    ///    - returning a value other than Success implies an error reply (error and data are mutually exclusive)
94
    ///
95
    /// Preconditions:
96
    ///    - `request.path` MUST refer to a command that actually exists.  This is because in practice
97
    ///       callers must do ACL and flag checks (e.g. for timed invoke) before calling this function.
98
    ///
99
    ///       Callers that do not care about those checks should use `ProviderMetadataTree::AcceptedCommands`
100
    ///       to check for command existence.
101
    ///
102
    ///    - TODO: as interfaces are updated, we may want to make the above requirement more
103
    ///            relaxed, as it seems desirable for users of this interface to have guaranteed
104
    ///            behavior (like error on invalid paths) whereas today this seems unclear as some
105
    ///            command intercepts do not validate that the command is in fact accepted on the
106
    ///            endpoint provided.
107
    ///
108
    /// Return value expectations:
109
    ///   - if a response has been placed into `handler` then std::nullopt MUST be returned. In particular
110
    ///     note that CHIP_NO_ERROR is NOT the same as std::nullopt:
111
    ///        > CHIP_NO_ERROR means handler had no status set and we expect the caller to AddStatus(success)
112
    ///        > std::nullopt means that handler has added an appropriate data/status response
113
    ///   - if a value is returned (not nullopt) then the handler response MUST NOT be filled. The caller
114
    ///     will then issue `handler->AddStatus(request.path, <return_value>->GetStatusCode())`. This is a
115
    ///     convenience to make writing Invoke calls easier.
116
    virtual std::optional<ActionReturnStatus> InvokeCommand(const InvokeRequest & request, chip::TLV::TLVReader & input_arguments,
117
                                                            CommandHandler * handler) = 0;
118
};
119
120
} // namespace DataModel
121
} // namespace app
122
} // namespace chip