/* * Copyright (c) 2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "access/SubjectDescriptor.h" #include "app/EventPathParams.h" #include "lib/core/CHIPError.h" #include #include #include #include #include #include #include #include #include namespace chip { namespace app { namespace DataModel { /// Represents operations against a matter-defined data model. /// /// Class is SINGLE-THREADED: /// - operations are assumed to only be ever run in a single event-loop /// thread or equivalent /// - class is allowed to attempt to cache indexes/locations for faster /// lookups of things (e.g during iterations) class Provider : public ProviderMetadataTree { public: virtual ~Provider() = default; // `context` pointers will be guaranteed valid until Shutdown is called() virtual CHIP_ERROR Startup(InteractionModelContext context) { mContext = context; return CHIP_NO_ERROR; } virtual CHIP_ERROR Shutdown() = 0; // During the transition phase, we expect a large subset of code to require access to // event emitting, path marking and other operations virtual InteractionModelContext CurrentContext() const { return mContext; } /// Validates that the given event path is supported, where path may contain wildcards. /// /// If any wild cards exist on the given path, the implementation is expected to validate /// that an accessible event path exists on some wildcard expansion. /// /// At the very minimum this will validate that a valid endpoint/cluster can be expanded /// from the input path and that the given descriptor has access to it. virtual bool EventPathIncludesAccessibleConcretePath(const EventPathParams & path, const Access::SubjectDescriptor & descriptor) = 0; /// TEMPORARY/TRANSITIONAL requirement for transitioning from ember-specific code /// ReadAttribute is REQUIRED to perform: /// - ACL validation (see notes on OperationFlags::kInternal) /// - Validation of readability/writability (also controlled by OperationFlags::kInternal) /// - use request.path.mExpanded to skip encoding replies for data according /// to 8.4.3.2 of the spec: /// > If the path indicates attribute data that is not readable, then the path SHALL /// be discarded. /// > Else if reading from the attribute in the path requires a privilege that is not /// granted to access the cluster in the path, then the path SHALL be discarded. /// /// Return value notes: /// ActionReturnStatus::IsOutOfSpaceEncodingResponse /// - Indicates that list encoding had insufficient buffer space to encode elements. /// - encoder::GetState().AllowPartialData() determines if these errors are permanent (no partial /// data allowed) or further encoding can be retried (AllowPartialData true for list encoding) virtual ActionReturnStatus ReadAttribute(const ReadAttributeRequest & request, AttributeValueEncoder & encoder) = 0; /// Requests a write of an attribute. /// /// When this is invoked, caller is expected to have already done some validations: /// - cluster `data version` has been checked for the incoming request if applicable /// /// TEMPORARY/TRANSITIONAL requirement for transitioning from ember-specific code /// WriteAttribute is REQUIRED to perform: /// - ACL validation (see notes on OperationFlags::kInternal) /// - Validation of readability/writability (also controlled by OperationFlags::kInternal) /// - Validation of timed interaction required (also controlled by OperationFlags::kInternal) virtual ActionReturnStatus WriteAttribute(const WriteAttributeRequest & request, AttributeValueDecoder & decoder) = 0; /// `handler` is used to send back the reply. /// - returning `std::nullopt` means that return value was placed in handler directly. /// This includes cases where command handling and value return will be done asynchronously. /// - returning a value other than Success implies an error reply (error and data are mutually exclusive) /// /// Return value expectations: /// - if a response has been placed into `handler` then std::nullopt MUST be returned. In particular /// note that CHIP_NO_ERROR is NOT the same as std::nullopt: /// > CHIP_NO_ERROR means handler had no status set and we expect the caller to AddStatus(success) /// > std::nullopt means that handler has added an appropriate data/status response /// - if a value is returned (not nullopt) then the handler response MUST NOT be filled. The caller /// will then issue `handler->AddStatus(request.path, ->GetStatusCode())`. This is a /// convenience to make writing Invoke calls easier. virtual std::optional Invoke(const InvokeRequest & request, chip::TLV::TLVReader & input_arguments, CommandHandler * handler) = 0; private: InteractionModelContext mContext = { nullptr }; }; } // namespace DataModel } // namespace app } // namespace chip