3 #import <Foundation/Foundation.h>
6 #import "CHIPDevice_Internal.h"
8 #import "gen/CHIPClustersObjc.h"
9 #import "gen/CHIPClientCallbacks.h"
11 #include <controller/CHIPClusters.h>
12 #include <lib/support/Span.h>
14 using namespace ::chip;
16 class CHIPDefaultSuccessCallbackBridge : public Callback::Callback<DefaultSuccessCallback> {
18 CHIPDefaultSuccessCallbackBridge(ResponseHandler handler, dispatch_queue_t queue)
19 : Callback::Callback<DefaultSuccessCallback>(CallbackFn, this)
25 ~CHIPDefaultSuccessCallbackBridge() {};
27 static void CallbackFn(void * context)
29 CHIPDefaultSuccessCallbackBridge * callback = reinterpret_cast<CHIPDefaultSuccessCallbackBridge *>(context);
30 if (callback && callback->mQueue) {
31 dispatch_async(callback->mQueue, ^{
32 callback->mHandler(nil, nil);
40 ResponseHandler mHandler;
41 dispatch_queue_t mQueue;
44 class CHIPDefaultFailureCallbackBridge : public Callback::Callback<DefaultFailureCallback> {
46 CHIPDefaultFailureCallbackBridge(ResponseHandler handler, dispatch_queue_t queue)
47 : Callback::Callback<DefaultFailureCallback>(CallbackFn, this)
53 ~CHIPDefaultFailureCallbackBridge() {};
55 static void CallbackFn(void * context, uint8_t status)
57 CHIPDefaultFailureCallbackBridge * callback = reinterpret_cast<CHIPDefaultFailureCallbackBridge *>(context);
58 if (callback && callback->mQueue) {
59 dispatch_async(callback->mQueue, ^{
60 NSError* error = [NSError errorWithDomain:CHIPErrorDomain code:status userInfo:@{NSLocalizedDescriptionKey:@""}];
61 callback->mHandler(error, nil);
69 ResponseHandler mHandler;
70 dispatch_queue_t mQueue;
73 class CHIPUnsupportedAttributeCallbackBridge : public Callback::Callback<DefaultSuccessCallback> {
75 CHIPUnsupportedAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue)
76 : Callback::Callback<DefaultSuccessCallback>(CallbackFn, this)
80 ~CHIPUnsupportedAttributeCallbackBridge() {};
82 static void CallbackFn(void * context)
84 CHIPUnsupportedAttributeCallbackBridge * callback = reinterpret_cast<CHIPUnsupportedAttributeCallbackBridge *>(context);
85 if (callback && callback->mQueue) {
86 dispatch_async(callback->mQueue, ^{
87 NSError* error = [NSError errorWithDomain:CHIPErrorDomain code:CHIPErrorCodeUndefinedError userInfo:@{NSLocalizedDescriptionKey:@"Unsupported attribute type"}];
88 callback->mHandler(error, nil);
96 ResponseHandler mHandler;
97 dispatch_queue_t mQueue;
100 class CHIPBooleanAttributeCallbackBridge : public Callback::Callback<BooleanAttributeCallback> {
102 CHIPBooleanAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
103 : Callback::Callback<BooleanAttributeCallback>(CallbackFn, this)
106 , mKeepAlive(keepAlive)
110 ~CHIPBooleanAttributeCallbackBridge() {};
112 static void CallbackFn(void * context, bool value)
114 CHIPBooleanAttributeCallbackBridge * callback = reinterpret_cast<CHIPBooleanAttributeCallbackBridge *>(context);
115 if (callback && callback->mQueue) {
116 dispatch_async(callback->mQueue, ^{
117 callback->mHandler(nil, @{ @"value": [NSNumber numberWithBool:value] });
118 if (!callback->mKeepAlive)
128 ResponseHandler mHandler;
129 dispatch_queue_t mQueue;
133 class CHIPInt8uAttributeCallbackBridge : public Callback::Callback<Int8uAttributeCallback> {
135 CHIPInt8uAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
136 : Callback::Callback<Int8uAttributeCallback>(CallbackFn, this)
139 , mKeepAlive(keepAlive)
143 ~CHIPInt8uAttributeCallbackBridge() {};
145 static void CallbackFn(void * context, uint8_t value)
147 CHIPInt8uAttributeCallbackBridge * callback = reinterpret_cast<CHIPInt8uAttributeCallbackBridge *>(context);
148 if (callback && callback->mQueue) {
149 dispatch_async(callback->mQueue, ^{
150 callback->mHandler(nil, @{ @"value": [NSNumber numberWithUnsignedChar:value] });
151 if (!callback->mKeepAlive)
161 ResponseHandler mHandler;
162 dispatch_queue_t mQueue;
166 class CHIPInt8sAttributeCallbackBridge : public Callback::Callback<Int8sAttributeCallback> {
168 CHIPInt8sAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
169 : Callback::Callback<Int8sAttributeCallback>(CallbackFn, this)
172 , mKeepAlive(keepAlive)
176 ~CHIPInt8sAttributeCallbackBridge() {};
178 static void CallbackFn(void * context, int8_t value)
180 CHIPInt8sAttributeCallbackBridge * callback = reinterpret_cast<CHIPInt8sAttributeCallbackBridge *>(context);
181 if (callback && callback->mQueue) {
182 dispatch_async(callback->mQueue, ^{
183 callback->mHandler(nil, @{ @"value": [NSNumber numberWithChar:value] });
184 if (!callback->mKeepAlive)
194 ResponseHandler mHandler;
195 dispatch_queue_t mQueue;
199 class CHIPInt16uAttributeCallbackBridge : public Callback::Callback<Int16uAttributeCallback> {
201 CHIPInt16uAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
202 : Callback::Callback<Int16uAttributeCallback>(CallbackFn, this)
205 , mKeepAlive(keepAlive)
209 ~CHIPInt16uAttributeCallbackBridge() {};
211 static void CallbackFn(void * context, uint16_t value)
213 CHIPInt16uAttributeCallbackBridge * callback = reinterpret_cast<CHIPInt16uAttributeCallbackBridge *>(context);
214 if (callback && callback->mQueue) {
215 dispatch_async(callback->mQueue, ^{
216 callback->mHandler(nil, @{ @"value": [NSNumber numberWithUnsignedShort:value] });
217 if (!callback->mKeepAlive)
227 ResponseHandler mHandler;
228 dispatch_queue_t mQueue;
232 class CHIPInt16sAttributeCallbackBridge : public Callback::Callback<Int16sAttributeCallback> {
234 CHIPInt16sAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
235 : Callback::Callback<Int16sAttributeCallback>(CallbackFn, this)
238 , mKeepAlive(keepAlive)
242 ~CHIPInt16sAttributeCallbackBridge() {};
244 static void CallbackFn(void * context, int16_t value)
246 CHIPInt16sAttributeCallbackBridge * callback = reinterpret_cast<CHIPInt16sAttributeCallbackBridge *>(context);
247 if (callback && callback->mQueue) {
248 dispatch_async(callback->mQueue, ^{
249 callback->mHandler(nil, @{ @"value": [NSNumber numberWithShort:value] });
250 if (!callback->mKeepAlive)
260 ResponseHandler mHandler;
261 dispatch_queue_t mQueue;
265 {{#all_user_clusters}}
266 {{#if (isClient side) }}
267 {{#if (user_cluster_has_enabled_command name side)}}
268 {{#all_user_cluster_commands}}
269 {{#if (isStrEqual clusterName parent.name)}}
270 {{#if (isCommandAvailable parent.side incoming outgoing commandSource name)}}
271 class CHIP{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}CallbackBridge : public Callback::Callback<{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}Callback>
274 CHIP{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}CallbackBridge(ResponseHandler handler, dispatch_queue_t queue): Callback::Callback<{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}Callback>(CallbackFn, this), mHandler(handler), mQueue(queue) {}
276 ~CHIP{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}CallbackBridge() {};
278 static void CallbackFn(void * context{{#zcl_command_arguments}}{{#unless (isStrEqual label "status")}}, {{asUnderlyingZclType type}} {{asSymbol label}}{{/unless}}{{/zcl_command_arguments}})
280 CHIP{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}CallbackBridge * callback = reinterpret_cast<CHIP{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}CallbackBridge *>(context);
281 if (callback && callback->mQueue)
283 dispatch_async(callback->mQueue, ^{
284 callback->mHandler(nil, @{
285 {{#zcl_command_arguments}}
286 {{#unless (isStrEqual label "status")}}
288 // {{asSymbol label}}: {{asUnderlyingZclType type}}
289 // Conversion from this type to Objc is not properly implemented yet
290 {{else if (isShortString type)}}
291 @"{{asSymbol label}}": [NSString stringWithFormat:@"%s", {{asSymbol label}}],
293 @"{{asSymbol label}}": [NSNumber numberWith{{asObjectiveCNumberType label type}}:{{asSymbol label}}],
296 {{/zcl_command_arguments}}
305 ResponseHandler mHandler;
306 dispatch_queue_t mQueue;
311 {{/all_user_cluster_commands}}
314 {{/all_user_clusters}}
316 @interface CHIPCluster ()
317 @property (readonly, nonatomic) dispatch_queue_t callbackQueue;
318 - (Controller::ClusterBase *)getCluster;
321 @implementation CHIPCluster
322 - (instancetype)initWithDevice:(CHIPDevice *)device endpoint:(EndpointId)endpoint queue:(dispatch_queue_t)queue
324 if (self = [super init]) {
325 Controller::ClusterBase * cppCluster = [self getCluster];
326 if (cppCluster == nullptr)
331 CHIP_ERROR err = cppCluster->Associate([device internalDevice], endpoint);
332 if (err != CHIP_NO_ERROR) {
336 _callbackQueue = queue;
341 - (Controller::ClusterBase *)getCluster
350 @interface CHIP{{asCamelCased name false}} ()
351 @property (readonly) Controller::{{asCamelCased name false}}Cluster cppCluster;
354 @implementation CHIP{{asCamelCased name false}}
356 - (Controller::ClusterBase *)getCluster
361 {{#chip_server_cluster_commands}}
362 {{#if (zcl_command_arguments_count this.id)}}
363 - (void){{asCamelCased name}}:{{#chip_server_cluster_command_arguments}}{{#if (isFirstElement index)}}{{else}}{{asCamelCased label}}:{{/if}}({{#if (isByteString type)}}NSData *{{else}}{{asBasicType chipType}}{{/if}}){{asCamelCased label}} {{/chip_server_cluster_command_arguments}}completionHandler:(ResponseHandler)completionHandler
365 - (void){{asCamelCased name}}:(ResponseHandler)completionHandler
368 {{#if (hasSpecificResponse name)}}
369 CHIP{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}ResponseCallbackBridge * onSuccess = new CHIP{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}ResponseCallbackBridge(completionHandler, [self callbackQueue]);
371 CHIPDefaultSuccessCallbackBridge * onSuccess = new CHIPDefaultSuccessCallbackBridge(completionHandler, [self callbackQueue]);
374 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
378 CHIPDefaultFailureCallbackBridge * onFailure = new CHIPDefaultFailureCallbackBridge(completionHandler, [self callbackQueue]);
381 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
385 CHIP_ERROR err = self.cppCluster.{{asCamelCased name false}}(onSuccess->Cancel(), onFailure->Cancel(){{#chip_server_cluster_command_arguments}}, {{#if (isByteString type)}}chip::ByteSpan((const uint8_t*){{asCamelCased label}}.bytes, {{asCamelCased label}}.length){{else}}{{asCamelCased label}}{{/if}}{{/chip_server_cluster_command_arguments}});
386 if (err != CHIP_NO_ERROR) {
389 completionHandler([CHIPError errorForCHIPErrorCode:err], nil);
392 {{/chip_server_cluster_commands}}
394 {{#chip_server_cluster_attributes}}
395 - (void)readAttribute{{asCamelCased name false}}:(ResponseHandler)completionHandler
397 CHIP{{asCallbackAttributeType atomicTypeId}}AttributeCallbackBridge * onSuccess = new CHIP{{asCallbackAttributeType atomicTypeId}}AttributeCallbackBridge(completionHandler, [self callbackQueue]);
399 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
403 CHIPDefaultFailureCallbackBridge * onFailure = new CHIPDefaultFailureCallbackBridge(completionHandler, [self callbackQueue]);
406 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
410 CHIP_ERROR err = self.cppCluster.ReadAttribute{{asCamelCased name false}}(onSuccess->Cancel(), onFailure->Cancel());
411 if (err != CHIP_NO_ERROR) {
414 completionHandler([CHIPError errorForCHIPErrorCode:err], nil);
418 {{#if (isWritableAttribute)}}
419 - (void)writeAttribute{{asCamelCased name false}}:({{asUnderlyingZclType type}})value completionHandler:(ResponseHandler)completionHandler
421 CHIPDefaultSuccessCallbackBridge * onSuccess = new CHIPDefaultSuccessCallbackBridge(completionHandler, [self callbackQueue]);
423 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
427 CHIPDefaultFailureCallbackBridge * onFailure = new CHIPDefaultFailureCallbackBridge(completionHandler, [self callbackQueue]);
430 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
434 CHIP_ERROR err = self.cppCluster.WriteAttribute{{asCamelCased name false}}(onSuccess->Cancel(), onFailure->Cancel(), value);
435 if (err != CHIP_NO_ERROR) {
438 completionHandler([CHIPError errorForCHIPErrorCode:err], nil);
443 {{#if (isReportableAttribute)}}
444 - (void) configureAttribute{{asCamelCased name false}}:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval{{#unless (isDiscreteType)}} change:({{chipType}})change{{/unless}} completionHandler:(ResponseHandler)completionHandler
446 CHIPDefaultSuccessCallbackBridge * onSuccess = new CHIPDefaultSuccessCallbackBridge(completionHandler, [self callbackQueue]);
448 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
452 CHIPDefaultFailureCallbackBridge * onFailure = new CHIPDefaultFailureCallbackBridge(completionHandler, [self callbackQueue]);
455 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
460 CHIP_ERROR err = self.cppCluster.ConfigureAttribute{{asCamelCased name false}}(onSuccess->Cancel(), onFailure->Cancel(), minInterval, maxInterval{{#unless (isDiscreteType)}}, change{{/unless}});
461 if (err != CHIP_NO_ERROR) {
464 completionHandler([CHIPError errorForCHIPErrorCode:err], nil);
468 - (void) reportAttribute{{asCamelCased name false}}:(ResponseHandler)reportHandler
470 CHIP{{asCallbackAttributeType atomicTypeId}}AttributeCallbackBridge * onReport = new CHIP{{asCallbackAttributeType atomicTypeId}}AttributeCallbackBridge(reportHandler, [self callbackQueue], true);
472 reportHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
476 CHIP_ERROR err = self.cppCluster.ReportAttribute{{asCamelCased name false}}(onReport->Cancel());
477 if (err != CHIP_NO_ERROR) {
479 reportHandler([CHIPError errorForCHIPErrorCode:err], nil);
484 {{/chip_server_cluster_attributes}}