3 {{#if (chip_has_client_clusters)}}
4 #import <Foundation/Foundation.h>
7 #import "CHIPDevice_Internal.h"
9 #import "gen/CHIPClustersObjc.h"
10 #import "gen/CHIPClientCallbacks.h"
12 #include <controller/CHIPClusters.h>
13 #include <lib/support/Span.h>
15 using namespace ::chip;
17 class CHIPDefaultSuccessCallbackBridge : public Callback::Callback<DefaultSuccessCallback> {
19 CHIPDefaultSuccessCallbackBridge(ResponseHandler handler, dispatch_queue_t queue)
20 : Callback::Callback<DefaultSuccessCallback>(CallbackFn, this)
26 ~CHIPDefaultSuccessCallbackBridge() {};
28 static void CallbackFn(void * context)
30 CHIPDefaultSuccessCallbackBridge * callback = reinterpret_cast<CHIPDefaultSuccessCallbackBridge *>(context);
31 if (callback && callback->mQueue) {
32 dispatch_async(callback->mQueue, ^{
33 callback->mHandler(nil, nil);
41 ResponseHandler mHandler;
42 dispatch_queue_t mQueue;
45 class CHIPDefaultFailureCallbackBridge : public Callback::Callback<DefaultFailureCallback> {
47 CHIPDefaultFailureCallbackBridge(ResponseHandler handler, dispatch_queue_t queue)
48 : Callback::Callback<DefaultFailureCallback>(CallbackFn, this)
54 ~CHIPDefaultFailureCallbackBridge() {};
56 static void CallbackFn(void * context, uint8_t status)
58 CHIPDefaultFailureCallbackBridge * callback = reinterpret_cast<CHIPDefaultFailureCallbackBridge *>(context);
59 if (callback && callback->mQueue) {
60 dispatch_async(callback->mQueue, ^{
61 NSError * error = [CHIPError errorForCHIPErrorCode:status];
62 callback->mHandler(error, nil);
70 ResponseHandler mHandler;
71 dispatch_queue_t mQueue;
74 class CHIPStringAttributeCallbackBridge : public Callback::Callback<StringAttributeCallback> {
76 CHIPStringAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool octetString, bool keepAlive = false)
77 : Callback::Callback<StringAttributeCallback>(CallbackFn, this)
80 , mOctetString(octetString)
81 , mKeepAlive(keepAlive)
85 ~CHIPStringAttributeCallbackBridge() {};
87 static void CallbackFn(void * context, chip::ByteSpan value)
89 CHIPStringAttributeCallbackBridge * callback = reinterpret_cast<CHIPStringAttributeCallbackBridge *>(context);
90 if (callback && callback->mQueue) {
91 dispatch_async(callback->mQueue, ^{
92 if (callback->mOctetString)
94 NSData *data = [NSData dataWithBytes: value.data() length: value.size()];
95 callback->mHandler(nil, @{ @"value": data });
99 NSString * str = [[NSString alloc] initWithBytes:value.data() length:value.size() encoding:NSUTF8StringEncoding];
100 callback->mHandler(nil, @{ @"value": str });
103 if (!callback->mKeepAlive)
113 ResponseHandler mHandler;
114 dispatch_queue_t mQueue;
119 class CHIPBooleanAttributeCallbackBridge : public Callback::Callback<BooleanAttributeCallback> {
121 CHIPBooleanAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
122 : Callback::Callback<BooleanAttributeCallback>(CallbackFn, this)
125 , mKeepAlive(keepAlive)
129 ~CHIPBooleanAttributeCallbackBridge() {};
131 static void CallbackFn(void * context, bool value)
133 CHIPBooleanAttributeCallbackBridge * callback = reinterpret_cast<CHIPBooleanAttributeCallbackBridge *>(context);
134 if (callback && callback->mQueue) {
135 dispatch_async(callback->mQueue, ^{
136 callback->mHandler(nil, @{ @"value": [NSNumber numberWithBool:value] });
137 if (!callback->mKeepAlive)
147 ResponseHandler mHandler;
148 dispatch_queue_t mQueue;
152 class CHIPInt8uAttributeCallbackBridge : public Callback::Callback<Int8uAttributeCallback> {
154 CHIPInt8uAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
155 : Callback::Callback<Int8uAttributeCallback>(CallbackFn, this)
158 , mKeepAlive(keepAlive)
162 ~CHIPInt8uAttributeCallbackBridge() {};
164 static void CallbackFn(void * context, uint8_t value)
166 CHIPInt8uAttributeCallbackBridge * callback = reinterpret_cast<CHIPInt8uAttributeCallbackBridge *>(context);
167 if (callback && callback->mQueue) {
168 dispatch_async(callback->mQueue, ^{
169 callback->mHandler(nil, @{ @"value": [NSNumber numberWithUnsignedChar:value] });
170 if (!callback->mKeepAlive)
180 ResponseHandler mHandler;
181 dispatch_queue_t mQueue;
185 class CHIPInt8sAttributeCallbackBridge : public Callback::Callback<Int8sAttributeCallback> {
187 CHIPInt8sAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
188 : Callback::Callback<Int8sAttributeCallback>(CallbackFn, this)
191 , mKeepAlive(keepAlive)
195 ~CHIPInt8sAttributeCallbackBridge() {};
197 static void CallbackFn(void * context, int8_t value)
199 CHIPInt8sAttributeCallbackBridge * callback = reinterpret_cast<CHIPInt8sAttributeCallbackBridge *>(context);
200 if (callback && callback->mQueue) {
201 dispatch_async(callback->mQueue, ^{
202 callback->mHandler(nil, @{ @"value": [NSNumber numberWithChar:value] });
203 if (!callback->mKeepAlive)
213 ResponseHandler mHandler;
214 dispatch_queue_t mQueue;
218 class CHIPInt16uAttributeCallbackBridge : public Callback::Callback<Int16uAttributeCallback> {
220 CHIPInt16uAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
221 : Callback::Callback<Int16uAttributeCallback>(CallbackFn, this)
224 , mKeepAlive(keepAlive)
228 ~CHIPInt16uAttributeCallbackBridge() {};
230 static void CallbackFn(void * context, uint16_t value)
232 CHIPInt16uAttributeCallbackBridge * callback = reinterpret_cast<CHIPInt16uAttributeCallbackBridge *>(context);
233 if (callback && callback->mQueue) {
234 dispatch_async(callback->mQueue, ^{
235 callback->mHandler(nil, @{ @"value": [NSNumber numberWithUnsignedShort:value] });
236 if (!callback->mKeepAlive)
246 ResponseHandler mHandler;
247 dispatch_queue_t mQueue;
251 class CHIPInt32uAttributeCallbackBridge : public Callback::Callback<Int32uAttributeCallback> {
253 CHIPInt32uAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
254 : Callback::Callback<Int32uAttributeCallback>(CallbackFn, this)
257 , mKeepAlive(keepAlive)
261 ~CHIPInt32uAttributeCallbackBridge() {};
263 static void CallbackFn(void * context, uint32_t value)
265 CHIPInt32uAttributeCallbackBridge * callback = reinterpret_cast<CHIPInt32uAttributeCallbackBridge *>(context);
266 if (callback && callback->mQueue) {
267 dispatch_async(callback->mQueue, ^{
268 callback->mHandler(nil, @{ @"value": [NSNumber numberWithUnsignedLong:value] });
269 if (!callback->mKeepAlive)
279 ResponseHandler mHandler;
280 dispatch_queue_t mQueue;
284 class CHIPInt64uAttributeCallbackBridge : public Callback::Callback<Int64uAttributeCallback> {
286 CHIPInt64uAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
287 : Callback::Callback<Int64uAttributeCallback>(CallbackFn, this)
290 , mKeepAlive(keepAlive)
294 ~CHIPInt64uAttributeCallbackBridge() {};
296 static void CallbackFn(void * context, uint64_t value)
298 CHIPInt64uAttributeCallbackBridge * callback = reinterpret_cast<CHIPInt64uAttributeCallbackBridge *>(context);
299 if (callback && callback->mQueue) {
300 dispatch_async(callback->mQueue, ^{
301 callback->mHandler(nil, @{ @"value": [NSNumber numberWithUnsignedLongLong:value] });
302 if (!callback->mKeepAlive)
312 ResponseHandler mHandler;
313 dispatch_queue_t mQueue;
317 class CHIPInt16sAttributeCallbackBridge : public Callback::Callback<Int16sAttributeCallback> {
319 CHIPInt16sAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
320 : Callback::Callback<Int16sAttributeCallback>(CallbackFn, this)
323 , mKeepAlive(keepAlive)
327 ~CHIPInt16sAttributeCallbackBridge() {};
329 static void CallbackFn(void * context, int16_t value)
331 CHIPInt16sAttributeCallbackBridge * callback = reinterpret_cast<CHIPInt16sAttributeCallbackBridge *>(context);
332 if (callback && callback->mQueue) {
333 dispatch_async(callback->mQueue, ^{
334 callback->mHandler(nil, @{ @"value": [NSNumber numberWithShort:value] });
335 if (!callback->mKeepAlive)
345 ResponseHandler mHandler;
346 dispatch_queue_t mQueue;
350 {{#all_user_clusters}}
351 {{#if (isClient side) }}
352 {{#if (user_cluster_has_enabled_command name side)}}
353 {{#all_user_cluster_commands}}
354 {{#if (isStrEqual clusterName parent.name)}}
355 {{#if (isCommandAvailable parent.side incoming outgoing commandSource name)}}
356 class CHIP{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}CallbackBridge : public Callback::Callback<{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}Callback>
359 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) {}
361 ~CHIP{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}CallbackBridge() {};
363 static void CallbackFn(void * context{{#zcl_command_arguments}}{{#unless (isStrEqual label "status")}}, {{asUnderlyingZclType type}} {{asSymbol label}}{{/unless}}{{/zcl_command_arguments}})
365 CHIP{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}CallbackBridge * callback = reinterpret_cast<CHIP{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}CallbackBridge *>(context);
366 if (callback && callback->mQueue)
368 dispatch_async(callback->mQueue, ^{
369 callback->mHandler(nil, @{
370 {{#zcl_command_arguments}}
371 {{#unless (isStrEqual label "status")}}
373 // {{asSymbol label}}: {{asUnderlyingZclType type}}
374 // Conversion from this type to Objc is not properly implemented yet
375 {{else if (isShortString type)}}
376 @"{{asSymbol label}}": [NSString stringWithFormat:@"%s", {{asSymbol label}}],
378 @"{{asSymbol label}}": [NSNumber numberWith{{asObjectiveCNumberType label type}}:{{asSymbol label}}],
381 {{/zcl_command_arguments}}
390 ResponseHandler mHandler;
391 dispatch_queue_t mQueue;
396 {{/all_user_cluster_commands}}
399 {{/all_user_clusters}}
401 @interface CHIPCluster ()
402 @property (readonly, nonatomic) dispatch_queue_t callbackQueue;
403 - (Controller::ClusterBase *)getCluster;
406 @implementation CHIPCluster
407 - (instancetype)initWithDevice:(CHIPDevice *)device endpoint:(EndpointId)endpoint queue:(dispatch_queue_t)queue
409 if (self = [super init]) {
410 Controller::ClusterBase * cppCluster = [self getCluster];
411 if (cppCluster == nullptr)
416 CHIP_ERROR err = cppCluster->Associate([device internalDevice], endpoint);
417 if (err != CHIP_NO_ERROR) {
421 _callbackQueue = queue;
426 - (Controller::ClusterBase *)getCluster
433 {{#chip_client_clusters}}
435 @interface CHIP{{asCamelCased name false}} ()
436 @property (readonly) Controller::{{asCamelCased name false}}Cluster cppCluster;
439 @implementation CHIP{{asCamelCased name false}}
441 - (Controller::ClusterBase *)getCluster
446 {{#chip_server_cluster_commands}}
447 {{#if (zcl_command_arguments_count this.id)}}
448 - (void){{asCamelCased name}}:{{#chip_server_cluster_command_arguments}}{{#if (isFirstElement index)}}{{else}}{{asCamelCased label}}:{{/if}}({{asObjectiveCBasicType type}}){{asCamelCased label}} {{/chip_server_cluster_command_arguments}}completionHandler:(ResponseHandler)completionHandler
450 - (void){{asCamelCased name}}:(ResponseHandler)completionHandler
453 {{#if (hasSpecificResponse name)}}
454 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]);
456 CHIPDefaultSuccessCallbackBridge * onSuccess = new CHIPDefaultSuccessCallbackBridge(completionHandler, [self callbackQueue]);
459 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
463 CHIPDefaultFailureCallbackBridge * onFailure = new CHIPDefaultFailureCallbackBridge(completionHandler, [self callbackQueue]);
466 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
470 CHIP_ERROR err = self.cppCluster.{{asCamelCased name false}}(onSuccess->Cancel(), onFailure->Cancel(){{#chip_server_cluster_command_arguments}}, {{#if (isOctetString type)}}chip::ByteSpan((const uint8_t*){{asCamelCased label}}.bytes, {{asCamelCased label}}.length){{else if (isCharString type)}}chip::ByteSpan((const uint8_t*)[{{asCamelCased label}} dataUsingEncoding:NSUTF8StringEncoding].bytes, [{{asCamelCased label}} lengthOfBytesUsingEncoding:NSUTF8StringEncoding]){{else}}{{asCamelCased label}}{{/if}}{{/chip_server_cluster_command_arguments}});
471 if (err != CHIP_NO_ERROR) {
474 completionHandler([CHIPError errorForCHIPErrorCode:err], nil);
477 {{/chip_server_cluster_commands}}
479 {{#chip_server_cluster_attributes}}
480 - (void)readAttribute{{asCamelCased name false}}:(ResponseHandler)completionHandler
482 CHIP{{asCallbackAttributeType atomicTypeId}}AttributeCallbackBridge * onSuccess = new CHIP{{asCallbackAttributeType atomicTypeId}}AttributeCallbackBridge(completionHandler, [self callbackQueue]{{#if (isString type)}},{{#if (isOctetString type)}}true{{else}}false{{/if}}{{/if}});
484 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
488 CHIPDefaultFailureCallbackBridge * onFailure = new CHIPDefaultFailureCallbackBridge(completionHandler, [self callbackQueue]);
491 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
495 CHIP_ERROR err = self.cppCluster.ReadAttribute{{asCamelCased name false}}(onSuccess->Cancel(), onFailure->Cancel());
496 if (err != CHIP_NO_ERROR) {
499 completionHandler([CHIPError errorForCHIPErrorCode:err], nil);
503 {{#if (isWritableAttribute)}}
504 - (void)writeAttribute{{asCamelCased name false}}:({{asObjectiveCBasicType type}})value completionHandler:(ResponseHandler)completionHandler
506 CHIPDefaultSuccessCallbackBridge * onSuccess = new CHIPDefaultSuccessCallbackBridge(completionHandler, [self callbackQueue]);
508 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
512 CHIPDefaultFailureCallbackBridge * onFailure = new CHIPDefaultFailureCallbackBridge(completionHandler, [self callbackQueue]);
515 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
519 {{#if (isOctetString type)}}
520 CHIP_ERROR err = self.cppCluster.WriteAttribute{{asCamelCased name false}}(onSuccess->Cancel(), onFailure->Cancel(), chip::ByteSpan((const uint8_t*)value.bytes, value.length));
521 {{else if (isCharString type)}}
522 NSData * data = [value dataUsingEncoding:NSUTF8StringEncoding];
523 CHIP_ERROR err = self.cppCluster.WriteAttribute{{asCamelCased name false}}(onSuccess->Cancel(), onFailure->Cancel(), chip::ByteSpan((const uint8_t*)data.bytes, data.length));
525 CHIP_ERROR err = self.cppCluster.WriteAttribute{{asCamelCased name false}}(onSuccess->Cancel(), onFailure->Cancel(), value);
527 if (err != CHIP_NO_ERROR) {
530 completionHandler([CHIPError errorForCHIPErrorCode:err], nil);
535 {{#if (isReportableAttribute)}}
536 - (void) configureAttribute{{asCamelCased name false}}:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval{{#unless (isDiscreteType)}} change:({{chipType}})change{{/unless}} completionHandler:(ResponseHandler)completionHandler
538 CHIPDefaultSuccessCallbackBridge * onSuccess = new CHIPDefaultSuccessCallbackBridge(completionHandler, [self callbackQueue]);
540 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
544 CHIPDefaultFailureCallbackBridge * onFailure = new CHIPDefaultFailureCallbackBridge(completionHandler, [self callbackQueue]);
547 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
552 CHIP_ERROR err = self.cppCluster.ConfigureAttribute{{asCamelCased name false}}(onSuccess->Cancel(), onFailure->Cancel(), minInterval, maxInterval{{#unless (isDiscreteType)}}, change{{/unless}});
553 if (err != CHIP_NO_ERROR) {
556 completionHandler([CHIPError errorForCHIPErrorCode:err], nil);
560 - (void) reportAttribute{{asCamelCased name false}}:(ResponseHandler)reportHandler
562 CHIP{{asCallbackAttributeType atomicTypeId}}AttributeCallbackBridge * onReport = new CHIP{{asCallbackAttributeType atomicTypeId}}AttributeCallbackBridge(reportHandler, [self callbackQueue]{{#if (isString type)}},{{#if (isOctetString type)}}true{{else}}false{{/if}}{{/if}}, true);
564 reportHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
568 CHIP_ERROR err = self.cppCluster.ReportAttribute{{asCamelCased name false}}(onReport->Cancel());
569 if (err != CHIP_NO_ERROR) {
571 reportHandler([CHIPError errorForCHIPErrorCode:err], nil);
576 {{/chip_server_cluster_attributes}}
580 {{/chip_client_clusters}}