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 CHIPStringAttributeCallbackBridge : public Callback::Callback<StringAttributeCallback> {
75 CHIPStringAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool octetString, bool keepAlive = false)
76 : Callback::Callback<StringAttributeCallback>(CallbackFn, this)
79 , mOctetString(octetString)
80 , mKeepAlive(keepAlive)
84 ~CHIPStringAttributeCallbackBridge() {};
86 static void CallbackFn(void * context, chip::ByteSpan value)
88 CHIPStringAttributeCallbackBridge * callback = reinterpret_cast<CHIPStringAttributeCallbackBridge *>(context);
89 if (callback && callback->mQueue) {
90 dispatch_async(callback->mQueue, ^{
91 if (callback->mOctetString)
93 NSData *data = [NSData dataWithBytes: value.data() length: value.size()];
94 callback->mHandler(nil, @{ @"value": data });
98 NSString * str = [[NSString alloc] initWithBytes:value.data() length:value.size() encoding:NSUTF8StringEncoding];
99 callback->mHandler(nil, @{ @"value": str });
102 if (!callback->mKeepAlive)
112 ResponseHandler mHandler;
113 dispatch_queue_t mQueue;
118 class CHIPBooleanAttributeCallbackBridge : public Callback::Callback<BooleanAttributeCallback> {
120 CHIPBooleanAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
121 : Callback::Callback<BooleanAttributeCallback>(CallbackFn, this)
124 , mKeepAlive(keepAlive)
128 ~CHIPBooleanAttributeCallbackBridge() {};
130 static void CallbackFn(void * context, bool value)
132 CHIPBooleanAttributeCallbackBridge * callback = reinterpret_cast<CHIPBooleanAttributeCallbackBridge *>(context);
133 if (callback && callback->mQueue) {
134 dispatch_async(callback->mQueue, ^{
135 callback->mHandler(nil, @{ @"value": [NSNumber numberWithBool:value] });
136 if (!callback->mKeepAlive)
146 ResponseHandler mHandler;
147 dispatch_queue_t mQueue;
151 class CHIPInt8uAttributeCallbackBridge : public Callback::Callback<Int8uAttributeCallback> {
153 CHIPInt8uAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
154 : Callback::Callback<Int8uAttributeCallback>(CallbackFn, this)
157 , mKeepAlive(keepAlive)
161 ~CHIPInt8uAttributeCallbackBridge() {};
163 static void CallbackFn(void * context, uint8_t value)
165 CHIPInt8uAttributeCallbackBridge * callback = reinterpret_cast<CHIPInt8uAttributeCallbackBridge *>(context);
166 if (callback && callback->mQueue) {
167 dispatch_async(callback->mQueue, ^{
168 callback->mHandler(nil, @{ @"value": [NSNumber numberWithUnsignedChar:value] });
169 if (!callback->mKeepAlive)
179 ResponseHandler mHandler;
180 dispatch_queue_t mQueue;
184 class CHIPInt8sAttributeCallbackBridge : public Callback::Callback<Int8sAttributeCallback> {
186 CHIPInt8sAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
187 : Callback::Callback<Int8sAttributeCallback>(CallbackFn, this)
190 , mKeepAlive(keepAlive)
194 ~CHIPInt8sAttributeCallbackBridge() {};
196 static void CallbackFn(void * context, int8_t value)
198 CHIPInt8sAttributeCallbackBridge * callback = reinterpret_cast<CHIPInt8sAttributeCallbackBridge *>(context);
199 if (callback && callback->mQueue) {
200 dispatch_async(callback->mQueue, ^{
201 callback->mHandler(nil, @{ @"value": [NSNumber numberWithChar:value] });
202 if (!callback->mKeepAlive)
212 ResponseHandler mHandler;
213 dispatch_queue_t mQueue;
217 class CHIPInt16uAttributeCallbackBridge : public Callback::Callback<Int16uAttributeCallback> {
219 CHIPInt16uAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
220 : Callback::Callback<Int16uAttributeCallback>(CallbackFn, this)
223 , mKeepAlive(keepAlive)
227 ~CHIPInt16uAttributeCallbackBridge() {};
229 static void CallbackFn(void * context, uint16_t value)
231 CHIPInt16uAttributeCallbackBridge * callback = reinterpret_cast<CHIPInt16uAttributeCallbackBridge *>(context);
232 if (callback && callback->mQueue) {
233 dispatch_async(callback->mQueue, ^{
234 callback->mHandler(nil, @{ @"value": [NSNumber numberWithUnsignedShort:value] });
235 if (!callback->mKeepAlive)
245 ResponseHandler mHandler;
246 dispatch_queue_t mQueue;
250 class CHIPInt32uAttributeCallbackBridge : public Callback::Callback<Int32uAttributeCallback> {
252 CHIPInt32uAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
253 : Callback::Callback<Int32uAttributeCallback>(CallbackFn, this)
256 , mKeepAlive(keepAlive)
260 ~CHIPInt32uAttributeCallbackBridge() {};
262 static void CallbackFn(void * context, uint32_t value)
264 CHIPInt32uAttributeCallbackBridge * callback = reinterpret_cast<CHIPInt32uAttributeCallbackBridge *>(context);
265 if (callback && callback->mQueue) {
266 dispatch_async(callback->mQueue, ^{
267 callback->mHandler(nil, @{ @"value": [NSNumber numberWithUnsignedLong:value] });
268 if (!callback->mKeepAlive)
278 ResponseHandler mHandler;
279 dispatch_queue_t mQueue;
283 class CHIPInt16sAttributeCallbackBridge : public Callback::Callback<Int16sAttributeCallback> {
285 CHIPInt16sAttributeCallbackBridge(ResponseHandler handler, dispatch_queue_t queue, bool keepAlive = false)
286 : Callback::Callback<Int16sAttributeCallback>(CallbackFn, this)
289 , mKeepAlive(keepAlive)
293 ~CHIPInt16sAttributeCallbackBridge() {};
295 static void CallbackFn(void * context, int16_t value)
297 CHIPInt16sAttributeCallbackBridge * callback = reinterpret_cast<CHIPInt16sAttributeCallbackBridge *>(context);
298 if (callback && callback->mQueue) {
299 dispatch_async(callback->mQueue, ^{
300 callback->mHandler(nil, @{ @"value": [NSNumber numberWithShort:value] });
301 if (!callback->mKeepAlive)
311 ResponseHandler mHandler;
312 dispatch_queue_t mQueue;
316 {{#all_user_clusters}}
317 {{#if (isClient side) }}
318 {{#if (user_cluster_has_enabled_command name side)}}
319 {{#all_user_cluster_commands}}
320 {{#if (isStrEqual clusterName parent.name)}}
321 {{#if (isCommandAvailable parent.side incoming outgoing commandSource name)}}
322 class CHIP{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}CallbackBridge : public Callback::Callback<{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}Callback>
325 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) {}
327 ~CHIP{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}CallbackBridge() {};
329 static void CallbackFn(void * context{{#zcl_command_arguments}}{{#unless (isStrEqual label "status")}}, {{asUnderlyingZclType type}} {{asSymbol label}}{{/unless}}{{/zcl_command_arguments}})
331 CHIP{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}CallbackBridge * callback = reinterpret_cast<CHIP{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}CallbackBridge *>(context);
332 if (callback && callback->mQueue)
334 dispatch_async(callback->mQueue, ^{
335 callback->mHandler(nil, @{
336 {{#zcl_command_arguments}}
337 {{#unless (isStrEqual label "status")}}
339 // {{asSymbol label}}: {{asUnderlyingZclType type}}
340 // Conversion from this type to Objc is not properly implemented yet
341 {{else if (isShortString type)}}
342 @"{{asSymbol label}}": [NSString stringWithFormat:@"%s", {{asSymbol label}}],
344 @"{{asSymbol label}}": [NSNumber numberWith{{asObjectiveCNumberType label type}}:{{asSymbol label}}],
347 {{/zcl_command_arguments}}
356 ResponseHandler mHandler;
357 dispatch_queue_t mQueue;
362 {{/all_user_cluster_commands}}
365 {{/all_user_clusters}}
367 @interface CHIPCluster ()
368 @property (readonly, nonatomic) dispatch_queue_t callbackQueue;
369 - (Controller::ClusterBase *)getCluster;
372 @implementation CHIPCluster
373 - (instancetype)initWithDevice:(CHIPDevice *)device endpoint:(EndpointId)endpoint queue:(dispatch_queue_t)queue
375 if (self = [super init]) {
376 Controller::ClusterBase * cppCluster = [self getCluster];
377 if (cppCluster == nullptr)
382 CHIP_ERROR err = cppCluster->Associate([device internalDevice], endpoint);
383 if (err != CHIP_NO_ERROR) {
387 _callbackQueue = queue;
392 - (Controller::ClusterBase *)getCluster
401 @interface CHIP{{asCamelCased name false}} ()
402 @property (readonly) Controller::{{asCamelCased name false}}Cluster cppCluster;
405 @implementation CHIP{{asCamelCased name false}}
407 - (Controller::ClusterBase *)getCluster
412 {{#chip_server_cluster_commands}}
413 {{#if (zcl_command_arguments_count this.id)}}
414 - (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
416 - (void){{asCamelCased name}}:(ResponseHandler)completionHandler
419 {{#if (hasSpecificResponse name)}}
420 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]);
422 CHIPDefaultSuccessCallbackBridge * onSuccess = new CHIPDefaultSuccessCallbackBridge(completionHandler, [self callbackQueue]);
425 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
429 CHIPDefaultFailureCallbackBridge * onFailure = new CHIPDefaultFailureCallbackBridge(completionHandler, [self callbackQueue]);
432 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
436 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}});
437 if (err != CHIP_NO_ERROR) {
440 completionHandler([CHIPError errorForCHIPErrorCode:err], nil);
443 {{/chip_server_cluster_commands}}
445 {{#chip_server_cluster_attributes}}
446 - (void)readAttribute{{asCamelCased name false}}:(ResponseHandler)completionHandler
448 CHIP{{asCallbackAttributeType atomicTypeId}}AttributeCallbackBridge * onSuccess = new CHIP{{asCallbackAttributeType atomicTypeId}}AttributeCallbackBridge(completionHandler, [self callbackQueue]{{#if (isString type)}},{{#if (isOctetString type)}}true{{else}}false{{/if}}{{/if}});
450 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
454 CHIPDefaultFailureCallbackBridge * onFailure = new CHIPDefaultFailureCallbackBridge(completionHandler, [self callbackQueue]);
457 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
461 CHIP_ERROR err = self.cppCluster.ReadAttribute{{asCamelCased name false}}(onSuccess->Cancel(), onFailure->Cancel());
462 if (err != CHIP_NO_ERROR) {
465 completionHandler([CHIPError errorForCHIPErrorCode:err], nil);
469 {{#if (isWritableAttribute)}}
470 - (void)writeAttribute{{asCamelCased name false}}:({{asObjectiveCBasicType type}})value completionHandler:(ResponseHandler)completionHandler
472 CHIPDefaultSuccessCallbackBridge * onSuccess = new CHIPDefaultSuccessCallbackBridge(completionHandler, [self callbackQueue]);
474 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
478 CHIPDefaultFailureCallbackBridge * onFailure = new CHIPDefaultFailureCallbackBridge(completionHandler, [self callbackQueue]);
481 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
485 {{#if (isOctetString type)}}
486 CHIP_ERROR err = self.cppCluster.WriteAttribute{{asCamelCased name false}}(onSuccess->Cancel(), onFailure->Cancel(), chip::ByteSpan((const uint8_t*)value.bytes, value.length));
487 {{else if (isCharString type)}}
488 NSData * data = [value dataUsingEncoding:NSUTF8StringEncoding];
489 CHIP_ERROR err = self.cppCluster.WriteAttribute{{asCamelCased name false}}(onSuccess->Cancel(), onFailure->Cancel(), chip::ByteSpan((const uint8_t*)data.bytes, data.length));
491 CHIP_ERROR err = self.cppCluster.WriteAttribute{{asCamelCased name false}}(onSuccess->Cancel(), onFailure->Cancel(), value);
493 if (err != CHIP_NO_ERROR) {
496 completionHandler([CHIPError errorForCHIPErrorCode:err], nil);
501 {{#if (isReportableAttribute)}}
502 - (void) configureAttribute{{asCamelCased name false}}:(uint16_t)minInterval maxInterval:(uint16_t)maxInterval{{#unless (isDiscreteType)}} change:({{chipType}})change{{/unless}} completionHandler:(ResponseHandler)completionHandler
504 CHIPDefaultSuccessCallbackBridge * onSuccess = new CHIPDefaultSuccessCallbackBridge(completionHandler, [self callbackQueue]);
506 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
510 CHIPDefaultFailureCallbackBridge * onFailure = new CHIPDefaultFailureCallbackBridge(completionHandler, [self callbackQueue]);
513 completionHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
518 CHIP_ERROR err = self.cppCluster.ConfigureAttribute{{asCamelCased name false}}(onSuccess->Cancel(), onFailure->Cancel(), minInterval, maxInterval{{#unless (isDiscreteType)}}, change{{/unless}});
519 if (err != CHIP_NO_ERROR) {
522 completionHandler([CHIPError errorForCHIPErrorCode:err], nil);
526 - (void) reportAttribute{{asCamelCased name false}}:(ResponseHandler)reportHandler
528 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);
530 reportHandler([CHIPError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil);
534 CHIP_ERROR err = self.cppCluster.ReportAttribute{{asCamelCased name false}}(onReport->Cancel());
535 if (err != CHIP_NO_ERROR) {
537 reportHandler([CHIPError errorForCHIPErrorCode:err], nil);
542 {{/chip_server_cluster_attributes}}