Jerry Johns | 4efc582 | 2021-10-19 14:22:36 -0700 | [diff] [blame] | 1 | /* |
| 2 | * |
| 3 | * Copyright (c) 2021 Project CHIP Authors |
| 4 | * All rights reserved. |
| 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 | #pragma once |
| 20 | |
Michael Spang | c6b6fb3 | 2023-11-17 02:21:20 -0500 | [diff] [blame] | 21 | #include <app/AppConfig.h> |
Jerry Johns | 4efc582 | 2021-10-19 14:22:36 -0700 | [diff] [blame] | 22 | #include <app/AttributePathParams.h> |
| 23 | #include <app/InteractionModelEngine.h> |
| 24 | #include <app/ReadPrepareParams.h> |
| 25 | #include <controller/TypedReadCallback.h> |
| 26 | |
Wang Qixiang | 14bdc24 | 2023-08-04 13:04:55 +0800 | [diff] [blame] | 27 | #if CHIP_CONFIG_ENABLE_READ_CLIENT |
Jerry Johns | 4efc582 | 2021-10-19 14:22:36 -0700 | [diff] [blame] | 28 | namespace chip { |
| 29 | namespace Controller { |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 30 | namespace detail { |
Jerry Johns | 4efc582 | 2021-10-19 14:22:36 -0700 | [diff] [blame] | 31 | |
Jeff Tung | ad58d80 | 2022-10-26 07:37:36 -0700 | [diff] [blame] | 32 | using SubscriptionOnDoneCallback = std::function<void(void)>; |
| 33 | |
Boris Zbarsky | 9964cdb | 2021-11-10 17:12:24 -0500 | [diff] [blame] | 34 | template <typename DecodableAttributeType> |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 35 | struct ReportAttributeParams : public app::ReadPrepareParams |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 36 | { |
Marc Lepage | 9a595a4 | 2021-12-16 03:53:52 -0500 | [diff] [blame] | 37 | ReportAttributeParams(const SessionHandle & sessionHandle) : app::ReadPrepareParams(sessionHandle) |
| 38 | { |
| 39 | mKeepSubscriptions = false; |
| 40 | } |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 41 | typename TypedReadAttributeCallback<DecodableAttributeType>::OnSuccessCallbackType mOnReportCb; |
| 42 | typename TypedReadAttributeCallback<DecodableAttributeType>::OnErrorCallbackType mOnErrorCb; |
| 43 | typename TypedReadAttributeCallback<DecodableAttributeType>::OnSubscriptionEstablishedCallbackType |
yunhanw-google | dce8007 | 2022-06-08 13:16:49 -0700 | [diff] [blame] | 44 | mOnSubscriptionEstablishedCb = nullptr; |
| 45 | typename TypedReadAttributeCallback<DecodableAttributeType>::OnResubscriptionAttemptCallbackType mOnResubscriptionAttemptCb = |
| 46 | nullptr; |
Jeff Tung | ad58d80 | 2022-10-26 07:37:36 -0700 | [diff] [blame] | 47 | SubscriptionOnDoneCallback mOnDoneCb = nullptr; |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 48 | app::ReadClient::InteractionType mReportType = app::ReadClient::InteractionType::Read; |
| 49 | }; |
| 50 | |
| 51 | template <typename DecodableAttributeType> |
| 52 | CHIP_ERROR ReportAttribute(Messaging::ExchangeManager * exchangeMgr, EndpointId endpointId, ClusterId clusterId, |
yunhanw-google | 0edb9f9 | 2022-02-11 00:50:59 -0800 | [diff] [blame] | 53 | AttributeId attributeId, ReportAttributeParams<DecodableAttributeType> && readParams, |
| 54 | const Optional<DataVersion> & aDataVersion = NullOptional) |
Jerry Johns | 4efc582 | 2021-10-19 14:22:36 -0700 | [diff] [blame] | 55 | { |
Jerry Johns | 4efc582 | 2021-10-19 14:22:36 -0700 | [diff] [blame] | 56 | app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); |
| 57 | CHIP_ERROR err = CHIP_NO_ERROR; |
| 58 | |
yunhanw-google | 2cd1e1e | 2022-01-29 16:20:00 -0800 | [diff] [blame] | 59 | auto readPaths = Platform::MakeUnique<app::AttributePathParams>(endpointId, clusterId, attributeId); |
| 60 | VerifyOrReturnError(readPaths != nullptr, CHIP_ERROR_NO_MEMORY); |
| 61 | readParams.mpAttributePathParamsList = readPaths.get(); |
Jerry Johns | 4efc582 | 2021-10-19 14:22:36 -0700 | [diff] [blame] | 62 | readParams.mAttributePathParamsListSize = 1; |
yunhanw-google | 0edb9f9 | 2022-02-11 00:50:59 -0800 | [diff] [blame] | 63 | chip::Platform::UniquePtr<chip::app::DataVersionFilter> dataVersionFilters; |
| 64 | if (aDataVersion.HasValue()) |
| 65 | { |
| 66 | dataVersionFilters = Platform::MakeUnique<app::DataVersionFilter>(endpointId, clusterId, aDataVersion.Value()); |
| 67 | VerifyOrReturnError(dataVersionFilters != nullptr, CHIP_ERROR_NO_MEMORY); |
| 68 | readParams.mpDataVersionFilterList = dataVersionFilters.get(); |
| 69 | readParams.mDataVersionFilterListSize = 1; |
| 70 | } |
Jeff Tung | ad58d80 | 2022-10-26 07:37:36 -0700 | [diff] [blame] | 71 | auto onDoneCb = readParams.mOnDoneCb; |
| 72 | auto onDone = [onDoneCb](TypedReadAttributeCallback<DecodableAttributeType> * callback) { |
| 73 | if (onDoneCb) |
| 74 | { |
| 75 | onDoneCb(); |
| 76 | } |
| 77 | chip::Platform::Delete(callback); |
| 78 | }; |
Jerry Johns | 4efc582 | 2021-10-19 14:22:36 -0700 | [diff] [blame] | 79 | |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 80 | auto callback = chip::Platform::MakeUnique<TypedReadAttributeCallback<DecodableAttributeType>>( |
yunhanw-google | dce8007 | 2022-06-08 13:16:49 -0700 | [diff] [blame] | 81 | clusterId, attributeId, readParams.mOnReportCb, readParams.mOnErrorCb, onDone, readParams.mOnSubscriptionEstablishedCb, |
| 82 | readParams.mOnResubscriptionAttemptCb); |
yunhanw-google | f3d6b7c | 2021-11-17 13:42:38 -0800 | [diff] [blame] | 83 | VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); |
| 84 | |
Jerry Johns | 118ab9d | 2021-12-21 18:01:54 -0800 | [diff] [blame] | 85 | auto readClient = |
| 86 | chip::Platform::MakeUnique<app::ReadClient>(engine, exchangeMgr, callback->GetBufferedCallback(), readParams.mReportType); |
yunhanw-google | 2cd1e1e | 2022-01-29 16:20:00 -0800 | [diff] [blame] | 87 | VerifyOrReturnError(readClient != nullptr, CHIP_ERROR_NO_MEMORY); |
yunhanw-google | f3d6b7c | 2021-11-17 13:42:38 -0800 | [diff] [blame] | 88 | |
yunhanw-google | 2cd1e1e | 2022-01-29 16:20:00 -0800 | [diff] [blame] | 89 | if (readClient->IsSubscriptionType()) |
| 90 | { |
| 91 | readPaths.release(); |
yunhanw-google | 0edb9f9 | 2022-02-11 00:50:59 -0800 | [diff] [blame] | 92 | dataVersionFilters.release(); |
| 93 | |
yunhanw-google | 2cd1e1e | 2022-01-29 16:20:00 -0800 | [diff] [blame] | 94 | err = readClient->SendAutoResubscribeRequest(std::move(readParams)); |
| 95 | ReturnErrorOnFailure(err); |
| 96 | } |
| 97 | else |
| 98 | { |
| 99 | err = readClient->SendRequest(readParams); |
| 100 | ReturnErrorOnFailure(err); |
| 101 | } |
yunhanw-google | f3d6b7c | 2021-11-17 13:42:38 -0800 | [diff] [blame] | 102 | |
| 103 | // |
| 104 | // At this point, we'll get a callback through the OnDone callback above regardless of success or failure |
| 105 | // of the read operation to permit us to free up the callback object. So, release ownership of the callback |
| 106 | // object now to prevent it from being reclaimed at the end of this scoped block. |
| 107 | // |
Michael Spang | a2f1743 | 2022-01-26 20:52:14 -0500 | [diff] [blame] | 108 | callback->AdoptReadClient(std::move(readClient)); |
yunhanw-google | f3d6b7c | 2021-11-17 13:42:38 -0800 | [diff] [blame] | 109 | callback.release(); |
Jerry Johns | 118ab9d | 2021-12-21 18:01:54 -0800 | [diff] [blame] | 110 | |
yunhanw-google | f3d6b7c | 2021-11-17 13:42:38 -0800 | [diff] [blame] | 111 | return err; |
| 112 | } |
| 113 | |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 114 | } // namespace detail |
| 115 | |
| 116 | /** |
| 117 | * To avoid instantiating all the complicated read code on a per-attribute |
| 118 | * basis, we have a helper that's just templated on the type. |
| 119 | */ |
| 120 | template <typename DecodableAttributeType> |
Marc Lepage | 9a595a4 | 2021-12-16 03:53:52 -0500 | [diff] [blame] | 121 | CHIP_ERROR ReadAttribute(Messaging::ExchangeManager * exchangeMgr, const SessionHandle & sessionHandle, EndpointId endpointId, |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 122 | ClusterId clusterId, AttributeId attributeId, |
| 123 | typename TypedReadAttributeCallback<DecodableAttributeType>::OnSuccessCallbackType onSuccessCb, |
Song GUO | e17d767 | 2022-01-22 10:11:27 +0800 | [diff] [blame] | 124 | typename TypedReadAttributeCallback<DecodableAttributeType>::OnErrorCallbackType onErrorCb, |
yunhanw-google | dbc91b7 | 2022-05-27 11:08:03 -0700 | [diff] [blame] | 125 | bool fabricFiltered = true) |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 126 | { |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 127 | detail::ReportAttributeParams<DecodableAttributeType> params(sessionHandle); |
Song GUO | e17d767 | 2022-01-22 10:11:27 +0800 | [diff] [blame] | 128 | params.mOnReportCb = onSuccessCb; |
| 129 | params.mOnErrorCb = onErrorCb; |
| 130 | params.mIsFabricFiltered = fabricFiltered; |
yunhanw-google | dbc91b7 | 2022-05-27 11:08:03 -0700 | [diff] [blame] | 131 | return detail::ReportAttribute(exchangeMgr, endpointId, clusterId, attributeId, std::move(params), NullOptional); |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 132 | } |
| 133 | |
| 134 | /* |
| 135 | * A typed read attribute function that takes as input a template parameter that encapsulates the type information |
| 136 | * for a given attribute as well as callbacks for success and failure and either returns a decoded cluster-object representation |
| 137 | * of the requested attribute through the provided success callback or calls the provided failure callback. |
| 138 | * |
| 139 | * The AttributeTypeInfo is generally expected to be a ClusterName::Attributes::AttributeName::TypeInfo struct, but any |
| 140 | * object that contains type information exposed through a 'DecodableType' type declaration as well as GetClusterId() and |
| 141 | * GetAttributeId() methods is expected to work. |
| 142 | */ |
| 143 | template <typename AttributeTypeInfo> |
| 144 | CHIP_ERROR |
Marc Lepage | 9a595a4 | 2021-12-16 03:53:52 -0500 | [diff] [blame] | 145 | ReadAttribute(Messaging::ExchangeManager * exchangeMgr, const SessionHandle & sessionHandle, EndpointId endpointId, |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 146 | typename TypedReadAttributeCallback<typename AttributeTypeInfo::DecodableType>::OnSuccessCallbackType onSuccessCb, |
Song GUO | e17d767 | 2022-01-22 10:11:27 +0800 | [diff] [blame] | 147 | typename TypedReadAttributeCallback<typename AttributeTypeInfo::DecodableType>::OnErrorCallbackType onErrorCb, |
yunhanw-google | dbc91b7 | 2022-05-27 11:08:03 -0700 | [diff] [blame] | 148 | bool fabricFiltered = true) |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 149 | { |
Song GUO | e17d767 | 2022-01-22 10:11:27 +0800 | [diff] [blame] | 150 | return ReadAttribute<typename AttributeTypeInfo::DecodableType>( |
| 151 | exchangeMgr, sessionHandle, endpointId, AttributeTypeInfo::GetClusterId(), AttributeTypeInfo::GetAttributeId(), onSuccessCb, |
yunhanw-google | dbc91b7 | 2022-05-27 11:08:03 -0700 | [diff] [blame] | 152 | onErrorCb, fabricFiltered); |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 153 | } |
| 154 | |
| 155 | // Helper for SubscribeAttribute to reduce the amount of code generated. |
| 156 | template <typename DecodableAttributeType> |
yunhanw-google | 0edb9f9 | 2022-02-11 00:50:59 -0800 | [diff] [blame] | 157 | CHIP_ERROR SubscribeAttribute( |
| 158 | Messaging::ExchangeManager * exchangeMgr, const SessionHandle & sessionHandle, EndpointId endpointId, ClusterId clusterId, |
| 159 | AttributeId attributeId, typename TypedReadAttributeCallback<DecodableAttributeType>::OnSuccessCallbackType onReportCb, |
| 160 | typename TypedReadAttributeCallback<DecodableAttributeType>::OnErrorCallbackType onErrorCb, uint16_t minIntervalFloorSeconds, |
| 161 | uint16_t maxIntervalCeilingSeconds, |
| 162 | typename TypedReadAttributeCallback<DecodableAttributeType>::OnSubscriptionEstablishedCallbackType onSubscriptionEstablishedCb = |
| 163 | nullptr, |
yunhanw-google | dce8007 | 2022-06-08 13:16:49 -0700 | [diff] [blame] | 164 | typename TypedReadAttributeCallback<DecodableAttributeType>::OnResubscriptionAttemptCallbackType onResubscriptionAttemptCb = |
| 165 | nullptr, |
Jeff Tung | ad58d80 | 2022-10-26 07:37:36 -0700 | [diff] [blame] | 166 | bool fabricFiltered = true, bool keepPreviousSubscriptions = false, const Optional<DataVersion> & aDataVersion = NullOptional, |
| 167 | typename detail::SubscriptionOnDoneCallback onDoneCb = nullptr) |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 168 | { |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 169 | detail::ReportAttributeParams<DecodableAttributeType> params(sessionHandle); |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 170 | params.mOnReportCb = onReportCb; |
| 171 | params.mOnErrorCb = onErrorCb; |
| 172 | params.mOnSubscriptionEstablishedCb = onSubscriptionEstablishedCb; |
yunhanw-google | dce8007 | 2022-06-08 13:16:49 -0700 | [diff] [blame] | 173 | params.mOnResubscriptionAttemptCb = onResubscriptionAttemptCb; |
Jeff Tung | ad58d80 | 2022-10-26 07:37:36 -0700 | [diff] [blame] | 174 | params.mOnDoneCb = onDoneCb; |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 175 | params.mMinIntervalFloorSeconds = minIntervalFloorSeconds; |
| 176 | params.mMaxIntervalCeilingSeconds = maxIntervalCeilingSeconds; |
Jerry Johns | 12db26d | 2022-01-26 10:06:04 -0800 | [diff] [blame] | 177 | params.mKeepSubscriptions = keepPreviousSubscriptions; |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 178 | params.mReportType = app::ReadClient::InteractionType::Subscribe; |
Song GUO | e17d767 | 2022-01-22 10:11:27 +0800 | [diff] [blame] | 179 | params.mIsFabricFiltered = fabricFiltered; |
yunhanw-google | 0edb9f9 | 2022-02-11 00:50:59 -0800 | [diff] [blame] | 180 | return detail::ReportAttribute(exchangeMgr, endpointId, clusterId, attributeId, std::move(params), aDataVersion); |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 181 | } |
| 182 | |
| 183 | /* |
| 184 | * A typed way to subscribe to the value of a single attribute. See |
| 185 | * documentation for ReadAttribute above for details on how AttributeTypeInfo |
| 186 | * works. |
Jerry Johns | b697b29 | 2022-03-29 22:24:11 -0700 | [diff] [blame] | 187 | * |
| 188 | * A const view-only reference to the underlying ReadClient is passed in through the OnSubscriptionEstablishedCallbackType |
| 189 | * argument. This reference is valid until the error callback is invoked at which point, this reference is no longer valid |
| 190 | * and should not be used any more. |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 191 | */ |
| 192 | template <typename AttributeTypeInfo> |
| 193 | CHIP_ERROR SubscribeAttribute( |
Marc Lepage | 9a595a4 | 2021-12-16 03:53:52 -0500 | [diff] [blame] | 194 | Messaging::ExchangeManager * exchangeMgr, const SessionHandle & sessionHandle, EndpointId endpointId, |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 195 | typename TypedReadAttributeCallback<typename AttributeTypeInfo::DecodableType>::OnSuccessCallbackType onReportCb, |
| 196 | typename TypedReadAttributeCallback<typename AttributeTypeInfo::DecodableType>::OnErrorCallbackType onErrorCb, |
| 197 | uint16_t aMinIntervalFloorSeconds, uint16_t aMaxIntervalCeilingSeconds, |
| 198 | typename TypedReadAttributeCallback<typename AttributeTypeInfo::DecodableType>::OnSubscriptionEstablishedCallbackType |
Song GUO | e17d767 | 2022-01-22 10:11:27 +0800 | [diff] [blame] | 199 | onSubscriptionEstablishedCb = nullptr, |
yunhanw-google | dce8007 | 2022-06-08 13:16:49 -0700 | [diff] [blame] | 200 | typename TypedReadAttributeCallback<typename AttributeTypeInfo::DecodableType>::OnResubscriptionAttemptCallbackType |
| 201 | onResubscriptionAttemptCb = nullptr, |
Jeff Tung | ad58d80 | 2022-10-26 07:37:36 -0700 | [diff] [blame] | 202 | bool fabricFiltered = true, bool keepPreviousSubscriptions = false, const Optional<DataVersion> & aDataVersion = NullOptional, |
| 203 | typename detail::SubscriptionOnDoneCallback onDoneCb = nullptr) |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 204 | { |
| 205 | return SubscribeAttribute<typename AttributeTypeInfo::DecodableType>( |
| 206 | exchangeMgr, sessionHandle, endpointId, AttributeTypeInfo::GetClusterId(), AttributeTypeInfo::GetAttributeId(), onReportCb, |
yunhanw-google | dce8007 | 2022-06-08 13:16:49 -0700 | [diff] [blame] | 207 | onErrorCb, aMinIntervalFloorSeconds, aMaxIntervalCeilingSeconds, onSubscriptionEstablishedCb, onResubscriptionAttemptCb, |
Jeff Tung | ad58d80 | 2022-10-26 07:37:36 -0700 | [diff] [blame] | 208 | fabricFiltered, keepPreviousSubscriptions, aDataVersion, onDoneCb); |
Boris Zbarsky | a8b7f4b | 2021-12-09 09:14:58 -0500 | [diff] [blame] | 209 | } |
| 210 | |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 211 | namespace detail { |
| 212 | |
yunhanw-google | 5c70530 | 2021-12-06 17:41:52 -0800 | [diff] [blame] | 213 | template <typename DecodableEventType> |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 214 | struct ReportEventParams : public app::ReadPrepareParams |
| 215 | { |
Boris Zbarsky | 772c060 | 2022-03-02 12:40:35 -0500 | [diff] [blame] | 216 | ReportEventParams(const SessionHandle & sessionHandle) : app::ReadPrepareParams(sessionHandle) {} |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 217 | typename TypedReadEventCallback<DecodableEventType>::OnSuccessCallbackType mOnReportCb; |
| 218 | typename TypedReadEventCallback<DecodableEventType>::OnErrorCallbackType mOnErrorCb; |
yunhanw-google | dbc91b7 | 2022-05-27 11:08:03 -0700 | [diff] [blame] | 219 | typename TypedReadEventCallback<DecodableEventType>::OnDoneCallbackType mOnDoneCb; |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 220 | typename TypedReadEventCallback<DecodableEventType>::OnSubscriptionEstablishedCallbackType mOnSubscriptionEstablishedCb = |
| 221 | nullptr; |
yunhanw-google | dce8007 | 2022-06-08 13:16:49 -0700 | [diff] [blame] | 222 | typename TypedReadEventCallback<DecodableEventType>::OnResubscriptionAttemptCallbackType mOnResubscriptionAttemptCb = nullptr; |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 223 | app::ReadClient::InteractionType mReportType = app::ReadClient::InteractionType::Read; |
| 224 | }; |
| 225 | |
| 226 | template <typename DecodableEventType> |
| 227 | CHIP_ERROR ReportEvent(Messaging::ExchangeManager * apExchangeMgr, EndpointId endpointId, |
yunhanw-google | cd44f9b | 2022-03-09 10:36:31 -0800 | [diff] [blame] | 228 | ReportEventParams<DecodableEventType> && readParams, bool aIsUrgentEvent) |
yunhanw-google | f3d6b7c | 2021-11-17 13:42:38 -0800 | [diff] [blame] | 229 | { |
yunhanw-google | 2cd1e1e | 2022-01-29 16:20:00 -0800 | [diff] [blame] | 230 | ClusterId clusterId = DecodableEventType::GetClusterId(); |
| 231 | EventId eventId = DecodableEventType::GetEventId(); |
yunhanw-google | f3d6b7c | 2021-11-17 13:42:38 -0800 | [diff] [blame] | 232 | app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); |
| 233 | CHIP_ERROR err = CHIP_NO_ERROR; |
| 234 | |
yunhanw-google | cd44f9b | 2022-03-09 10:36:31 -0800 | [diff] [blame] | 235 | auto readPaths = Platform::MakeUnique<app::EventPathParams>(endpointId, clusterId, eventId, aIsUrgentEvent); |
yunhanw-google | 2cd1e1e | 2022-01-29 16:20:00 -0800 | [diff] [blame] | 236 | VerifyOrReturnError(readPaths != nullptr, CHIP_ERROR_NO_MEMORY); |
| 237 | |
| 238 | readParams.mpEventPathParamsList = readPaths.get(); |
| 239 | |
yunhanw-google | f3d6b7c | 2021-11-17 13:42:38 -0800 | [diff] [blame] | 240 | readParams.mEventPathParamsListSize = 1; |
| 241 | |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 242 | auto callback = chip::Platform::MakeUnique<TypedReadEventCallback<DecodableEventType>>( |
yunhanw-google | dce8007 | 2022-06-08 13:16:49 -0700 | [diff] [blame] | 243 | readParams.mOnReportCb, readParams.mOnErrorCb, readParams.mOnDoneCb, readParams.mOnSubscriptionEstablishedCb, |
| 244 | readParams.mOnResubscriptionAttemptCb); |
yunhanw-google | f3d6b7c | 2021-11-17 13:42:38 -0800 | [diff] [blame] | 245 | |
Jerry Johns | 4efc582 | 2021-10-19 14:22:36 -0700 | [diff] [blame] | 246 | VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); |
| 247 | |
Jerry Johns | 118ab9d | 2021-12-21 18:01:54 -0800 | [diff] [blame] | 248 | auto readClient = chip::Platform::MakeUnique<app::ReadClient>(engine, apExchangeMgr, *callback.get(), readParams.mReportType); |
yunhanw-google | 2cd1e1e | 2022-01-29 16:20:00 -0800 | [diff] [blame] | 249 | VerifyOrReturnError(readClient != nullptr, CHIP_ERROR_NO_MEMORY); |
| 250 | |
| 251 | if (readClient->IsSubscriptionType()) |
| 252 | { |
| 253 | readPaths.release(); |
| 254 | err = readClient->SendAutoResubscribeRequest(std::move(readParams)); |
| 255 | ReturnErrorOnFailure(err); |
| 256 | } |
| 257 | else |
| 258 | { |
| 259 | err = readClient->SendRequest(readParams); |
| 260 | ReturnErrorOnFailure(err); |
| 261 | } |
Jerry Johns | 4efc582 | 2021-10-19 14:22:36 -0700 | [diff] [blame] | 262 | |
| 263 | // |
| 264 | // At this point, we'll get a callback through the OnDone callback above regardless of success or failure |
| 265 | // of the read operation to permit us to free up the callback object. So, release ownership of the callback |
| 266 | // object now to prevent it from being reclaimed at the end of this scoped block. |
| 267 | // |
Michael Spang | a2f1743 | 2022-01-26 20:52:14 -0500 | [diff] [blame] | 268 | callback->AdoptReadClient(std::move(readClient)); |
yunhanw-google | dbc91b7 | 2022-05-27 11:08:03 -0700 | [diff] [blame] | 269 | callback.release(); |
Jerry Johns | 118ab9d | 2021-12-21 18:01:54 -0800 | [diff] [blame] | 270 | |
Jerry Johns | 4efc582 | 2021-10-19 14:22:36 -0700 | [diff] [blame] | 271 | return err; |
| 272 | } |
| 273 | |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 274 | } // namespace detail |
| 275 | |
| 276 | /* |
| 277 | * A typed read event function that takes as input a template parameter that encapsulates the type information |
| 278 | * for a given attribute as well as callbacks for success and failure and either returns a decoded cluster-object representation |
| 279 | * of the requested attribute through the provided success callback or calls the provided failure callback. |
| 280 | * |
| 281 | * The DecodableEventType is generally expected to be a ClusterName::Events::EventName::DecodableEventType struct, but any |
| 282 | * object that contains type information exposed through a 'DecodableType' type declaration as well as GetClusterId() and |
| 283 | * GetEventId() methods is expected to work. |
yunhanw-google | dbc91b7 | 2022-05-27 11:08:03 -0700 | [diff] [blame] | 284 | * |
| 285 | * @param[in] onSuccessCb Used to deliver event data received through the Read interactions |
| 286 | * @param[in] onErrorCb failureCb will be called when an error occurs *after* a successful call to ReadEvent. |
| 287 | * @param[in] onDoneCb OnDone will be called when ReadClient has finished all work for event retrieval, it is possible that there |
| 288 | * is no event. |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 289 | */ |
| 290 | template <typename DecodableEventType> |
Marc Lepage | 9a595a4 | 2021-12-16 03:53:52 -0500 | [diff] [blame] | 291 | CHIP_ERROR ReadEvent(Messaging::ExchangeManager * exchangeMgr, const SessionHandle & sessionHandle, EndpointId endpointId, |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 292 | typename TypedReadEventCallback<DecodableEventType>::OnSuccessCallbackType onSuccessCb, |
yunhanw-google | dbc91b7 | 2022-05-27 11:08:03 -0700 | [diff] [blame] | 293 | typename TypedReadEventCallback<DecodableEventType>::OnErrorCallbackType onErrorCb, |
| 294 | typename TypedReadEventCallback<DecodableEventType>::OnDoneCallbackType onDoneCb) |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 295 | { |
| 296 | detail::ReportEventParams<DecodableEventType> params(sessionHandle); |
| 297 | params.mOnReportCb = onSuccessCb; |
| 298 | params.mOnErrorCb = onErrorCb; |
yunhanw-google | dbc91b7 | 2022-05-27 11:08:03 -0700 | [diff] [blame] | 299 | params.mOnDoneCb = onDoneCb; |
yunhanw-google | cd44f9b | 2022-03-09 10:36:31 -0800 | [diff] [blame] | 300 | return detail::ReportEvent(exchangeMgr, endpointId, std::move(params), false /*aIsUrgentEvent*/); |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 301 | } |
| 302 | |
| 303 | /** |
| 304 | * A functon that allows subscribing to one particular event. This works |
| 305 | * similarly to ReadEvent but keeps reporting events as they are emitted. |
| 306 | */ |
| 307 | template <typename DecodableEventType> |
yunhanw-google | dce8007 | 2022-06-08 13:16:49 -0700 | [diff] [blame] | 308 | CHIP_ERROR SubscribeEvent( |
| 309 | Messaging::ExchangeManager * exchangeMgr, const SessionHandle & sessionHandle, EndpointId endpointId, |
| 310 | typename TypedReadEventCallback<DecodableEventType>::OnSuccessCallbackType onReportCb, |
| 311 | typename TypedReadEventCallback<DecodableEventType>::OnErrorCallbackType onErrorCb, uint16_t minIntervalFloorSeconds, |
| 312 | uint16_t maxIntervalCeilingSeconds, |
| 313 | typename TypedReadEventCallback<DecodableEventType>::OnSubscriptionEstablishedCallbackType onSubscriptionEstablishedCb = |
| 314 | nullptr, |
| 315 | typename TypedReadEventCallback<DecodableEventType>::OnResubscriptionAttemptCallbackType onResubscriptionAttemptCb = nullptr, |
| 316 | bool keepPreviousSubscriptions = false, bool aIsUrgentEvent = false) |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 317 | { |
| 318 | detail::ReportEventParams<DecodableEventType> params(sessionHandle); |
| 319 | params.mOnReportCb = onReportCb; |
| 320 | params.mOnErrorCb = onErrorCb; |
yunhanw-google | dbc91b7 | 2022-05-27 11:08:03 -0700 | [diff] [blame] | 321 | params.mOnDoneCb = nullptr; |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 322 | params.mOnSubscriptionEstablishedCb = onSubscriptionEstablishedCb; |
yunhanw-google | dce8007 | 2022-06-08 13:16:49 -0700 | [diff] [blame] | 323 | params.mOnResubscriptionAttemptCb = onResubscriptionAttemptCb; |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 324 | params.mMinIntervalFloorSeconds = minIntervalFloorSeconds; |
| 325 | params.mMaxIntervalCeilingSeconds = maxIntervalCeilingSeconds; |
Boris Zbarsky | 772c060 | 2022-03-02 12:40:35 -0500 | [diff] [blame] | 326 | params.mKeepSubscriptions = keepPreviousSubscriptions; |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 327 | params.mReportType = app::ReadClient::InteractionType::Subscribe; |
yunhanw-google | cd44f9b | 2022-03-09 10:36:31 -0800 | [diff] [blame] | 328 | return detail::ReportEvent(exchangeMgr, endpointId, std::move(params), aIsUrgentEvent); |
Boris Zbarsky | 5018ff9 | 2021-12-10 00:38:45 -0500 | [diff] [blame] | 329 | } |
| 330 | |
Jerry Johns | 4efc582 | 2021-10-19 14:22:36 -0700 | [diff] [blame] | 331 | } // namespace Controller |
| 332 | } // namespace chip |
Wang Qixiang | 14bdc24 | 2023-08-04 13:04:55 +0800 | [diff] [blame] | 333 | #endif // CHIP_CONFIG_ENABLE_READ_CLIENT |