618eb90b95cb95eef73412fb3db8bd8cae8a4776
[platform/core/api/zigbee.git] / lib / zbl-dbus.c
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <errno.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <glib.h>
20 #include <gio/gio.h>
21
22 #include <zb-log.h>
23 #include <zb-type.h>
24 #include <zb-utils.h>
25 #include <zb-error.h>
26 #include <zb-common.h>
27 #include <zcl/zb-zcl-type.h>
28 #include <zdo/zb-zdo-type.h>
29
30 #include "zbl.h"
31 #include "zbl-dbus.h"
32
33 #define USE_ASYNC_DBUS_CALL
34
35 static int zbl_ref_count;
36
37 static GDBusConnection *gdbus_conn = NULL;
38 static GDBusProxy *service_gproxy = NULL;
39 static GDBusProxy *on_off_gproxy = NULL;
40 static GDBusProxy *door_lock_gproxy = NULL;
41 static GDBusProxy *level_control_gproxy = NULL;
42 static GDBusProxy *thermostat_gproxy = NULL;
43 static GDBusProxy *alarm_gproxy = NULL;
44 static GDBusProxy *fan_control_gproxy = NULL;
45 static GDBusProxy *mfglib_gproxy = NULL;
46 static GDBusProxy *zcl_global_proxy = NULL;
47 static GDBusProxy *zdo_dev_proxy = NULL;
48 static GDBusProxy *zcl_basic_proxy = NULL;
49 static GDBusProxy *zcl_identify_proxy = NULL;
50 static GDBusProxy *zcl_ias_zone_proxy = NULL;
51 static GDBusProxy *zcl_poll_control_proxy = NULL;
52 static GDBusProxy *zcl_group_proxy = NULL;
53 static GDBusProxy *zcl_scene_proxy = NULL;
54 static GDBusProxy *zdo_bind_proxy = NULL;
55 static GDBusProxy *zcl_color_control_proxy = NULL;
56 static GDBusProxy *custom_gproxy = NULL;
57
58 /* command id */
59 typedef enum {
60         /* Service */
61         ZBL_SERVICE_FORM_NETWORK = 0,
62         ZBL_SERVICE_DISABLE_NETWORK,
63         /* ZDP except Bind */
64         ZBL_ZDO_NWK_ADDR_REQ,
65         ZBL_ZDO_NWK_ADDR_EXT_REQ,
66         ZBL_ZDO_ACTIVE_EP_REQ,
67         ZBL_ZDO_SIMPLE_DESC_REQ,
68         ZBL_ZDO_MATCHED_DESCRIPTOR_REQ,
69         ZBL_ZDO_COMPLEX_DESC_REQ,
70         ZBL_ZDO_MGMT_BIND_REQ,
71         ZBL_ZDO_MGMT_LQI_REQ,
72         ZBL_ZDO_MGMT_RTG_REQ,
73         ZBL_ZDO_MGMT_NWK_DISC_REQ,
74         ZBL_ZDO_MGMT_PERMIT_JOIN_REQ,
75         ZBL_ZDO_MGMT_LEAVE_REQ,
76         ZBL_ZDO_NODE_DESC_REQ,
77         ZBL_ZDO_POWER_DESC_REQ,
78         ZBL_ZDO_USER_DESC_REQ,
79         ZBL_ZDO_USER_DESC_SET_REQ,
80         /* ZDP Bind */
81         ZBL_ZDO_BIND_REQ,
82         ZBL_ZDO_UNBIND_REQ,
83         /* ZCL Global */
84         ZBL_ZCL_GLOBAL_READ_ATTRIBUTE_REQ,
85         ZBL_ZCL_GLOBAL_WRITE_ATTRIBUTE_REQ,
86         ZBL_ZCL_GLOBAL_CONFIGURE_REPORTING_REQ,
87         ZBL_ZCL_GLOBAL_DISCOVER_ATTRIBUTE_REQ,
88         ZBL_ZCL_GLOBAL_WRITE_ATTRIBUTE_STRUCTURED_REQ,
89         ZBL_ZCL_GLOBAL_DISCOVER_COMMAND_RECEIVED_REQ,
90         ZBL_ZCL_GLOBAL_DISCOVER_COMMAND_GENERATED_REQ,
91         ZBL_ZCL_GLOBAL_DISCOVER_ATTRIBUTE_EXTENDED_REQ,
92         ZBL_ZCL_GLOBAL_READ_CONFIGURE_REPORTING_REQ,
93         /* Custom */
94         ZBL_CUSTOM_APS_SEND_REQ,
95         ZBL_CUSTOM_ZCL_SEND_REQ,
96         ZBL_CUSTOM_LOCAL_SEND_REQ,
97         /* ZCL Alarm */
98         ZBL_ZCL_ALARM_GET_ALARM_REQ,
99         /* ZCL Doorlock */
100         ZBL_ZCL_DOORLOCK_LOCK_STATE,
101         /* ZCL Fanmode */
102         ZBL_ZCL_FANMODE_FAN_MODE_STATE,
103         /* ZCL Group */
104         ZBL_ZCL_GROUP_ADD_GROUP_REQ,
105         ZBL_ZCL_GROUP_VIEW_GROUP_REQ,
106         ZBL_ZCL_GROUP_GET_GROUP_MEMBERSHIP_REQ,
107         ZBL_ZCL_GROUP_REMOVE_GROUP_REQ,
108         /* ZCL Identify */
109         ZBL_ZCL_IDENTIFY_QUERY_REQ,
110         /* ZCL On/Off */
111         ZBL_ZCL_ON_OFF_GET_ON_OFF_STATE,
112         /* ZCL Pollcontrol */
113         ZBL_ZCL_POLLCONTROL_SET_POLL_INTERVAL_REQ,
114         /* ZCL Scene */
115         ZBL_ZCL_SCENE_ADD_SCENE_REQ,
116         ZBL_ZCL_SCENE_VIEW_SCENE_REQ,
117         ZBL_ZCL_SCENE_REMOVE_SCENE_REQ,
118         ZBL_ZCL_SCENE_STORE_SCENE_REQ,
119         ZBL_ZCL_SCENE_REMOVE_ALL_SCENE_REQ,
120         ZBL_ZCL_SCENE_GET_SCENE_MEMBERSHIP_REQ,
121         /* ZCL Thermostat */
122         ZBL_ZCL_THERMOSTAT_GET_LOCAL_TEMP,
123 } zbl_command_id_e;
124
125 typedef struct {
126         bool found;
127         void *cb;
128         void *userdata;
129         unsigned int sid;
130         int tid;
131 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
132         void *global_cmd;
133         void *handle;
134 #endif
135         zbl_command_id_e cid;
136 } zbl_req_cb_s;
137
138 #define ZCL_REPORTING_DIRECTION_REPORTED 0x00
139 #define ZCL_REPORTING_DIRECTION_RECEIVED 0x01
140
141 static GDBusConnection *_zbl_get_connection(void)
142 {
143         GError *error = NULL;
144
145         return g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
146 }
147
148 static GDBusProxy *_zbl_get_service_proxy(void)
149 {
150         GDBusProxy *proxy = NULL;
151         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
152
153         if (NULL == service_gproxy) {
154                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
155                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH, ZIGBEE_SERVICE_INTERFACE,
156                         NULL, NULL);
157         } else
158                 proxy = service_gproxy;
159
160         return proxy;
161 }
162
163 static GDBusProxy *_zbl_get_on_off_proxy(void)
164 {
165         GDBusProxy *proxy = NULL;
166         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
167
168         if (NULL == on_off_gproxy) {
169                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
170                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH,
171                         ZIGBEE_ZCL_ON_OFF_INTERFACE, NULL, NULL);
172         } else
173                 proxy = on_off_gproxy;
174
175         return proxy;
176 }
177
178 static GDBusProxy *_zbl_get_door_lock_proxy(void)
179 {
180         GDBusProxy *proxy = NULL;
181         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
182
183         if (NULL == door_lock_gproxy) {
184                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
185                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH,
186                         ZIGBEE_ZCL_DOOR_LOCK_INTERFACE, NULL, NULL);
187         } else
188                 proxy = door_lock_gproxy;
189
190         return proxy;
191 }
192
193 static GDBusProxy *_zbl_get_level_control_proxy(void)
194 {
195         GDBusProxy *proxy = NULL;
196         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
197
198         if (NULL == level_control_gproxy) {
199                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
200                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH,
201                         ZIGBEE_ZCL_LEVEL_CONTROL_INTERFACE, NULL, NULL);
202         } else
203                 proxy = level_control_gproxy;
204
205         return proxy;
206 }
207
208 static GDBusProxy *_zbl_get_thermostat_proxy(void)
209 {
210         GDBusProxy *proxy = NULL;
211         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
212
213         if (NULL == thermostat_gproxy) {
214                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
215                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH,
216                         ZIGBEE_ZCL_THERMOSTAT_INTERFACE, NULL, NULL);
217         } else
218                 proxy = thermostat_gproxy;
219
220         return proxy;
221 }
222
223 static GDBusProxy *_zbl_get_alarm_proxy(void)
224 {
225         GDBusProxy *proxy = NULL;
226         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
227
228         if (NULL == alarm_gproxy) {
229                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
230                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH, ZIGBEE_ZCL_ALARM_INTERFACE,
231                         NULL, NULL);
232         } else
233                 proxy = alarm_gproxy;
234
235         return proxy;
236 }
237
238 static GDBusProxy *_zbl_get_fan_control_proxy(void)
239 {
240         GDBusProxy *proxy = NULL;
241         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
242
243         if (NULL == fan_control_gproxy) {
244                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
245                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH,
246                         ZIGBEE_ZCL_FAN_CONTROL_INTERFACE, NULL, NULL);
247         } else
248                 proxy = fan_control_gproxy;
249
250         return proxy;
251 }
252
253 static GDBusProxy *_zbl_get_mfglib_proxy(void)
254 {
255         GDBusProxy *proxy = NULL;
256         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
257
258         if (NULL == mfglib_gproxy) {
259                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
260                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH,
261                         ZIGBEE_MFGLIB_CONTROL_INTERFACE, NULL, NULL);
262         } else
263                 proxy = mfglib_gproxy;
264
265         return proxy;
266 }
267
268 static GDBusProxy *_zbl_get_zcl_global_proxy(void)
269 {
270         GDBusProxy *proxy = NULL;
271         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
272
273         if (NULL == zcl_global_proxy) {
274                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
275                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH,
276                         ZIGBEE_ZCL_GLOBAL_CONTROL_INTERFACE, NULL, NULL);
277         } else
278                 proxy = zcl_global_proxy;
279
280         return proxy;
281 }
282
283 static GDBusProxy *_zbl_get_zdo_dev_proxy(void)
284 {
285         GDBusProxy *proxy = NULL;
286         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
287
288         if (NULL == zdo_dev_proxy) {
289                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
290                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH,
291                         ZIGBEE_ZDO_DEV_CONTROL_INTERFACE, NULL, NULL);
292         } else
293                 proxy = zdo_dev_proxy;
294
295         return proxy;
296 }
297
298 static GDBusProxy *_zbl_get_basic_proxy(void)
299 {
300         GDBusProxy *proxy = NULL;
301         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
302
303         if (NULL == zcl_basic_proxy) {
304                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
305                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH, ZIGBEE_ZCL_BASIC_INTERFACE,
306                         NULL, NULL);
307         } else
308                 proxy = zcl_basic_proxy;
309
310         return proxy;
311 }
312
313 static GDBusProxy *_zbl_get_identify_proxy(void)
314 {
315         GDBusProxy *proxy = NULL;
316         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
317
318         if (NULL == zcl_identify_proxy) {
319                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
320                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH,
321                         ZIGBEE_ZCL_IDENTIFY_INTERFACE, NULL, NULL);
322         } else
323                 proxy = zcl_identify_proxy;
324
325         return proxy;
326 }
327
328 static GDBusProxy *_zbl_get_ias_zone_proxy(void)
329 {
330         GDBusProxy *proxy = NULL;
331         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
332
333         if (NULL == zcl_ias_zone_proxy) {
334                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
335                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH,
336                         ZIGBEE_ZCL_IAS_ZONE_INTERFACE, NULL, NULL);
337         } else
338                 proxy = zcl_ias_zone_proxy;
339
340         return proxy;
341 }
342
343 static GDBusProxy *_zbl_get_poll_control_proxy(void)
344 {
345         GDBusProxy *proxy = NULL;
346         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
347
348         if (NULL == zcl_poll_control_proxy) {
349                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
350                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH,
351                         ZIGBEE_ZCL_POLL_CONTROL_INTERFACE, NULL, NULL);
352         } else
353                 proxy = zcl_poll_control_proxy;
354
355         return proxy;
356 }
357
358 static GDBusProxy *_zbl_get_group_proxy(void)
359 {
360         GDBusProxy *proxy = NULL;
361         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
362
363         if (NULL == zcl_group_proxy) {
364                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
365                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH, ZIGBEE_ZCL_GROUP_INTERFACE,
366                         NULL, NULL);
367         } else
368                 proxy = zcl_group_proxy;
369
370         return proxy;
371 }
372
373 static GDBusProxy *_zbl_get_scene_proxy(void)
374 {
375         GDBusProxy *proxy = NULL;
376         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
377
378         if (NULL == zcl_scene_proxy) {
379                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
380                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH, ZIGBEE_ZCL_SCENE_INTERFACE,
381                         NULL, NULL);
382         } else
383                 proxy = zcl_scene_proxy;
384
385         return proxy;
386 }
387
388 static GDBusProxy *_zbl_get_zdo_bind_proxy(void)
389 {
390         GDBusProxy *proxy = NULL;
391         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
392
393         if (NULL == zdo_bind_proxy) {
394                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
395                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH, ZIGBEE_ZDO_BIND_INTERFACE,
396                         NULL, NULL);
397         } else
398                 proxy = zdo_bind_proxy;
399
400         return proxy;
401 }
402
403 static GDBusProxy *_zbl_get_color_control_proxy(void)
404 {
405         GDBusProxy *proxy = NULL;
406         RETVM_IF(NULL == gdbus_conn, NULL, "Connection Object is invalid");
407
408         if (NULL == zcl_color_control_proxy) {
409                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
410                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH,
411                         ZIGBEE_ZCL_COLOR_CONTROL_INTERFACE, NULL, NULL);
412         } else
413                 proxy = zcl_color_control_proxy;
414
415         return proxy;
416 }
417
418 static GDBusProxy *_zbl_get_custom_gproxy(void)
419 {
420         GDBusProxy *proxy = NULL;
421         RETVM_IF(NULL == gdbus_conn, NULL, "Custom Object is invalid");
422
423         if (NULL == custom_gproxy) {
424                 proxy = g_dbus_proxy_new_sync(gdbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
425                         ZIGBEE_SERVER_NAME, ZIGBEE_CONTROL_OBJECT_PATH, ZIGBEE_CUSTOM_INTERFACE,
426                         NULL, NULL);
427         } else
428                 proxy = custom_gproxy;
429
430         return proxy;
431 }
432
433 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
434 static gint _global_compare_func(gconstpointer a, gconstpointer b)
435 {
436         const zbl_req_cb_s *left = (const zbl_req_cb_s*)a;
437         const zbl_req_cb_s *right = (const zbl_req_cb_s*)b;
438         zb_event_global_default_rsp_s *left_data = NULL;
439         zb_event_global_default_rsp_s *right_data = NULL;
440
441         if (NULL == left || NULL == left->global_cmd)
442                 return -1;
443         if (NULL == right || NULL == right->global_cmd)
444                 return 1;
445
446         left_data = left->global_cmd;
447         right_data = right->global_cmd;
448
449         if (left_data->ep > right_data->ep)
450                 return 1;
451         else if (left_data->ep < right_data->ep)
452                 return -1;
453
454         if (left_data->cluster_id > right_data->cluster_id)
455                 return 1;
456         else if (left_data->cluster_id < right_data->cluster_id)
457                 return -1;
458
459         if (left_data->command_id > right_data->command_id)
460                 return 1;
461         else if (left_data->command_id < right_data->command_id)
462                 return -1;
463
464         /* endpoint, cluster_id and command_id are equal */
465         return 0;
466 }
467
468 static void _zbl_register_global_req(zigbee_h handle, zbl_req_cb_s *container)
469 {
470         GList *list = NULL;
471         GList *item = NULL;
472
473         if (NULL == handle || NULL == container)
474                 return;
475
476         list = handle->global_cmd_req;
477
478         /* Insert item if not exists */
479         DBG("Insert global cmd info");
480         if (list) {
481                 item = g_list_find_custom(list, container, _global_compare_func);
482                 if (NULL != item)
483                         handle->global_cmd_req = g_list_append(list, container);
484         } else
485                 handle->global_cmd_req = g_list_append(list, container);
486 }
487
488 static void _zbl_deregister_global_req(zigbee_h handle, zbl_req_cb_s *container)
489 {
490         GList *list = NULL;
491         GList *item = NULL;
492
493         if (NULL == handle || NULL == container)
494                 return;
495
496         list = handle->global_cmd_req;
497         if (NULL == list)
498                 return;
499
500         /* Remove item if exists */
501         DBG("Remove global cmd info");
502         item = g_list_find_custom(list, container, _global_compare_func);
503         if (NULL != item)
504                 handle->global_cmd_req = g_list_remove(list, container);
505 }
506
507 static void _zbl_remove_global_req(zigbee_h handle, unsigned char ep,
508         unsigned short cluster_id, unsigned char command_id)
509 {
510         GList *head = NULL;
511         GList *iter = NULL;
512         zbl_req_cb_s *ret = NULL;
513
514         if (NULL == handle)
515                 return;
516
517         head = handle->global_cmd_req;
518         iter = head;
519
520         while (NULL != iter) {
521                 GList *next = iter->next;
522                 zbl_req_cb_s *container = iter->data;
523                 if (container && container->global_cmd) {
524                         zb_event_global_default_rsp_s *data = container->global_cmd;
525
526                         if (data && data->ep == ep && data->cluster_id == cluster_id
527                                         && data->command_id == command_id) {
528                                 DBG("  Found: ep[%d] cluster_id[%X] command_id[%X] / sid[%d]",
529                                         ep, cluster_id, command_id, container->sid);
530                                 ret = container;
531                                 break;
532                         }
533                 }
534                 iter = next;
535         }
536
537         if (ret) {
538                 if (ret->sid)
539                         g_dbus_connection_signal_unsubscribe(gdbus_conn, ret->sid);
540
541                 if (ret->tid) {
542                         g_source_remove(ret->tid);
543                         DBG("tid=%d removed");
544                         ret->tid = 0;
545                 }
546
547                 _zbl_deregister_global_req(handle, ret);
548         }
549
550 }
551 #endif /* ZB_FEATURE_GLOBAL_RSP_SYNC */
552
553 static void _zbl_signal_handler(GDBusConnection *connection,
554                 const gchar *sender_name, const gchar *object_path, const gchar *interface_name,
555                 const gchar *signal_name, GVariant *parameters, gpointer user_data)
556 {
557         zigbee_h container = (zigbee_h)user_data;
558         RETM_IF(NULL == container, "container is null");
559         RETM_IF(NULL == container->event_handler, "event_handler is null");
560         DBG("%s signal received", signal_name);
561
562         if (g_strcmp0(signal_name, "service_enabled") == 0) {
563                 gboolean enabled;
564                 g_variant_get(parameters, "(b)", &enabled);
565
566                 zb_event_data_s ev;
567                 ev.data.enable = calloc(1, sizeof(zb_event_enable_s));
568                 RETM_IF(NULL == ev.data.enable, "Failed to memory allocation !");
569
570                 ev.data.enable->status = (unsigned char)enabled;
571                 container->event_handler(0, NULL, ZB_ZDP_ENABLE_EVENT, ev);
572                 free(ev.data.enable);
573         } else if (g_strcmp0(signal_name, "form_network_done") == 0) {
574                 nwk_addr pan_id;
575                 g_variant_get(parameters, "(q)", &pan_id);
576
577                 zb_event_data_s ev;
578                 ev.data.form_network = calloc(1, sizeof(zb_event_form_network_s));
579                 RETM_IF(NULL == ev.data.form_network, "Failed to memory allocation !");
580
581                 memcpy(&ev.data.form_network->pan_id, &pan_id, sizeof(nwk_addr));
582                 container->event_handler(pan_id, NULL, ZB_ZDP_FORM_NETWORK_DONE, ev);
583                 free(ev.data.form_network);
584         } else if (g_strcmp0(signal_name, "child_joined") == 0) {
585                 nwk_addr addr16;
586                 ieee_addr addr64;
587                 unsigned char count;
588                 unsigned char ep[10];
589                 unsigned char value;
590
591                 int j = 0;
592                 GVariantIter *iter1 = NULL;
593                 GVariantIter *iter2 = NULL;
594
595                 g_variant_get(parameters, "(a(y)ya(y)q)", &iter1, &count, &iter2, &addr16);
596                 while (g_variant_iter_loop(iter1, "(y)", &value)) {
597                         addr64[j] = value;
598                         j++;
599                 }
600                 if (NULL != iter1)
601                         g_variant_iter_free(iter1);
602
603                 j = 0;
604                 while (g_variant_iter_loop(iter2, "(y)", &value)) {
605                         ep[j] = value;
606                         j++;
607                 }
608                 if (NULL != iter2)
609                         g_variant_iter_free(iter2);
610
611                 zb_event_data_s ev;
612                 ev.data.join = calloc(1, sizeof(zb_event_join_s));
613                 RETM_IF(NULL == ev.data.join, "Failed to memory allocation !");
614
615                 ev.data.join->count = count;
616                 memcpy(ev.data.join->ep, ep, count);
617                 container->event_handler(addr16, addr64, ZB_ZDP_JOIN_EVENT, ev);
618                 free(ev.data.join);
619         } else if (g_strcmp0(signal_name, "child_rejoined") == 0) {
620                 ieee_addr addr64;
621                 unsigned char value;
622
623                 int j = 0;
624                 GVariantIter *iter = NULL;
625
626                 g_variant_get(parameters, "(a(y))", &iter);
627                 while (g_variant_iter_loop(iter, "(y)", &value)) {
628                         addr64[j] = value;
629                         j++;
630                 }
631                 if (NULL != iter)
632                         g_variant_iter_free(iter);
633
634                 zb_event_data_s ev;
635                 memset(&ev, 0, sizeof(zb_event_data_s));
636                 container->event_handler(0, addr64, ZB_ZDP_REJOIN_EVENT, ev);
637         } else if (g_strcmp0(signal_name, "child_left") == 0) {
638                 int j = 0;
639                 ieee_addr addr64;
640                 GVariantIter *iter = NULL;
641                 unsigned char value, status;
642
643                 g_variant_get(parameters, "(a(y)y)", &iter, &status);
644                 while (g_variant_iter_loop(iter, "(y)", &value)) {
645                         addr64[j] = value;
646                         j++;
647                 }
648                 if (NULL != iter)
649                         g_variant_iter_free(iter);
650
651                 zb_event_data_s ev;
652                 ev.data.child_left = calloc(1, sizeof(zb_event_child_left_s));
653                 RETM_IF(NULL == ev.data.child_left, "Failed to memory allocation !");
654
655                 ev.data.child_left->status = status;
656                 container->event_handler(0, addr64, ZB_ZDP_CHILD_LEFT, ev);
657                 free(ev.data.child_left);
658         } else if (g_strcmp0(signal_name, "leave_network_done") == 0) {
659                 nwk_addr addr16;
660                 g_variant_get(parameters, "(q)", &addr16);
661
662                 zb_event_data_s ev;
663                 memset(&ev, 0, sizeof(zb_event_data_s));
664                 container->event_handler(addr16, NULL, ZB_ZDP_LEAVE_DONE_EVENT, ev);
665         } else if (!g_strcmp0(signal_name, "zcl_global_default_response")) {
666                 nwk_addr addr16;
667                 unsigned char ep;
668                 unsigned short cluster_id;
669                 unsigned char command_id;
670                 unsigned char status;
671
672                 g_variant_get(parameters, "(qyqyy)",  &addr16, &ep, &cluster_id, &command_id, &status);
673
674                 zb_event_data_s ev;
675                 ev.data.global_default_rsp = calloc(1, sizeof(zb_event_global_default_rsp_s));
676                 RETM_IF(NULL == ev.data.global_default_rsp, "Failed to memory allocation !");
677
678                 ev.data.global_default_rsp->ep = ep;
679                 ev.data.global_default_rsp->cluster_id = cluster_id;
680                 ev.data.global_default_rsp->command_id = command_id;
681                 ev.data.global_default_rsp->status = status;
682
683 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
684                 /* If there is global request already, remove that. */
685                 if (0x00 != status)
686                         _zbl_remove_global_req(container, ep, cluster_id, command_id);
687 #endif
688
689                 container->event_handler(addr16, NULL, ZB_ZCL_GLOBAL_DEFAULT_RSP_EVENT, ev);
690                 free(ev.data.global_default_rsp);
691         } else if (!g_strcmp0(signal_name, "alarm_count")) {
692                 unsigned short alarm_count;
693                 g_variant_get(parameters, "(q)", &alarm_count);
694
695                 zb_event_data_s ev;
696                 ev.data.alarm = calloc(1, sizeof(zb_event_alarm_s));
697                 RETM_IF(NULL == ev.data.alarm, "Failed to memory allocation !");
698
699                 ev.data.alarm->count = alarm_count;
700                 container->event_handler(0, NULL, ZB_ZCL_ALARM_EVENT, ev);
701                 free(ev.data.alarm);
702         } else if (!g_strcmp0(signal_name, "report_attr_handler_rsp")) {
703                 nwk_addr addr16;
704                 unsigned char ep;
705                 unsigned char value;
706                 unsigned short attrData;
707                 unsigned short cluster_id;
708                 unsigned char dataType;
709                 unsigned short data_size;
710                 int dsizeIndex = 0;
711                 char dSize[3] = {'\0', '\0'};
712                 int i = 0, j = 0, records_len;
713                 GVariantIter *attr_iter = NULL;
714                 GVariantIter *dataType_iter = NULL;
715                 GVariantIter *data_iter = NULL;
716
717                 attr_report_h *records = NULL;
718
719                 g_variant_get(parameters, "(qyqaqayayi)",  &addr16, &ep,
720                          &cluster_id, &attr_iter, &dataType_iter, &data_iter, &records_len);
721
722                 records = calloc(records_len, sizeof(attr_report_h));
723                 RETM_IF(NULL == records, "calloc() Fail(%d)", errno);
724                 for (j = 0; j < records_len; j++) {
725                         records[j] = calloc(1, sizeof(struct attribute_report_s));
726                         if (NULL == records[j]) {
727                                 for (i = 0; i < j; i++)
728                                         free(records[i]);
729                                 free(records);
730                                 if (NULL != attr_iter)
731                                         g_variant_iter_free(attr_iter);
732                                 if (NULL != dataType_iter)
733                                         g_variant_iter_free(dataType_iter);
734                                 if (NULL != data_iter)
735                                         g_variant_iter_free(data_iter);
736
737                                 ERR("calloc() Fail(%d)", errno);
738                                 return;
739                         }
740                 }
741                 DBG("record_length %d", records_len);
742
743                 j = 0;
744                 while (g_variant_iter_loop(attr_iter, "q", &attrData)
745                                 && g_variant_iter_loop(dataType_iter, "y", &dataType)) {
746                         records[j]->id = attrData;
747                         records[j]->type = dataType;
748                         DBG("dataType 0x%02x", records[j]->type);
749                         DBG("AttributeId 0x%04x", records[j]->id);
750                         j++;
751                 }
752                 if (NULL != attr_iter)
753                         g_variant_iter_free(attr_iter);
754                 if (NULL != dataType_iter)
755                         g_variant_iter_free(dataType_iter);
756
757                 j = 0;
758                 while (j < records_len) {
759                         switch (records[j]->type) {
760                         /* String */
761                         case ZB_ZCL_OCTAT_STRING:
762                         case ZB_ZCL_CHRACTER_STRING:
763                                 g_variant_iter_loop(data_iter, "y", &value);
764                                 data_size = value + 1;
765                                 records[j]->value = calloc(data_size, sizeof(unsigned char));
766                                 if (NULL == records[j]->value) {
767                                         for (i = 0; i < j; i++)
768                                                 free(records[i]->value);
769                                         for (i = 0; i < records_len; i++)
770                                                 free(records[i]);
771                                         free(records);
772                                         ERR("calloc() Fail(%d)", errno);
773                                         return;
774                                 }
775                                 records[j]->value[dsizeIndex] = value;
776                                 dsizeIndex++;
777                                 for (i = dsizeIndex; i < data_size - 2; i++) {
778                                         g_variant_iter_loop(data_iter, "y", &value);
779                                         records[j]->value[i] = value;
780                                 }
781                                 if (NULL != data_iter)
782                                         g_variant_iter_free(data_iter);
783                                 break;
784                         case ZB_ZCL_LONG_OCTAT_STRING:
785                         case ZB_ZCL_LONG_CHRACTER_STRING:
786                                 g_variant_iter_loop(data_iter, "y", &value);
787                                 dSize[0] = value;
788                                 g_variant_iter_loop(data_iter, "y", &value);
789                                 dSize[1] =  value;
790                                 data_size = dSize[1];
791                                 data_size = (data_size << 8) | dSize[0];
792                                 data_size += 2;
793                                 records[j]->value = calloc(data_size, sizeof(unsigned char));
794                                 if (NULL == records[j]->value) {
795                                         for (i = 0; i < j; i++)
796                                                 free(records[i]->value);
797                                         for (i = 0; i < records_len; i++)
798                                                 free(records[i]);
799                                         free(records);
800                                         ERR("calloc() Fail(%d)", errno);
801                                         return;
802                                 }
803                                 records[j]->value[dsizeIndex] = dSize[dsizeIndex];
804                                 dsizeIndex++;
805                                 records[j]->value[dsizeIndex] = dSize[dsizeIndex];
806                                 dsizeIndex++;
807                                 for (i = dsizeIndex; i < data_size - 2; i++) {
808                                         g_variant_iter_loop(data_iter, "y", &value);
809                                         records[j]->value[i] = value;
810                                 }
811                                 if (NULL != data_iter)
812                                         g_variant_iter_free(data_iter);
813                                 break;
814                         /* Array, set and bag */
815                         case ZB_ZCL_ARRAY:
816                         case ZB_ZCL_SET:
817                         case ZB_ZCL_BAG:
818                         /* structure */
819                         case ZB_ZCL_STRUCTURE:
820                                 ERR("Not supported type = %d", records[i]->type);
821                                 continue;
822                         default:
823                                 data_size = zb_get_data_size(records[j]->type);
824                                 records[j]->value = calloc(data_size, sizeof(unsigned char));
825                                 if (NULL == records[j]->value) {
826                                         for (i = 0; i < j; i++)
827                                                 free(records[i]->value);
828                                         for (i = 0; i < records_len; i++)
829                                                 free(records[i]);
830                                         free(records);
831                                         ERR("calloc() Fail(%d)", errno);
832                                         return;
833                                 }
834                                 if (data_size != 0xFF) {
835                                         for (i = 0; i < data_size; i++) {
836                                                 g_variant_iter_loop(data_iter, "y", &value);
837                                                 records[j]->value[i] = value;
838                                                 DBG("value[%d] 0x%02X", i, records[j]->value[i]);
839                                         }
840                                 }
841                                 if (NULL != data_iter)
842                                         g_variant_iter_free(data_iter);
843                         }
844                         DBG("DataType = 0x%02X Data Size = %d", records[j]->type, data_size);
845                         j++;
846                 }
847
848                 zb_event_data_s ev;
849                 ev.data.global_attr_report = calloc(1, sizeof(zb_event_global_attr_report_s));
850                 if (NULL == ev.data.global_attr_report) {
851                         ERR("Failed to memory allocation !");
852                         for (j = 0; j < records_len; j++) {
853                                 free(records[j]->value);
854                                 free(records[j]);
855                         }
856                         return;
857                 }
858
859                 ev.data.global_attr_report->records = records;
860                 ev.data.global_attr_report->count = records_len;
861                 container->event_handler(addr16, NULL, ZB_ZCL_GLOBAL_ATTRIBUTE_REPORT_EVENT, ev);
862                 for (j = 0; j < records_len; j++) {
863                         free(records[j]->value);
864                         free(records[j]);
865                 }
866                 free(records);
867                 free(ev.data.global_attr_report);
868         } else if (!g_strcmp0(signal_name, "status_change_rsp")) {
869                 zb_event_data_s ev;
870                 nwk_addr addr16;
871                 unsigned char src_ep;
872                 unsigned char extended_status;
873                 unsigned short zone_status;
874                 unsigned short delay;
875                 unsigned char zone_id;
876                 g_variant_get(parameters, "(qyqyyq)", &addr16, &src_ep, &zone_status,
877                         &extended_status, &zone_id, &delay);
878                 if (0xff == zone_id) {
879                         ev.data.ias_noti = calloc(1, sizeof(zb_event_ias_noti_s));
880                         RETM_IF(NULL == ev.data.ias_noti, "Failed to memory allocation !");
881
882                         ev.data.ias_noti->src_ep = src_ep;
883                         ev.data.ias_noti->zone_status = zone_status;
884                         container->event_handler(addr16, NULL,
885                                 ZB_ZCL_IAS_ZONE_STATUS_CHANGE_NOTIFICATION_EVENT, ev);
886
887                         free(ev.data.ias_noti);
888                 } else {
889                         ev.data.ias_extended_noti = calloc(1, sizeof(zb_event_ias_extended_noti_s));
890                         RETM_IF(NULL == ev.data.ias_extended_noti, "Failed to memory allocation !");
891
892                         ev.data.ias_extended_noti->src_ep = src_ep;
893                         ev.data.ias_extended_noti->zone_status = zone_status;
894                         ev.data.ias_extended_noti->extended_status = extended_status;
895                         ev.data.ias_extended_noti->zone_id = zone_id;
896                         ev.data.ias_extended_noti->delay = delay;
897                         container->event_handler(addr16, NULL,
898                                 ZB_ZCL_IAS_ZONE_STATUS_CHANGE_EXTENDED_NOTIFICATION_EVENT, ev);
899
900                         free(ev.data.ias_extended_noti);
901                 }
902         } else if (!g_strcmp0(signal_name, "enroll_request")) {
903                 nwk_addr addr16;
904                 unsigned char src_ep;
905                 unsigned short zone_type;
906                 unsigned char mfg_code;
907                 zb_event_data_s ev;
908                 ev.data.ias_enroll_request = calloc(1, sizeof(zb_event_ias_enroll_request_s));
909                 RETM_IF(NULL == ev.data.ias_enroll_request, "Failed to memory allocation !");
910
911                 g_variant_get(parameters, "(qyqy)", &addr16, &src_ep, &zone_type, &mfg_code);
912                 ev.data.ias_enroll_request->src_ep = src_ep;
913                 ev.data.ias_enroll_request->zone_type = zone_type;
914                 ev.data.ias_enroll_request->mfg_code = mfg_code;
915                 container->event_handler(addr16, NULL, ZB_ZCL_IAS_ZONE_ENROLL_REQUEST_EVENT, ev);
916                 free(ev.data.ias_enroll_request);
917         } else
918                 ERR("Can't handle this signal=%s", signal_name);
919         return;
920 }
921
922 static void _zbl_dbus_unsubscribe_signal(GList *sub_ids)
923 {
924         GDBusConnection *conn = _zbl_get_connection();
925         if (NULL == conn || NULL == sub_ids)
926                 return;
927
928         while (sub_ids) {
929                 g_dbus_connection_signal_unsubscribe(conn, GPOINTER_TO_UINT(sub_ids));
930                 sub_ids = g_list_remove(sub_ids, sub_ids);
931         }
932 }
933
934 static int _zbl_dbus_subscribe_signal(zigbee_h handle)
935 {
936         unsigned int id;
937
938         /* Section 1. Subscribe ZDO signal */
939         id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL, ZIGBEE_SERVICE_INTERFACE,
940                                                 "service_enabled", ZIGBEE_CONTROL_OBJECT_PATH, NULL,
941                                                 G_DBUS_CALL_FLAGS_NONE, _zbl_signal_handler, handle, NULL);
942         if (0 == id) {
943                 ERR("g_dbus_connection_signal_subscribe(service_enabled) Fail(%d)", errno);
944                 return ZIGBEE_ERROR_IO_ERROR;
945         }
946         handle->dbus_sub_ids = g_list_append(handle->dbus_sub_ids, GUINT_TO_POINTER(id));
947         DBG("subscribed for service_enabled signal %d", id);
948
949         id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL, ZIGBEE_SERVICE_INTERFACE,
950                                                 "child_joined", ZIGBEE_CONTROL_OBJECT_PATH, NULL,
951                                                 G_DBUS_CALL_FLAGS_NONE, _zbl_signal_handler, handle, NULL);
952         if (0 == id) {
953                 ERR("g_dbus_connection_signal_subscribe(child_rejoined) Fail(%d)\n", errno);
954                 _zbl_dbus_unsubscribe_signal(handle->dbus_sub_ids);
955                 return ZIGBEE_ERROR_IO_ERROR;
956         }
957         handle->dbus_sub_ids = g_list_append(handle->dbus_sub_ids, GUINT_TO_POINTER(id));
958         DBG("subscribed for child_joined signal %d", id);
959
960         id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL, ZIGBEE_SERVICE_INTERFACE,
961                                                 "child_rejoined", ZIGBEE_CONTROL_OBJECT_PATH, NULL,
962                                                 G_DBUS_CALL_FLAGS_NONE, _zbl_signal_handler, handle, NULL);
963         if (0 == id) {
964                 ERR("g_dbus_connection_signal_subscribe(child_rejoined) Fail(%d)\n", errno);
965                 _zbl_dbus_unsubscribe_signal(handle->dbus_sub_ids);
966                 return ZIGBEE_ERROR_IO_ERROR;
967         }
968         handle->dbus_sub_ids = g_list_append(handle->dbus_sub_ids, GUINT_TO_POINTER(id));
969         DBG("subscribed for child_rejoined signal %d", id);
970
971         id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL, ZIGBEE_SERVICE_INTERFACE,
972                                                 "child_left", ZIGBEE_CONTROL_OBJECT_PATH, NULL,
973                                                 G_DBUS_CALL_FLAGS_NONE, _zbl_signal_handler, handle, NULL);
974         if (0 == id) {
975                 ERR("g_dbus_connection_signal_subscribe(child_left) Fail(%d)\n", errno);
976                 _zbl_dbus_unsubscribe_signal(handle->dbus_sub_ids);
977                 return ZIGBEE_ERROR_IO_ERROR;
978         }
979         handle->dbus_sub_ids = g_list_append(handle->dbus_sub_ids, GUINT_TO_POINTER(id));
980         DBG("subscribed for child_left signal %d", id);
981
982         id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL, ZIGBEE_SERVICE_INTERFACE,
983                                                 "leave_network_done", ZIGBEE_CONTROL_OBJECT_PATH, NULL,
984                                                 G_DBUS_CALL_FLAGS_NONE, _zbl_signal_handler, handle, NULL);
985         if (0 == id) {
986                 ERR("g_dbus_connection_signal_subscribe(leave_network_done) Fail(%d)\n", errno);
987                 _zbl_dbus_unsubscribe_signal(handle->dbus_sub_ids);
988                 return ZIGBEE_ERROR_IO_ERROR;
989         }
990         handle->dbus_sub_ids = g_list_append(handle->dbus_sub_ids, GUINT_TO_POINTER(id));
991         DBG("subscribed for leave_network_done signal %d", id);
992
993         id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL, ZIGBEE_SERVICE_INTERFACE,
994                                                 "form_network_done", ZIGBEE_CONTROL_OBJECT_PATH, NULL,
995                                                 G_DBUS_CALL_FLAGS_NONE, _zbl_signal_handler, handle, NULL);
996         if (0 == id) {
997                 ERR("g_dbus_connection_signal_subscribe(form_network_done) Fail(%d)\n", errno);
998                 _zbl_dbus_unsubscribe_signal(handle->dbus_sub_ids);
999                 return ZIGBEE_ERROR_IO_ERROR;
1000         }
1001         handle->dbus_sub_ids = g_list_append(handle->dbus_sub_ids, GUINT_TO_POINTER(id));
1002         DBG("subscribed for form_network_done signal %d", id);
1003
1004         /* Section 3. Subscribe ZCL global command */
1005         id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL,
1006                 ZIGBEE_ZCL_GLOBAL_CONTROL_INTERFACE, "zcl_global_default_response",
1007                 ZIGBEE_CONTROL_OBJECT_PATH, NULL, G_DBUS_CALL_FLAGS_NONE,
1008                 _zbl_signal_handler, handle, NULL);
1009         if (0 == id) {
1010                 ERR("g_dbus_connection_signal_subscribe(zcl_global_default_response) Fail(%d)\n", errno);
1011                 _zbl_dbus_unsubscribe_signal(handle->dbus_sub_ids);
1012                 return ZIGBEE_ERROR_IO_ERROR;
1013         }
1014         handle->dbus_sub_ids = g_list_append(handle->dbus_sub_ids, GUINT_TO_POINTER(id));
1015         DBG("subscribed for zcl_global_default_response signal %d", id);
1016
1017         id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL,
1018                 ZIGBEE_ZCL_GLOBAL_CONTROL_INTERFACE, "report_attr_handler_rsp",
1019                 ZIGBEE_CONTROL_OBJECT_PATH, NULL, G_DBUS_CALL_FLAGS_NONE,
1020                 _zbl_signal_handler, handle, NULL);
1021         if (0 == id) {
1022                 ERR("g_dbus_connection_signal_subscribe(report_attr_handler_rsp) Fail(%d)\n", errno);
1023                 _zbl_dbus_unsubscribe_signal(handle->dbus_sub_ids);
1024                 return ZIGBEE_ERROR_IO_ERROR;
1025         }
1026         handle->dbus_sub_ids = g_list_append(handle->dbus_sub_ids, GUINT_TO_POINTER(id));
1027         DBG("subscribed for report_attr_handler_rsp signal %d", id);
1028
1029         /* Section 2. Subscribe ZCL alarm cluster signal */
1030         id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL, ZIGBEE_ZCL_ALARM_INTERFACE,
1031                                                 "alarm_count", ZIGBEE_CONTROL_OBJECT_PATH, NULL,
1032                                                 G_DBUS_CALL_FLAGS_NONE, _zbl_signal_handler, handle, NULL);
1033         if (0 == id) {
1034                 ERR("g_dbus_connection_signal_subscribe(alarm_count) Fail(%d)\n", errno);
1035                 _zbl_dbus_unsubscribe_signal(handle->dbus_sub_ids);
1036                 return ZIGBEE_ERROR_IO_ERROR;
1037         }
1038         handle->dbus_sub_ids = g_list_append(handle->dbus_sub_ids, GUINT_TO_POINTER(id));
1039         DBG("subscribed for alarm_count signal %d", id);
1040
1041         /* Section 3. Subscribe ZCL IAS cluster signal */
1042         id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL, ZIGBEE_ZCL_IAS_ZONE_INTERFACE,
1043                                         "status_change_rsp", ZIGBEE_CONTROL_OBJECT_PATH, NULL,
1044                                         G_DBUS_CALL_FLAGS_NONE, _zbl_signal_handler, handle, NULL);
1045         if (0 == id) {
1046                 ERR("g_dbus_connection_signal_subscribe(status_change_rsp) Fail(%d)\n", errno);
1047                 _zbl_dbus_unsubscribe_signal(handle->dbus_sub_ids);
1048                 return ZIGBEE_ERROR_IO_ERROR;
1049         }
1050         handle->dbus_sub_ids = g_list_append(handle->dbus_sub_ids, GUINT_TO_POINTER(id));
1051         DBG("subscribed for status_change_rsp signal %d", id);
1052
1053         id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL, ZIGBEE_ZCL_IAS_ZONE_INTERFACE,
1054                                                 "enroll_request", ZIGBEE_CONTROL_OBJECT_PATH, NULL,
1055                                                 G_DBUS_CALL_FLAGS_NONE, _zbl_signal_handler, handle, NULL);
1056         if (0 == id) {
1057                 ERR("g_dbus_connection_signal_subscribe(enroll_request) Fail(%d)\n", errno);
1058                 _zbl_dbus_unsubscribe_signal(handle->dbus_sub_ids);
1059                 return ZIGBEE_ERROR_IO_ERROR;
1060         }
1061         handle->dbus_sub_ids = g_list_append(handle->dbus_sub_ids, GUINT_TO_POINTER(id));
1062         DBG("subscribed for enroll_request signal %d", id);
1063
1064         return ZIGBEE_ERROR_NONE;
1065 }
1066
1067 static void _zbl_dbus_name_owner_notify(GObject *object, GParamSpec *pspec,
1068                 gpointer *user_data)
1069 {
1070         GDBusProxy *proxy = G_DBUS_PROXY(object);
1071         gchar *name_owner = g_dbus_proxy_get_name_owner(proxy);
1072         if (name_owner)
1073                 return;
1074         zbl_dbus_stop();
1075 }
1076
1077 static void _zbl_request_cleanup(gpointer data)
1078 {
1079         zbl_req_cb_s *container = data;
1080         RET_IF(NULL == container);
1081
1082         if (container->tid) {
1083                 g_source_remove(container->tid);
1084                 DBG("tid=%d removed");
1085                 container->tid = 0;
1086         }
1087
1088 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
1089         _zbl_deregister_global_req(container->handle, container);
1090 #endif
1091
1092         free(container);
1093 }
1094
1095 static gboolean _zbl_timeout_cb(gpointer p)
1096 {
1097         zbl_req_cb_s *container = (zbl_req_cb_s *)p;
1098
1099         RETVM_IF(NULL == gdbus_conn, G_SOURCE_REMOVE, "gdbus_conn is NULL");
1100         RETVM_IF(NULL == p, G_SOURCE_REMOVE, "container is NULL");
1101         RETVM_IF(NULL == container->cb, G_SOURCE_REMOVE, "cb is NULL");
1102         RETVM_IF(true == container->found, G_SOURCE_REMOVE, "cb was alreay handled");
1103
1104         switch (container->cid) {
1105                 /* Service */
1106         case ZBL_SERVICE_FORM_NETWORK: {
1107                 zb_form_network_cb cb = container->cb;
1108                 cb(0x0000, container->userdata);
1109         }
1110         break;
1111         case ZBL_SERVICE_DISABLE_NETWORK: {
1112                 zb_disable_network_cb cb = container->cb;
1113                 cb(0x0000, container->userdata);
1114                 cb(ZB_ZDP_TIMEOUT, container->userdata);
1115         }
1116         break;
1117         /* ZDP except Bind */
1118         case ZBL_ZDO_NWK_ADDR_REQ: {
1119                 zb_zdo_addr_rsp cb = container->cb;
1120                 cb(ZB_ZDP_TIMEOUT, NULL, 0, 0, 0, NULL, container->userdata);
1121         }
1122         break;
1123         case ZBL_ZDO_NWK_ADDR_EXT_REQ: {
1124                 zb_zdo_addr_rsp cb = container->cb;
1125                 cb(ZB_ZDP_TIMEOUT, NULL, 0, 0, 0, NULL, container->userdata);
1126         }
1127         break;
1128         case ZBL_ZDO_ACTIVE_EP_REQ: {
1129                 zb_zdo_active_ep_rsp cb = container->cb;
1130                 cb(ZB_ZDP_TIMEOUT, 0, 0, NULL, container->userdata);
1131         }
1132         break;
1133         case ZBL_ZDO_SIMPLE_DESC_REQ: {
1134                 zb_zdo_simple_desc_rsp cb = container->cb;
1135                 cb(0, 0, NULL, container->userdata);
1136         }
1137         break;
1138         case ZBL_ZDO_MATCHED_DESCRIPTOR_REQ: {
1139                 zb_zdo_match_desc_rsp cb = container->cb;
1140                 cb(ZB_ZDP_TIMEOUT, 0, 0, NULL, container->userdata);
1141         }
1142         break;
1143         case ZBL_ZDO_COMPLEX_DESC_REQ: {
1144                 zb_zdo_complex_desc_rsp cb = container->cb;
1145                 cb(ZB_ZDP_TIMEOUT, 0, 0, NULL, container->userdata);
1146         }
1147         break;
1148         case ZBL_ZDO_MGMT_BIND_REQ: {
1149                 zb_zdo_mgmt_bind_rsp cb = container->cb;
1150                 zb_zdo_binding_table_h *records = NULL;
1151
1152                 records = calloc(1, sizeof(zb_zdo_binding_table_h));
1153                 if (records)
1154                         records[0] = calloc(1, sizeof(struct zb_zdo_binding_table_s));
1155
1156                 cb(ZB_ZDP_TIMEOUT, 0, 0, 0, records, container->userdata);
1157
1158                 free(records[0]);
1159                 free(records);
1160         }
1161         break;
1162         case ZBL_ZDO_MGMT_LQI_REQ: {
1163                 zb_zdo_mgmt_lqi_rsp cb = container->cb;
1164                 zb_zdo_neighbor_table_desc_h *records = NULL;
1165
1166                 records = calloc(1, sizeof(zb_zdo_neighbor_table_desc_h));
1167                 if (records)
1168                         records[0] = calloc(1, sizeof(struct zb_zdo_neighbor_table_desc_s));
1169
1170                 cb(ZB_ZDP_TIMEOUT, 0, 0, 0, records, container->userdata);
1171
1172                 free(records[0]);
1173                 free(records);
1174         }
1175         break;
1176         case ZBL_ZDO_MGMT_RTG_REQ: {
1177                 zb_zdo_mgmt_rtg_rsp cb = container->cb;
1178                 zb_zdo_routing_table_h *records = NULL;
1179
1180                 records = calloc(1, sizeof(zb_zdo_routing_table_h));
1181                 if (records)
1182                         records[0] = calloc(1, sizeof(struct zb_zdo_routing_table_s));
1183
1184                 cb(ZB_ZDP_TIMEOUT, 0, 0, 0, records, container->userdata);
1185
1186                 free(records[0]);
1187                 free(records);
1188         }
1189         break;
1190         case ZBL_ZDO_MGMT_NWK_DISC_REQ: {
1191                 zb_zdo_mgmt_nwk_disc_rsp cb = container->cb;
1192                 zb_zdo_network_list_record_h *records = NULL;
1193                 records = calloc(1, sizeof(zb_zdo_network_list_record_h));
1194                 if (records)
1195                         records[0] = calloc(1, sizeof(struct zb_zdo_network_list_record_s));
1196
1197                 cb(0, 0, 0, 0, records, container->userdata);
1198                 free(records[0]);
1199                 free(records);
1200         }
1201         break;
1202         case ZBL_ZDO_MGMT_PERMIT_JOIN_REQ: {
1203                 zb_zdo_mgmt_permit_joining_rsp cb = container->cb;
1204                 cb(ZB_ZDP_TIMEOUT, container->userdata);
1205         }
1206         break;
1207         case ZBL_ZDO_MGMT_LEAVE_REQ: {
1208                 zb_zdo_mgmt_leave_rsp cb = container->cb;
1209                 cb(ZB_ZDP_TIMEOUT, container->userdata);
1210         }
1211         break;
1212         case ZBL_ZDO_NODE_DESC_REQ: {
1213                 zb_zdo_node_desc_rsp cb = container->cb;
1214                 cb(ZB_ZDP_TIMEOUT, 0, NULL, container->userdata);
1215         }
1216         break;
1217         case ZBL_ZDO_POWER_DESC_REQ: {
1218                 zb_zdo_power_desc_rsp cb = container->cb;
1219                 cb(0, 0, NULL, container->userdata);
1220         }
1221         break;
1222         case ZBL_ZDO_USER_DESC_REQ: {
1223                 zb_zdo_user_desc_rsp cb = container->cb;
1224                 cb(ZB_ZDP_TIMEOUT, 0, 0, NULL, container->userdata);
1225         }
1226         case ZBL_ZDO_USER_DESC_SET_REQ: {
1227                 zb_zdo_user_desc_conf cb = container->cb;
1228                 cb(ZB_ZDP_TIMEOUT, container->userdata);
1229         }
1230         break;
1231         /* ZDP Bind */
1232         case ZBL_ZDO_BIND_REQ: {
1233                 zb_zdo_bind_rsp cb = container->cb;
1234                 cb(ZB_ZDP_TIMEOUT, container->userdata);
1235         }
1236         break;
1237         case ZBL_ZDO_UNBIND_REQ: {
1238                 zb_zdo_unbind_rsp cb = container->cb;
1239                 cb(ZB_ZDP_TIMEOUT, container->userdata);
1240         }
1241         break;
1242         /* Custom */
1243         case ZBL_CUSTOM_APS_SEND_REQ: {
1244                 zb_aps_send_rsp cb = container->cb;
1245                 cb(0, 0, 0, 0, 0, 0, NULL, container->userdata);
1246         } break;
1247         case ZBL_CUSTOM_ZCL_SEND_REQ: {
1248                 zb_zcl_send_rsp cb = container->cb;
1249                 cb(0, 0, 0, 0, 0, 0, NULL, container->userdata);
1250         }
1251         break;
1252         case ZBL_CUSTOM_LOCAL_SEND_REQ: {
1253                 zb_send_to_local_rsp cb = container->cb;
1254                 cb(0, NULL, container->userdata);
1255         }
1256         break;
1257         /* ZCL Global */
1258         case ZBL_ZCL_GLOBAL_READ_ATTRIBUTE_REQ: {
1259                 zb_zcl_global_rsp cb = container->cb;
1260                 cb(0, 0, 0, NULL, 0, container->userdata);
1261         }
1262         break;
1263         case ZBL_ZCL_GLOBAL_WRITE_ATTRIBUTE_REQ: {
1264                 zb_zcl_global_rsp cb = container->cb;
1265                 cb(0, 0, 0, NULL, 0, container->userdata);
1266         }
1267         break;
1268         case ZBL_ZCL_GLOBAL_CONFIGURE_REPORTING_REQ: {
1269                 zb_zcl_global_rsp cb = container->cb;
1270                 cb(0, 0, 0, NULL, 0, container->userdata);
1271         }
1272         break;
1273         case ZBL_ZCL_GLOBAL_DISCOVER_ATTRIBUTE_REQ: {
1274                 zb_zcl_global_discover_attr_rsp cb = container->cb;
1275                 cb(0, 0, 0, 0, NULL, 0, container->userdata);
1276         }
1277         break;
1278         case ZBL_ZCL_GLOBAL_WRITE_ATTRIBUTE_STRUCTURED_REQ: {
1279                 zb_zcl_global_rsp cb = container->cb;
1280                 cb(0, 0, 0, NULL, 0, container->userdata);
1281         }
1282         break;
1283         case ZBL_ZCL_GLOBAL_DISCOVER_COMMAND_RECEIVED_REQ: {
1284                 zb_zcl_global_discover_cmds_rsp cb = container->cb;
1285                 cb(0, 0, 0, 0, NULL, 0, container->userdata);
1286         }
1287         break;
1288         case ZBL_ZCL_GLOBAL_DISCOVER_COMMAND_GENERATED_REQ: {
1289                 zb_zcl_global_discover_cmds_rsp cb = container->cb;
1290                 cb(0, 0, 0, 0, NULL, 0, container->userdata);
1291         }
1292         break;
1293         case ZBL_ZCL_GLOBAL_DISCOVER_ATTRIBUTE_EXTENDED_REQ: {
1294                 zb_zcl_global_discover_attr_extended_rsp cb = container->cb;
1295                 cb(0, 0, 0, 0, NULL, 0, container->userdata);
1296         }
1297         break;
1298         case ZBL_ZCL_GLOBAL_READ_CONFIGURE_REPORTING_REQ: {
1299                 zb_zcl_global_rsp cb = container->cb;
1300                 cb(0, 0, 0, NULL, 0, container->userdata);
1301         }
1302         break;
1303         /* ZCL Alarm */
1304         case ZBL_ZCL_ALARM_GET_ALARM_REQ: {
1305                 zb_zcl_alarm_get_alarm_rsp cb = container->cb;
1306                 cb(ZB_ZCL_TIMEOUT, 0, ZB_ZCL_UNSUP_CLUSTER_COMMAND, 0, 0, 0, container->userdata);
1307         }
1308         break;
1309         /* ZCL Doorlock */
1310         case ZBL_ZCL_DOORLOCK_LOCK_STATE: {
1311                 zb_form_network_cb cb = container->cb;
1312                 cb(0x0000, container->userdata);
1313         }
1314         break;
1315         /* ZCL Fanmode */
1316         case ZBL_ZCL_FANMODE_FAN_MODE_STATE: {
1317                 zb_form_network_cb cb = container->cb;
1318                 cb(0x0000, container->userdata);
1319         }
1320         break;
1321         /* ZCL Group */
1322         case ZBL_ZCL_GROUP_ADD_GROUP_REQ: {
1323                 zb_zcl_group_add_group_rsp cb = container->cb;
1324                 cb(0, 0, 0, 0, container->userdata);
1325         }
1326         break;
1327         case ZBL_ZCL_GROUP_VIEW_GROUP_REQ: {
1328                 zb_zcl_group_view_group_rsp cb = container->cb;
1329                 cb(0, 0, 0, 0, NULL, container->userdata);
1330         }
1331         break;
1332         case ZBL_ZCL_GROUP_GET_GROUP_MEMBERSHIP_REQ: {
1333                 zb_zcl_group_get_group_membership_rsp cb = container->cb;
1334                 cb(0, 0, 0, 0, NULL, container->userdata);
1335         }
1336         break;
1337         case ZBL_ZCL_GROUP_REMOVE_GROUP_REQ: {
1338                 zb_zcl_group_remove_group_rsp cb = container->cb;
1339                 cb(0, 0, 0, 0, container->userdata);
1340         }
1341         break;
1342         /* ZCL Identify */
1343         case ZBL_ZCL_IDENTIFY_QUERY_REQ: {
1344                 zb_zcl_identify_query_cb cb = container->cb;
1345                 cb(0, 0, container->userdata);
1346         }
1347         break;
1348         /* ZCL On/Off */
1349         case ZBL_ZCL_ON_OFF_GET_ON_OFF_STATE: {
1350                 zb_form_network_cb cb = container->cb;
1351                 cb(0x0000, container->userdata);
1352         }
1353         break;
1354         /* ZCL Pollcontrol */
1355         case ZBL_ZCL_POLLCONTROL_SET_POLL_INTERVAL_REQ: {
1356                 zb_zcl_pollctrl_check_in cb = container->cb;
1357                 cb(0, 0, container->userdata);
1358         }
1359         break;
1360         /* ZCL Scene */
1361         case ZBL_ZCL_SCENE_ADD_SCENE_REQ: {
1362                 zb_zcl_scene_add_scene_rsp cb = container->cb;
1363                 cb(0, 0, 0, 0, 0, container->userdata);
1364         }
1365         break;
1366         case ZBL_ZCL_SCENE_VIEW_SCENE_REQ: {
1367                 zb_zcl_scene_view_scene_rsp cb = container->cb;
1368                 cb(0, 0, 0, 0, 0, 0, NULL, NULL, 0, container->userdata);
1369         }
1370         break;
1371         case ZBL_ZCL_SCENE_REMOVE_SCENE_REQ: {
1372                 zb_zcl_scene_remove_scene_rsp cb = container->cb;
1373                 cb(0, 0, 0, 0, 0, container->userdata);
1374         }
1375         break;
1376         case ZBL_ZCL_SCENE_STORE_SCENE_REQ: {
1377                 zb_zcl_scene_store_scene_rsp cb = container->cb;
1378                 cb(0, 0, 0, 0, 0, container->userdata);
1379         }
1380         break;
1381         case ZBL_ZCL_SCENE_REMOVE_ALL_SCENE_REQ: {
1382                 zb_zcl_scene_remove_all_scene_rsp cb = container->cb;
1383                 cb(0, 0, 0, 0, container->userdata);
1384         }
1385         break;
1386         case ZBL_ZCL_SCENE_GET_SCENE_MEMBERSHIP_REQ: {
1387                 zb_zcl_scene_get_scene_membership_rsp cb = container->cb;
1388                 cb(0, 0, 0, 0, 0, 0, NULL, container->userdata);
1389         }
1390         break;
1391         /* ZCL Thermostat */
1392         case ZBL_ZCL_THERMOSTAT_GET_LOCAL_TEMP: {
1393                 zb_form_network_cb cb = container->cb;
1394                 cb(0x0000, container->userdata);
1395         }
1396         break;
1397         default:
1398                 ERR("Unhandled cid = %d", container->cid);
1399         }
1400
1401         container->tid = 0;
1402         g_dbus_connection_signal_unsubscribe(gdbus_conn, container->sid);
1403         container->sid = 0;
1404
1405         return G_SOURCE_REMOVE;
1406 }
1407
1408 static void _zbl_response_cb(GDBusConnection *connection,
1409                 const gchar *sender_name, const gchar *object_path, const gchar *interface_name,
1410                 const gchar *signal_name, GVariant *parameters, gpointer user_data)
1411 {
1412         zbl_req_cb_s *container = user_data;
1413         RETM_IF(NULL == container, "container is null");
1414         RETM_IF(NULL == container->cb, "cb is NULL");
1415
1416         container->found = true;
1417         g_dbus_connection_signal_unsubscribe(gdbus_conn, container->sid);
1418
1419         switch (container->cid) {
1420                 /* Service */
1421         case ZBL_SERVICE_FORM_NETWORK: {
1422                 zb_form_network_cb cb = container->cb;
1423                 nwk_addr panid;
1424                 g_variant_get(parameters, "(q)", &panid);
1425                 cb(panid, container->userdata);
1426         }
1427         break;
1428         case ZBL_SERVICE_DISABLE_NETWORK: {
1429                 zb_disable_network_cb cb = container->cb;
1430                 unsigned char ret = ZB_ZDP_SUCCESS;
1431                 g_variant_get(parameters, "(y)", &ret);
1432                 cb(ret, container->userdata);
1433         }
1434         break;
1435         /* ZDP except Bind */
1436         case ZBL_ZDO_NWK_ADDR_REQ: {
1437                 zb_zdo_addr_rsp cb = container->cb;
1438
1439                 int j = 0;
1440                 nwk_addr addr16;
1441                 ieee_addr addr64;
1442                 unsigned char status;
1443                 unsigned char num;
1444                 unsigned char start_idx;
1445                 unsigned char value;
1446                 GVariantIter *mac_iter = NULL;
1447
1448                 g_variant_get(parameters, "(ya(y)qyy)", &status, &mac_iter, &addr16, &num, &start_idx);
1449                 while (g_variant_iter_loop(mac_iter, "(y)", &value)) {
1450                         addr64[j] = value;
1451                         j++;
1452                 }
1453
1454                 cb(status, addr64, addr16, num, start_idx, NULL, container->userdata);
1455                 if (NULL != mac_iter)
1456                         g_variant_iter_free(mac_iter);
1457         }
1458         break;
1459         case ZBL_ZDO_NWK_ADDR_EXT_REQ: {
1460                 zb_zdo_addr_rsp cb = container->cb;
1461
1462                 int j = 0;
1463                 nwk_addr addr16;
1464                 ieee_addr addr64;
1465                 unsigned char status;
1466                 unsigned char num;
1467                 unsigned char start_idx;
1468                 unsigned char value;
1469                 GVariantIter *mac_iter = NULL;
1470                 GVariantIter *assoc_iter = NULL;
1471
1472                 g_variant_get(parameters, "(ya(y)qyyaq)", &status, &mac_iter,
1473                         &addr16, &num, &start_idx, &assoc_iter);
1474                 while (g_variant_iter_loop(mac_iter, "(y)", &value)) {
1475                         addr64[j] = value;
1476                         j++;
1477                 }
1478                 if (NULL != mac_iter)
1479                         g_variant_iter_free(mac_iter);
1480                 if (NULL != assoc_iter)
1481                         g_variant_iter_free(assoc_iter);
1482
1483                 cb(status, addr64, addr16, num, start_idx, NULL, container->userdata);
1484         }
1485         break;
1486         case ZBL_ZDO_ACTIVE_EP_REQ: {
1487                 zb_zdo_active_ep_rsp cb = container->cb;
1488
1489                 int j = 0;
1490                 nwk_addr addr16;
1491                 unsigned char status;
1492                 unsigned char count;
1493                 unsigned char value;
1494                 GVariantIter *ep_iter = NULL;
1495                 unsigned char *ep_list;
1496
1497                 g_variant_get(parameters, "(yqa(y)y)", &status, &addr16, &ep_iter, &count);
1498                 ep_list = calloc(count+1, sizeof(unsigned char));
1499                 RETM_IF(NULL == ep_list, "calloc() Fail(%d)", errno);
1500
1501                 while (g_variant_iter_loop(ep_iter, "(y)", &value)) {
1502                         ep_list[j] = value;
1503                         j++;
1504                 }
1505                 if (NULL != ep_iter)
1506                         g_variant_iter_free(ep_iter);
1507
1508                 cb(status, addr16, count, ep_list, container->userdata);
1509                 free(ep_list);
1510         }
1511         break;
1512         case ZBL_ZDO_SIMPLE_DESC_REQ: {
1513                 zb_zdo_simple_desc_rsp cb = container->cb;
1514
1515                 int j = 0;
1516                 int count;
1517                 unsigned short addr16;
1518                 unsigned short value;
1519                 GVariantIter *in_iter = NULL;
1520                 GVariantIter *out_iter = NULL;
1521                 zb_zdo_simple_desc_h records;
1522
1523                 records = calloc(1, sizeof(struct zb_zdo_simple_desc_s));
1524                 RETM_IF(NULL == records, "calloc() Fail(%d)", errno);
1525
1526                 container->found = true;
1527
1528                 g_variant_get(parameters, "(qiyyqqyyaqaq)", &addr16, &count,
1529                                 &records->device_ver,
1530                                 &records->ep, &records->profile_id, &records->device_id,
1531                                 &records->num_of_in_clusters, &records->num_of_out_clusters,
1532                                 &in_iter, &out_iter);
1533 #if 0
1534                 records->in_clusters = calloc(records->num_of_in_clusters, sizeof(unsigned short));
1535                 if (NULL == records->in_clusters) {
1536                         ERR("calloc() Fail(%d)", errno);
1537                         if (NULL != in_iter)
1538                                 g_variant_iter_free(in_iter);
1539                         if (NULL != out_iter)
1540                                 g_variant_iter_free(out_iter);
1541                         return;
1542                 }
1543                 records->out_clusters = calloc(records->num_of_out_clusters, sizeof(unsigned short));
1544                 if (NULL == records->out_clusters) {
1545                         ERR("calloc() Fail(%d)", errno);
1546                         free(records->in_clusters);
1547                         if (NULL != in_iter)
1548                                 g_variant_iter_free(in_iter);
1549                         if (NULL != out_iter)
1550                                 g_variant_iter_free(out_iter);
1551                         return;
1552                 }
1553 #endif
1554                 while (g_variant_iter_loop(in_iter, "q", &value)) {
1555                         records->in_clusters[j] = value;
1556                         j++;
1557                 }
1558                 if (NULL != in_iter)
1559                         g_variant_iter_free(in_iter);
1560
1561                 j = 0;
1562                 while (g_variant_iter_loop(out_iter, "q", &value)) {
1563                         records->out_clusters[j] = value;
1564                         j++;
1565                 }
1566                 if (NULL != out_iter)
1567                         g_variant_iter_free(out_iter);
1568
1569                 DBG("addr16=0x%x, count=%d, records->ep=%d, records->device_id=0x%x",
1570                         addr16, count, records->ep, records->device_id);
1571                 for (j = 0; j < records->num_of_in_clusters; j++)
1572                         DBG("in_clusters[%d] = 0x%x", j, records->in_clusters[j]);
1573                 for (j = 0; j < records->num_of_out_clusters; j++)
1574                         DBG("out_clusters[%d] = 0x%x", j, records->out_clusters[j]);
1575
1576                 cb(addr16, count, records, container->userdata);
1577 #if 0
1578                 free(records->in_clusters);
1579                 free(records->out_clusters);
1580 #endif
1581                 free(records);
1582         }
1583         break;
1584         case ZBL_ZDO_MATCHED_DESCRIPTOR_REQ: {
1585                 zb_zdo_match_desc_rsp cb = container->cb;
1586
1587                 int j = 0;
1588                 int match_len;
1589                 nwk_addr addr16;
1590                 unsigned char value;
1591                 unsigned char status;
1592                 GVariantIter *ml_iter = NULL;
1593                 unsigned char *match_list = NULL;
1594                 g_variant_get(parameters, "(yqya(y))", &status, &addr16, &value, &ml_iter);
1595                 match_len = value;
1596
1597                 if (match_len > 0) {
1598                         match_list = calloc(match_len+1, sizeof(unsigned char));
1599                         RETM_IF(NULL == match_list, "calloc() Fail(%d)", errno);
1600                         while (g_variant_iter_loop(ml_iter, "(y)", &value)) {
1601                                 match_list[j] = value;
1602                                 DBG("match_list[i]=%d", j, match_list[j]);
1603                                 j++;
1604                         }
1605                         if (NULL != ml_iter)
1606                                 g_variant_iter_free(ml_iter);
1607                 }
1608
1609                 DBG("Match count : [%d]", match_len);
1610                 DBG("Match list  : [%p]", match_list);
1611
1612                 cb(status, addr16, match_len, match_list, container->userdata);
1613
1614                 if (match_list)
1615                         free(match_list);
1616         }
1617         break;
1618         case ZBL_ZDO_NODE_DESC_REQ: {
1619                 zb_zdo_node_desc_rsp cb = container->cb;
1620
1621                 nwk_addr addr16;
1622                 unsigned char status;
1623                 zb_zdo_node_descriptor_h desc;
1624
1625                 desc = calloc(1, sizeof(struct zb_zdo_node_descriptor_s));
1626                 RETM_IF(NULL == desc, "calloc() Fail(%d)", errno);
1627
1628                 container->found = true;
1629
1630                 g_variant_get(parameters, "(yqyyyyyyqyqqqy)", &status, &addr16,
1631                         &desc->logical_type, &desc->complex_desciptor_available,
1632                         &desc->user_descriptor_available, &desc->aps_flags, &desc->frequency_band,
1633                         &desc->mac_capability_flags, &desc->manufacturer_code, &desc->maximum_buffer_size,
1634                         &desc->maximum_incoming_transfer_size, &desc->server_mask,
1635                         &desc->maximum_outgoing_transfer_size, &desc->descriptor_capability_field);
1636
1637                 cb(status, addr16, desc, container->userdata);
1638                 free(desc);
1639         }
1640         break;
1641         case ZBL_ZDO_POWER_DESC_REQ: {
1642                 zb_zdo_power_desc_rsp cb = container->cb;
1643
1644                 nwk_addr addr16;
1645                 unsigned char status;
1646                 zb_zdo_node_power_descriptor_h desc;
1647
1648                 desc = calloc(1, sizeof(struct zb_zdo_node_power_descriptor_s));
1649                 RETM_IF(NULL == desc, "calloc() Fail(%d)", errno);
1650
1651                 g_variant_get(parameters, "(yqyyyy)", &status, &addr16,
1652                                         &desc->current_power_mode, &desc->available_power_sources,
1653                                         &desc->current_power_source, &desc->current_power_source_level);
1654
1655                 cb(status, addr16, desc, container->userdata);
1656                 free(desc);
1657         }
1658         break;
1659         case ZBL_ZDO_COMPLEX_DESC_REQ: {
1660                 zb_zdo_complex_desc_rsp cb = container->cb;
1661
1662                 int length;
1663                 nwk_addr addr16;
1664                 unsigned char j = 0;
1665                 unsigned char value;
1666                 unsigned char status;
1667                 GVariantIter *comp_iter = NULL;
1668                 unsigned char *complex_desc = NULL;
1669
1670                 g_variant_get(parameters, "(yqya(y))", &status, &addr16, &length, &comp_iter);
1671                 if (length > 0) {
1672                         complex_desc = calloc(length, sizeof(char));
1673                         if (NULL == complex_desc) {
1674                                 if (NULL != comp_iter)
1675                                         g_variant_iter_free(comp_iter);
1676                                 ERR("calloc() Fail(%d)", errno);
1677                                 return;
1678                         }
1679
1680                         while (g_variant_iter_loop(comp_iter, "(y)", &value)) {
1681                                 complex_desc[j] = value;
1682                                 j++;
1683                         }
1684                         if (NULL != comp_iter)
1685                                 g_variant_iter_free(comp_iter);
1686                 }
1687
1688                 cb(status, addr16, length, complex_desc, container->userdata);
1689                 free(complex_desc);
1690         }
1691         break;
1692         case ZBL_ZDO_USER_DESC_REQ: {
1693                 zb_zdo_user_desc_rsp cb = container->cb;
1694
1695                 int length;
1696                 nwk_addr addr16;
1697                 unsigned char j = 0;
1698                 unsigned char value;
1699                 unsigned char status;
1700                 GVariantIter *comp_iter = NULL;
1701                 unsigned char *complex_desc = NULL;
1702
1703                 g_variant_get(parameters, "(yqya(y))", &status, &addr16, &length, &comp_iter);
1704                 if (length > 0) {
1705                         complex_desc = calloc(length, sizeof(char));
1706                         if (NULL == complex_desc) {
1707                                 if (NULL != comp_iter)
1708                                         g_variant_iter_free(comp_iter);
1709                                 ERR("calloc() Fail(%d)", errno);
1710                                 return;
1711                         }
1712                         while (g_variant_iter_loop(comp_iter, "(y)", &value)) {
1713                                 complex_desc[j] = value;
1714                                 j++;
1715                         }
1716                         if (NULL != comp_iter)
1717                                 g_variant_iter_free(comp_iter);
1718                 }
1719
1720                 cb(status, addr16, length, complex_desc, container->userdata);
1721                 free(complex_desc);
1722         }
1723         case ZBL_ZDO_USER_DESC_SET_REQ: {
1724                 zb_zdo_user_desc_conf cb = container->cb;
1725                 unsigned char status;
1726                 g_variant_get(parameters, "(y)", &status);
1727                 cb(status, container->userdata);
1728         }
1729         break;
1730         case ZBL_ZDO_MGMT_BIND_REQ: {
1731                 zb_zdo_mgmt_bind_rsp cb = container->cb;
1732
1733                 unsigned char status;
1734                 unsigned char value;
1735
1736                 int i = 0;
1737                 int j = 0;
1738                 unsigned char binding_table_enteries;
1739                 unsigned char binding_table_list_count;
1740                 unsigned char start_index;
1741                 unsigned short dst_addr16 = 0;
1742                 unsigned char dst_ep = 0;
1743
1744                 GVariantIter *mac_iter = NULL;
1745                 GVariantIter *rsp_iter = NULL;
1746                 GVariantIter *destep_iter = NULL;
1747                 zb_zdo_binding_table_h *records = NULL;
1748
1749                 g_variant_get(parameters, "(yyyya(ayyqyqayy))", &status,
1750                                 &binding_table_enteries, &start_index,
1751                                 &binding_table_list_count, &rsp_iter);
1752
1753                 if (binding_table_list_count > 0) {
1754                         records = calloc(binding_table_list_count, sizeof(zb_zdo_binding_table_h));
1755                         RETM_IF(NULL == records, "calloc() Fail(%d)", errno);
1756                         for (i = 0; i < binding_table_list_count; i++) {
1757                                 records[i] = calloc(binding_table_list_count, sizeof(struct zb_zdo_binding_table_s));
1758                                 if (NULL == records[i]) {
1759                                         if (NULL != mac_iter)
1760                                                 g_variant_iter_free(mac_iter);
1761                                         if (NULL != rsp_iter)
1762                                                 g_variant_iter_free(rsp_iter);
1763                                         if (NULL != destep_iter)
1764                                                 g_variant_iter_free(destep_iter);
1765                                         ERR("calloc() Fail(%d)", errno);
1766                                         goto MGMT_NWK_BIND_REQ_OUT;
1767                                 }
1768                         }
1769                 }
1770                 for (i = 0; i < binding_table_list_count; i++) {
1771                         g_variant_iter_loop(rsp_iter, "(ayyqyqayy)", &mac_iter,
1772                                 &records[i]->src_ep, &records[i]->cluster_id,
1773                                 &records[i]->dst_addr_mode, &dst_addr16,
1774                                 &destep_iter, &dst_ep);
1775                         for (j = 0; j < 8; j++) {
1776                                 g_variant_iter_loop(mac_iter, "y", &value);
1777                                 records[i]->src_addr64[j] = value;
1778                         }
1779                         if (NULL != mac_iter)
1780                                 g_variant_iter_free(mac_iter);
1781
1782                         if (0x03 == records[i]->dst_addr_mode) {
1783                                 for (j = 0; j < 8; j++) {
1784                                         g_variant_iter_loop(destep_iter, "y", &value);
1785                                         records[i]->dst_addr64[j] = value;
1786                                 }
1787                                 records[i]->dst_ep = dst_ep;
1788                                 DBG("Destination MAC Addr : %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
1789                                         records[i]->dst_addr64[7], records[i]->dst_addr64[6],
1790                                         records[i]->dst_addr64[5], records[i]->dst_addr64[4],
1791                                         records[i]->dst_addr64[3], records[i]->dst_addr64[2],
1792                                         records[i]->dst_addr64[1], records[i]->dst_addr64[0]);
1793
1794                         } else if (0x01 == records[i]->dst_addr_mode) {
1795                                 records[i]->dst_addr16 = dst_addr16;
1796                         }
1797                         if (NULL != destep_iter)
1798                                 g_variant_iter_free(destep_iter);
1799                 }
1800                 if (NULL != rsp_iter)
1801                         g_variant_iter_free(rsp_iter);
1802
1803                 cb(status, binding_table_enteries, start_index, binding_table_list_count,
1804                         records, container->userdata);
1805
1806 MGMT_NWK_BIND_REQ_OUT:
1807                 for (i = 0; i < binding_table_list_count; i++) {
1808                         if (records[i])
1809                                 free(records[i]);
1810                 }
1811                 free(records);
1812         }
1813         break;
1814         case ZBL_ZDO_MGMT_LQI_REQ: {
1815                 zb_zdo_mgmt_lqi_rsp cb = container->cb;
1816
1817                 int i = 0;
1818                 int j = 0;
1819                 unsigned char value;
1820                 unsigned char status;
1821                 unsigned char start_index;
1822                 unsigned char neighbor_table_enteries;
1823                 unsigned char neighbor_table_list_count;
1824
1825                 GVariantIter *resp_iter = NULL;
1826                 GVariantIter *mac_iter = NULL;
1827                 GVariantIter *mac_iter1 = NULL;
1828                 zb_zdo_neighbor_table_desc_h *records = NULL;
1829
1830                 g_variant_get(parameters, "(yyyya(ayayyqyyyyy))", &status, &neighbor_table_enteries,
1831                                 &start_index, &neighbor_table_list_count, &resp_iter);
1832
1833                 if (neighbor_table_list_count > 0) {
1834                         records = calloc(neighbor_table_list_count, sizeof(zb_zdo_neighbor_table_desc_h));
1835                         RETM_IF(NULL == records, "calloc() Fail(%d)", errno);
1836                         for (i = 0; i < neighbor_table_list_count; i++) {
1837                                 records[i] = calloc(1, sizeof(struct zb_zdo_neighbor_table_desc_s));
1838                                 if (NULL == records[i]) {
1839                                         ERR("calloc() Fail(%d)", errno);
1840                                         goto MGMT_LQI_REQ_OUT;
1841                                 }
1842                         }
1843                 }
1844                 for (i = 0; i < neighbor_table_list_count; i++) {
1845                         g_variant_iter_loop(resp_iter, "(ayayyqyyyyy)",
1846                                         &mac_iter, &mac_iter1,
1847                                         &records[i]->device_type, &records[i]->addr16,
1848                                         &records[i]->rx_on_when_idle, &records[i]->relationship,
1849                                         &records[i]->permit_joining, &records[i]->depth,
1850                                         &records[i]->lqi);
1851                         for (j = 0; j < 8; j++) {
1852                                 g_variant_iter_loop(mac_iter, "y", &value);
1853                                 records[i]->extended_pan_id[j] = value;
1854                                 g_variant_iter_loop(mac_iter1, "y", &value);
1855                                 records[i]->addr64[j] = value;
1856                         }
1857                         if (NULL != mac_iter)
1858                                 g_variant_iter_free(mac_iter);
1859                         if (NULL != mac_iter1)
1860                                 g_variant_iter_free(mac_iter1);
1861
1862                         DBG("ext PAN ID = %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
1863                         records[i]->extended_pan_id[0], records[i]->extended_pan_id[1],
1864                         records[i]->extended_pan_id[2], records[i]->extended_pan_id[3],
1865                         records[i]->extended_pan_id[4], records[i]->extended_pan_id[5],
1866                         records[i]->extended_pan_id[6], records[i]->extended_pan_id[7]);
1867
1868                         DBG("IEEE address = %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
1869                         records[i]->addr64[0], records[i]->addr64[1], records[i]->addr64[2], records[i]->addr64[3],
1870                         records[i]->addr64[4], records[i]->addr64[5], records[i]->addr64[6], records[i]->addr64[7]);
1871                 }
1872                 if (NULL != resp_iter)
1873                         g_variant_iter_free(resp_iter);
1874
1875                 cb(status, neighbor_table_enteries, start_index, neighbor_table_list_count,
1876                         records, container->userdata);
1877
1878 MGMT_LQI_REQ_OUT:
1879                 for (i = 0; i < neighbor_table_list_count; i++) {
1880                         if (records[i])
1881                                 free(records[i]);
1882                 }
1883                 free(records);
1884         }
1885         break;
1886         case ZBL_ZDO_MGMT_RTG_REQ: {
1887                 zb_zdo_mgmt_rtg_rsp cb = container->cb;
1888
1889                 int i;
1890                 unsigned char status;
1891                 unsigned char start_index;
1892                 unsigned char routing_table_enteries;
1893                 unsigned char routing_table_list_count;
1894
1895                 GVariantIter *rsp_iter = NULL;
1896                 zb_zdo_routing_table_h *records = NULL;
1897
1898                 g_variant_get(parameters, "(yyyya(qyyyyq))", &status, &routing_table_enteries,
1899                                 &start_index, &routing_table_list_count, &rsp_iter);
1900
1901                 if (routing_table_list_count > 0) {
1902                         records = calloc(routing_table_list_count, sizeof(zb_zdo_routing_table_h));
1903                         RETM_IF(NULL == records, "calloc() Fail(%d)", errno);
1904                         for (i = 0; i < routing_table_list_count; i++) {
1905                                 records[i] = calloc(1, sizeof(struct zb_zdo_routing_table_s));
1906                                 if (NULL == records[i]) {
1907                                         ERR("calloc() Fail(%d)", errno);
1908                                         goto MGMT_NWK_RTG_REQ_OUT;
1909                                 }
1910                         }
1911                 }
1912
1913                 for (i = 0; i < routing_table_list_count; i++) {
1914                         g_variant_iter_loop(rsp_iter, "(qyyyyq)", &records[i]->dst_addr,
1915                                 &records[i]->status, &records[i]->memory_constrained,
1916                                 &records[i]->route_record_required,
1917                                 &records[i]->many_to_one, &records[i]->next_hop_addr);
1918                 }
1919                 if (NULL != rsp_iter)
1920                         g_variant_iter_free(rsp_iter);
1921
1922                 cb(status, routing_table_enteries, start_index, routing_table_list_count,
1923                         records, container->userdata);
1924
1925 MGMT_NWK_RTG_REQ_OUT:
1926                 for (i = 0; i < routing_table_list_count; i++) {
1927                         if (records[i])
1928                                 free(records[i]);
1929                 }
1930                 free(records);
1931         }
1932         break;
1933         case ZBL_ZDO_MGMT_NWK_DISC_REQ: {
1934                 zb_zdo_mgmt_nwk_disc_rsp cb = container->cb;
1935                         int i = 0;
1936                 int j = 0;
1937                 unsigned char value;
1938                 unsigned char status = 0;
1939                 unsigned char nwk_count = 0;
1940                 unsigned char start_index = 0;
1941                 unsigned char nwk_list_count = 0;
1942
1943                 GVariantIter *mac_iter = NULL;
1944                 GVariantIter *resp_iter = NULL;
1945
1946                 DBG("_zbl_mgmt_nwk_disc_req_cb()");
1947
1948                 g_variant_get(parameters, "(yyyya(ayyyyyyy))", &status, &nwk_count,
1949                         &start_index, &nwk_list_count, &resp_iter);
1950
1951                 zb_zdo_network_list_record_h *records = NULL;
1952
1953                 if (!status) {
1954                         if (nwk_list_count > 0) {
1955                                 records = calloc(nwk_list_count, sizeof(zb_zdo_network_list_record_h));
1956                                 RETM_IF(NULL == records, "calloc() Fail(%d)", errno);
1957                                 for (i = 0; i < nwk_list_count; i++) {
1958                                         records[i] = calloc(1, sizeof(struct zb_zdo_network_list_record_s));
1959                                         if (NULL == records[i]) {
1960                                                 ERR("calloc() Fail(%d)", errno);
1961                                                 goto MGMT_NWK_DISC_REQ_OUT;
1962                                         }
1963                                 }
1964                         }
1965                         for (i = 0; i < nwk_list_count; i++) {
1966                                 g_variant_iter_loop(resp_iter, "(ayyyyyyy)", &mac_iter, &records[i]->logical_channel,
1967                                         &records[i]->stack_profile, &records[i]->zigbee_version, &records[i]->beacon_order,
1968                                         &records[i]->superframe_order, &records[i]->permit_joining);
1969                                 for (j = 0; j < 8; j++) {
1970                                         g_variant_iter_loop(mac_iter, "y", &value);
1971                                         records[i]->extended_pan_id[j] = value;
1972                                 }
1973                                 if (NULL != mac_iter)
1974                                         g_variant_iter_free(mac_iter);
1975                         }
1976                         if (NULL != resp_iter)
1977                                 g_variant_iter_free(resp_iter);
1978                 }
1979
1980                 cb(status, nwk_count, start_index, nwk_list_count, records, container->userdata);
1981
1982 MGMT_NWK_DISC_REQ_OUT:
1983                 for (i = 0; i < nwk_list_count; i++) {
1984                         if (records[i])
1985                                 free(records[i]);
1986                 }
1987                 free(records);
1988         }
1989         break;
1990         case ZBL_ZDO_MGMT_PERMIT_JOIN_REQ: {
1991                 zb_zdo_mgmt_permit_joining_rsp cb = container->cb;
1992                 unsigned char status;
1993                 g_variant_get(parameters, "(y)", &status);
1994                 cb(status, container->userdata);
1995         }
1996         break;
1997         case ZBL_ZDO_MGMT_LEAVE_REQ: {
1998                 zb_zdo_mgmt_leave_rsp cb = container->cb;
1999                 unsigned char status;
2000                 g_variant_get(parameters, "(y)", &status);
2001                 cb(status, container->userdata);
2002         }
2003         break;
2004         /* ZDP Bind */
2005         case ZBL_ZDO_BIND_REQ: {
2006                 zb_zdo_bind_rsp cb = container->cb;
2007                 unsigned char status;
2008                 g_variant_get(parameters, "(y)", &status);
2009                 cb(status, container->userdata);
2010         }
2011         break;
2012         case ZBL_ZDO_UNBIND_REQ: {
2013                 zb_zdo_unbind_rsp cb = container->cb;
2014                 unsigned char status;
2015                 g_variant_get(parameters, "(y)", &status);
2016                 cb(status, container->userdata);
2017         }
2018         break;
2019         /* Custom */
2020         case ZBL_CUSTOM_APS_SEND_REQ: {
2021                 zb_aps_send_rsp cb = container->cb;
2022
2023                 unsigned short addr16;
2024                 unsigned char src_ep;
2025                 unsigned char dst_ep;
2026                 unsigned short cluster_id;
2027                 unsigned short profile_id;
2028                 unsigned short payload_len = 0;
2029                 unsigned char *payload = NULL;
2030
2031                 unsigned char value;
2032                 GVariantIter *payload_iter = NULL;
2033                 int i = 0;
2034
2035                 g_variant_get(parameters, "(qyyqqqa(y))", &addr16, &src_ep, &dst_ep,
2036                                 &cluster_id, &profile_id, &payload_len, &payload_iter);
2037
2038                 if (payload_len > 0) {
2039                         payload = calloc(payload_len+1, sizeof(unsigned char));
2040                         while (g_variant_iter_loop(payload_iter, "(y)", &value))
2041                                 payload[i++] = value;
2042
2043                         if (NULL != payload_iter)
2044                                 g_variant_iter_free(payload_iter);
2045                 }
2046
2047                 cb(addr16, src_ep, dst_ep, cluster_id, profile_id, payload_len, payload,
2048                         container->userdata);
2049
2050                 free(payload);
2051         }
2052         break;
2053         case ZBL_CUSTOM_ZCL_SEND_REQ: {
2054                 zb_zcl_send_rsp cb = container->cb;
2055
2056                 unsigned short addr16;
2057                 unsigned char src_ep;
2058                 unsigned char dst_ep;
2059                 unsigned short cluster_id;
2060                 unsigned short profile_id;
2061                 unsigned short payload_len = 0;
2062                 unsigned char *payload = NULL;
2063
2064                 unsigned char value;
2065                 GVariantIter *payload_iter = NULL;
2066                 int i = 0;
2067
2068                 g_variant_get(parameters, "(qyyqqqa(y))", &addr16, &src_ep, &dst_ep,
2069                                 &cluster_id, &profile_id, &payload_len, &payload_iter);
2070
2071                 if (payload_len > 0) {
2072                         payload = calloc(payload_len + 1, sizeof(unsigned char));
2073                         while (g_variant_iter_loop(payload_iter, "(y)", &value))
2074                                 payload[i++] = value;
2075
2076                         if (NULL != payload_iter)
2077                                 g_variant_iter_free(payload_iter);
2078                 }
2079
2080                 cb(addr16, src_ep, dst_ep, cluster_id, profile_id, payload_len, payload,
2081                         container->userdata);
2082
2083                 free(payload);
2084         }
2085         break;
2086         case ZBL_CUSTOM_LOCAL_SEND_REQ: {
2087                 zb_send_to_local_rsp cb = container->cb;
2088
2089                 unsigned char *data = NULL;
2090                 unsigned short length = 0;
2091                 unsigned char value;
2092                 GVariantIter *payload_iter = NULL;
2093                 int i = 0;
2094
2095                 g_variant_get(parameters, "(qa(y))", &length, &payload_iter);
2096
2097                 if (length > 0) {
2098                         data = calloc(length, sizeof(unsigned char));
2099                         while (g_variant_iter_loop(payload_iter, "(y)", &value))
2100                                 data[i++] = value;
2101
2102                         if (NULL != payload_iter)
2103                                 g_variant_iter_free(payload_iter);
2104                 }
2105
2106                 cb(length, data, container->userdata);
2107
2108                 free(data);
2109         }
2110         break;
2111         /* ZCL Global */
2112         case ZBL_ZCL_GLOBAL_READ_ATTRIBUTE_REQ: {
2113                 zb_zcl_global_rsp cb = container->cb;
2114
2115                 int j = 0;
2116                 int isString;
2117                 unsigned char value;
2118
2119                 nwk_addr addr16;
2120                 unsigned char ep;
2121                 unsigned short attr_id;
2122                 unsigned short cluster_id;
2123                 unsigned char status;
2124                 unsigned char type;
2125                 unsigned short records_len;
2126                 unsigned char attr_value[128];
2127
2128                 GVariantIter *iter = NULL;
2129                 read_attr_status_record_h records;
2130                 zb_global_record_data_s *data;
2131
2132                 data = calloc(1, sizeof(zb_global_record_data_s));
2133                 records = calloc(1, sizeof(struct read_attribute_status_record_s));
2134                 if (!records || !data) {
2135                         ERR("calloc() Fail(%d)", errno);
2136                         goto GLOBAL_READ_ATTRIBUTE_REQ_OUT;
2137                 }
2138
2139                 g_variant_get(parameters, "(qya(y)qqyyqi)",
2140                         &addr16, &ep, &iter, &attr_id, &cluster_id, &status, &type, &records_len, &isString);
2141                 if (!isString) {
2142                         while (g_variant_iter_loop(iter, "(y)", &value)) {
2143                                 attr_value[j] = value;
2144                                 DBG("attr_value[%d] = 0x%02X", j, value);
2145                                 j++;
2146                         }
2147                         if (NULL != iter)
2148                                 g_variant_iter_free(iter);
2149                 } else {
2150                         while (g_variant_iter_loop(iter, "(y)", &value)) {
2151                                 if (j == 0)
2152                                         records_len = value;
2153                                 attr_value[j] = value;
2154                                 DBG("attr_value[%d] = 0x%02X", j, value);
2155                                 j++;
2156                         }
2157                         if (NULL != iter)
2158                                 g_variant_iter_free(iter);
2159                 }
2160
2161                 records->id = attr_id;
2162                 records->status = status;
2163                 records->type = type;
2164                 records->value = attr_value;
2165                 data->type = ZB_GLOBAL_READ_ATTR;
2166                 data->record.read_attr = &records;
2167                 data->records_len = records_len;
2168
2169                 cb(addr16, ep, cluster_id, data, records_len, container->userdata);
2170
2171 GLOBAL_READ_ATTRIBUTE_REQ_OUT:
2172                 if (records)
2173                         free(records);
2174                 if (data)
2175                         free(data);
2176         }
2177         break;
2178         case ZBL_ZCL_GLOBAL_WRITE_ATTRIBUTE_REQ: {
2179                 zb_zcl_global_rsp cb = container->cb;
2180
2181                 int i = 0;
2182                 nwk_addr addr16;
2183                 unsigned char ep;
2184                 unsigned short cluster_id;
2185                 unsigned short attribute_id;
2186                 int records_len;
2187                 unsigned char value;
2188
2189                 GVariantIter *stat_iter = NULL;
2190                 GVariantIter *attr_iter = NULL;
2191                 write_attr_status_record_h records;
2192                 zb_global_record_data_s *data;
2193
2194                 g_variant_get(parameters, "(qya(y)aqqi)",
2195                         &addr16, &ep, &stat_iter, &attr_iter, &cluster_id, &records_len);
2196
2197                 records = calloc(records_len, sizeof(struct write_attribute_status_record_s));
2198                 data = calloc(1, sizeof(zb_global_record_data_s));
2199                 if (!records || !data) {
2200                         if (NULL != stat_iter)
2201                                 g_variant_iter_free(stat_iter);
2202                         if (NULL != attr_iter)
2203                                 g_variant_iter_free(attr_iter);
2204                         ERR("calloc() Fail(%d)", errno);
2205                         goto GLOBAL_WRITE_ATTRIBUTE_REQ_OUT;
2206                 }
2207
2208                 while (g_variant_iter_loop(stat_iter, "(y)", &value)) {
2209                         records[i].status = value;
2210                         i++;
2211                 }
2212                 if (NULL != stat_iter)
2213                         g_variant_iter_free(stat_iter);
2214
2215                 i = 0;
2216                 while (g_variant_iter_loop(attr_iter, "q", &attribute_id)) {
2217                         records[i].id = attribute_id;
2218                         DBG("Attribute Id 0x%04X", attribute_id);
2219                         i++;
2220                 }
2221                 if (NULL != attr_iter)
2222                         g_variant_iter_free(attr_iter);
2223
2224                 data->type = ZB_GLOBAL_WRITE_ATTR;
2225                 data->record.write_attr = &records;
2226                 data->records_len = records_len;
2227
2228                 cb(addr16, ep, cluster_id, data, records_len, container->userdata);
2229
2230 GLOBAL_WRITE_ATTRIBUTE_REQ_OUT:
2231                 free(records);
2232                 free(data);
2233         }
2234         break;
2235         case ZBL_ZCL_GLOBAL_CONFIGURE_REPORTING_REQ: {
2236                 zb_zcl_global_rsp cb = container->cb;
2237                 nwk_addr addr16;
2238                 unsigned char ep;
2239                 unsigned short cluster_id;
2240                 unsigned short attIdVal;
2241                 unsigned char value;
2242                 int j = 0, l = 0, k = 0, rec_len;
2243                 GVariantIter *stat_iter = NULL;
2244                 GVariantIter *attr_iter = NULL;
2245                 GVariantIter *dir_iter = NULL;
2246                 report_config_response_record_h records;
2247                 zb_global_record_data_s *data;
2248
2249                 g_variant_get(parameters, "(a(y)aqa(y)qiqy)",
2250                         &stat_iter, &attr_iter, &dir_iter, &cluster_id, &rec_len, &addr16, &ep);
2251
2252                 records = calloc(rec_len, sizeof(struct reporting_configuration_response_record_s));
2253                 data = calloc(1, sizeof(zb_global_record_data_s));
2254                 if (!data || !records) {
2255                         if (NULL != stat_iter)
2256                                 g_variant_iter_free(stat_iter);
2257                         if (NULL != attr_iter)
2258                                 g_variant_iter_free(attr_iter);
2259                         if (NULL != dir_iter)
2260                                 g_variant_iter_free(dir_iter);
2261                         ERR("calloc() Fail(%d)", errno);
2262                         goto GLOBAL_CONFIGURE_REPORTING_REQ_OUT;
2263                 }
2264
2265                 while (g_variant_iter_loop(stat_iter, "(y)", &value)) {
2266                         DBG("Value 0x%02X", value);
2267                         records[j].status = value;
2268                         j++;
2269                 }
2270                 if (NULL != stat_iter)
2271                         g_variant_iter_free(stat_iter);
2272
2273                 while (g_variant_iter_loop(attr_iter, "q", &attIdVal)) {
2274                         if (records[l].status != ZB_ZCL_SUCCESS)
2275                                 records[l].id = attIdVal;
2276                         l++;
2277                 }
2278                 if (NULL != attr_iter)
2279                         g_variant_iter_free(attr_iter);
2280
2281                 while (g_variant_iter_loop(dir_iter, "(y)", &value)) {
2282                         if (records[k].status != ZB_ZCL_SUCCESS)
2283                                 records[k].dir = value;
2284                         k++;
2285                 }
2286                 if (NULL != dir_iter)
2287                         g_variant_iter_free(dir_iter);
2288
2289                 data->type = ZB_GLOBAL_CONFIG_REPORT;
2290                 data->record.report_config_rsp = &records;
2291                 data->records_len = rec_len;
2292
2293                 cb(addr16, ep, cluster_id, data, rec_len, container->userdata);
2294
2295 GLOBAL_CONFIGURE_REPORTING_REQ_OUT:
2296                 free(records);
2297                 free(data);
2298         }
2299         break;
2300         case ZBL_ZCL_GLOBAL_DISCOVER_ATTRIBUTE_REQ: {
2301                 zb_zcl_global_discover_attr_rsp cb = container->cb;
2302                 nwk_addr addr16;
2303                 unsigned char ep;
2304                 discover_attr_info_record_h *records;
2305
2306                 int records_len;
2307                 unsigned short cluster_id;
2308                 unsigned short attribute_id;
2309                 unsigned char value;
2310                 int j = 0, l = 0;
2311                 int discovery_complete;
2312                 GVariantIter *stat_iter = NULL;
2313                 GVariantIter *attr_iter = NULL;
2314
2315                 g_variant_get(parameters, "(qya(y)aqqii)",  &addr16, &ep, &stat_iter,
2316                                                 &attr_iter, &cluster_id, &records_len, &discovery_complete);
2317                 records = calloc(records_len, sizeof(discover_attr_info_record_h));
2318                 RETM_IF(NULL == records, "calloc() Fail(%d)", errno);
2319                 for (j = 0; j < records_len; j++) {
2320                         records[j] = calloc(1, sizeof(struct discover_attribute_info_record_s));
2321                         if (NULL == records[j]) {
2322                                 ERR("calloc() Fail(%d)", errno);
2323                                 for (l = 0; l < j; l++)
2324                                         free(records[l]);
2325                                 free(records);
2326                                 if (NULL != stat_iter)
2327                                         g_variant_iter_free(stat_iter);
2328                                 if (NULL != attr_iter)
2329                                         g_variant_iter_free(attr_iter);
2330                                 return;
2331                         }
2332                 }
2333
2334                 j = 0;
2335                 while (g_variant_iter_loop(stat_iter, "(y)", &value)) {
2336                         records[j]->type = value;
2337                         DBG("Attribute Type 0x%02X", value);
2338                         j++;
2339                 }
2340                 if (NULL != stat_iter)
2341                         g_variant_iter_free(stat_iter);
2342
2343                 while (g_variant_iter_loop(attr_iter, "q", &attribute_id)) {
2344                         records[l]->id = attribute_id;
2345                         DBG("Attribute Id 0x%04X", attribute_id);
2346                         l++;
2347                 }
2348                 if (NULL != attr_iter)
2349                         g_variant_iter_free(attr_iter);
2350
2351                 cb(addr16, ep, cluster_id, discovery_complete, records, records_len,
2352                         container->userdata);
2353
2354                 for (j = 0; j < records_len; j++)
2355                         free(records[j]);
2356                 free(records);
2357         }
2358         break;
2359         case ZBL_ZCL_GLOBAL_WRITE_ATTRIBUTE_STRUCTURED_REQ: {
2360                 zb_zcl_global_rsp cb = container->cb;
2361                 cb(0, 0, 0, NULL, 0, container->userdata);
2362         }
2363         break;
2364         case ZBL_ZCL_GLOBAL_DISCOVER_COMMAND_RECEIVED_REQ: {
2365                 zb_zcl_global_discover_cmds_rsp cb = container->cb;
2366
2367                 nwk_addr addr16;
2368                 unsigned char ep;
2369
2370                 int j = 0;
2371                 char value;
2372                 unsigned short cluster_id;
2373                 unsigned short cmd_len;
2374                 unsigned char *cmd_data;
2375                 unsigned char discoveryComplete;
2376                 GVariantIter *cmd_iter = NULL;
2377
2378                 g_variant_get(parameters, "(a(y)qqqyy)",  &cmd_iter, &cluster_id, &cmd_len,
2379                         &addr16, &ep, &discoveryComplete);
2380
2381                 cmd_data = calloc(cmd_len+1, sizeof(char));
2382                 if (NULL == cmd_data) {
2383                         ERR("calloc() Fail(%d)", errno);
2384                         if (NULL != cmd_iter)
2385                                 g_variant_iter_free(cmd_iter);
2386                         return;
2387                 }
2388
2389                 while (g_variant_iter_loop(cmd_iter, "(y)", &value)) {
2390                         DBG("Value 0x%02X", value);
2391                         cmd_data[j] = value;
2392                         j++;
2393                 }
2394                 if (NULL != cmd_iter)
2395                         g_variant_iter_free(cmd_iter);
2396
2397                 cb(addr16, ep, cluster_id, discoveryComplete, cmd_data, cmd_len, container->userdata);
2398                 free(cmd_data);
2399         }
2400         break;
2401         case ZBL_ZCL_GLOBAL_DISCOVER_COMMAND_GENERATED_REQ: {
2402                 zb_zcl_global_discover_cmds_rsp cb = container->cb;
2403                 cb(0, 0, 0, 0, NULL, 0, container->userdata);
2404         }
2405         break;
2406         case ZBL_ZCL_GLOBAL_DISCOVER_ATTRIBUTE_EXTENDED_REQ: {
2407                 zb_zcl_global_discover_attr_extended_rsp cb = container->cb;
2408                 nwk_addr addr16;
2409                 unsigned char ep;
2410
2411                 int i = 0;
2412                 int j = 0;
2413                 unsigned short cluster_id;
2414                 unsigned char t_value;
2415                 unsigned char ac_value;
2416
2417                 unsigned short rec_len;
2418                 unsigned short attr_data;
2419                 unsigned char discoveryComplete;
2420                 GVariantIter *attr_iter = NULL;
2421                 GVariantIter *type_iter = NULL;
2422                 GVariantIter *ac_iter = NULL;
2423                 extended_attr_info_h *records;
2424
2425                 DBG("Will get the value now");
2426
2427                 g_variant_get(parameters, "(aqa(y)a(y)qqqyy)", &attr_iter, &type_iter, &ac_iter,
2428                         &cluster_id, &rec_len, &addr16, &ep, &discoveryComplete);
2429
2430                 DBG("records length 0x%04X", rec_len);
2431
2432                 records = calloc(rec_len, sizeof(extended_attr_info_h));
2433                 RETM_IF(NULL == records, "calloc() Fail(%d)", errno);
2434                 for (j = 0; j < rec_len; j++) {
2435                         records[j] = calloc(1, sizeof(struct extended_attribute_infomation_s));
2436                         if (NULL == records[j]) {
2437                                 for (i = 0; i < j; i++)
2438                                         free(records[i]);
2439                                 free(records);
2440                                 if (NULL != attr_iter)
2441                                         g_variant_iter_free(attr_iter);
2442                                 if (NULL != type_iter)
2443                                         g_variant_iter_free(type_iter);
2444                                 if (NULL != ac_iter)
2445                                         g_variant_iter_free(ac_iter);
2446
2447                                 ERR("calloc() Fail(%d)", errno);
2448                                 return;
2449                         }
2450                 }
2451
2452                 j = 0;
2453                 while (g_variant_iter_loop(attr_iter, "q", &attr_data)
2454                                 && g_variant_iter_loop(type_iter, "(y)", &t_value)
2455                                 && g_variant_iter_loop(ac_iter, "(y)", &ac_value)) {
2456                         DBG("attrData 0x%04X", attr_data);
2457                         DBG("t_value 0x%02X", t_value);
2458                         DBG("ac_value 0x%02X", ac_value);
2459                         records[j]->id = attr_data;
2460                         records[j]->type = t_value;
2461                         records[j]->acl = ac_value;
2462                         j++;
2463                 }
2464                 if (NULL != attr_iter)
2465                         g_variant_iter_free(attr_iter);
2466                 if (NULL != type_iter)
2467                         g_variant_iter_free(type_iter);
2468                 if (NULL != ac_iter)
2469                         g_variant_iter_free(ac_iter);
2470
2471                 cb(addr16, ep, cluster_id, discoveryComplete, records, rec_len, container->userdata);
2472
2473                 for (j = 0; j < rec_len; j++)
2474                         free(records[j]);
2475                 free(records);
2476         }
2477         break;
2478         case ZBL_ZCL_GLOBAL_READ_CONFIGURE_REPORTING_REQ: {
2479                 zb_zcl_global_rsp cb = container->cb;
2480                 nwk_addr addr16;
2481                 unsigned char ep;
2482                 unsigned short cluster_id;
2483
2484                 int i = 0;
2485                 int j = 0;
2486                 char value;
2487                 unsigned char *status = NULL;
2488                 unsigned char *data_size = NULL;
2489                 unsigned char *change = NULL;
2490                 unsigned short record_length;
2491                 GVariantIter *resp_iter = NULL;
2492                 GVariantIter *data_iter = NULL;
2493
2494                 report_config_record_h *records = NULL;
2495                 zb_global_record_data_s *data = NULL;
2496
2497                 g_variant_get(parameters, "(qyqqa(yyqyqqayq))",
2498                         &addr16, &ep, &cluster_id, &record_length, &resp_iter);
2499
2500                 records = calloc(record_length, sizeof(report_config_record_h));
2501                 for (i = 0; i < record_length; i++) {
2502                         records[i] = calloc(1, sizeof(struct reporting_configuration_record_s));
2503                         if (NULL == records[i]) {
2504                                 ERR("calloc() Fail(%d)", errno);
2505                                 goto GLOBAL_READ_CONFIGURE_REPORTING_REQ_OUT;
2506                         }
2507                 }
2508                 data = calloc(1, sizeof(zb_global_record_data_s));
2509                 if (!data || !records) {
2510                         ERR("calloc() Fail(%d)", errno);
2511                         goto GLOBAL_READ_CONFIGURE_REPORTING_REQ_OUT;
2512                 }
2513
2514                 DBG("record_length %d", record_length);
2515                 status = calloc(record_length, sizeof(unsigned char));
2516                 data_size = calloc(record_length, sizeof(unsigned char));
2517                 if (!status || !data_size) {
2518                         ERR("Couldn't allocate the memory (%s)", errno);
2519                         goto GLOBAL_READ_CONFIGURE_REPORTING_REQ_OUT;
2520                 }
2521
2522                 for (i = 0; i < record_length; i++) {
2523                         g_variant_iter_loop(resp_iter, "(yyqyqqayq)", &status[i], &records[i]->dir,
2524                                 &records[i]->id, &records[i]->type, &records[i]->max_i, &records[i]->min_i,
2525                                 &data_iter, &records[i]->to);
2526                         if (records[i]->dir != ZCL_REPORTING_DIRECTION_REPORTED &&
2527                                 (zb_get_analog_or_discret(records[i]->type) == DATA_TYPE_ANALOG)) {
2528                                 data_size[i] = zb_get_data_size(records[j]->type);
2529                                 j = 0;
2530                                 if (data_size[i] != 0xff) {
2531                                         change = calloc(data_size[i]+1, sizeof(unsigned char));
2532                                         if (!change) {
2533                                                 ERR("calloc() Fail(%d)", errno);
2534                                                 records[i]->change = NULL;
2535                                                 if (NULL != data_iter)
2536                                                         g_variant_iter_free(data_iter);
2537                                                 continue;
2538                                         }
2539                                         while (g_variant_iter_loop(data_iter, "y", &value)) {
2540                                                 change[j] = value;
2541                                                 j++;
2542                                         }
2543                                         if (NULL != data_iter)
2544                                                 g_variant_iter_free(data_iter);
2545                                         records[i]->change = change;
2546                                 } else
2547                                         records[i]->change = NULL;
2548                         } else
2549                                 records[i]->change = NULL;
2550                 }
2551                 if (NULL != resp_iter)
2552                         g_variant_iter_free(resp_iter);
2553
2554                 data->type = ZB_GLOBAL_READ_REPORT_CONFIG;
2555                 data->record.report_config = records;
2556                 data->records_len = record_length;
2557
2558                 cb(addr16, ep, cluster_id, data, record_length, container->userdata);
2559
2560 GLOBAL_READ_CONFIGURE_REPORTING_REQ_OUT:
2561                 free(data_size);
2562                 free(status);
2563                 for (i = 0; i < record_length; i++)
2564                         free(records[i]);
2565                 free(records);
2566                 free(data);
2567         }
2568         break;
2569         /* ZCL Alarm */
2570         case ZBL_ZCL_ALARM_GET_ALARM_REQ: {
2571                 zb_zcl_alarm_get_alarm_rsp cb = container->cb;
2572
2573                 nwk_addr addr16 = 0;
2574                 unsigned char ep = 0;
2575                 unsigned char status = 0;
2576                 unsigned char alarm_code = 0;
2577                 unsigned short cluster_id = 0;
2578                 unsigned int time_stamp = 0;
2579
2580                 g_variant_get(parameters, "(qyyyqu)", &addr16, &ep, &status, &alarm_code,
2581                                         &cluster_id, &time_stamp);
2582                 cb(addr16, ep, status, alarm_code, cluster_id, time_stamp, container->userdata);
2583         }
2584         break;
2585         /* ZCL Doorlock */
2586         case ZBL_ZCL_DOORLOCK_LOCK_STATE: {
2587                 ERR("Unhandled cid = %d", container->cid);
2588         }
2589         break;
2590         /* ZCL Fanmode */
2591         case ZBL_ZCL_FANMODE_FAN_MODE_STATE: {
2592                 ERR("Unhandled cid = %d", container->cid);
2593         }
2594         break;
2595         /* ZCL Group */
2596         case ZBL_ZCL_GROUP_ADD_GROUP_REQ: {
2597                 zb_zcl_group_add_group_rsp cb = container->cb;
2598
2599                 nwk_addr addr16;
2600                 unsigned char ep;
2601                 unsigned char status;
2602                 unsigned short group_id;
2603
2604                 g_variant_get(parameters, "(qyyq)", &addr16, &ep, &status, &group_id);
2605                 cb(addr16, ep, status, group_id, container->userdata);
2606         }
2607         break;
2608         case ZBL_ZCL_GROUP_VIEW_GROUP_REQ: {
2609                 zb_zcl_group_view_group_rsp cb = container->cb;
2610
2611                 int j = 0;
2612                 nwk_addr addr16;
2613                 unsigned char ep;
2614                 unsigned char value;
2615                 unsigned char status;
2616                 unsigned short group_id;
2617                 char *group_name = NULL;
2618                 GVariantIter *grpNameiter = NULL;
2619
2620                 g_variant_get(parameters, "(qyyqay)", &addr16, &ep, &status, &group_id, &grpNameiter);
2621                 g_variant_iter_loop(grpNameiter, "y", &value);
2622                 /* first byte indicates the length of the string */
2623                 if ((value - '0') > 0) {
2624                         DBG("Value %d ", (value - '0'));
2625                         group_name = calloc((value - '0') + 1, sizeof(char));
2626                         if (NULL == group_name) {
2627                                 if (NULL != grpNameiter)
2628                                         g_variant_iter_free(grpNameiter);
2629                                 ERR("calloc() Fail(%d)", errno);
2630                                 goto GROUP_VIEW_GROUP_REQ_OUT;
2631                         }
2632                         group_name[j] = value;
2633                         j++;
2634                         while (g_variant_iter_loop(grpNameiter, "y", &value) && (j <= (value - '0'))) {
2635                                 group_name[j] = value;
2636                                 DBG("Name %c", group_name[j]);
2637                                 j++;
2638                         }
2639                         if (NULL != grpNameiter)
2640                                 g_variant_iter_free(grpNameiter);
2641                 } else {
2642                         group_name = calloc(1, sizeof(char));
2643                         if (NULL == group_name) {
2644                                 if (NULL != grpNameiter)
2645                                         g_variant_iter_free(grpNameiter);
2646                                 ERR("calloc() Fail(%d)", errno);
2647                                 goto GROUP_VIEW_GROUP_REQ_OUT;
2648                         }
2649                         group_name[j] = value;
2650                         j++;
2651                         group_name[j] = '\0';
2652                         j++;
2653                 }
2654
2655                 DBG("GroupName = %s", group_name);
2656                 cb(addr16, ep, status, group_id, group_name, container->userdata);
2657 GROUP_VIEW_GROUP_REQ_OUT:
2658                 free(group_name);
2659         }
2660         break;
2661         case ZBL_ZCL_GROUP_GET_GROUP_MEMBERSHIP_REQ: {
2662                 zb_zcl_group_get_group_membership_rsp cb = container->cb;
2663
2664                 int j = 0;
2665                 nwk_addr addr16;
2666                 unsigned char ep;
2667                 unsigned short gl_value;
2668                 unsigned char capacity;
2669                 unsigned char group_count;
2670                 unsigned short *grouplist = NULL;
2671                 GVariantIter *grpListiter = NULL;
2672
2673                 g_variant_get(parameters, "(qyyyaq)", &addr16, &ep, &capacity, &group_count, &grpListiter);
2674
2675                 if (group_count > 0) {
2676                         grouplist = calloc(group_count+1, sizeof(unsigned short));
2677                         if (NULL == grouplist) {
2678                                 if (NULL != grpListiter)
2679                                         g_variant_iter_free(grpListiter);
2680                                 ERR("calloc() Fail(%d)", errno);
2681                                 return;
2682                         }
2683                         RETM_IF(NULL == grouplist, "calloc() Fail(%d)", errno);
2684
2685                         while (g_variant_iter_loop(grpListiter, "q", &gl_value)) {
2686                                 grouplist[j] = gl_value;
2687                                 j++;
2688                         }
2689                         if (NULL != grpListiter)
2690                                 g_variant_iter_free(grpListiter);
2691                 }
2692
2693                 cb(addr16, ep, capacity, group_count, grouplist, container->userdata);
2694
2695                 free(grouplist);
2696         }
2697         break;
2698         case ZBL_ZCL_GROUP_REMOVE_GROUP_REQ: {
2699                 zb_zcl_group_remove_group_rsp cb = container->cb;
2700
2701                 nwk_addr addr16;
2702                 unsigned char ep;
2703                 unsigned char status;
2704                 unsigned short group_id;
2705
2706                 g_variant_get(parameters, "(qyyq)", &addr16, &ep, &status, &group_id);
2707
2708                 cb(addr16, ep, status, group_id, container->userdata);
2709         }
2710         break;
2711         /* ZCL Identify */
2712         case ZBL_ZCL_IDENTIFY_QUERY_REQ: {
2713                 zb_zcl_identify_query_cb cb = container->cb;
2714
2715                 nwk_addr addr16 = 0;
2716                 unsigned short identify_time = 0;
2717                 g_variant_get(parameters, "(qq)", &addr16, &identify_time);
2718
2719                 cb(addr16, identify_time, container->userdata);
2720         }
2721         break;
2722         /* ZCL On/Off */
2723         case ZBL_ZCL_ON_OFF_GET_ON_OFF_STATE: {
2724                 ERR("Unhandled cid = %d", container->cid);
2725         }
2726         break;
2727         /* ZCL Pollcontrol */
2728         case ZBL_ZCL_POLLCONTROL_SET_POLL_INTERVAL_REQ: {
2729                 zb_zcl_pollctrl_check_in cb = container->cb;
2730
2731                 nwk_addr addr16 = 0;
2732                 unsigned char ep = 0;
2733
2734                 g_variant_get(parameters, "(qy)", &addr16, &ep);
2735                 cb(addr16, ep, container->userdata);
2736         }
2737         break;
2738         /* ZCL Scene */
2739         case ZBL_ZCL_SCENE_ADD_SCENE_REQ: {
2740                 zb_zcl_scene_add_scene_rsp cb = container->cb;
2741
2742                 nwk_addr addr16 = 0;
2743                 unsigned char ep;
2744                 unsigned char status;
2745                 unsigned short group_id;
2746                 unsigned char scene_id;
2747
2748                 g_variant_get(parameters, "(qyyqy)", &addr16, &ep, &status,     &group_id, &scene_id);
2749                 cb(addr16, ep, status, group_id, scene_id, container->userdata);
2750         }
2751         break;
2752         case ZBL_ZCL_SCENE_VIEW_SCENE_REQ: {
2753                 zb_zcl_scene_view_scene_rsp cb = container->cb;
2754
2755                 int j = 0;
2756                 int len;
2757                 nwk_addr addr16 = 0;
2758                 unsigned char ep;
2759                 unsigned char status;
2760                 unsigned short group_id;
2761                 unsigned char scene_id;
2762                 unsigned short transition_time = 0;
2763                 unsigned char value;
2764                 unsigned short ext_len = 0;
2765                 char *scene_name = NULL;
2766                 char *extendedFieldSets = NULL;
2767                 GVariantIter *sceneNameIter = NULL;
2768                 GVariantIter *extendedSetIter = NULL;
2769
2770                 g_variant_get(parameters, "(qyyqyqa(y)ya(y))", &addr16, &ep, &status, &group_id, &scene_id,
2771                         &transition_time, &sceneNameIter, &ext_len, &extendedSetIter);
2772
2773                 g_variant_iter_loop(sceneNameIter, "(y)", &value);
2774
2775                 /** first byte indicates the length of the string */
2776                 len = value -'0';
2777                 if (0 < len) {
2778                         scene_name = calloc(len + 1, sizeof(char));
2779                         if (NULL == scene_name) {
2780                                 ERR("calloc() Fail(%d)", errno);
2781                                 goto SCENE_VIEW_SCENE_REQ_OUT;
2782                         }
2783                         scene_name[j] = value;
2784                         j++;
2785                         while (g_variant_iter_loop(sceneNameIter, "(y)", &value)) {
2786                                 scene_name[j] = value;
2787                                 j++;
2788                         }
2789                 } else {
2790                         scene_name = calloc(1 + 1, sizeof(char));
2791                         if (NULL == scene_name) {
2792                                 ERR("calloc() Fail(%d)", errno);
2793                                 goto SCENE_VIEW_SCENE_REQ_OUT;
2794                         }
2795                         scene_name[j] = value;
2796                 }
2797
2798                 j = 0;
2799                 if (0 < ext_len) {
2800                         extendedFieldSets = calloc(ext_len + 1, sizeof(char));
2801                         if (NULL == extendedFieldSets) {
2802                                 ERR("calloc() Fail(%d)", errno);
2803                                 goto SCENE_VIEW_SCENE_REQ_OUT;
2804                         }
2805                         while (g_variant_iter_loop(extendedSetIter, "(y)", &value)) {
2806                                 extendedFieldSets[j] = value;
2807                                 j++;
2808                         }
2809                 }
2810
2811                 cb(addr16, ep, status, group_id, scene_id, transition_time, scene_name,
2812                                 extendedFieldSets, ext_len, container->userdata);
2813
2814 SCENE_VIEW_SCENE_REQ_OUT:
2815                 free(scene_name);
2816                 free(extendedFieldSets);
2817         }
2818         break;
2819         case ZBL_ZCL_SCENE_REMOVE_SCENE_REQ: {
2820                 zb_zcl_scene_remove_scene_rsp cb = container->cb;
2821
2822                 nwk_addr addr16 = 0;
2823                 unsigned char ep;
2824                 unsigned char status;
2825                 unsigned short group_id;
2826                 unsigned char scene_id;
2827
2828                 g_variant_get(parameters, "(qyyqy)", &addr16, &ep, &status, &group_id, &scene_id);
2829                 cb(addr16, ep, status, group_id, scene_id, container->userdata);
2830         }
2831         break;
2832         case ZBL_ZCL_SCENE_STORE_SCENE_REQ: {
2833                 zb_zcl_scene_store_scene_rsp cb = container->cb;
2834
2835                 nwk_addr addr16 = 0;
2836                 unsigned char ep;
2837                 unsigned char status;
2838                 unsigned short group_id;
2839                 unsigned char scene_id;
2840
2841                 g_variant_get(parameters, "(qyyqy)", &addr16, &ep, &status, &group_id, &scene_id);
2842                 cb(addr16, ep, status, group_id, scene_id, container->userdata);
2843         }
2844         break;
2845         case ZBL_ZCL_SCENE_REMOVE_ALL_SCENE_REQ: {
2846                 zb_zcl_scene_remove_all_scene_rsp cb = container->cb;
2847
2848                 nwk_addr addr16 = 0;
2849                 unsigned char ep;
2850                 unsigned char status;
2851                 unsigned short group_id;
2852
2853                 g_variant_get(parameters, "(qyyq)", &addr16, &ep, &status, &group_id);
2854                 cb(addr16, ep, status, group_id, container->userdata);
2855         }
2856         break;
2857         case ZBL_ZCL_SCENE_GET_SCENE_MEMBERSHIP_REQ: {
2858                 zb_zcl_scene_get_scene_membership_rsp cb = container->cb;
2859
2860                 int j = 0;
2861                 nwk_addr addr16 = 0;
2862                 unsigned char ep;
2863                 unsigned char status;
2864                 unsigned short group_id;
2865                 unsigned char capacity;
2866                 unsigned char value;
2867                 unsigned char scene_count = 0;
2868                 unsigned char *scene_list = NULL;
2869                 GVariantIter *sceneListIter = NULL;
2870
2871                 g_variant_get(parameters, "(qyyyqya(y))", &addr16, &ep, &status, &capacity, &group_id,
2872                         &scene_count, &sceneListIter);
2873
2874                 if (0 < scene_count) {
2875                         scene_list = calloc(scene_count+1, sizeof(char));
2876                         if (NULL == scene_list) {
2877                                 ERR("calloc() Fail(%d)", errno);
2878                                 goto SCENE_GET_SCENE_MEMBERSHIP_REQ_OUT;
2879                         }
2880                         while (g_variant_iter_loop(sceneListIter, "(y)", &value)) {
2881                                 scene_list[j] = value;
2882                                 DBG("Scene_List 0x%02X", scene_list[j]);
2883                                 j++;
2884                         }
2885                 }
2886
2887                 cb(addr16, ep, status, capacity, group_id, scene_count, scene_list, container->userdata);
2888 SCENE_GET_SCENE_MEMBERSHIP_REQ_OUT:
2889                 free(scene_list);
2890         }
2891         break;
2892         /* ZCL Thermostat */
2893         case ZBL_ZCL_THERMOSTAT_GET_LOCAL_TEMP: {
2894                 ERR("Unhandled cid = %d", container->cid);
2895         }
2896         break;
2897         default:
2898                 ERR("Unhandled cid = %d", container->cid);
2899         }
2900 }
2901
2902
2903 int zbl_enable(zigbee_h handle, zb_event_cb event_handler)
2904 {
2905         char enabled;
2906         int result = ZIGBEE_ERROR_NONE;
2907         GVariant *variant = NULL;
2908         GError *dbus_err = NULL;
2909
2910         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
2911         RETV_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR);
2912         RETV_IF(NULL == handle, ZIGBEE_ERROR_INVALID_PARAMETER);
2913
2914         handle->event_handler = event_handler;
2915
2916         variant = g_dbus_proxy_call_sync(service_gproxy, "enable", NULL,
2917                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
2918
2919         if (!variant) {
2920                 ERR("Failed to get 'enable' [%s]", dbus_err->message);
2921                 g_error_free(dbus_err);
2922                 return ZIGBEE_ERROR_IO_ERROR;
2923         }
2924
2925         g_variant_get(variant, "(ib)", &result, &enabled);
2926         DBG("ret = [0x%x]", result);
2927         if (variant) {
2928                 g_variant_unref(variant);
2929         }
2930
2931         return result;
2932 }
2933
2934 int zbl_disable(void)
2935 {
2936         GVariant *variant = NULL;
2937         GError *dbus_err = NULL;
2938         int result = ZIGBEE_ERROR_NONE;
2939
2940         DBG("zbl_disable()");
2941
2942         if (0 >= zbl_ref_count) {
2943                 WARN("dbus does not initiaized\n");
2944                 return ZIGBEE_ERROR_NO_DATA;
2945         }
2946
2947         if (0 > --zbl_ref_count) {
2948                 DBG("all connections closed\n");
2949                 return ZIGBEE_ERROR_NONE;
2950         }
2951
2952         if (gdbus_conn) {
2953
2954                 if (service_gproxy) {
2955                         variant = g_dbus_proxy_call_sync(service_gproxy, "disable", NULL,
2956                                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
2957
2958                         if (!variant) {
2959                                 ERR("Failed to get 'disable' [%s]", dbus_err->message);
2960                                 g_error_free(dbus_err);
2961                         }
2962
2963                         g_variant_get(variant, "(i)", &result);
2964                         DBG("ret = [0x%x]", result);
2965                         g_variant_unref(variant);
2966
2967                         g_object_unref(service_gproxy);
2968                         service_gproxy = NULL;
2969                         g_object_unref(on_off_gproxy);
2970                         on_off_gproxy = NULL;
2971                         g_object_unref(door_lock_gproxy);
2972                         door_lock_gproxy = NULL;
2973                         g_object_unref(level_control_gproxy);
2974                         level_control_gproxy = NULL;
2975                         g_object_unref(thermostat_gproxy);
2976                         thermostat_gproxy = NULL;
2977                         g_object_unref(alarm_gproxy);
2978                         alarm_gproxy = NULL;
2979                         g_object_unref(fan_control_gproxy);
2980                         fan_control_gproxy = NULL;
2981
2982                         g_object_unref(mfglib_gproxy);
2983                         mfglib_gproxy = NULL;
2984                         g_object_unref(zcl_global_proxy);
2985                         zcl_global_proxy = NULL;
2986                         g_object_unref(zcl_color_control_proxy);
2987                         zcl_color_control_proxy = NULL;
2988                         g_object_unref(custom_gproxy);
2989                         custom_gproxy = NULL;
2990                 }
2991
2992                 g_object_unref(gdbus_conn);
2993                 gdbus_conn = NULL;
2994         }
2995
2996         return ZIGBEE_ERROR_NONE;
2997 }
2998
2999 int zbl_hw_reset(void)
3000 {
3001         int result = ZIGBEE_ERROR_NONE;
3002         GVariant *variant = NULL;
3003         GError *dbus_err = NULL;
3004
3005         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3006         RETV_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR);
3007
3008         variant = g_dbus_proxy_call_sync(service_gproxy, "zb_hw_reset", NULL,
3009                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
3010
3011         if (!variant) {
3012                 ERR("Failed to get 'zb_hw_reset' [%s]", dbus_err->message);
3013                 g_error_free(dbus_err);
3014                 return ZIGBEE_ERROR_IO_ERROR;
3015         }
3016
3017         g_variant_get(variant, "(i)", &result);
3018         DBG("ret = [0x%x]", result);
3019         g_variant_unref(variant);
3020
3021         return result;
3022 }
3023
3024 int zbl_get_network_info(ieee_addr addr64, nwk_addr *nodeid, nwk_addr *panid,
3025                 unsigned char *channel, unsigned char *tx_power)
3026 {
3027         GVariant *variant = NULL;
3028         GVariantIter *iter = NULL;
3029         GError *dbus_err = NULL;
3030         int result = ZIGBEE_ERROR_NONE;
3031
3032         nwk_addr _nodeid;
3033         nwk_addr _panid;
3034         unsigned char _radio_channel;
3035         unsigned char _radio_tx_power;
3036         unsigned char value;
3037         int i = 0;
3038
3039         DBG("zbl_get_network_info()");
3040         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3041         RETV_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR);
3042
3043         variant = g_dbus_proxy_call_sync(service_gproxy, "get_network_info",
3044                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
3045
3046         if (!variant) {
3047                 ERR("Failed to 'get_network_info' [%s]", dbus_err->message);
3048                 g_error_free(dbus_err);
3049                 return ZIGBEE_ERROR_IO_ERROR;
3050         }
3051
3052         g_variant_get(variant, "(ia(y)qqyy)", &result, &iter,
3053                                 &_nodeid, &_panid, &_radio_channel, &_radio_tx_power);
3054
3055         /* Get EUI */
3056         i = 0;
3057         while (g_variant_iter_loop(iter, "(y)", &value)) {
3058                 addr64[i] = value;
3059                 i++;
3060         }
3061
3062         DBG("  Result: [%X]", result);
3063         DBG("  EUI(%d) : %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", i,
3064                         addr64[0], addr64[1], addr64[2], addr64[3],
3065                         addr64[4], addr64[5], addr64[6], addr64[7]);
3066         DBG("  nodeID [0x%04X]", _nodeid);
3067         DBG("  PanID [0x%04X]", _panid);
3068         DBG("  Channel [%d] Tx Power [%d]", _radio_channel, _radio_tx_power);
3069
3070         if (nodeid)
3071                 *nodeid = _nodeid;
3072         if (panid)
3073                 *panid = _panid;
3074         if (channel)
3075                 *channel = _radio_channel;
3076         if (tx_power)
3077                 *tx_power = _radio_tx_power;
3078
3079         if (iter)
3080                 g_variant_iter_free(iter);
3081         g_variant_unref(variant);
3082
3083         return result;
3084 }
3085
3086 int zbl_get_controller_mac_address(ieee_addr addr64)
3087 {
3088         GVariant *variant = NULL;
3089         GVariantIter *iter = NULL;
3090         GError *dbus_err = NULL;
3091
3092         char value;
3093         int j = 0;
3094         int result = ZIGBEE_ERROR_NONE;
3095
3096         DBG("zbl_get_controller_mac_address()");
3097         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3098         RETV_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR);
3099
3100         variant = g_dbus_proxy_call_sync(service_gproxy, "get_mac",
3101                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
3102
3103         if (!variant) {
3104                 ERR("Failed to get_mac [%s]", dbus_err->message);
3105                 g_error_free(dbus_err);
3106                 return ZIGBEE_ERROR_IO_ERROR;
3107         }
3108         g_variant_get(variant, "(ia(y))", &result, &iter);
3109
3110         while (g_variant_iter_loop(iter, "(y)", &value)) {
3111                 addr64[j] = value;
3112                 j++;
3113         }
3114
3115         DBG("IEEE ADDR 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:0x%02X, Ret=%d ",
3116                 addr64[0], addr64[1], addr64[2], addr64[3], addr64[4], addr64[5],
3117                 addr64[6], addr64[7], result);
3118
3119         if (iter)
3120                 g_variant_iter_free(iter);
3121         g_variant_unref(variant);
3122
3123         return result;
3124 }
3125
3126 int zbl_get_cluster_list(ieee_addr eui64, unsigned char endpoint, unsigned short list[],
3127                 unsigned char *count)
3128 {
3129         GVariant *variant = NULL;
3130         GVariantBuilder *mac_builder = NULL;
3131         GVariant *mac_variant = NULL;
3132         GVariantIter *iter = NULL;
3133         GError *dbus_err = NULL;
3134         unsigned short cluster;
3135         int i = 0;
3136         int result = 0;
3137
3138         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3139         RETV_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR);
3140
3141         mac_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
3142         g_variant_builder_add(mac_builder, "(y)", eui64[7]);
3143         g_variant_builder_add(mac_builder, "(y)", eui64[6]);
3144         g_variant_builder_add(mac_builder, "(y)", eui64[5]);
3145         g_variant_builder_add(mac_builder, "(y)", eui64[4]);
3146         g_variant_builder_add(mac_builder, "(y)", eui64[3]);
3147         g_variant_builder_add(mac_builder, "(y)", eui64[2]);
3148         g_variant_builder_add(mac_builder, "(y)", eui64[1]);
3149         g_variant_builder_add(mac_builder, "(y)", eui64[0]);
3150         mac_variant = g_variant_builder_end(mac_builder);
3151         g_variant_builder_unref(mac_builder);
3152
3153         variant = g_dbus_proxy_call_sync(service_gproxy, "get_cluster_list",
3154                                 g_variant_new("(@ayy)", mac_variant, endpoint), G_DBUS_CALL_FLAGS_NONE,
3155                                 -1, NULL, &dbus_err);
3156
3157         if (variant) {
3158                 g_variant_get(variant, "(iaq)", &result, &iter);
3159                 DBG("ret = [0x%x]", result);
3160
3161                 while (g_variant_iter_loop(iter, "q", &cluster)) {
3162                         DBG("Cluster 0x%04X", cluster);
3163                         list[i++] = cluster;
3164                 }
3165                 *count = i;
3166                 if (0 == i)
3167                         ERR("No Clusters for Endpoint %0X", endpoint);
3168
3169                 if (NULL != iter)
3170                         g_variant_iter_free(iter);
3171                 g_variant_unref(variant);
3172         } else {
3173                 ERR("No Clusters for Endpoint %0X [%s]", endpoint, dbus_err->message);
3174                 g_error_free(dbus_err);
3175                 *count = 0;
3176         }
3177
3178         return ZIGBEE_ERROR_NONE;
3179 }
3180
3181 int zbl_get_endpoint_list(ieee_addr eui64, unsigned char list[], unsigned char *count)
3182 {
3183         GVariant *variant = NULL;
3184         GVariantBuilder *mac_builder = NULL;
3185         GVariant *mac_variant = NULL;
3186         GVariantIter *iter = NULL;
3187         GError *dbus_err = NULL;
3188         unsigned char endpoint;
3189         int i = 0;
3190         int result = ZIGBEE_ERROR_NONE;
3191
3192         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3193         RETV_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR);
3194
3195         mac_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
3196         g_variant_builder_add(mac_builder, "(y)", eui64[7]);
3197         g_variant_builder_add(mac_builder, "(y)", eui64[6]);
3198         g_variant_builder_add(mac_builder, "(y)", eui64[5]);
3199         g_variant_builder_add(mac_builder, "(y)", eui64[4]);
3200         g_variant_builder_add(mac_builder, "(y)", eui64[3]);
3201         g_variant_builder_add(mac_builder, "(y)", eui64[2]);
3202         g_variant_builder_add(mac_builder, "(y)", eui64[1]);
3203         g_variant_builder_add(mac_builder, "(y)", eui64[0]);
3204         mac_variant = g_variant_builder_end(mac_builder);
3205         g_variant_builder_unref(mac_builder);
3206
3207         variant = g_dbus_proxy_call_sync(service_gproxy, "get_endpoint_list",
3208                 g_variant_new("(@a(y))", mac_variant),
3209                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
3210
3211         if (variant) {
3212                 g_variant_get(variant, "(ia(y))", &result, &iter);
3213                 DBG("ret = [0x%x]", result);
3214
3215                 while (g_variant_iter_loop(iter, "(y)", &endpoint)) {
3216                         DBG("Endpoint 0x%X", endpoint);
3217                         list[i++] = endpoint;
3218                 }
3219                 if (i > 0) {
3220                         *count = i;
3221                         DBG("Endpoint Count %d", i);
3222                 } else {
3223                         ERR("No Endpoints");
3224                         *count = 0;
3225                 }
3226                 if (NULL != iter)
3227                         g_variant_iter_free(iter);
3228                 g_variant_unref(variant);
3229
3230         } else {
3231                 ERR("NULL Variant");
3232                 ERR("No Endpoints");
3233                 ERR("[%s]", dbus_err->message);
3234                 g_error_free(dbus_err);
3235                 *count = 0;
3236         }
3237
3238         return ZIGBEE_ERROR_NONE;
3239 }
3240
3241 int zbl_api_get_node_type(ieee_addr eui64, unsigned char *node_type)
3242 {
3243         GVariant *variant = NULL;
3244         GVariantBuilder *mac_builder = NULL;
3245         int result = ZIGBEE_ERROR_NONE;
3246         GVariant *mac_variant = NULL;
3247         GError *dbus_err = NULL;
3248
3249         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3250         RETV_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR);
3251
3252         mac_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
3253         g_variant_builder_add(mac_builder, "(y)", eui64[7]);
3254         g_variant_builder_add(mac_builder, "(y)", eui64[6]);
3255         g_variant_builder_add(mac_builder, "(y)", eui64[5]);
3256         g_variant_builder_add(mac_builder, "(y)", eui64[4]);
3257         g_variant_builder_add(mac_builder, "(y)", eui64[3]);
3258         g_variant_builder_add(mac_builder, "(y)", eui64[2]);
3259         g_variant_builder_add(mac_builder, "(y)", eui64[1]);
3260         g_variant_builder_add(mac_builder, "(y)", eui64[0]);
3261         mac_variant = g_variant_builder_end(mac_builder);
3262         g_variant_builder_unref(mac_builder);
3263
3264         variant = g_dbus_proxy_call_sync(service_gproxy, "get_node_type",
3265                 g_variant_new("(@a(y))", mac_variant),
3266                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
3267
3268         if (!variant) {
3269                 ERR("Failed to get 'get_node_type' [%s]", dbus_err->message);
3270                 g_error_free(dbus_err);
3271                 return ZIGBEE_ERROR_IO_ERROR;
3272         }
3273
3274         g_variant_get(variant, "(i)", &result);
3275         DBG("ret = [0x%x]", result);
3276         g_variant_unref(variant);
3277
3278         return result;
3279 }
3280
3281 int zbl_get_all_device_info(zb_end_device_info_h **dev_list, unsigned char* num)
3282 {
3283         int i = 0;
3284         int j = 0;
3285         int k = 0;
3286         struct zb_end_device_info_s **list;
3287         GVariant *variant = NULL;
3288         GVariantIter *iter = NULL;
3289         GVariantIter *mac_iter = NULL;
3290         GVariantIter *endpoint_iter = NULL;
3291         GError *dbus_err = NULL;
3292         int result = 0;
3293         unsigned short node_id;
3294         unsigned char node_type;
3295         unsigned char node_mac_address[8] = {0x00};
3296         unsigned char endpoint_cnt = 0;
3297         unsigned char value;
3298         unsigned char value_endpoint;
3299
3300         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3301         RETV_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR);
3302
3303         /* check the format string when there are no input args */
3304         variant = g_dbus_proxy_call_sync(service_gproxy, "get_device_info",
3305                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
3306
3307         if (variant) {
3308                 g_variant_get(variant, "(ia(qyayyay))", &result, &iter);
3309                 DBG("ret = [0x%x]", result);
3310
3311                 list = calloc(MAX_DEVICE_LIST+1, sizeof(zb_end_device_info_h));
3312                 RETV_IF(NULL == list, ZIGBEE_ERROR_OUT_OF_MEMORY);
3313                 for (i = 0; i < MAX_DEVICE_LIST && list; i++) {
3314                         list[i] = calloc(1, sizeof(struct zb_end_device_info_s));
3315                         if (NULL == list[i]) {
3316                                 for (j = 0; j < i; j++)
3317                                         free(list[j]);
3318                                 free(list);
3319                                 g_variant_unref(variant);
3320                                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
3321                         }
3322                 }
3323
3324                 i = 0;
3325                 while (g_variant_iter_loop(iter, "(qyayyay)", &node_id, &node_type, &mac_iter,
3326                                 &endpoint_cnt, &endpoint_iter)) {
3327                         j = 0;
3328                         k = 0;
3329                         /* Get Network Address */
3330                         list[i]->addr16 = node_id;
3331                         DBG("Node ID: 0x%04X", node_id);
3332                         /* Get Node Type */
3333                         list[i]->node_type = node_type;
3334                         DBG("Node Type : 0x%02X", node_type);
3335                         /* Get End-Point count */
3336                         list[i]->num_of_ep = endpoint_cnt;
3337                         DBG("Endpoint Count: 0x%X", endpoint_cnt);
3338                         /* Get End-Point list */
3339                         list[i]->num_of_ep = endpoint_cnt;
3340                         while (g_variant_iter_loop(endpoint_iter, "y", &value_endpoint)) {
3341                                 list[i]->ep[k] = value_endpoint;
3342                                 DBG("Endpoint : %d", value_endpoint);
3343                                 k++;
3344                         }
3345                         /* Get IEEE address */
3346                         while (g_variant_iter_loop(mac_iter, "y", &value)) {
3347                                 node_mac_address[j] = value;
3348                                 j++;
3349                         }
3350                         memcpy(list[i]->addr64, node_mac_address, sizeof(ieee_addr));
3351                         DBG("Node MAC Addr : %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
3352                                 node_mac_address[0], node_mac_address[1], node_mac_address[2],
3353                                 node_mac_address[3], node_mac_address[4], node_mac_address[5],
3354                                 node_mac_address[6], node_mac_address[7]);
3355                         i++;
3356
3357                 }
3358                 if (0 == i)
3359                         ERR("No attached nodes");
3360
3361                 *num = i;
3362                 *dev_list = list;
3363                 if (NULL != iter)
3364                         g_variant_iter_free(iter);
3365                 g_variant_unref(variant);
3366         } else {
3367                 ERR("NULL Variant [%s]", dbus_err->message);
3368                 ERR("No attached nodes");
3369                 g_error_free(dbus_err);
3370                 *num = 0;
3371         }
3372
3373         return ZIGBEE_ERROR_NONE;
3374 }
3375
3376 int zbl_coex_start(unsigned char channel)
3377 {
3378         int result = ZIGBEE_ERROR_NONE;
3379         GVariant *variant = NULL;
3380         GError *dbus_err = NULL;
3381
3382         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3383         RETV_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR);
3384
3385         variant = g_dbus_proxy_call_sync(service_gproxy, "coex_start", g_variant_new("(y)", channel),
3386                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
3387
3388         if (!variant) {
3389                 ERR("Failed to get 'coex_start' [%s]", dbus_err->message);
3390                 g_error_free(dbus_err);
3391                 return ZIGBEE_ERROR_IO_ERROR;
3392         }
3393
3394         g_variant_get(variant, "(i)", &result);
3395         DBG("ret = [0x%x]", result);
3396         g_variant_unref(variant);
3397
3398         return result;
3399 }
3400
3401 int zbl_coex_stop(void)
3402 {
3403         int result = ZIGBEE_ERROR_NONE;
3404         GVariant *variant = NULL;
3405         GError *dbus_err = NULL;
3406
3407         DBG("zbl_coex_stop()");
3408
3409         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3410         RETV_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR);
3411
3412         variant = g_dbus_proxy_call_sync(service_gproxy, "coex_stop", NULL,
3413                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
3414
3415         if (!variant) {
3416                 ERR("Failed to get 'coex_stop' [%s]", dbus_err->message);
3417                 g_error_free(dbus_err);
3418                 return ZIGBEE_ERROR_IO_ERROR;
3419         }
3420
3421         g_variant_get(variant, "(i)", &result);
3422         DBG("ret = [0x%x]", result);
3423         g_variant_unref(variant);
3424
3425         return result;
3426 }
3427
3428 int zbl_form_network(zigbee_h handle, zb_form_network_cb cb, void *user_data)
3429 {
3430         int sub_id, to;
3431         zbl_req_cb_s *container;
3432
3433         int result = ZIGBEE_ERROR_NONE;
3434         GVariant *variant = NULL;
3435         GError *dbus_err = NULL;
3436
3437         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3438         RETV_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR);
3439
3440         container = calloc(1, sizeof(zbl_req_cb_s));
3441         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
3442
3443         to = zbl_dbus_get_timeout(service_gproxy);
3444         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
3445                         ZIGBEE_SERVICE_INTERFACE,  "form_network_done", ZIGBEE_SERVICE_OBJECT_PATH, NULL, 0,
3446                         _zbl_response_cb, container, _zbl_request_cleanup);
3447
3448         if (0 == sub_id) {
3449                 ERR("g_dbus_connection_signal_subscribe() Fail");
3450                 free(container);
3451                 return ZIGBEE_ERROR_IO_ERROR;
3452         }
3453
3454         container->cb = cb;
3455         container->sid = sub_id;
3456         container->cid = ZBL_SERVICE_FORM_NETWORK;
3457         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
3458         container->userdata = user_data;
3459
3460         variant = g_dbus_proxy_call_sync(service_gproxy, "form_network", NULL,
3461                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
3462
3463         if (!variant) {
3464                 ERR("Failed to get 'form_network' [%s]", dbus_err->message);
3465                 g_error_free(dbus_err);
3466                 return ZIGBEE_ERROR_IO_ERROR;
3467         }
3468
3469         g_variant_get(variant, "(i)", &result);
3470         DBG("ret = [0x%x]", result);
3471         g_variant_unref(variant);
3472
3473         return result;
3474 }
3475
3476 int zbl_disable_network(zigbee_h handle, zb_disable_network_cb cb, void *user_data)
3477 {
3478         int sub_id, to;
3479         zbl_req_cb_s *container;
3480
3481         int result = ZIGBEE_ERROR_NONE;
3482         GVariant *variant = NULL;
3483         GError *dbus_err = NULL;
3484
3485         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3486         RETV_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR);
3487
3488         DBG("zbl_disable_network()");
3489
3490         container = calloc(1, sizeof(zbl_req_cb_s));
3491         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
3492
3493         to = zbl_dbus_get_timeout(service_gproxy);
3494         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
3495                         ZIGBEE_SERVICE_INTERFACE,  "disable_network_done", ZIGBEE_SERVICE_OBJECT_PATH, NULL, 0,
3496                         _zbl_response_cb, container, _zbl_request_cleanup);
3497
3498         if (0 == sub_id) {
3499                 ERR("g_dbus_connection_signal_subscribe() Fail");
3500                 free(container);
3501                 return ZIGBEE_ERROR_IO_ERROR;
3502         }
3503
3504         container->cb = cb;
3505         container->sid = sub_id;
3506         container->cid = ZBL_SERVICE_DISABLE_NETWORK;
3507         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
3508         container->userdata = user_data;
3509
3510         variant = g_dbus_proxy_call_sync(service_gproxy, "leave_network", NULL,
3511                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
3512
3513         if (!variant) {
3514                 ERR("Failed to get 'leave_network' [%s]", dbus_err->message);
3515                 g_error_free(dbus_err);
3516                 return ZIGBEE_ERROR_IO_ERROR;
3517         }
3518
3519         g_variant_get(variant, "(i)", &result);
3520         DBG("ret = [0x%x]", result);
3521         g_variant_unref(variant);
3522
3523         return result;
3524 }
3525
3526 int zbl_leave_device(ieee_addr addr64, bool remove_children, bool rejoin)
3527 {
3528         int result = ZIGBEE_ERROR_NONE;
3529         GVariant *variant = NULL;
3530         GError *dbus_err = NULL;
3531
3532         GVariantBuilder *mac_builder = NULL;
3533         GVariant* mac_variant = NULL;
3534         unsigned char _remove_children = (remove_children) ? 1 : 0;
3535         unsigned char _rejoin = (rejoin) ? 1 : 0;
3536
3537         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3538         RETV_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR);
3539
3540         DBG("IEEE Address = %X:%X:%X:%X:%X:%X:%X:%X",
3541                 addr64[0], addr64[1], addr64[2], addr64[3],
3542                 addr64[4], addr64[5], addr64[6], addr64[7]);
3543
3544         mac_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
3545         g_variant_builder_add(mac_builder, "(y)", addr64[7]);
3546         g_variant_builder_add(mac_builder, "(y)", addr64[6]);
3547         g_variant_builder_add(mac_builder, "(y)", addr64[5]);
3548         g_variant_builder_add(mac_builder, "(y)", addr64[4]);
3549         g_variant_builder_add(mac_builder, "(y)", addr64[3]);
3550         g_variant_builder_add(mac_builder, "(y)", addr64[2]);
3551         g_variant_builder_add(mac_builder, "(y)", addr64[1]);
3552         g_variant_builder_add(mac_builder, "(y)", addr64[0]);
3553         mac_variant = g_variant_builder_end(mac_builder);
3554         g_variant_builder_unref(mac_builder);
3555
3556         variant = g_dbus_proxy_call_sync(service_gproxy, "leave_request",
3557                 g_variant_new("(@a(y)yy)", mac_variant, _remove_children, _rejoin),
3558                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
3559
3560         if (!variant) {
3561                 ERR("Failed to get 'leave_request' [%s]", dbus_err->message);
3562                 g_error_free(dbus_err);
3563                 return ZIGBEE_ERROR_IO_ERROR;
3564         }
3565
3566         g_variant_get(variant, "(i)", &result);
3567         DBG("ret = [0x%x]", result);
3568         g_variant_unref(variant);
3569
3570         return result;
3571 }
3572
3573 int zbl_permit_join(unsigned char duration, bool broadcast)
3574 {
3575         int result = ZIGBEE_ERROR_NONE;
3576         GVariant *variant = NULL;
3577         GError *dbus_err = NULL;
3578
3579         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3580         RETV_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR);
3581
3582         variant = g_dbus_proxy_call_sync(service_gproxy, "permit_join",
3583                 g_variant_new("(ib)", duration, broadcast),     G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
3584
3585         if (!variant) {
3586                 ERR("Failed to get 'permit_join' [%s]", dbus_err->message);
3587                 g_error_free(dbus_err);
3588                 return ZIGBEE_ERROR_IO_ERROR;
3589         }
3590
3591         g_variant_get(variant, "(i)", &result);
3592         DBG("ret = [0x%x]", result);
3593         g_variant_unref(variant);
3594
3595         return result;
3596 }
3597
3598 int zbl_nwk_addr_req(zigbee_h handle, ieee_addr addr64, unsigned char request_type,
3599         unsigned char start_idx, zb_zdo_addr_rsp cb, void *user_data)
3600 {
3601         int sub_id, to;
3602         zbl_req_cb_s *container;
3603         GVariantBuilder *mac_builder = NULL;
3604         GVariant* mac_variant = NULL;
3605
3606         int result = ZIGBEE_ERROR_NONE;
3607         GVariant *variant = NULL;
3608         GError *dbus_err = NULL;
3609
3610         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3611         RETV_IF(NULL == zdo_dev_proxy, ZIGBEE_ERROR_IO_ERROR);
3612
3613         DBG(" zbl_nwk_addr_req()");
3614
3615         container = calloc(1, sizeof(zbl_req_cb_s));
3616         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
3617
3618         to = zbl_dbus_get_timeout(zdo_dev_proxy);
3619         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
3620                         ZIGBEE_ZDO_DEV_CONTROL_INTERFACE,  "nwk_addr_rsp",
3621                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0, _zbl_response_cb, container,
3622                         _zbl_request_cleanup);
3623
3624         if (0 == sub_id) {
3625                 ERR("g_dbus_connection_signal_subscribe() Fail");
3626                 free(container);
3627                 return ZIGBEE_ERROR_IO_ERROR;
3628         }
3629
3630         container->cb = cb;
3631         container->sid = sub_id;
3632         container->cid = ZBL_ZDO_NWK_ADDR_REQ;
3633         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
3634         container->userdata = user_data;
3635
3636         mac_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
3637         g_variant_builder_add(mac_builder, "(y)", addr64[7]);
3638         g_variant_builder_add(mac_builder, "(y)", addr64[6]);
3639         g_variant_builder_add(mac_builder, "(y)", addr64[5]);
3640         g_variant_builder_add(mac_builder, "(y)", addr64[4]);
3641         g_variant_builder_add(mac_builder, "(y)", addr64[3]);
3642         g_variant_builder_add(mac_builder, "(y)", addr64[2]);
3643         g_variant_builder_add(mac_builder, "(y)", addr64[1]);
3644         g_variant_builder_add(mac_builder, "(y)", addr64[0]);
3645         mac_variant = g_variant_builder_end(mac_builder);
3646         g_variant_builder_unref(mac_builder);
3647
3648         variant = g_dbus_proxy_call_sync(zdo_dev_proxy, "nwk_addr_req",
3649                 g_variant_new("(@a(y)yy)", mac_variant, request_type, start_idx),
3650                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
3651
3652         if (!variant) {
3653                 ERR("Failed to get 'nwk_addr_req' [%s]", dbus_err->message);
3654                 g_error_free(dbus_err);
3655                 return ZIGBEE_ERROR_IO_ERROR;
3656         }
3657
3658         g_variant_get(variant, "(i)", &result);
3659         DBG("ret = [0x%x]", result);
3660         g_variant_unref(variant);
3661
3662         return result;
3663 }
3664
3665 int zbl_ieee_addr_req(zigbee_h handle, nwk_addr addr16, zb_zdo_addr_rsp cb,
3666                 void *user_data)
3667 {
3668         int sub_id, to;
3669         zbl_req_cb_s *container;
3670
3671         int result = ZIGBEE_ERROR_NONE;
3672         GVariant *variant = NULL;
3673         GError *dbus_err = NULL;
3674
3675         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3676         RETV_IF(NULL == zdo_dev_proxy, ZIGBEE_ERROR_IO_ERROR);
3677
3678         DBG("zbl_ieee_addr_req()");
3679
3680         container = calloc(1, sizeof(zbl_req_cb_s));
3681         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
3682
3683         to = zbl_dbus_get_timeout(zdo_dev_proxy);
3684         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
3685                         ZIGBEE_ZDO_DEV_CONTROL_INTERFACE,  "nwk_addr_rsp",
3686                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
3687                         _zbl_response_cb, container, _zbl_request_cleanup);
3688
3689         if (0 == sub_id) {
3690                 ERR("g_dbus_connection_signal_subscribe() Fail");
3691                 free(container);
3692                 return ZIGBEE_ERROR_IO_ERROR;
3693         }
3694
3695         container->cb = cb;
3696         container->sid = sub_id;
3697         container->cid = ZBL_ZDO_NWK_ADDR_REQ;
3698         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
3699         container->userdata = user_data;
3700
3701         variant = g_dbus_proxy_call_sync(zdo_dev_proxy, "ieee_addr_req", g_variant_new("(q)", addr16),
3702                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
3703
3704         if (!variant) {
3705                 ERR("Failed to get 'ieee_addr_req' [%s]", dbus_err->message);
3706                 g_error_free(dbus_err);
3707                 return ZIGBEE_ERROR_IO_ERROR;
3708         }
3709
3710         g_variant_get(variant, "(i)", &result);
3711         DBG("ret = [0x%x]", result);
3712         g_variant_unref(variant);
3713
3714         return result;
3715 }
3716
3717 int zbl_active_ep(zigbee_h handle, nwk_addr addr16, zb_zdo_active_ep_rsp cb,
3718                 void *user_data)
3719 {
3720         int sub_id, to;
3721         zbl_req_cb_s *container;
3722
3723         int result = ZIGBEE_ERROR_NONE;
3724         GVariant *variant = NULL;
3725         GError *dbus_err = NULL;
3726
3727         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3728         RETV_IF(NULL == zdo_dev_proxy, ZIGBEE_ERROR_IO_ERROR);
3729
3730         DBG("zbl_active_ep()");
3731
3732         container = calloc(1, sizeof(zbl_req_cb_s));
3733         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
3734
3735         to = zbl_dbus_get_timeout(zdo_dev_proxy);
3736         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
3737                         ZIGBEE_ZDO_DEV_CONTROL_INTERFACE,  "active_ep_rsp",
3738                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
3739                         _zbl_response_cb, container, _zbl_request_cleanup);
3740
3741         if (0 == sub_id) {
3742                 ERR("g_dbus_connection_signal_subscribe() Fail");
3743                 free(container);
3744                 return ZIGBEE_ERROR_IO_ERROR;
3745         }
3746
3747         container->cb = cb;
3748         container->sid = sub_id;
3749         container->cid = ZBL_ZDO_ACTIVE_EP_REQ;
3750         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
3751         container->userdata = user_data;
3752
3753         variant = g_dbus_proxy_call_sync(zdo_dev_proxy, "active_ep_req",
3754                 g_variant_new("(q)", addr16), G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
3755
3756         if (!variant) {
3757                 ERR("Failed to get 'active_ep_req' [%s]", dbus_err->message);
3758                 g_error_free(dbus_err);
3759                 return ZIGBEE_ERROR_IO_ERROR;
3760         }
3761
3762         g_variant_get(variant, "(i)", &result);
3763         DBG("ret = [0x%x]", result);
3764         g_variant_unref(variant);
3765
3766         return result;
3767 }
3768
3769 int zbl_simple_desc_req(zigbee_h handle, nwk_addr addr16, unsigned char ep,
3770                 zb_zdo_simple_desc_rsp cb, void *user_data)
3771 {
3772         int sub_id, to;
3773         zbl_req_cb_s *container;
3774
3775         int result = ZIGBEE_ERROR_NONE;
3776         GVariant *variant = NULL;
3777         GError *dbus_err = NULL;
3778
3779         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3780         RETV_IF(NULL == zdo_dev_proxy, ZIGBEE_ERROR_IO_ERROR);
3781
3782         DBG("zbl_simple_desc_req() : [%X]", addr16);
3783
3784         container = calloc(1, sizeof(zbl_req_cb_s));
3785         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
3786
3787         to = zbl_dbus_get_timeout(zdo_dev_proxy);
3788         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
3789                         ZIGBEE_ZDO_DEV_CONTROL_INTERFACE,  "simple_desc_rsp",
3790                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
3791                         _zbl_response_cb, container, _zbl_request_cleanup);
3792
3793         if (0 == sub_id) {
3794                 ERR("g_dbus_connection_signal_subscribe() Fail");
3795                 free(container);
3796                 return ZIGBEE_ERROR_IO_ERROR;
3797         }
3798
3799         container->cb = cb;
3800         container->sid = sub_id;
3801         container->cid = ZBL_ZDO_SIMPLE_DESC_REQ;
3802         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
3803         container->userdata = user_data;
3804
3805         variant = g_dbus_proxy_call_sync(zdo_dev_proxy, "simple_desc_req",
3806                 g_variant_new("(qy)", addr16, ep), G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
3807
3808         if (!variant) {
3809                 ERR("Failed to get 'simple_desc_req' [%s]", dbus_err->message);
3810                 g_error_free(dbus_err);
3811                 return ZIGBEE_ERROR_IO_ERROR;
3812         }
3813
3814         g_variant_get(variant, "(i)", &result);
3815         DBG("ret = [0x%x]", result);
3816         g_variant_unref(variant);
3817
3818         return result;
3819 }
3820
3821 #ifdef ZB_SUPPORT_PRIORITY_5
3822 int zbl_extended_simple_desc_req(zigbee_h handle, nwk_addr addr16,
3823                 unsigned char start_idx, zb_zdo_extended_simple_desc_rsp cb, void *user_data)
3824 {
3825         return ZIGBEE_ERROR_NOT_SUPPORTED;
3826 }
3827 #endif /* ZB_SUPPORT_PRIORITY_5 */
3828
3829 int zbl_match_desc_req(zigbee_h handle, nwk_addr addr16,
3830                 unsigned short profile_id, unsigned char num_in_clusters,
3831                 unsigned short *in_clusters, unsigned char num_out_clusters,
3832                 unsigned short *out_clusters, zb_zdo_match_desc_rsp cb, void *user_data)
3833 {
3834         int sub_id, to;
3835         zbl_req_cb_s *container;
3836
3837         int result = ZIGBEE_ERROR_NONE;
3838         GVariant *variant = NULL;
3839         GError *dbus_err = NULL;
3840
3841         int i;
3842         GVariantBuilder *incl_builder = NULL;
3843         GVariant* incl_variant = NULL;
3844         GVariantBuilder *outcl_builder = NULL;
3845         GVariant* outcl_variant = NULL;
3846
3847         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3848         RETV_IF(NULL == zdo_dev_proxy, ZIGBEE_ERROR_IO_ERROR);
3849
3850         DBG("zbl_match_desc_req()");
3851
3852         container = calloc(1, sizeof(zbl_req_cb_s));
3853         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
3854
3855         to = zbl_dbus_get_timeout(zdo_dev_proxy);
3856         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
3857                         ZIGBEE_ZDO_DEV_CONTROL_INTERFACE,  "matched_descriptor_rsp",
3858                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
3859                         _zbl_response_cb, container, _zbl_request_cleanup);
3860
3861         if (0 == sub_id) {
3862                 ERR("g_dbus_connection_signal_subscribe() Fail");
3863                 free(container);
3864                 return ZIGBEE_ERROR_IO_ERROR;
3865         }
3866
3867         container->cb = cb;
3868         container->sid = sub_id;
3869         container->cid = ZBL_ZDO_MATCHED_DESCRIPTOR_REQ;
3870         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
3871         container->userdata = user_data;
3872
3873         incl_builder = g_variant_builder_new(G_VARIANT_TYPE("aq"));
3874         for (i = 0; i < num_in_clusters; i++)
3875                 g_variant_builder_add(incl_builder, "q", in_clusters[i]);
3876
3877         outcl_builder = g_variant_builder_new(G_VARIANT_TYPE("aq"));
3878         for (i = 0; i < num_out_clusters; i++)
3879                 g_variant_builder_add(outcl_builder, "q", out_clusters[i]);
3880
3881         incl_variant = g_variant_builder_end(incl_builder);
3882         outcl_variant = g_variant_builder_end(outcl_builder);
3883         g_variant_builder_unref(incl_builder);
3884         g_variant_builder_unref(outcl_builder);
3885
3886         variant = g_dbus_proxy_call_sync(zdo_dev_proxy, "matched_descriptor_req",
3887                 g_variant_new("(qqy@aqy@aq)", addr16, profile_id, num_in_clusters,
3888                 incl_variant, num_out_clusters, outcl_variant),
3889                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
3890
3891         if (!variant) {
3892                 ERR("Failed to get 'matched_descriptor_req' [%s]", dbus_err->message);
3893                 g_error_free(dbus_err);
3894                 return ZIGBEE_ERROR_IO_ERROR;
3895         }
3896
3897         g_variant_get(variant, "(i)", &result);
3898         DBG("ret = [0x%x]", result);
3899         g_variant_unref(variant);
3900
3901         return result;
3902 }
3903
3904 int zbl_node_desc_req(nwk_addr addr16, zb_zdo_node_desc_rsp cb, void *user_data)
3905 {
3906         int sub_id, to;
3907         zbl_req_cb_s *container;
3908
3909         int result = ZIGBEE_ERROR_NONE;
3910         GVariant *variant = NULL;
3911         GError *dbus_err = NULL;
3912
3913         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3914         RETV_IF(NULL == zdo_dev_proxy, ZIGBEE_ERROR_IO_ERROR);
3915
3916         DBG("zbl_node_desc_req()");
3917
3918         container = calloc(1, sizeof(zbl_req_cb_s));
3919         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
3920
3921         to = zbl_dbus_get_timeout(zdo_dev_proxy);
3922         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
3923                         ZIGBEE_ZDO_DEV_CONTROL_INTERFACE,  "node_desc_rsp",
3924                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
3925                         _zbl_response_cb, container, _zbl_request_cleanup);
3926
3927         if (0 == sub_id) {
3928                 ERR("g_dbus_connection_signal_subscribe() Fail");
3929                 free(container);
3930                 return ZIGBEE_ERROR_IO_ERROR;
3931         }
3932
3933         container->cb = cb;
3934         container->sid = sub_id;
3935         container->cid = ZBL_ZDO_NODE_DESC_REQ;
3936         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
3937         container->userdata = user_data;
3938
3939         variant = g_dbus_proxy_call_sync(zdo_dev_proxy, "node_desc_req",
3940                 g_variant_new("(q)", addr16), G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
3941
3942         if (!variant) {
3943                 ERR("Failed to get 'node_desc_req' [%s]", dbus_err->message);
3944                 g_error_free(dbus_err);
3945                 return ZIGBEE_ERROR_IO_ERROR;
3946         }
3947
3948         g_variant_get(variant, "(i)", &result);
3949         DBG("ret = [0x%x]", result);
3950         g_variant_unref(variant);
3951
3952         return result;
3953 }
3954
3955 int zbl_power_desc_req(nwk_addr addr16, zb_zdo_power_desc_rsp cb,       void *user_data)
3956 {
3957         int sub_id, to;
3958         zbl_req_cb_s *container;
3959
3960         int result = ZIGBEE_ERROR_NONE;
3961         GVariant *variant = NULL;
3962         GError *dbus_err = NULL;
3963
3964         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
3965         RETV_IF(NULL == zdo_dev_proxy, ZIGBEE_ERROR_IO_ERROR);
3966
3967         container = calloc(1, sizeof(zbl_req_cb_s));
3968         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
3969
3970         to = zbl_dbus_get_timeout(zdo_dev_proxy);
3971         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
3972                         ZIGBEE_ZDO_DEV_CONTROL_INTERFACE,  "power_desc_rsp",
3973                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
3974                         _zbl_response_cb, container, _zbl_request_cleanup);
3975
3976         if (0 == sub_id) {
3977                 ERR("g_dbus_connection_signal_subscribe() Fail");
3978                 free(container);
3979                 return ZIGBEE_ERROR_IO_ERROR;
3980         }
3981
3982         container->cb = cb;
3983         container->sid = sub_id;
3984         container->cid = ZBL_ZDO_POWER_DESC_REQ;
3985         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
3986         container->userdata = user_data;
3987
3988         variant = g_dbus_proxy_call_sync(zdo_dev_proxy, "power_desc_req",
3989                 g_variant_new("(q)", addr16), G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
3990
3991         if (!variant) {
3992                 ERR("Failed to get 'power_desc_req' [%s]", dbus_err->message);
3993                 g_error_free(dbus_err);
3994                 return ZIGBEE_ERROR_IO_ERROR;
3995         }
3996
3997         g_variant_get(variant, "(i)", &result);
3998         DBG("ret = [0x%x]", result);
3999         g_variant_unref(variant);
4000
4001         return result;
4002 }
4003
4004 int zbl_complex_desc_req(nwk_addr addr16, zb_zdo_complex_desc_rsp cb, void *user_data)
4005 {
4006         int sub_id, to;
4007         zbl_req_cb_s *container;
4008
4009         int result = ZIGBEE_ERROR_NONE;
4010         GVariant *variant = NULL;
4011         GError *dbus_err = NULL;
4012
4013         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
4014         RETV_IF(NULL == zdo_dev_proxy, ZIGBEE_ERROR_IO_ERROR);
4015
4016         container = calloc(1, sizeof(zbl_req_cb_s));
4017         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
4018
4019         to = zbl_dbus_get_timeout(zdo_dev_proxy);
4020         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
4021                         ZIGBEE_ZDO_DEV_CONTROL_INTERFACE,  "complex_desc_rsp",
4022                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
4023                         _zbl_response_cb, container, _zbl_request_cleanup);
4024
4025         if (0 == sub_id) {
4026                 ERR("g_dbus_connection_signal_subscribe() Fail");
4027                 free(container);
4028                 return ZIGBEE_ERROR_IO_ERROR;
4029         }
4030
4031         container->cb = cb;
4032         container->sid = sub_id;
4033         container->cid = ZBL_ZDO_COMPLEX_DESC_REQ;
4034         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
4035         container->userdata = user_data;
4036
4037         variant = g_dbus_proxy_call_sync(zdo_dev_proxy, "complex_desc_req",
4038                 g_variant_new("(q)", addr16), G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
4039
4040         if (!variant) {
4041                 ERR("Failed to get 'complex_desc_req' [%s]", dbus_err->message);
4042                 g_error_free(dbus_err);
4043                 return ZIGBEE_ERROR_IO_ERROR;
4044         }
4045
4046         g_variant_get(variant, "(i)", &result);
4047         DBG("ret = [0x%x]", result);
4048         g_variant_unref(variant);
4049
4050         return result;
4051 }
4052
4053 int zbl_user_desc_req(nwk_addr addr16, zb_zdo_user_desc_rsp cb, void *user_data)
4054 {
4055         int sub_id, to;
4056         zbl_req_cb_s *container;
4057
4058         int result = ZIGBEE_ERROR_NONE;
4059         GVariant *variant = NULL;
4060         GError *dbus_err = NULL;
4061
4062         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
4063         RETV_IF(NULL == zdo_dev_proxy, ZIGBEE_ERROR_IO_ERROR);
4064
4065         container = calloc(1, sizeof(zbl_req_cb_s));
4066         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
4067
4068         to = zbl_dbus_get_timeout(zdo_dev_proxy);
4069         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
4070                         ZIGBEE_ZDO_DEV_CONTROL_INTERFACE,  "user_desc_rsp",
4071                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
4072                         _zbl_response_cb, container, _zbl_request_cleanup);
4073
4074         if (0 == sub_id) {
4075                 ERR("g_dbus_connection_signal_subscribe() Fail");
4076                 free(container);
4077                 return ZIGBEE_ERROR_IO_ERROR;
4078         }
4079
4080         container->cb = cb;
4081         container->sid = sub_id;
4082         container->cid = ZBL_ZDO_USER_DESC_REQ;
4083         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
4084         container->userdata = user_data;
4085
4086         variant = g_dbus_proxy_call_sync(zdo_dev_proxy, "user_desc_req",
4087                 g_variant_new("(q)", addr16), G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
4088
4089         if (!variant) {
4090                 ERR("Failed to get 'user_desc_req' [%s]", dbus_err->message);
4091                 g_error_free(dbus_err);
4092                 return ZIGBEE_ERROR_IO_ERROR;
4093         }
4094
4095         g_variant_get(variant, "(i)", &result);
4096         DBG("ret = [0x%x]", result);
4097         g_variant_unref(variant);
4098
4099         return result;
4100 }
4101
4102 #define MAX_USER_DESC_SIZE 0x10
4103 #define USER_DESC_COMMAND_SIZE 20
4104
4105 int zbl_user_desc_set(zigbee_h handle, nwk_addr addr16, unsigned char len,
4106                 unsigned char *user_desc, zb_zdo_user_desc_conf cb, void *user_data)
4107 {
4108         int sub_id, to;
4109         zbl_req_cb_s *container;
4110
4111         int result = ZIGBEE_ERROR_NONE;
4112         GVariant *variant = NULL;
4113         GError *dbus_err = NULL;
4114
4115         unsigned char j = 0x00;
4116         GVariantBuilder *user_desc_builder = NULL;
4117         GVariant *user_desc_variant = NULL;
4118
4119         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
4120         RETV_IF(NULL == zdo_dev_proxy, ZIGBEE_ERROR_IO_ERROR);
4121         RETVM_IF(len > MAX_USER_DESC_SIZE || len < 0x00, ZIGBEE_ERROR_INVALID_PARAMETER,
4122                 "invalid length=%d", len);
4123         RETVM_IF(NULL == user_data, ZIGBEE_ERROR_INVALID_PARAMETER, "invalid data");
4124
4125         container = calloc(1, sizeof(zbl_req_cb_s));
4126         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
4127
4128         to = zbl_dbus_get_timeout(zdo_dev_proxy);
4129         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
4130                         ZIGBEE_ZDO_DEV_CONTROL_INTERFACE,  "user_desc_confirm",
4131                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
4132                         _zbl_response_cb, container, _zbl_request_cleanup);
4133
4134         if (0 == sub_id) {
4135                 ERR("g_dbus_connection_signal_subscribe() Fail");
4136                 free(container);
4137                 return ZIGBEE_ERROR_IO_ERROR;
4138         }
4139
4140         container->cb = cb;
4141         container->sid = sub_id;
4142         container->cid = ZBL_ZDO_USER_DESC_SET_REQ;
4143         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
4144         container->userdata = user_data;
4145
4146         user_desc_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
4147         for (j = 0; j < len; j++)
4148                 g_variant_builder_add(user_desc_builder, "(y)", user_desc[j]);
4149
4150         user_desc_variant = g_variant_builder_end(user_desc_builder);
4151         g_variant_builder_unref(user_desc_builder);
4152
4153         variant = g_dbus_proxy_call_sync(zdo_dev_proxy, "user_desc_set_req",
4154                 g_variant_new("(qy@a(y))", addr16, len, user_desc_variant),
4155                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
4156
4157         if (!variant) {
4158                 ERR("Failed to get 'user_desc_set_req' [%s]", dbus_err->message);
4159                 g_error_free(dbus_err);
4160                 return ZIGBEE_ERROR_IO_ERROR;
4161         }
4162
4163         g_variant_get(variant, "(i)", &result);
4164         DBG("ret = [0x%x]", result);
4165         g_variant_unref(variant);
4166
4167         return result;
4168 }
4169
4170 int zbl_device_annce(zigbee_h handle, nwk_addr addr16, ieee_addr addr64,
4171                 unsigned char capability)
4172 {
4173         int result = ZIGBEE_ERROR_NONE;
4174         GError *dbus_err = NULL;
4175         GVariant *variant = NULL;
4176
4177         GVariantBuilder *mac_builder = NULL;
4178         GVariant* mac_variant = NULL;
4179
4180         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
4181         RETV_IF(NULL == zdo_dev_proxy, ZIGBEE_ERROR_IO_ERROR);
4182
4183         mac_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
4184         g_variant_builder_add(mac_builder, "(y)", addr64[7]);
4185         g_variant_builder_add(mac_builder, "(y)", addr64[6]);
4186         g_variant_builder_add(mac_builder, "(y)", addr64[5]);
4187         g_variant_builder_add(mac_builder, "(y)", addr64[4]);
4188         g_variant_builder_add(mac_builder, "(y)", addr64[3]);
4189         g_variant_builder_add(mac_builder, "(y)", addr64[2]);
4190         g_variant_builder_add(mac_builder, "(y)", addr64[1]);
4191         g_variant_builder_add(mac_builder, "(y)", addr64[0]);
4192         mac_variant = g_variant_builder_end(mac_builder);
4193         g_variant_builder_unref(mac_builder);
4194
4195         variant = g_dbus_proxy_call_sync(zdo_dev_proxy, "device_announce",
4196                 g_variant_new("(q@a(y)y)", addr16, mac_variant, capability),
4197                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
4198
4199         if (!variant) {
4200                 ERR("Failed to get 'device_announce' [%s]", dbus_err->message);
4201                 g_error_free(dbus_err);
4202                 return ZIGBEE_ERROR_IO_ERROR;
4203         }
4204
4205         g_variant_get(variant, "(i)", &result);
4206         DBG("ret = [0x%x]", result);
4207         g_variant_unref(variant);
4208
4209         return result;
4210 }
4211
4212 int zbl_bind_req(nwk_addr dst_addr16, ieee_addr src_addr64,
4213                 unsigned char src_ep, unsigned short cluster_id, ieee_addr dst_addr64,
4214                 unsigned char type, nwk_addr group_addr, unsigned char dst_ep,
4215                 zb_zdo_bind_rsp cb, void *user_data)
4216 {
4217         int i;
4218         int sub_id, to;
4219         zbl_req_cb_s *container;
4220
4221         int result = ZIGBEE_ERROR_NONE;
4222         GError *dbus_err = NULL;
4223         GVariant *variant = NULL;
4224
4225         GVariantBuilder *src_addr64_builder = NULL;
4226         GVariant* src_addr64_variant = NULL;
4227         GVariantBuilder *dst_addr64_builder = NULL;
4228         GVariant* dst_addr64_variant = NULL;
4229
4230         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
4231         RETV_IF(NULL == zdo_bind_proxy, ZIGBEE_ERROR_IO_ERROR);
4232
4233         DBG("zbl_zdo_bind_req()");
4234
4235         container = calloc(1, sizeof(zbl_req_cb_s));
4236         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
4237
4238         to = zbl_dbus_get_timeout(zdo_bind_proxy);
4239         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
4240                         ZIGBEE_ZDO_BIND_INTERFACE,  "bind_rsp", ZIGBEE_CONTROL_OBJECT_PATH,
4241                         NULL, 0, _zbl_response_cb, container, _zbl_request_cleanup);
4242         if (0 == sub_id) {
4243                 ERR("g_dbus_connection_signal_subscribe() Fail");
4244                 free(container);
4245                 return ZIGBEE_ERROR_IO_ERROR;
4246         }
4247
4248         container->cb = cb;
4249         container->sid = sub_id;
4250         container->cid = ZBL_ZDO_BIND_REQ;
4251         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
4252         container->userdata = user_data;
4253
4254         src_addr64_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
4255
4256         if (src_addr64) {
4257                 for (i = sizeof(ieee_addr) - 1 ; i >= 0; i--)
4258                         g_variant_builder_add(src_addr64_builder, "(y)", src_addr64[i]);
4259         }
4260         src_addr64_variant = g_variant_builder_end(src_addr64_builder);
4261         g_variant_builder_unref(src_addr64_builder);
4262
4263         dst_addr64_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
4264         if (dst_addr64) {
4265                 for (i = sizeof(ieee_addr) - 1 ; i >= 0; i--)
4266                         g_variant_builder_add(dst_addr64_builder, "(y)", dst_addr64[i]);
4267         }
4268         dst_addr64_variant = g_variant_builder_end(dst_addr64_builder);
4269         g_variant_builder_unref(dst_addr64_builder);
4270
4271         variant = g_dbus_proxy_call_sync(zdo_bind_proxy, "bind_req",
4272                 g_variant_new("(q@a(y)yq@a(y)yqy)", dst_addr16, src_addr64_variant, src_ep,
4273                                                 cluster_id, dst_addr64_variant, type, group_addr, dst_ep),
4274                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
4275
4276         if (!variant) {
4277                 ERR("Failed to get 'bind_req' [%s]", dbus_err->message);
4278                 g_error_free(dbus_err);
4279                 return ZIGBEE_ERROR_IO_ERROR;
4280         }
4281
4282         g_variant_get(variant, "(i)", &result);
4283         DBG("ret = [0x%x]", result);
4284         g_variant_unref(variant);
4285
4286         return result;
4287 }
4288
4289 int zbl_unbind_req(nwk_addr dst_addr16,
4290                 ieee_addr src_addr64, unsigned char src_ep, unsigned short cluster_id,
4291                 ieee_addr dst_addr64, unsigned char type, nwk_addr group_addr,
4292                 unsigned char dst_ep, zb_zdo_unbind_rsp cb, void *user_data)
4293 {
4294         int i;
4295         int sub_id, to;
4296         zbl_req_cb_s *container;
4297
4298         int result = ZIGBEE_ERROR_NONE;
4299         GError *dbus_err = NULL;
4300         GVariant *variant = NULL;
4301
4302         GVariantBuilder *src_addr64_builder = NULL;
4303         GVariant* src_addr64_variant = NULL;
4304         GVariantBuilder *dst_addr64_builder = NULL;
4305         GVariant* dst_addr64_variant = NULL;
4306
4307         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
4308         RETV_IF(NULL == zdo_bind_proxy, ZIGBEE_ERROR_IO_ERROR);
4309
4310         DBG("zbl_zdo_unbind_req()");
4311
4312         container = calloc(1, sizeof(zbl_req_cb_s));
4313         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
4314
4315         to = zbl_dbus_get_timeout(zdo_bind_proxy);
4316         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
4317                         ZIGBEE_ZDO_BIND_INTERFACE,  "unbind_rsp", ZIGBEE_CONTROL_OBJECT_PATH,
4318                         NULL, 0, _zbl_response_cb, container, _zbl_request_cleanup);
4319         if (0 == sub_id) {
4320                 ERR("g_dbus_connection_signal_subscribe() Fail");
4321                 free(container);
4322                 return ZIGBEE_ERROR_IO_ERROR;
4323         }
4324
4325         container->cb = cb;
4326         container->sid = sub_id;
4327         container->cid = ZBL_ZDO_UNBIND_REQ;
4328         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
4329         container->userdata = user_data;
4330
4331         src_addr64_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
4332         if (src_addr64) {
4333                 for (i = sizeof(ieee_addr) - 1 ; i >= 0; i--)
4334                         g_variant_builder_add(src_addr64_builder, "(y)", src_addr64[i]);
4335         }
4336         src_addr64_variant = g_variant_builder_end(src_addr64_builder);
4337         g_variant_builder_unref(src_addr64_builder);
4338
4339         dst_addr64_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
4340         if (dst_addr64) {
4341                 for (i = sizeof(ieee_addr) - 1 ; i >= 0; i--)
4342                         g_variant_builder_add(dst_addr64_builder, "(y)", dst_addr64[i]);
4343         }
4344         dst_addr64_variant = g_variant_builder_end(dst_addr64_builder);
4345         g_variant_builder_unref(dst_addr64_builder);
4346
4347         variant = g_dbus_proxy_call_sync(zdo_bind_proxy, "unbind_req",
4348                 g_variant_new("(q@a(y)yq@a(y)yqy)", dst_addr16, src_addr64_variant, src_ep,
4349                                                 cluster_id, dst_addr64_variant, type, group_addr, dst_ep),
4350                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
4351
4352         if (!variant) {
4353                 ERR("Failed to get 'unbind_req' [%s]", dbus_err->message);
4354                 g_error_free(dbus_err);
4355                 return ZIGBEE_ERROR_IO_ERROR;
4356         }
4357
4358         g_variant_get(variant, "(i)", &result);
4359         DBG("ret = [0x%x]", result);
4360         g_variant_unref(variant);
4361
4362         return result;
4363 }
4364
4365 int zbl_mgmt_nwk_disc_req(nwk_addr addr16, unsigned int scan_channels,
4366         unsigned char scan_duration, unsigned char scan_count, unsigned char start_idx,
4367         zb_zdo_mgmt_nwk_disc_rsp cb, void *user_data)
4368 {
4369         int sub_id, to;
4370         zbl_req_cb_s *container;
4371
4372         int result = ZIGBEE_ERROR_NONE;
4373         GVariant *variant = NULL;
4374         GError *dbus_err = NULL;
4375
4376         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
4377         RETV_IF(NULL == zdo_dev_proxy, ZIGBEE_ERROR_IO_ERROR);
4378
4379         DBG("zbl_mgmt_nwk_disc_req()");
4380
4381         container = calloc(1, sizeof(zbl_req_cb_s));
4382         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
4383
4384         to = zbl_dbus_get_timeout(zdo_dev_proxy);
4385         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
4386                         ZIGBEE_ZDO_DEV_CONTROL_INTERFACE,  "nwk_disc_rsp",
4387                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0, _zbl_response_cb,
4388                         container, _zbl_request_cleanup);
4389
4390         if (0 == sub_id) {
4391                 ERR("g_dbus_connection_signal_subscribe() Fail");
4392                 free(container);
4393                 return ZIGBEE_ERROR_IO_ERROR;
4394         }
4395
4396         container->cb = cb;
4397         container->sid = sub_id;
4398         container->cid = ZBL_ZDO_MGMT_NWK_DISC_REQ;
4399         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
4400         container->userdata = user_data;
4401
4402         variant = g_dbus_proxy_call_sync(zdo_dev_proxy, "nwk_disc_req",
4403                 g_variant_new("(quyqy)", addr16, scan_channels, scan_duration, scan_count, start_idx),
4404                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
4405
4406         if (!variant) {
4407                 ERR("Failed to get 'nwk_disc_req' [%s]", dbus_err->message);
4408                 g_error_free(dbus_err);
4409                 return ZIGBEE_ERROR_IO_ERROR;
4410         }
4411
4412         g_variant_get(variant, "(i)", &result);
4413         DBG("ret = [0x%x]", result);
4414         g_variant_unref(variant);
4415
4416         return result;
4417 }
4418
4419 int zbl_mgmt_nwk_update_req(unsigned int scan_channels, unsigned char scan_duration,
4420         unsigned char scan_count, unsigned char nwk_update_id, nwk_addr nwk_manager_addr)
4421 {
4422         int result = ZIGBEE_ERROR_NONE;
4423         GVariant *variant = NULL;
4424         GError *dbus_err = NULL;
4425
4426         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
4427         RETV_IF(NULL == zdo_dev_proxy, ZIGBEE_ERROR_IO_ERROR);
4428
4429         DBG("zbl_mgmt_nwk_update_req()");
4430
4431         variant = g_dbus_proxy_call_sync(zdo_dev_proxy, "nwk_update_req",
4432                 g_variant_new("(quyyy)", nwk_manager_addr, scan_channels, scan_duration,
4433                 scan_count, nwk_update_id), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
4434
4435         if (!variant) {
4436                 ERR("Failed to get 'nwk_update_req' [%s]", dbus_err->message);
4437                 g_error_free(dbus_err);
4438                 return ZIGBEE_ERROR_IO_ERROR;
4439         }
4440
4441         g_variant_get(variant, "(i)", &result);
4442         DBG("ret = [0x%x]", result);
4443         g_variant_unref(variant);
4444
4445         return result;
4446 }
4447
4448 int zbl_mgmt_lqi_req(nwk_addr addr16, unsigned char start_idx,
4449                 zb_zdo_mgmt_lqi_rsp cb, void *user_data)
4450 {
4451         int sub_id, to;
4452         zbl_req_cb_s *container;
4453
4454         int result = ZIGBEE_ERROR_NONE;
4455         GVariant *variant = NULL;
4456         GError *dbus_err = NULL;
4457
4458         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
4459         RETV_IF(NULL == zdo_dev_proxy, ZIGBEE_ERROR_IO_ERROR);
4460
4461         DBG("zbl_mgmt_lqi_req()");
4462
4463         container = calloc(1, sizeof(zbl_req_cb_s));
4464         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
4465
4466         to = zbl_dbus_get_timeout(zdo_dev_proxy);
4467         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
4468                         ZIGBEE_ZDO_DEV_CONTROL_INTERFACE,  "mgmt_lqi_rsp",
4469                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0, _zbl_response_cb, container,
4470                         _zbl_request_cleanup);
4471
4472         if (0 == sub_id) {
4473                 ERR("g_dbus_connection_signal_subscribe() Fail");
4474                 free(container);
4475                 return ZIGBEE_ERROR_IO_ERROR;
4476         }
4477
4478         container->cb = cb;
4479         container->sid = sub_id;
4480         container->cid = ZBL_ZDO_MGMT_LQI_REQ;
4481         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
4482         container->userdata = user_data;
4483
4484         variant = g_dbus_proxy_call_sync(zdo_dev_proxy, "mgmt_lqi_req",
4485                 g_variant_new("(qy)", addr16, start_idx),
4486                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
4487
4488         if (!variant) {
4489                 ERR("Failed to get 'mgmt_lqi_req' [%s]", dbus_err->message);
4490                 g_error_free(dbus_err);
4491                 return ZIGBEE_ERROR_IO_ERROR;
4492         }
4493
4494         g_variant_get(variant, "(i)", &result);
4495         DBG("ret = [0x%x]", result);
4496         g_variant_unref(variant);
4497
4498         return result;
4499 }
4500
4501 int zbl_mgmt_rtg_req(nwk_addr addr16, unsigned char start_idx,
4502                 zb_zdo_mgmt_rtg_rsp cb, void *user_data)
4503 {
4504         int sub_id, to;
4505         zbl_req_cb_s *container;
4506
4507         int result = ZIGBEE_ERROR_NONE;
4508         GVariant *variant = NULL;
4509         GError *dbus_err = NULL;
4510
4511         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
4512         RETV_IF(NULL == zdo_dev_proxy, ZIGBEE_ERROR_IO_ERROR);
4513
4514         DBG("zbl_mgmt_rtg_req()");
4515
4516         container = calloc(1, sizeof(zbl_req_cb_s));
4517         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
4518
4519         to = zbl_dbus_get_timeout(zdo_dev_proxy);
4520         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
4521                         ZIGBEE_ZDO_DEV_CONTROL_INTERFACE,  "mgmt_rtg_rsp",
4522                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,  _zbl_response_cb, container,
4523                         _zbl_request_cleanup);
4524
4525         if (0 == sub_id) {
4526                 ERR("g_dbus_connection_signal_subscribe() Fail");
4527                 free(container);
4528                 return ZIGBEE_ERROR_IO_ERROR;
4529         }
4530
4531         container->cb = cb;
4532         container->sid = sub_id;
4533         container->cid = ZBL_ZDO_MGMT_RTG_REQ;
4534         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
4535         container->userdata = user_data;
4536
4537         variant = g_dbus_proxy_call_sync(zdo_dev_proxy, "mgmt_rtg_req",
4538                 g_variant_new("(qy)", addr16, start_idx),
4539                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
4540
4541         if (!variant) {
4542                 ERR("Failed to get 'mgmt_rtg_req' [%s]", dbus_err->message);
4543                 g_error_free(dbus_err);
4544                 return ZIGBEE_ERROR_IO_ERROR;
4545         }
4546
4547         g_variant_get(variant, "(i)", &result);
4548         DBG("ret = [0x%x]", result);
4549         g_variant_unref(variant);
4550
4551         return result;
4552 }
4553
4554 int zbl_mgmt_bind_req(nwk_addr addr16, unsigned char start_idx,
4555                 zb_zdo_mgmt_bind_rsp cb, void *user_data)
4556 {
4557         int sub_id, to;
4558         zbl_req_cb_s *container;
4559
4560         int result = ZIGBEE_ERROR_NONE;
4561         GVariant *variant = NULL;
4562         GError *dbus_err = NULL;
4563
4564         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
4565         RETV_IF(NULL == zdo_dev_proxy, ZIGBEE_ERROR_IO_ERROR);
4566
4567         DBG("zbl_mgmt_bind_req()");
4568
4569         container = calloc(1, sizeof(zbl_req_cb_s));
4570         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
4571
4572         to = zbl_dbus_get_timeout(zdo_dev_proxy);
4573         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
4574                         ZIGBEE_ZDO_DEV_CONTROL_INTERFACE,  "mgmt_bind_rsp",
4575                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,  _zbl_response_cb, container,
4576                         _zbl_request_cleanup);
4577
4578         if (0 == sub_id) {
4579                 ERR("g_dbus_connection_signal_subscribe() Fail");
4580                 free(container);
4581                 return ZIGBEE_ERROR_IO_ERROR;
4582         }
4583
4584         container->cb = cb;
4585         container->sid = sub_id;
4586         container->cid = ZBL_ZDO_MGMT_BIND_REQ;
4587         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
4588         container->userdata = user_data;
4589
4590         variant = g_dbus_proxy_call_sync(zdo_dev_proxy, "mgmt_bind_req",
4591                 g_variant_new("(qy)", addr16, start_idx),
4592                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
4593
4594         if (!variant) {
4595                 ERR("Failed to get 'mgmt_bind_req' [%s]", dbus_err->message);
4596                 g_error_free(dbus_err);
4597                 return ZIGBEE_ERROR_IO_ERROR;
4598         }
4599
4600         g_variant_get(variant, "(i)", &result);
4601         DBG("ret = [0x%x]", result);
4602         g_variant_unref(variant);
4603
4604         return result;
4605 }
4606
4607 int zbl_mgmt_leave_device(ieee_addr addr64, unsigned char remove_children,
4608                 unsigned rejoin, zb_zdo_mgmt_leave_rsp cb, void *user_data)
4609 {
4610         int sub_id, to;
4611         zbl_req_cb_s *container;
4612
4613         int result = ZIGBEE_ERROR_NONE;
4614         GVariant *variant = NULL;
4615         GError *dbus_err = NULL;
4616
4617         GVariantBuilder *mac_builder = NULL;
4618         GVariant* mac_variant = NULL;
4619
4620         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
4621         RETV_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR);
4622
4623         container = calloc(1, sizeof(zbl_req_cb_s));
4624         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
4625
4626         to = zbl_dbus_get_timeout(zdo_dev_proxy);
4627         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
4628                         ZIGBEE_ZDO_DEV_CONTROL_INTERFACE,  "mgmt_leave_rsp",
4629                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,  _zbl_response_cb, container,
4630                         _zbl_request_cleanup);
4631
4632         if (0 == sub_id) {
4633                 ERR("g_dbus_connection_signal_subscribe() Fail");
4634                 free(container);
4635                 return ZIGBEE_ERROR_IO_ERROR;
4636         }
4637
4638         container->cb = cb;
4639         container->sid = sub_id;
4640         container->cid = ZBL_ZDO_MGMT_LEAVE_REQ;
4641         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
4642         container->userdata = user_data;
4643
4644         mac_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
4645         g_variant_builder_add(mac_builder, "(y)", addr64[7]);
4646         g_variant_builder_add(mac_builder, "(y)", addr64[6]);
4647         g_variant_builder_add(mac_builder, "(y)", addr64[5]);
4648         g_variant_builder_add(mac_builder, "(y)", addr64[4]);
4649         g_variant_builder_add(mac_builder, "(y)", addr64[3]);
4650         g_variant_builder_add(mac_builder, "(y)", addr64[2]);
4651         g_variant_builder_add(mac_builder, "(y)", addr64[1]);
4652         g_variant_builder_add(mac_builder, "(y)", addr64[0]);
4653         mac_variant = g_variant_builder_end(mac_builder);
4654         g_variant_builder_unref(mac_builder);
4655
4656         variant = g_dbus_proxy_call_sync(service_gproxy, "leave_request",
4657                 g_variant_new("(@a(y)yy)", mac_variant, remove_children, rejoin),
4658                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
4659
4660         if (!variant) {
4661                 ERR("Failed to get 'leave_request' [%s]", dbus_err->message);
4662                 g_error_free(dbus_err);
4663                 return ZIGBEE_ERROR_IO_ERROR;
4664         }
4665
4666         g_variant_get(variant, "(i)", &result);
4667         DBG("ret = [0x%x]", result);
4668         g_variant_unref(variant);
4669
4670         return result;
4671 }
4672
4673 int zbl_mgmt_permit_joining_req(nwk_addr addr16, unsigned char duration,
4674                 unsigned char tc_significance, zb_zdo_mgmt_permit_joining_rsp cb, void *user_data)
4675 {
4676         int sub_id, to;
4677         zbl_req_cb_s *container;
4678
4679         int result = ZIGBEE_ERROR_NONE;
4680         GVariant *variant = NULL;
4681         GError *dbus_err = NULL;
4682
4683         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
4684         RETV_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR);
4685
4686         container = calloc(1, sizeof(zbl_req_cb_s));
4687         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
4688
4689         to = zbl_dbus_get_timeout(zdo_dev_proxy);
4690         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
4691                         ZIGBEE_ZDO_DEV_CONTROL_INTERFACE,  "mgmt_permit_join_rsp",
4692                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0, _zbl_response_cb,
4693                         container, _zbl_request_cleanup);
4694
4695         if (0 == sub_id) {
4696                 ERR("g_dbus_connection_signal_subscribe() Fail");
4697                 free(container);
4698                 return ZIGBEE_ERROR_IO_ERROR;
4699         }
4700
4701         container->cb = cb;
4702         container->sid = sub_id;
4703         container->cid = ZBL_ZDO_MGMT_PERMIT_JOIN_REQ;
4704         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
4705         container->userdata = user_data;
4706
4707         variant = g_dbus_proxy_call_sync(zdo_dev_proxy, "mgmt_permit_join_req",
4708                 g_variant_new("(qyy)", addr16, duration, tc_significance),
4709                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
4710
4711         if (!variant) {
4712                 ERR("Failed to get 'mgmt_permit_join_req' [%s]", dbus_err->message);
4713                 g_error_free(dbus_err);
4714                 return ZIGBEE_ERROR_IO_ERROR;
4715         }
4716
4717         g_variant_get(variant, "(i)", &result);
4718         DBG("ret = [0x%x]", result);
4719         g_variant_unref(variant);
4720
4721         return result;
4722 }
4723
4724 int zbl_aps_send(nwk_addr addr16, unsigned char aps_frame_ctl, unsigned char src_ep,
4725         unsigned char dst_ep, unsigned short cluster_id, unsigned short profile_id,
4726         unsigned char zcl_frame_ctl, unsigned short mfg_code, unsigned char cmd_id,
4727         unsigned short payload_len, unsigned char *payload, zb_aps_send_rsp cb, void *user_data)
4728 {
4729         int sub_id, to, i;
4730         zbl_req_cb_s *container;
4731
4732         int result = ZIGBEE_ERROR_NONE;
4733         GVariant *variant = NULL;
4734         GError *dbus_err = NULL;
4735
4736         GVariantBuilder *payload_builder = NULL;
4737         GVariant *payload_variant = NULL;
4738
4739         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
4740         RETV_IF(NULL == custom_gproxy, ZIGBEE_ERROR_IO_ERROR);
4741
4742         container = calloc(1, sizeof(zbl_req_cb_s));
4743         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
4744
4745         to = zbl_dbus_get_timeout(custom_gproxy);
4746         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
4747                         ZIGBEE_CUSTOM_INTERFACE,  "aps_send_rsp", ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
4748                         _zbl_response_cb, container, _zbl_request_cleanup);
4749
4750         if (0 == sub_id) {
4751                 ERR("g_dbus_connection_signal_subscribe() Fail");
4752                 free(container);
4753                 return ZIGBEE_ERROR_IO_ERROR;
4754         }
4755
4756         container->cb = cb;
4757         container->sid = sub_id;
4758         container->cid = ZBL_CUSTOM_APS_SEND_REQ;
4759         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
4760         container->userdata = user_data;
4761
4762         payload_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
4763         if (payload_len > 0) {
4764                 for (i = payload_len - 1; i >= 0 ; i--)
4765                         g_variant_builder_add(payload_builder, "(y)", payload[i]);
4766         }
4767         payload_variant = g_variant_builder_end(payload_builder);
4768         g_variant_builder_unref(payload_builder);
4769
4770         variant = g_dbus_proxy_call_sync(custom_gproxy, "aps_send",
4771                 g_variant_new("(qyyyqqyqyq@a(y))", addr16, aps_frame_ctl, src_ep, dst_ep, cluster_id,
4772                 profile_id, zcl_frame_ctl, mfg_code, cmd_id, payload_len, payload_variant),
4773                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
4774
4775         if (!variant) {
4776                 ERR("Failed to get 'aps_send' [%s]", dbus_err->message);
4777                 g_error_free(dbus_err);
4778                 return ZIGBEE_ERROR_IO_ERROR;
4779         }
4780
4781         g_variant_get(variant, "(i)", &result);
4782         DBG("ret = [0x%x]", result);
4783         g_variant_unref(variant);
4784
4785         return result;
4786 }
4787
4788 int zbl_zcl_send(nwk_addr addr16, unsigned char src_ep, unsigned char dst_ep,
4789                 unsigned short cluster_id, unsigned char zcl_frame_ctl, unsigned char cmd,
4790                 unsigned short payload_len, unsigned char *payload,
4791                 zb_zcl_send_rsp cb, void *user_data)
4792 {
4793         int sub_id, to, i;
4794         zbl_req_cb_s *container;
4795
4796         int result = ZIGBEE_ERROR_NONE;
4797         GVariant *variant = NULL;
4798         GError *dbus_err = NULL;
4799
4800         GVariantBuilder *payload_builder = NULL;
4801         GVariant *payload_variant = NULL;
4802
4803         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
4804         RETV_IF(NULL == custom_gproxy, ZIGBEE_ERROR_IO_ERROR);
4805
4806         container = calloc(1, sizeof(zbl_req_cb_s));
4807         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
4808
4809         to = zbl_dbus_get_timeout(custom_gproxy);
4810         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
4811                         ZIGBEE_CUSTOM_INTERFACE,  "zcl_send_rsp", ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
4812                         _zbl_response_cb, container, _zbl_request_cleanup);
4813
4814         if (0 == sub_id) {
4815                 ERR("g_dbus_connection_signal_subscribe() Fail");
4816                 free(container);
4817                 return ZIGBEE_ERROR_IO_ERROR;
4818         }
4819
4820         container->cb = cb;
4821         container->sid = sub_id;
4822         container->cid = ZBL_CUSTOM_ZCL_SEND_REQ;
4823         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
4824         container->userdata = user_data;
4825
4826         payload_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
4827         if (payload_len > 0) {
4828                 for (i = payload_len - 1; i >= 0 ; i--)
4829                         g_variant_builder_add(payload_builder, "(y)", payload[i]);
4830         }
4831         payload_variant = g_variant_builder_end(payload_builder);
4832         g_variant_builder_unref(payload_builder);
4833
4834         variant = g_dbus_proxy_call_sync(custom_gproxy, "zcl_send",
4835                 g_variant_new("(qyyqyyq@a(y))", addr16, src_ep, dst_ep, cluster_id, zcl_frame_ctl,
4836                 cmd, payload_len, payload_variant), G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
4837
4838         if (!variant) {
4839                 ERR("Failed to get 'zcl_send' [%s]", dbus_err->message);
4840                 g_error_free(dbus_err);
4841                 return ZIGBEE_ERROR_IO_ERROR;
4842         }
4843
4844         g_variant_get(variant, "(i)", &result);
4845         DBG("ret = [0x%x]", result);
4846         g_variant_unref(variant);
4847
4848         return result;
4849 }
4850
4851 int zbl_send_to_local(unsigned short length, unsigned char *data,
4852                 zb_send_to_local_rsp cb, void *user_data)
4853 {
4854         int sub_id, to, i;
4855         zbl_req_cb_s *container;
4856
4857         int result = ZIGBEE_ERROR_NONE;
4858         GVariant *variant = NULL;
4859         GError *dbus_err = NULL;
4860
4861         GVariantBuilder *payload_builder = NULL;
4862         GVariant *payload_variant = NULL;
4863
4864         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
4865         RETV_IF(NULL == custom_gproxy, ZIGBEE_ERROR_IO_ERROR);
4866
4867         container = calloc(1, sizeof(zbl_req_cb_s));
4868         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
4869
4870         to = zbl_dbus_get_timeout(custom_gproxy);
4871         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
4872                         ZIGBEE_CUSTOM_INTERFACE,  "send_to_local_rsp", ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
4873                         _zbl_response_cb, container, _zbl_request_cleanup);
4874
4875         if (0 == sub_id) {
4876                 ERR("g_dbus_connection_signal_subscribe() Fail");
4877                 free(container);
4878                 return ZIGBEE_ERROR_IO_ERROR;
4879         }
4880
4881         container->cb = cb;
4882         container->sid = sub_id;
4883         container->cid = ZBL_CUSTOM_LOCAL_SEND_REQ;
4884         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
4885         container->userdata = user_data;
4886
4887         payload_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
4888         if (length > 0) {
4889                 for (i = length - 1; i >= 0 ; i--)
4890                         g_variant_builder_add(payload_builder, "(y)", data[i]);
4891         }
4892         payload_variant = g_variant_builder_end(payload_builder);
4893         g_variant_builder_unref(payload_builder);
4894
4895         variant = g_dbus_proxy_call_sync(custom_gproxy, "send_to_local",
4896                 g_variant_new("(q@a(y))", length, payload_variant),
4897                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
4898
4899         if (!variant) {
4900                 ERR("Failed to get 'send_to_local' [%s]", dbus_err->message);
4901                 g_error_free(dbus_err);
4902                 return ZIGBEE_ERROR_IO_ERROR;
4903         }
4904
4905         g_variant_get(variant, "(i)", &result);
4906         DBG("ret = [0x%x]", result);
4907         g_variant_unref(variant);
4908
4909         return result;
4910 }
4911
4912 int zbl_read_attr_req(zigbee_h handle, unsigned short addr16, unsigned char dest_ep,
4913         unsigned char zcl_frame_ctl, unsigned short cluster_id, unsigned short *attribute_ids,
4914         int attribute_ids_len, zb_zcl_global_rsp cb, void *user_data)
4915 {
4916         int sub_id, to;
4917         zbl_req_cb_s *container;
4918
4919         int result = ZIGBEE_ERROR_NONE;
4920         GVariant *variant = NULL;
4921         GError *dbus_err = NULL;
4922
4923 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
4924         zb_event_global_default_rsp_s *global_req = NULL;
4925 #endif
4926
4927         int i = 0;
4928         unsigned char *t;
4929         GVariant *attr_variant = NULL;
4930         GVariantBuilder *attr_builder = NULL;
4931
4932         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
4933         RETV_IF(NULL == zcl_global_proxy, ZIGBEE_ERROR_IO_ERROR);
4934
4935         DBG("zbl_read_attr_req()");
4936
4937         container = calloc(1, sizeof(zbl_req_cb_s));
4938         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
4939
4940         to = zbl_dbus_get_timeout(zcl_global_proxy);
4941         sub_id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL,
4942                 ZIGBEE_ZCL_GLOBAL_CONTROL_INTERFACE, "read_attributes_rsp",
4943                 ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
4944                 _zbl_response_cb, container, _zbl_request_cleanup);
4945
4946         if (0 == sub_id) {
4947                 ERR("g_dbus_connection_signal_subscribe() Fail");
4948                 free(container);
4949                 return ZIGBEE_ERROR_IO_ERROR;
4950         }
4951
4952         container->cb = cb;
4953         container->sid = sub_id;
4954         container->cid = ZBL_ZCL_GLOBAL_READ_ATTRIBUTE_REQ;
4955         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
4956         container->userdata = user_data;
4957 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
4958         global_req = calloc(1, sizeof(zb_event_global_default_rsp_s));
4959         if (NULL == global_req) {
4960                 g_dbus_connection_signal_unsubscribe(gdbus_conn, sub_id);
4961                 g_source_remove(container->tid);
4962                 container->tid = 0;
4963                 free(container);
4964                 ERR("calloc() Fail(%d)", errno);
4965                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
4966         }
4967         global_req->ep = dest_ep;
4968         global_req->cluster_id = cluster_id;
4969         global_req->command_id = ZB_ZCL_READ_ATTRIBUTES_COMMAND_ID;
4970
4971         container->global_cmd = global_req;
4972         container->handle = handle;
4973
4974         /* Register global request information into handle */
4975         _zbl_register_global_req(handle, container);
4976 #endif
4977
4978         t = (unsigned char *)attribute_ids;
4979         attr_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
4980         for (i = 0; i < attribute_ids_len*sizeof(unsigned short); i++)
4981                 g_variant_builder_add(attr_builder, "(y)", t[i]);
4982         attr_variant = g_variant_builder_end(attr_builder);
4983         g_variant_builder_unref(attr_builder);
4984
4985         variant = g_dbus_proxy_call_sync(zcl_global_proxy, "read_attributes_req",
4986                 g_variant_new("(@a(y)iqqyy)", attr_variant, attribute_ids_len,
4987                 addr16, cluster_id, zcl_frame_ctl, dest_ep), G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
4988
4989         if (!variant) {
4990                 ERR("Failed to get 'read_attributes_req' [%s]", dbus_err->message);
4991                 g_error_free(dbus_err);
4992                 return ZIGBEE_ERROR_IO_ERROR;
4993         }
4994
4995         g_variant_get(variant, "(i)", &result);
4996         DBG("ret = [0x%x]", result);
4997         g_variant_unref(variant);
4998
4999         return result;
5000 }
5001
5002 int zbl_write_attr_req(zigbee_h handle, nwk_addr addr16, unsigned char src_ep, unsigned char dst_ep,
5003                 unsigned char zcl_frame_ctl, unsigned short cluster_id, write_attr_record_h *records,
5004                 int records_len, zb_zcl_global_rsp cb, void *user_data)
5005 {
5006         int sub_id, to;
5007         zbl_req_cb_s *container;
5008
5009         int result = ZIGBEE_ERROR_NONE;
5010         GVariant *variant = NULL;
5011         GError *dbus_err = NULL;
5012
5013 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
5014         zb_event_global_default_rsp_s *global_req = NULL;
5015 #endif
5016
5017         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
5018         RETV_IF(NULL == zcl_global_proxy, ZIGBEE_ERROR_IO_ERROR);
5019
5020         DBG("zbl_write_attr_req()");
5021
5022         GVariantBuilder *rec_builder = NULL;
5023         GVariant *rec_variant = NULL;
5024
5025         int i = 0;
5026         int j = 0;
5027
5028         char dSize[3] = {'\0', '\0'};
5029         int writeAttributeIndex = 0;
5030         int size_of_allo = 0;
5031
5032         unsigned char *isString = NULL;
5033         unsigned short *dataSize = NULL;
5034         unsigned char *writeAttribute = NULL;
5035
5036         isString = calloc(records_len + 1, sizeof(unsigned char));
5037         RETVM_IF(NULL == isString, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
5038
5039         dataSize = calloc(records_len + 1, sizeof(unsigned short));
5040         if (NULL == dataSize) {
5041                 ERR("calloc() Fail(%d)", errno);
5042                 free(isString);
5043                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
5044         }
5045
5046         DBG("Records Length %d", records_len);
5047
5048         while (j < records_len) {
5049                 dataSize[j] = zb_get_data_size((*records)[j].type);
5050                 if (0xff != dataSize[j]) {
5051                         isString[j] = 0;
5052                         size_of_allo = size_of_allo + (dataSize[j] + 3);
5053                 } else {
5054                         if ((*records)[j].value) {
5055                                 if ((*records)[j].type == ZB_ZCL_CHRACTER_STRING
5056                                         || (*records)[j].type == ZB_ZCL_OCTAT_STRING) {
5057                                                 isString[j] = 1;
5058                                                 dataSize[j] = (*records)[j].value[0];
5059                                                 size_of_allo = size_of_allo + (dataSize[j] + 3 + 1);
5060                                 } else if ((*records)[j].type == ZB_ZCL_LONG_OCTAT_STRING
5061                                         || (*records)[j].type == ZB_ZCL_LONG_CHRACTER_STRING) {
5062                                         isString[j] = 2;
5063                                         dSize[0] = (*records)[j].value[0];
5064                                         dSize[1] = (*records)[j].value[1];
5065                                         dataSize[j] = dSize[1];
5066                                         dataSize[j] = (dataSize[j] << 8) | dSize[0];
5067                                         size_of_allo = size_of_allo + (dataSize[j] + 3 + 2);
5068                                 }
5069                         } else
5070                                 ERR("Data is not present");
5071                 }
5072                 j++;
5073         }
5074         DBG("size_of_allo Length %d", size_of_allo);
5075
5076         writeAttribute = calloc(size_of_allo + 1, sizeof(unsigned char));
5077         if (NULL == writeAttribute) {
5078                 ERR("Couldn't Allocate Memory");
5079                 free(isString);
5080                 free(dataSize);
5081                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
5082         }
5083
5084         j = 0;
5085         while (j < records_len && writeAttributeIndex < size_of_allo) {
5086                 writeAttribute[writeAttributeIndex++] = ((*records)[j].id) & 0xff;
5087                 writeAttribute[writeAttributeIndex++] = (((*records)[j].id) >> 8) & 0xff;
5088                 writeAttribute[writeAttributeIndex++] = (*records)[j].type;
5089                 for (i = 0; i < (dataSize[j] + isString[j]); i++) {
5090                         writeAttribute[writeAttributeIndex++] = (*records)[j].value[i];
5091                         DBG("0x%02X", (*records)[j].value[i]);
5092                 }
5093                 j++;
5094         }
5095
5096         rec_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
5097         DBG("   ");
5098         for (i = 0; i < writeAttributeIndex ; i++) {
5099                 DBG("0x%02X", writeAttribute[i]);
5100                 g_variant_builder_add(rec_builder, "(y)", writeAttribute[i]);
5101         }
5102
5103         rec_variant = g_variant_builder_end(rec_builder);
5104         g_variant_builder_unref(rec_builder);
5105
5106         container = calloc(1, sizeof(zbl_req_cb_s));
5107         if (NULL == container) {
5108                 ERR("calloc() Fail(%d)", errno);
5109                 free(isString);
5110                 free(dataSize);
5111                 free(writeAttribute);
5112                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
5113         }
5114
5115         to = zbl_dbus_get_timeout(zcl_global_proxy);
5116         sub_id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL,
5117                 ZIGBEE_ZCL_GLOBAL_CONTROL_INTERFACE, "write_attributes_rsp",
5118                 ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0, _zbl_response_cb,
5119                 container, _zbl_request_cleanup);
5120
5121         if (0 == sub_id) {
5122                 ERR("g_dbus_connection_signal_subscribe() Fail");
5123                 free(isString);
5124                 free(dataSize);
5125                 free(container);
5126                 free(writeAttribute);
5127                 return ZIGBEE_ERROR_IO_ERROR;
5128         }
5129
5130         container->cb = cb;
5131         container->sid = sub_id;
5132         container->cid = ZBL_ZCL_GLOBAL_WRITE_ATTRIBUTE_REQ;
5133         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
5134         container->userdata = user_data;
5135 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
5136         global_req = calloc(1, sizeof(zb_event_global_default_rsp_s));
5137         if (NULL == global_req) {
5138                 g_dbus_connection_signal_unsubscribe(gdbus_conn, sub_id);
5139                 g_source_remove(container->tid);
5140                 container->tid = 0;
5141                 free(container);
5142                 free(isString);
5143                 free(dataSize);
5144                 free(writeAttribute);
5145                 ERR("calloc() Fail(%d)", errno);
5146                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
5147         }
5148         global_req->ep = dst_ep;
5149         global_req->cluster_id = cluster_id;
5150         global_req->command_id = ZB_ZCL_WRITE_ATTRIBUTES_COMMAND_ID;
5151
5152         container->global_cmd = global_req;
5153         container->handle = handle;
5154
5155         /* Register global request information into handle */
5156         _zbl_register_global_req(handle, container);
5157 #endif
5158
5159         variant = g_dbus_proxy_call_sync(zcl_global_proxy, "write_attributes_req",
5160                 g_variant_new("(@a(y)iqqyyy)", rec_variant, writeAttributeIndex, addr16,
5161                 cluster_id, zcl_frame_ctl, src_ep, dst_ep), G_DBUS_CALL_FLAGS_NONE,
5162                 to, NULL, &dbus_err);
5163
5164         free(isString);
5165         free(dataSize);
5166         free(writeAttribute);
5167
5168         if (!variant) {
5169                 ERR("Failed to get 'write_attributes_req' [%s]", dbus_err->message);
5170                 g_error_free(dbus_err);
5171                 return ZIGBEE_ERROR_IO_ERROR;
5172         }
5173
5174         g_variant_get(variant, "(i)", &result);
5175         DBG("ret = [0x%x]", result);
5176         g_variant_unref(variant);
5177
5178         return result;
5179 }
5180
5181 int zbl_wattr_undivided_req(zigbee_h handle, nwk_addr addr16, unsigned char src_ep,
5182                 unsigned char dst_ep, unsigned char zcl_frame_ctl, unsigned short cluster_id,
5183                 write_attr_record_h *records, int records_len,
5184                 zb_zcl_global_rsp cb, void *user_data)
5185 {
5186         int sub_id, to;
5187         zbl_req_cb_s *container;
5188
5189         int result = ZIGBEE_ERROR_NONE;
5190         GVariant *variant = NULL;
5191         GError *dbus_err = NULL;
5192
5193 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
5194         zb_event_global_default_rsp_s *global_req = NULL;
5195 #endif
5196
5197         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
5198         RETV_IF(NULL == zcl_global_proxy, ZIGBEE_ERROR_IO_ERROR);
5199
5200         DBG("zbl_wattr_undivided_req()");
5201
5202         GVariantBuilder *rec_builder = NULL;
5203         GVariant *rec_variant = NULL;
5204
5205         int i = 0;
5206         int j = 0;
5207
5208         char dSize[3] = {'\0', '\0'};
5209         int writeAttributeIndex = 0;
5210         int size_of_allo = 0;
5211
5212         unsigned char *isString = NULL;
5213         unsigned short *dataSize = NULL;
5214         unsigned char *writeAttribute = NULL;
5215
5216         isString = calloc(records_len + 1, sizeof(unsigned char));
5217         RETVM_IF(NULL == isString, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
5218
5219         dataSize = calloc(records_len + 1, sizeof(unsigned short));
5220         if (NULL == dataSize) {
5221                 ERR("calloc() Fail(%d)", errno);
5222                 free(isString);
5223                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
5224         }
5225
5226         DBG("Records Length %d", records_len);
5227
5228         while (j < records_len) {
5229                 dataSize[j] = zb_get_data_size((*records)[j].type);
5230                 if (0xff != dataSize[j]) {
5231                         isString[j] = 0;
5232                         size_of_allo = size_of_allo + (dataSize[j] + 3);
5233                 } else {
5234                         if ((*records)[j].value) {
5235                                 if ((*records)[j].type == ZB_ZCL_CHRACTER_STRING
5236                                         || (*records)[j].type == ZB_ZCL_OCTAT_STRING) {
5237                                                 isString[j] = 1;
5238                                                 dataSize[j] = (*records)[j].value[0];
5239                                                 size_of_allo = size_of_allo + (dataSize[j] + 3 + 1);
5240                                 } else if ((*records)[j].type == ZB_ZCL_LONG_OCTAT_STRING
5241                                         || (*records)[j].type == ZB_ZCL_LONG_CHRACTER_STRING) {
5242                                         isString[j] = 2;
5243                                         dSize[0] = (*records)[j].value[0];
5244                                         dSize[1] = (*records)[j].value[1];
5245                                         dataSize[j] = dSize[1];
5246                                         dataSize[j] = (dataSize[j] << 8) | dSize[0];
5247                                         size_of_allo = size_of_allo + (dataSize[j] + 3 + 2);
5248                                 }
5249                         } else
5250                                 ERR("Data is not present");
5251                 }
5252                 j++;
5253         }
5254         DBG("size_of_allo Length %d", size_of_allo);
5255
5256         writeAttribute = calloc(size_of_allo + 1, sizeof(unsigned char));
5257         if (NULL == writeAttribute) {
5258                 ERR("Couldn't Allocate Memory");
5259                 free(isString);
5260                 free(dataSize);
5261                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
5262         }
5263
5264         j = 0;
5265         while (j < records_len && writeAttributeIndex < size_of_allo) {
5266                 writeAttribute[writeAttributeIndex++] = ((*records)[j].id) & 0xff;
5267                 writeAttribute[writeAttributeIndex++] = (((*records)[j].id) >> 8) & 0xff;
5268                 writeAttribute[writeAttributeIndex++] = (*records)[j].type;
5269                 for (i = 0; i < (dataSize[j] + isString[j]); i++) {
5270                         writeAttribute[writeAttributeIndex++] = (*records)[j].value[i];
5271                         DBG("0x%02X", (*records)[j].value[i]);
5272                 }
5273                 j++;
5274         }
5275
5276         rec_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
5277         DBG("   ");
5278         for (i = 0; i < writeAttributeIndex ; i++) {
5279                 DBG("0x%02X", writeAttribute[i]);
5280                 g_variant_builder_add(rec_builder, "(y)", writeAttribute[i]);
5281         }
5282
5283         rec_variant = g_variant_builder_end(rec_builder);
5284         g_variant_builder_unref(rec_builder);
5285
5286         container = calloc(1, sizeof(zbl_req_cb_s));
5287         if (NULL == container) {
5288                 ERR("calloc() Fail(%d)", errno);
5289                 free(isString);
5290                 free(dataSize);
5291                 free(writeAttribute);
5292                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
5293         }
5294
5295         to = zbl_dbus_get_timeout(zcl_global_proxy);
5296         sub_id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL,
5297                 ZIGBEE_ZCL_GLOBAL_CONTROL_INTERFACE, "write_attributes_rsp",
5298                 ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0, _zbl_response_cb,
5299                 container, _zbl_request_cleanup);
5300
5301         if (0 == sub_id) {
5302                 ERR("g_dbus_connection_signal_subscribe() Fail");
5303                 free(isString);
5304                 free(dataSize);
5305                 free(container);
5306                 free(writeAttribute);
5307                 return ZIGBEE_ERROR_IO_ERROR;
5308         }
5309
5310         container->cb = cb;
5311         container->sid = sub_id;
5312         container->cid = ZBL_ZCL_GLOBAL_WRITE_ATTRIBUTE_REQ;
5313         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
5314         container->userdata = user_data;
5315 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
5316         global_req = calloc(1, sizeof(zb_event_global_default_rsp_s));
5317         if (NULL == global_req) {
5318                 g_dbus_connection_signal_unsubscribe(gdbus_conn, sub_id);
5319                 g_source_remove(container->tid);
5320                 container->tid = 0;
5321                 free(container);
5322                 free(isString);
5323                 free(dataSize);
5324                 free(writeAttribute);
5325                 ERR("calloc() Fail(%d)", errno);
5326                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
5327         }
5328         global_req->ep = dst_ep;
5329         global_req->cluster_id = cluster_id;
5330         global_req->command_id = ZB_ZCL_WRITE_ATTRIBUTES_UNDIVIDED_COMMAND_ID;
5331
5332         container->global_cmd = global_req;
5333         container->handle = handle;
5334
5335         /* Register global request information into handle */
5336         _zbl_register_global_req(handle, container);
5337 #endif
5338
5339         variant = g_dbus_proxy_call_sync(zcl_global_proxy, "write_attributes_undivided_req",
5340                 g_variant_new("(@a(y)iqqyyy)", rec_variant, writeAttributeIndex, addr16,
5341                 cluster_id, zcl_frame_ctl, src_ep, dst_ep), G_DBUS_CALL_FLAGS_NONE,
5342                 to, NULL, &dbus_err);
5343
5344         free(isString);
5345         free(dataSize);
5346         free(writeAttribute);
5347
5348         if (!variant) {
5349                 ERR("Failed to get 'write_attributes_undivided_req' [%s]", dbus_err->message);
5350                 g_error_free(dbus_err);
5351                 return ZIGBEE_ERROR_IO_ERROR;
5352         }
5353
5354         g_variant_get(variant, "(i)", &result);
5355         DBG("ret = [0x%x]", result);
5356         g_variant_unref(variant);
5357
5358         return result;
5359 }
5360
5361 int zbl_wattr_req_no_rsp(zigbee_h handle, nwk_addr addr16, unsigned char src_ep,
5362                 unsigned char dst_ep, unsigned char zcl_frame_ctl, unsigned short cluster_id,
5363                 write_attr_record_h *records, int records_len)
5364 {
5365         int result = ZIGBEE_ERROR_NONE;
5366         GError *dbus_err = NULL;
5367         GVariant *variant = NULL;
5368
5369         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
5370         RETV_IF(NULL == zcl_global_proxy, ZIGBEE_ERROR_IO_ERROR);
5371
5372         DBG("zbl_wattr_req_no_rsp()");
5373
5374         GVariantBuilder *rec_builder = NULL;
5375         GVariant *rec_variant = NULL;
5376
5377         int i = 0;
5378         int j = 0;
5379
5380         char dSize[3] = {'\0', '\0'};
5381         int writeAttributeIndex = 0;
5382         int size_of_allo = 0;
5383
5384         unsigned char *isString = NULL;
5385         unsigned short *dataSize = NULL;
5386         unsigned char *writeAttribute = NULL;
5387
5388         isString = calloc(records_len + 1, sizeof(unsigned char));
5389         RETVM_IF(NULL == isString, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
5390
5391         dataSize = calloc(records_len + 1, sizeof(unsigned short));
5392         if (NULL == dataSize) {
5393                 ERR("calloc() Fail(%d)", errno);
5394                 free(isString);
5395                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
5396         }
5397
5398         DBG("Records Length %d", records_len);
5399
5400         while (j < records_len) {
5401                 dataSize[j] = zb_get_data_size((*records)[j].type);
5402                 if (0xff != dataSize[j]) {
5403                         isString[j] = 0;
5404                         size_of_allo = size_of_allo + (dataSize[j] + 3);
5405                 } else {
5406                         if ((*records)[j].value) {
5407                                 if ((*records)[j].type == ZB_ZCL_CHRACTER_STRING
5408                                         || (*records)[j].type == ZB_ZCL_OCTAT_STRING) {
5409                                                 isString[j] = 1;
5410                                                 dataSize[j] = (*records)[j].value[0];
5411                                                 size_of_allo = size_of_allo + (dataSize[j] + 3 + 1);
5412                                 } else if ((*records)[j].type == ZB_ZCL_LONG_OCTAT_STRING
5413                                         || (*records)[j].type == ZB_ZCL_LONG_CHRACTER_STRING) {
5414                                         isString[j] = 2;
5415                                         dSize[0] = (*records)[j].value[0];
5416                                         dSize[1] = (*records)[j].value[1];
5417                                         dataSize[j] = dSize[1];
5418                                         dataSize[j] = (dataSize[j] << 8) | dSize[0];
5419                                         size_of_allo = size_of_allo + (dataSize[j] + 3 + 2);
5420                                 }
5421                         } else
5422                                 ERR("Data is not present");
5423                 }
5424                 j++;
5425         }
5426         DBG("size_of_allo Length %d", size_of_allo);
5427
5428         writeAttribute = calloc(size_of_allo + 1, sizeof(unsigned char));
5429         if (NULL == writeAttribute) {
5430                 ERR("Couldn't Allocate Memory");
5431                 free(isString);
5432                 free(dataSize);
5433                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
5434         }
5435
5436         j = 0;
5437         while (j < records_len && writeAttributeIndex < size_of_allo) {
5438                 writeAttribute[writeAttributeIndex++] = ((*records)[j].id) & 0xff;
5439                 writeAttribute[writeAttributeIndex++] = (((*records)[j].id) >> 8) & 0xff;
5440                 writeAttribute[writeAttributeIndex++] = (*records)[j].type;
5441                 for (i = 0; i < (dataSize[j] + isString[j]); i++) {
5442                         writeAttribute[writeAttributeIndex++] = (*records)[j].value[i];
5443                         DBG("0x%02X", (*records)[j].value[i]);
5444                 }
5445                 j++;
5446         }
5447
5448         rec_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
5449         DBG("   ");
5450         for (i = 0; i < writeAttributeIndex ; i++) {
5451                 DBG("0x%02X", writeAttribute[i]);
5452                 g_variant_builder_add(rec_builder, "(y)", writeAttribute[i]);
5453         }
5454
5455         rec_variant = g_variant_builder_end(rec_builder);
5456         g_variant_builder_unref(rec_builder);
5457
5458         variant = g_dbus_proxy_call_sync(zcl_global_proxy, "write_attributes_no_resp",
5459                 g_variant_new("(@a(y)iqqyyy)", rec_variant, writeAttributeIndex, addr16,
5460                 cluster_id, zcl_frame_ctl, src_ep, dst_ep), G_DBUS_CALL_FLAGS_NONE,
5461                 -1, NULL, &dbus_err);
5462
5463         free(isString);
5464         free(dataSize);
5465         free(writeAttribute);
5466
5467         if (!variant) {
5468                 ERR("Failed to get 'write_attributes_no_rep' [%s]", dbus_err->message);
5469                 g_error_free(dbus_err);
5470                 return ZIGBEE_ERROR_IO_ERROR;
5471         }
5472
5473         g_variant_get(variant, "(i)", &result);
5474         DBG("ret = [0x%x]", result);
5475         g_variant_unref(variant);
5476
5477         return result;
5478 }
5479
5480 int zbl_configure_reporting(zigbee_h handle, nwk_addr addr16, unsigned char src_ep,
5481                 unsigned char dst_ep, unsigned char zcl_frame_ctl, unsigned short cluster_id,
5482                 report_config_record_h *records, int records_len,
5483                 zb_zcl_global_rsp cb, void *user_data)
5484 {
5485         int sub_id, to;
5486         zbl_req_cb_s *container;
5487
5488         int result = ZIGBEE_ERROR_NONE;
5489         GVariant *variant = NULL;
5490         GError *dbus_err = NULL;
5491
5492 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
5493         zb_event_global_default_rsp_s *global_req = NULL;
5494 #endif
5495
5496         int i = 0;
5497         int j = 0;
5498         int len = 0;
5499         int count = 0;
5500
5501         GVariantBuilder *rec_builder = NULL;
5502         GVariant *rec_variant = NULL;
5503
5504         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
5505         RETV_IF(NULL == zcl_global_proxy, ZIGBEE_ERROR_IO_ERROR);
5506
5507         DBG("zbl_configure_reporting()");
5508
5509         container = calloc(1, sizeof(zbl_req_cb_s));
5510         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
5511
5512         to = zbl_dbus_get_timeout(zcl_global_proxy);
5513         sub_id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL,
5514                 ZIGBEE_ZCL_GLOBAL_CONTROL_INTERFACE, "configure_reporting_rsp",
5515                 ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0, _zbl_response_cb,
5516                 container, _zbl_request_cleanup);
5517
5518         if (0 == sub_id) {
5519                 ERR("g_dbus_connection_signal_subscribe() Fail");
5520                 free(container);
5521                 return ZIGBEE_ERROR_IO_ERROR;
5522         }
5523
5524         container->cb = cb;
5525         container->sid = sub_id;
5526         container->cid = ZBL_ZCL_GLOBAL_CONFIGURE_REPORTING_REQ;
5527         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
5528         container->userdata = user_data;
5529 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
5530         global_req = calloc(1, sizeof(zb_event_global_default_rsp_s));
5531         if (NULL == global_req) {
5532                 g_dbus_connection_signal_unsubscribe(gdbus_conn, sub_id);
5533                 g_source_remove(container->tid);
5534                 container->tid = 0;
5535                 free(container);
5536                 ERR("calloc() Fail(%d)", errno);
5537                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
5538         }
5539         global_req->ep = dst_ep;
5540         global_req->cluster_id = cluster_id;
5541         global_req->command_id = ZB_ZCL_CONFIGURE_REPORTING_COMMAND_ID;
5542
5543         container->global_cmd = global_req;
5544         container->handle = handle;
5545
5546         /* Register global request information into handle */
5547         _zbl_register_global_req(handle, container);
5548 #endif
5549
5550         rec_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
5551         for (i = 0; i < records_len; i++) {
5552                 g_variant_builder_add(rec_builder, "(y)", (*records)[i].dir);
5553                 DBG("dir = 0x%02X", (*records)[i].dir);
5554                 count += sizeof((*records)[i].dir);
5555                 g_variant_builder_add(rec_builder, "(y)", (*records)[i].id & 0xff);
5556                 g_variant_builder_add(rec_builder, "(y)", ((*records)[i].id >> 8) & 0xff);
5557                 DBG("id = 0x%04X", (*records)[i].id);
5558                 count += sizeof((*records)[i].id);
5559                 g_variant_builder_add(rec_builder, "(y)", (*records)[i].type);
5560                 count += sizeof((*records)[i].type);
5561                 DBG("type = 0x%04X", (*records)[i].type);
5562                 g_variant_builder_add(rec_builder, "(y)", (*records)[i].min_i & 0xff);
5563                 g_variant_builder_add(rec_builder, "(y)", ((*records)[i].min_i >> 8) & 0xff);
5564                 DBG("min_i = 0x%04X", (*records)[i].min_i);
5565                 count += sizeof((*records)[i].min_i);
5566                 g_variant_builder_add(rec_builder, "(y)", (*records)[i].max_i & 0xff);
5567                 g_variant_builder_add(rec_builder, "(y)", ((*records)[i].max_i >> 8) & 0xff);
5568                 DBG("max_i = 0x%04X", (*records)[i].max_i);
5569                 count += sizeof((*records)[i].max_i);
5570
5571                 len = zb_get_data_size((*records)[i].type);
5572                 count += len;
5573                 DBG("change length = %d", len);
5574                 DBG("payload length = %d", count);
5575
5576                 for (j = 0; j < len && (*records)[i].change+j; j++) {
5577                         DBG("records[%d]->value[%d] = %d", i, j, (*records)[i].change[j]);
5578                         g_variant_builder_add(rec_builder, "(y)", (*records)[i].change[j]);
5579                 }
5580
5581         }
5582         rec_variant = g_variant_builder_end(rec_builder);
5583         g_variant_builder_unref(rec_builder);
5584
5585         variant = g_dbus_proxy_call_sync(zcl_global_proxy, "configure_reporting_req",
5586                 g_variant_new("(@a(y)qqqyyy)", rec_variant, count, addr16, cluster_id,
5587                 zcl_frame_ctl, src_ep, dst_ep), G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
5588
5589         if (!variant) {
5590                 ERR("Failed to get 'configure_reporting_req' [%s]", dbus_err->message);
5591                 g_error_free(dbus_err);
5592                 return ZIGBEE_ERROR_IO_ERROR;
5593         }
5594
5595         g_variant_get(variant, "(i)", &result);
5596         DBG("ret = [0x%x]", result);
5597         g_variant_unref(variant);
5598
5599         return result;
5600 }
5601
5602 int zbl_read_configure_reporting(zigbee_h handle, nwk_addr addr16, unsigned char src_ep,
5603                 unsigned char dst_ep, unsigned char zcl_frame_ctl, unsigned short cluster_id,
5604                 read_report_config_record_h *records, int records_len,
5605                 zb_zcl_global_rsp cb, void *user_data)
5606 {
5607         int sub_id, to;
5608         zbl_req_cb_s *container;
5609
5610         int result = ZIGBEE_ERROR_NONE;
5611         GVariant *variant = NULL;
5612         GError *dbus_err = NULL;
5613
5614 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
5615         zb_event_global_default_rsp_s *global_req = NULL;
5616 #endif
5617
5618         int i = 0;
5619         int j = 0;
5620         int size_of_allo = 0;
5621         unsigned short idx = 0;
5622         GVariantBuilder *rec_builder = NULL;
5623         GVariant *rec_variant = NULL;
5624         unsigned char *read_attributes;
5625
5626         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
5627         RETV_IF(NULL == zcl_global_proxy, ZIGBEE_ERROR_IO_ERROR);
5628
5629         DBG("zbl_read_configure_reporting()");
5630
5631         container = calloc(1, sizeof(zbl_req_cb_s));
5632         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
5633
5634         to = zbl_dbus_get_timeout(zcl_global_proxy);
5635         sub_id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL,
5636                 ZIGBEE_ZCL_GLOBAL_CONTROL_INTERFACE, "read_configure_reporting_rsp",
5637                 ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0, _zbl_response_cb,
5638                 container, _zbl_request_cleanup);
5639
5640         if (0 == sub_id) {
5641                 ERR("g_dbus_connection_signal_subscribe() Fail");
5642                 free(container);
5643                 return ZIGBEE_ERROR_IO_ERROR;
5644         }
5645
5646         container->cb = cb;
5647         container->sid = sub_id;
5648         container->cid = ZBL_ZCL_GLOBAL_READ_CONFIGURE_REPORTING_REQ;
5649         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
5650         container->userdata = user_data;
5651 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
5652         global_req = calloc(1, sizeof(zb_event_global_default_rsp_s));
5653         if (NULL == global_req) {
5654                 g_dbus_connection_signal_unsubscribe(gdbus_conn, sub_id);
5655                 g_source_remove(container->tid);
5656                 container->tid = 0;
5657                 free(container);
5658                 ERR("calloc() Fail(%d)", errno);
5659                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
5660         }
5661         global_req->ep = dst_ep;
5662         global_req->cluster_id = cluster_id;
5663         global_req->command_id = ZB_ZCL_READ_REPORTING_CONFIGURATION_COMMAND_ID;
5664
5665         container->global_cmd = global_req;
5666         container->handle = handle;
5667
5668         /* Register global request information into handle */
5669         _zbl_register_global_req(handle, container);
5670 #endif
5671
5672         DBG("Records Length %d", records_len);
5673         /**
5674          * According to zcl spec
5675          * Memory needed for the read_reporting_configured_frame.
5676          * 1 byte(direction) + 2 bytes(AttributeId)
5677          *  = 3 bytes/variable
5678          */
5679         while (j < records_len) {
5680                 size_of_allo = size_of_allo + 3;
5681                 j++;
5682         }
5683         DBG("size_of_allo Length %d", size_of_allo);
5684
5685         read_attributes = calloc(size_of_allo, sizeof(unsigned char));
5686         if (NULL == read_attributes) {
5687                 ERR("Couldn't Allocate Memory");
5688                 g_dbus_connection_signal_unsubscribe(gdbus_conn, container->sid);
5689                 g_source_remove(container->tid);
5690                 container->tid = 0;
5691                 free(container);
5692                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
5693         }
5694         j = 0;
5695         while (j < records_len && idx < size_of_allo) {
5696                 read_attributes[idx++] = (*records)[j].dir;
5697                 read_attributes[idx++] = (*records)[j].id & 0xff;
5698                 read_attributes[idx++] = (*records)[j].id >> 8 & 0xff;
5699                 DBG("Id copied \n");
5700                 j++;
5701         }
5702
5703         rec_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
5704
5705         for (i = 0; i < idx ; i++) {
5706                 DBG("0x%02X", read_attributes[i]);
5707                 g_variant_builder_add(rec_builder, "(y)", read_attributes[i]);
5708         }
5709
5710         rec_variant = g_variant_builder_end(rec_builder);
5711         g_variant_builder_unref(rec_builder);
5712
5713         variant = g_dbus_proxy_call_sync(zcl_global_proxy, "read_configure_reporting",
5714                 g_variant_new("(@a(y)qqqyyy)", rec_variant, idx, addr16, cluster_id, zcl_frame_ctl,
5715                 src_ep, dst_ep), G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
5716
5717         free(read_attributes);
5718
5719         if (!variant) {
5720                 ERR("Failed to get 'read_configure_reporting' [%s]", dbus_err->message);
5721                 g_error_free(dbus_err);
5722                 return ZIGBEE_ERROR_IO_ERROR;
5723         }
5724
5725         g_variant_get(variant, "(i)", &result);
5726         DBG("ret = [0x%x]", result);
5727         g_variant_unref(variant);
5728
5729         return result;
5730 }
5731
5732 int zbl_discover_attr_req(zigbee_h handle, unsigned short addr16, unsigned char src_ep,
5733                 unsigned char dest_ep, unsigned char zcl_frame_ctl, unsigned short cluster_id,
5734                 unsigned short start_id, unsigned char max_attribute_ids,
5735                 zb_zcl_global_discover_attr_rsp cb, void *user_data)
5736 {
5737         int sub_id, to;
5738         zbl_req_cb_s *container;
5739
5740         int result = ZIGBEE_ERROR_NONE;
5741         GVariant *variant = NULL;
5742         GError *dbus_err = NULL;
5743
5744 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
5745         zb_event_global_default_rsp_s *global_req = NULL;
5746 #endif
5747
5748         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
5749         RETV_IF(NULL == zcl_global_proxy, ZIGBEE_ERROR_IO_ERROR);
5750
5751         DBG("zbl_discover_attr_req()");
5752
5753         container = calloc(1, sizeof(zbl_req_cb_s));
5754         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
5755
5756         to = zbl_dbus_get_timeout(zcl_global_proxy);
5757         sub_id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL,
5758                         ZIGBEE_ZCL_GLOBAL_CONTROL_INTERFACE,  "discover_attribute_rsp",
5759                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
5760                         _zbl_response_cb, container, _zbl_request_cleanup);
5761
5762         if (0 == sub_id) {
5763                 ERR("g_dbus_connection_signal_subscribe() Fail");
5764                 free(container);
5765                 return ZIGBEE_ERROR_IO_ERROR;
5766         }
5767
5768         container->cb = cb;
5769         container->sid = sub_id;
5770         container->cid = ZBL_ZCL_GLOBAL_DISCOVER_ATTRIBUTE_REQ;
5771         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
5772         container->userdata = user_data;
5773 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
5774         global_req = calloc(1, sizeof(zb_event_global_default_rsp_s));
5775         if (NULL == global_req) {
5776                 g_dbus_connection_signal_unsubscribe(gdbus_conn, sub_id);
5777                 g_source_remove(container->tid);
5778                 container->tid = 0;
5779                 free(container);
5780                 ERR("calloc() Fail(%d)", errno);
5781                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
5782         }
5783         global_req->ep = dest_ep;
5784         global_req->cluster_id = cluster_id;
5785         global_req->command_id = ZB_ZCL_DISCOVER_ATTRIBUTES_COMMAND_ID;
5786
5787         container->global_cmd = global_req;
5788         container->handle = handle;
5789
5790         /* Register global request information into handle */
5791         _zbl_register_global_req(handle, container);
5792 #endif
5793
5794         variant = g_dbus_proxy_call_sync(zcl_global_proxy, "discover_attributes",
5795                 g_variant_new("(qyyqqy)",
5796                 addr16, dest_ep, zcl_frame_ctl, cluster_id, start_id, max_attribute_ids),
5797                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
5798
5799         if (!variant) {
5800                 ERR("Failed to get 'discover_attributes' [%s]", dbus_err->message);
5801                 g_error_free(dbus_err);
5802                 return ZIGBEE_ERROR_IO_ERROR;
5803         }
5804
5805         g_variant_get(variant, "(i)", &result);
5806         DBG("ret = [0x%x]", result);
5807         g_variant_unref(variant);
5808
5809         return result;
5810 }
5811
5812 int zbl_discover_cmds_gen(zigbee_h handle, nwk_addr addr16, unsigned char src_ep, unsigned char dst_ep,
5813                 unsigned char zcl_frame_ctl, unsigned short cluster_id, unsigned char start_command_id,
5814                 unsigned char max_command_ids, zb_zcl_global_discover_cmds_rsp cb, void *user_data)
5815 {
5816         int sub_id, to;
5817         zbl_req_cb_s *container;
5818
5819         int result = ZIGBEE_ERROR_NONE;
5820         GVariant *variant = NULL;
5821         GError *dbus_err = NULL;
5822
5823 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
5824         zb_event_global_default_rsp_s *global_req = NULL;
5825 #endif
5826
5827         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
5828         RETV_IF(NULL == zcl_global_proxy, ZIGBEE_ERROR_IO_ERROR);
5829
5830         DBG("zbl_discover_attr_gen()");
5831
5832         container = calloc(1, sizeof(zbl_req_cb_s));
5833         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
5834
5835         to = zbl_dbus_get_timeout(zcl_global_proxy);
5836         sub_id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL,
5837                 ZIGBEE_ZCL_GLOBAL_CONTROL_INTERFACE, "discover_commands_received_rsp",
5838                 ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0, _zbl_response_cb, container,
5839                 _zbl_request_cleanup);
5840
5841         if (0 == sub_id) {
5842                 ERR("g_dbus_connection_signal_subscribe() Fail");
5843                 free(container);
5844                 return ZIGBEE_ERROR_IO_ERROR;
5845         }
5846
5847         container->cb = cb;
5848         container->sid = sub_id;
5849         container->cid = ZBL_ZCL_GLOBAL_DISCOVER_COMMAND_RECEIVED_REQ;
5850         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
5851         container->userdata = user_data;
5852 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
5853         global_req = calloc(1, sizeof(zb_event_global_default_rsp_s));
5854         if (NULL == global_req) {
5855                 g_dbus_connection_signal_unsubscribe(gdbus_conn, sub_id);
5856                 g_source_remove(container->tid);
5857                 container->tid = 0;
5858                 free(container);
5859                 ERR("calloc() Fail(%d)", errno);
5860                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
5861         }
5862         global_req->ep = dst_ep;
5863         global_req->cluster_id = cluster_id;
5864         global_req->command_id = ZB_ZCL_DISCOVER_COMMANDS_GENERATED_COMMAND_ID;
5865
5866         container->global_cmd = global_req;
5867         container->handle = handle;
5868
5869         /* Register global request information into handle */
5870         _zbl_register_global_req(handle, container);
5871 #endif
5872
5873         variant = g_dbus_proxy_call_sync(zcl_global_proxy, "discover_commands_received",
5874                 g_variant_new("(qyyqqy)", addr16, dst_ep, zcl_frame_ctl, cluster_id,
5875                 start_command_id, max_command_ids), G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
5876
5877         if (!variant) {
5878                 ERR("Failed to get 'discover_commands_received' [%s]", dbus_err->message);
5879                 g_error_free(dbus_err);
5880                 return ZIGBEE_ERROR_IO_ERROR;
5881         }
5882
5883         g_variant_get(variant, "(i)", &result);
5884         DBG("ret = [0x%x]", result);
5885         g_variant_unref(variant);
5886
5887         return result;
5888 }
5889
5890 int zbl_discover_cmds_recv(zigbee_h handle, nwk_addr addr16, unsigned char src_ep, unsigned char dst_ep,
5891                 unsigned char zcl_frame_ctl, unsigned short cluster_id, unsigned char start_command_id,
5892                 unsigned char max_command_ids, zb_zcl_global_discover_cmds_rsp cb, void *user_data)
5893 {
5894         int sub_id, to;
5895         zbl_req_cb_s *container;
5896
5897         int result = ZIGBEE_ERROR_NONE;
5898         GVariant *variant = NULL;
5899         GError *dbus_err = NULL;
5900
5901 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
5902         zb_event_global_default_rsp_s *global_req = NULL;
5903 #endif
5904
5905         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
5906         RETV_IF(NULL == zcl_global_proxy, ZIGBEE_ERROR_IO_ERROR);
5907
5908         DBG("zbl_discover_cmds_recv()");
5909
5910         container = calloc(1, sizeof(zbl_req_cb_s));
5911         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
5912
5913         to = zbl_dbus_get_timeout(zcl_global_proxy);
5914         sub_id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL,
5915                 ZIGBEE_ZCL_GLOBAL_CONTROL_INTERFACE, "discover_commands_received_rsp",
5916                 ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0, _zbl_response_cb, container,
5917                 _zbl_request_cleanup);
5918
5919         if (0 == sub_id) {
5920                 ERR("g_dbus_connection_signal_subscribe() Fail");
5921                 free(container);
5922                 return ZIGBEE_ERROR_IO_ERROR;
5923         }
5924
5925         container->cb = cb;
5926         container->sid = sub_id;
5927         container->cid = ZBL_ZCL_GLOBAL_DISCOVER_COMMAND_GENERATED_REQ;
5928         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
5929         container->userdata = user_data;
5930 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
5931         global_req = calloc(1, sizeof(zb_event_global_default_rsp_s));
5932         if (NULL == global_req) {
5933                 g_dbus_connection_signal_unsubscribe(gdbus_conn, sub_id);
5934                 g_source_remove(container->tid);
5935                 container->tid = 0;
5936                 free(container);
5937                 ERR("calloc() Fail(%d)", errno);
5938                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
5939         }
5940         global_req->ep = dst_ep;
5941         global_req->cluster_id = cluster_id;
5942         global_req->command_id = ZB_ZCL_DISCOVER_COMMANDS_RECEIVED_COMMAND_ID;
5943
5944         container->global_cmd = global_req;
5945         container->handle = handle;
5946
5947         /* Register global request information into handle */
5948         _zbl_register_global_req(handle, container);
5949 #endif
5950
5951         variant = g_dbus_proxy_call_sync(zcl_global_proxy, "discover_commands_received",
5952                 g_variant_new("(qyyqqy)", addr16, dst_ep, zcl_frame_ctl, cluster_id,
5953                 start_command_id, max_command_ids), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
5954
5955         if (!variant) {
5956                 ERR("Failed to get 'discover_commands_received' [%s]", dbus_err->message);
5957                 g_error_free(dbus_err);
5958                 return ZIGBEE_ERROR_IO_ERROR;
5959         }
5960
5961         g_variant_get(variant, "(i)", &result);
5962         DBG("ret = [0x%x]", result);
5963         g_variant_unref(variant);
5964
5965         return result;
5966 }
5967
5968 int zbl_discover_attr_ext(zigbee_h handle, nwk_addr addr16, unsigned char src_ep,
5969         unsigned char dst_ep, unsigned char zcl_frame_ctl, unsigned short cluster_id,
5970         unsigned short start_id, unsigned char max_attribute_ids,
5971         zb_zcl_global_discover_attr_extended_rsp cb, void *user_data)
5972 {
5973         int sub_id, to;
5974         zbl_req_cb_s *container;
5975
5976         int result = ZIGBEE_ERROR_NONE;
5977         GVariant *variant = NULL;
5978         GError *dbus_err = NULL;
5979
5980 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
5981         zb_event_global_default_rsp_s *global_req = NULL;
5982 #endif
5983
5984         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
5985         RETV_IF(NULL == zcl_global_proxy, ZIGBEE_ERROR_IO_ERROR);
5986
5987         DBG("zbl_discover_attr_ext()");
5988
5989         container = calloc(1, sizeof(zbl_req_cb_s));
5990         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
5991
5992         to = zbl_dbus_get_timeout(zcl_global_proxy);
5993         sub_id = g_dbus_connection_signal_subscribe(gdbus_conn, NULL,
5994                 ZIGBEE_ZCL_GLOBAL_CONTROL_INTERFACE, "discover_attributes_extended_rsp",
5995                 ZIGBEE_CONTROL_OBJECT_PATH,     NULL, 0, _zbl_response_cb, container,
5996                 _zbl_request_cleanup);
5997
5998         if (0 == sub_id) {
5999                 ERR("g_dbus_connection_signal_subscribe() Fail");
6000                 free(container);
6001                 return ZIGBEE_ERROR_IO_ERROR;
6002         }
6003
6004         container->cb = cb;
6005         container->sid = sub_id;
6006         container->cid = ZBL_ZCL_GLOBAL_DISCOVER_ATTRIBUTE_EXTENDED_REQ;
6007         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
6008         container->userdata = user_data;
6009 #ifdef ZB_FEATURE_GLOBAL_RSP_SYNC
6010         global_req = calloc(1, sizeof(zb_event_global_default_rsp_s));
6011         if (NULL == global_req) {
6012                 g_dbus_connection_signal_unsubscribe(gdbus_conn, sub_id);
6013                 g_source_remove(container->tid);
6014                 container->tid = 0;
6015                 free(container);
6016                 ERR("calloc() Fail(%d)", errno);
6017                 return ZIGBEE_ERROR_OUT_OF_MEMORY;
6018         }
6019         global_req->ep = dst_ep;
6020         global_req->cluster_id = cluster_id;
6021         global_req->command_id = ZB_ZCL_DISCOVER_ATTRIBUTES_EXTENDED_COMMAND_ID;
6022
6023         container->global_cmd = global_req;
6024         container->handle = handle;
6025
6026         /* Register global request information into handle */
6027         _zbl_register_global_req(handle, container);
6028 #endif
6029
6030         variant = g_dbus_proxy_call_sync(zcl_global_proxy, "discover_attributes_extended",
6031                 g_variant_new("(qyyqqy)", addr16, dst_ep, zcl_frame_ctl, cluster_id, start_id,
6032                 max_attribute_ids), G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
6033
6034         if (!variant) {
6035                 ERR("Failed to get 'discover_attributes_extended' [%s]", dbus_err->message);
6036                 g_error_free(dbus_err);
6037                 return ZIGBEE_ERROR_IO_ERROR;
6038         }
6039
6040         g_variant_get(variant, "(i)", &result);
6041         DBG("ret = [0x%x]", result);
6042         g_variant_unref(variant);
6043
6044         return result;
6045 }
6046
6047 int zbl_reset_alarm(nwk_addr addr16, unsigned char ep, unsigned char alarm_code,
6048                 unsigned short cluster_id)
6049 {
6050         int result = ZIGBEE_ERROR_NONE;
6051         GVariant *variant = NULL;
6052         GError *dbus_err = NULL;
6053
6054         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6055         RETV_IF(NULL == alarm_gproxy, ZIGBEE_ERROR_IO_ERROR);
6056
6057         variant = g_dbus_proxy_call_sync(alarm_gproxy, "reset_alarm",
6058                 g_variant_new("(qyyq)", addr16, ep, alarm_code, cluster_id),
6059                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6060
6061         if (!variant) {
6062                 ERR("Failed to get 'reset_alarm' [%s]", dbus_err->message);
6063                 g_error_free(dbus_err);
6064                 return ZIGBEE_ERROR_IO_ERROR;
6065         }
6066
6067         g_variant_get(variant, "(i)", &result);
6068         DBG("ret = [0x%x]", result);
6069         g_variant_unref(variant);
6070
6071         return result;
6072 }
6073
6074 int zbl_reset_all_alarm(nwk_addr addr16, unsigned char ep)
6075 {
6076         int result = ZIGBEE_ERROR_NONE;
6077         GVariant *variant = NULL;
6078         GError *dbus_err = NULL;
6079
6080         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6081         RETV_IF(NULL == alarm_gproxy, ZIGBEE_ERROR_IO_ERROR);
6082
6083         variant = g_dbus_proxy_call_sync(alarm_gproxy, "reset_all_alarm",
6084                 g_variant_new("(qy)", addr16, ep), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6085
6086         if (!variant) {
6087                 ERR("Failed to get 'reset_all_alarm' [%s]", dbus_err->message);
6088                 g_error_free(dbus_err);
6089                 return ZIGBEE_ERROR_IO_ERROR;
6090         }
6091
6092         g_variant_get(variant, "(i)", &result);
6093         DBG("ret = [0x%x]", result);
6094         g_variant_unref(variant);
6095
6096         return result;
6097 }
6098
6099 int zbl_get_alarm(nwk_addr addr16, unsigned char ep, zb_zcl_alarm_get_alarm_rsp cb,
6100                 void *user_data)
6101 {
6102         int sub_id, to;
6103         zbl_req_cb_s *container;
6104
6105         int result = ZIGBEE_ERROR_NONE;
6106         GVariant *variant = NULL;
6107         GError *dbus_err = NULL;
6108
6109         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6110         RETV_IF(NULL == alarm_gproxy, ZIGBEE_ERROR_IO_ERROR);
6111
6112         DBG("zbl_get_alarm()");
6113
6114         container = calloc(1, sizeof(zbl_req_cb_s));
6115         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
6116
6117         to = zbl_dbus_get_timeout(alarm_gproxy);
6118         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
6119                         ZIGBEE_ZCL_ALARM_INTERFACE,  "get_alarm_rsp", ZIGBEE_CONTROL_OBJECT_PATH,
6120                         NULL, 0, _zbl_response_cb, container, _zbl_request_cleanup);
6121
6122         if (0 == sub_id) {
6123                 ERR("g_dbus_connection_signal_subscribe() Fail");
6124                 free(container);
6125                 return ZIGBEE_ERROR_IO_ERROR;
6126         }
6127
6128         container->cb = cb;
6129         container->sid = sub_id;
6130         container->cid = ZBL_ZCL_ALARM_GET_ALARM_REQ;
6131         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
6132         container->userdata = user_data;
6133
6134         variant = g_dbus_proxy_call_sync(alarm_gproxy, "get_alarm",
6135                 g_variant_new("(qy)", addr16, ep), G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
6136
6137         if (!variant) {
6138                 ERR("Failed to get 'get_alarm' [%s]", dbus_err->message);
6139                 g_error_free(dbus_err);
6140                 return ZIGBEE_ERROR_IO_ERROR;
6141         }
6142
6143         g_variant_get(variant, "(i)", &result);
6144         DBG("ret = [0x%x]", result);
6145         g_variant_unref(variant);
6146
6147         return result;
6148 }
6149
6150 int zbl_reset_all_alarm_log(nwk_addr addr16, unsigned char ep)
6151 {
6152         int result = ZIGBEE_ERROR_NONE;
6153         GVariant *variant = NULL;
6154         GError *dbus_err = NULL;
6155
6156         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6157         RETV_IF(NULL == alarm_gproxy, ZIGBEE_ERROR_IO_ERROR);
6158
6159         variant = g_dbus_proxy_call_sync(alarm_gproxy, "reset_alarm_log",
6160                 g_variant_new("(qy)", addr16, ep), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6161
6162         if (!variant) {
6163                 ERR("Failed to get 'reset_alarm_log' [%s]", dbus_err->message);
6164                 g_error_free(dbus_err);
6165                 return ZIGBEE_ERROR_IO_ERROR;
6166         }
6167
6168         g_variant_get(variant, "(i)", &result);
6169         DBG("ret = [0x%x]", result);
6170         g_variant_unref(variant);
6171
6172         return result;
6173 }
6174
6175 int zbl_ccontrol_move_to_hue(nwk_addr addr16, unsigned char ep,
6176                 unsigned char hue, unsigned char direction,
6177                 unsigned short transition_time)
6178 {
6179         int result = ZIGBEE_ERROR_NONE;
6180         GVariant *variant = NULL;
6181         GError *dbus_err = NULL;
6182
6183         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6184         RETV_IF(NULL == zcl_color_control_proxy, ZIGBEE_ERROR_IO_ERROR);
6185
6186         variant = g_dbus_proxy_call_sync(zcl_color_control_proxy, "move_to_hue",
6187                         g_variant_new("(qyyyq)", addr16, ep, hue, direction, transition_time),
6188                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6189
6190         if (!variant) {
6191                 ERR("Failed to get 'move_to_hue' [%s]", dbus_err->message);
6192                 g_error_free(dbus_err);
6193                 return ZIGBEE_ERROR_IO_ERROR;
6194         }
6195
6196         g_variant_get(variant, "(i)", &result);
6197         DBG("ret = [0x%x]", result);
6198         g_variant_unref(variant);
6199
6200         return result;
6201 }
6202
6203
6204 int zbl_ccontrol_move_hue(nwk_addr addr16, unsigned char ep,
6205                 unsigned char move_mode, unsigned char rate)
6206 {
6207         int result = ZIGBEE_ERROR_NONE;
6208         GVariant *variant = NULL;
6209         GError *dbus_err = NULL;
6210
6211         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6212         RETV_IF(NULL == zcl_color_control_proxy, ZIGBEE_ERROR_IO_ERROR);
6213
6214         variant = g_dbus_proxy_call_sync(zcl_color_control_proxy, "move_hue",
6215                         g_variant_new("(qyyy)", addr16, ep, move_mode, rate),
6216                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6217
6218         if (!variant) {
6219                 ERR("Failed to get 'move_hue' [%s]", dbus_err->message);
6220                 g_error_free(dbus_err);
6221                 return ZIGBEE_ERROR_IO_ERROR;
6222         }
6223
6224         g_variant_get(variant, "(i)", &result);
6225         DBG("ret = [0x%x]", result);
6226         g_variant_unref(variant);
6227
6228         return result;
6229 }
6230
6231 int zbl_ccontrol_step_hue(nwk_addr addr16, unsigned char ep,
6232                 unsigned char step_mode, unsigned char step_size,
6233                 unsigned char transition_time)
6234 {
6235         int result = ZIGBEE_ERROR_NONE;
6236         GVariant *variant = NULL;
6237         GError *dbus_err = NULL;
6238
6239         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6240         RETV_IF(NULL == zcl_color_control_proxy, ZIGBEE_ERROR_IO_ERROR);
6241
6242         variant = g_dbus_proxy_call_sync(zcl_color_control_proxy, "step_hue",
6243                         g_variant_new("(qyyyy)", addr16, ep, step_mode, step_size, transition_time),
6244                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6245
6246         if (!variant) {
6247                 ERR("Failed to get 'step_hue' [%s]", dbus_err->message);
6248                 g_error_free(dbus_err);
6249                 return ZIGBEE_ERROR_IO_ERROR;
6250         }
6251
6252         g_variant_get(variant, "(i)", &result);
6253         DBG("ret = [0x%x]", result);
6254         g_variant_unref(variant);
6255
6256         return result;
6257 }
6258
6259 int zbl_ccontrol_move_to_saturation(nwk_addr addr16, unsigned char ep,
6260                 unsigned char saturation, unsigned short transition_time)
6261 {
6262         int result = ZIGBEE_ERROR_NONE;
6263         GVariant *variant = NULL;
6264         GError *dbus_err = NULL;
6265
6266         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6267         RETV_IF(NULL == zcl_color_control_proxy, ZIGBEE_ERROR_IO_ERROR);
6268
6269         variant = g_dbus_proxy_call_sync(zcl_color_control_proxy, "move_to_saturation",
6270                         g_variant_new("(qyyq)", addr16, ep, saturation, transition_time),
6271                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6272
6273         if (!variant) {
6274                 ERR("Failed to get 'move_to_saturation' [%s]", dbus_err->message);
6275                 g_error_free(dbus_err);
6276                 return ZIGBEE_ERROR_IO_ERROR;
6277         }
6278
6279         g_variant_get(variant, "(i)", &result);
6280         DBG("ret = [0x%x]", result);
6281         g_variant_unref(variant);
6282
6283         return result;
6284 }
6285
6286 int zbl_ccontrol_move_saturation(nwk_addr addr16, unsigned char ep,
6287                 unsigned char move_mode, unsigned char rate)
6288 {
6289         int result = ZIGBEE_ERROR_NONE;
6290         GVariant *variant = NULL;
6291         GError *dbus_err = NULL;
6292
6293         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6294         RETV_IF(NULL == zcl_color_control_proxy, ZIGBEE_ERROR_IO_ERROR);
6295
6296         variant = g_dbus_proxy_call_sync(zcl_color_control_proxy, "move_saturation",
6297                         g_variant_new("(qyyy)", addr16, ep, move_mode, rate),
6298                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6299
6300         if (!variant) {
6301                 ERR("Failed to get 'move_saturation' [%s]", dbus_err->message);
6302                 g_error_free(dbus_err);
6303                 return ZIGBEE_ERROR_IO_ERROR;
6304         }
6305
6306         g_variant_get(variant, "(i)", &result);
6307         DBG("ret = [0x%x]", result);
6308         g_variant_unref(variant);
6309
6310         return result;
6311 }
6312
6313 int zbl_ccontrol_step_saturation(nwk_addr addr16, unsigned char ep,
6314                 unsigned char step_mode, unsigned char step_size,
6315                 unsigned char transition_time)
6316 {
6317         int result = ZIGBEE_ERROR_NONE;
6318         GVariant *variant = NULL;
6319         GError *dbus_err = NULL;
6320
6321         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6322         RETV_IF(NULL == zcl_color_control_proxy, ZIGBEE_ERROR_IO_ERROR);
6323
6324         variant = g_dbus_proxy_call_sync(zcl_color_control_proxy, "step_saturation",
6325                         g_variant_new("(qyyyy)", addr16, ep, step_mode, step_size, transition_time),
6326                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6327
6328         if (!variant) {
6329                 ERR("Failed to get 'step_saturation' [%s]", dbus_err->message);
6330                 g_error_free(dbus_err);
6331                 return ZIGBEE_ERROR_IO_ERROR;
6332         }
6333
6334         g_variant_get(variant, "(i)", &result);
6335         DBG("ret = [0x%x]", result);
6336         g_variant_unref(variant);
6337
6338         return result;
6339 }
6340
6341 int zbl_ccontrol_move_to_hue_and_saturation(nwk_addr addr16, unsigned char ep,
6342                 unsigned char hue, unsigned char saturation,
6343                 unsigned short transition_time)
6344 {
6345         int result = ZIGBEE_ERROR_NONE;
6346         GVariant *variant = NULL;
6347         GError *dbus_err = NULL;
6348
6349         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6350         RETV_IF(NULL == zcl_color_control_proxy, ZIGBEE_ERROR_IO_ERROR);
6351
6352         variant = g_dbus_proxy_call_sync(zcl_color_control_proxy, "move_to_hue_and_saturation",
6353                         g_variant_new("(qyyyq)", addr16, ep, hue, saturation, transition_time),
6354                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6355
6356         if (!variant) {
6357                 ERR("Failed to get 'move_to_hue_and_saturation' [%s]", dbus_err->message);
6358                 g_error_free(dbus_err);
6359                 return ZIGBEE_ERROR_IO_ERROR;
6360         }
6361
6362         g_variant_get(variant, "(i)", &result);
6363         DBG("ret = [0x%x]", result);
6364         g_variant_unref(variant);
6365
6366         return result;
6367 }
6368
6369 int zbl_ccontrol_move_to_color(nwk_addr addr16, unsigned char ep,
6370                 unsigned short color_x, unsigned short color_y,
6371                 unsigned short transition_time)
6372 {
6373         int result = ZIGBEE_ERROR_NONE;
6374         GVariant *variant = NULL;
6375         GError *dbus_err = NULL;
6376
6377         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6378         RETV_IF(NULL == zcl_color_control_proxy, ZIGBEE_ERROR_IO_ERROR);
6379
6380         variant = g_dbus_proxy_call_sync(zcl_color_control_proxy, "move_to_color",
6381                         g_variant_new("(qyqqq)", addr16, ep, color_x, color_y, transition_time),
6382                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6383
6384         if (!variant) {
6385                 ERR("Failed to get 'move_to_color' [%s]", dbus_err->message);
6386                 g_error_free(dbus_err);
6387                 return ZIGBEE_ERROR_IO_ERROR;
6388         }
6389
6390         g_variant_get(variant, "(i)", &result);
6391         DBG("ret = [0x%x]", result);
6392         g_variant_unref(variant);
6393
6394         return result;
6395 }
6396
6397 int zbl_ccontrol_move_color(nwk_addr addr16, unsigned char ep,
6398                 unsigned short rate_x, unsigned short rate_y)
6399 {
6400         int result = ZIGBEE_ERROR_NONE;
6401         GVariant *variant = NULL;
6402         GError *dbus_err = NULL;
6403
6404         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6405         RETV_IF(NULL == zcl_color_control_proxy, ZIGBEE_ERROR_IO_ERROR);
6406
6407         variant = g_dbus_proxy_call_sync(zcl_color_control_proxy, "move_color",
6408                         g_variant_new("(qyqq)", addr16, ep, rate_x, rate_y),
6409                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6410
6411         if (!variant) {
6412                 ERR("Failed to get 'move_color' [%s]", dbus_err->message);
6413                 g_error_free(dbus_err);
6414                 return ZIGBEE_ERROR_IO_ERROR;
6415         }
6416
6417         g_variant_get(variant, "(i)", &result);
6418         DBG("ret = [0x%x]", result);
6419         g_variant_unref(variant);
6420
6421         return result;
6422 }
6423
6424 int zbl_ccontrol_step_color(nwk_addr addr16, unsigned char ep,
6425                 unsigned short step_x, unsigned short step_y,
6426                 unsigned short transition_time)
6427 {
6428         int result = ZIGBEE_ERROR_NONE;
6429         GVariant *variant = NULL;
6430         GError *dbus_err = NULL;
6431
6432         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6433         RETV_IF(NULL == zcl_color_control_proxy, ZIGBEE_ERROR_IO_ERROR);
6434
6435         variant = g_dbus_proxy_call_sync(zcl_color_control_proxy, "step_color",
6436                         g_variant_new("(qyqqq)", addr16, ep, step_x, step_y, transition_time),
6437                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6438
6439         if (!variant) {
6440                 ERR("Failed to get 'step_color' [%s]", dbus_err->message);
6441                 g_error_free(dbus_err);
6442                 return ZIGBEE_ERROR_IO_ERROR;
6443         }
6444
6445         g_variant_get(variant, "(i)", &result);
6446         DBG("ret = [0x%x]", result);
6447         g_variant_unref(variant);
6448
6449         return result;
6450 }
6451
6452 int zbl_ccontrol_move_to_color_temperature(nwk_addr addr16, unsigned char ep,
6453                 unsigned short color_temperature,
6454                 unsigned short transition_time)
6455 {
6456         int result = ZIGBEE_ERROR_NONE;
6457         GVariant *variant = NULL;
6458         GError *dbus_err = NULL;
6459
6460         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6461         RETV_IF(NULL == zcl_color_control_proxy, ZIGBEE_ERROR_IO_ERROR);
6462
6463         variant = g_dbus_proxy_call_sync(zcl_color_control_proxy, "move_color_temperature",
6464                         g_variant_new("(qyqq)", addr16, ep, color_temperature, transition_time),
6465                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6466
6467         if (!variant) {
6468                 ERR("Failed to get 'move_color_temperature' [%s]", dbus_err->message);
6469                 g_error_free(dbus_err);
6470                 return ZIGBEE_ERROR_IO_ERROR;
6471         }
6472
6473         g_variant_get(variant, "(i)", &result);
6474         DBG("ret = [0x%x]", result);
6475         g_variant_unref(variant);
6476
6477         return result;
6478 }
6479
6480 int zbl_reset_factory_default(nwk_addr addr16, unsigned char ep)
6481 {
6482         int result = ZIGBEE_ERROR_NONE;
6483         GVariant *variant = NULL;
6484         GError *dbus_err = NULL;
6485
6486         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6487         RETV_IF(NULL == zcl_basic_proxy, ZIGBEE_ERROR_IO_ERROR);
6488
6489         variant = g_dbus_proxy_call_sync(zcl_basic_proxy, "reset_factory_default",
6490                 g_variant_new("(qy)", addr16, ep), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6491
6492         if (!variant) {
6493                 ERR("Failed to get 'reset_factory_default' [%s]", dbus_err->message);
6494                 g_error_free(dbus_err);
6495                 return ZIGBEE_ERROR_IO_ERROR;
6496         }
6497
6498         g_variant_get(variant, "(i)", &result);
6499         DBG("ret = [0x%x]", result);
6500         g_variant_unref(variant);
6501
6502         return result;
6503 }
6504
6505 int zbl_identify(nwk_addr addr16, unsigned char dst_ep, unsigned short identify_time)
6506 {
6507         int result = ZIGBEE_ERROR_NONE;
6508         GVariant *variant = NULL;
6509         GError *dbus_err = NULL;
6510
6511         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6512         RETV_IF(NULL == zcl_identify_proxy, ZIGBEE_ERROR_IO_ERROR);
6513
6514         variant = g_dbus_proxy_call_sync(zcl_identify_proxy, "identify",
6515                 g_variant_new("(qyq)", addr16, dst_ep, identify_time),
6516                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6517
6518         if (!variant) {
6519                 ERR("Failed to get 'identify' [%s]", dbus_err->message);
6520                 g_error_free(dbus_err);
6521                 return ZIGBEE_ERROR_IO_ERROR;
6522         }
6523
6524         g_variant_get(variant, "(i)", &result);
6525         DBG("ret = [0x%x]", result);
6526         g_variant_unref(variant);
6527
6528         return result;
6529 }
6530
6531 int zbl_identify_query(nwk_addr addr16, unsigned char dst_ep,
6532                 zb_zcl_identify_query_cb cb, void *user_data)
6533 {
6534         int result = ZIGBEE_ERROR_NONE;
6535         GVariant *variant = NULL;
6536         GError *dbus_err = NULL;
6537
6538         int sub_id, to;
6539         zbl_req_cb_s *container;
6540
6541         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6542         RETV_IF(NULL == zcl_identify_proxy, ZIGBEE_ERROR_IO_ERROR);
6543
6544         DBG("zbl_identify_query()");
6545
6546         container = calloc(1, sizeof(zbl_req_cb_s));
6547         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
6548
6549         to = zbl_dbus_get_timeout(zcl_identify_proxy);
6550         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
6551                         ZIGBEE_ZCL_IDENTIFY_INTERFACE, "query_rsp", ZIGBEE_CONTROL_OBJECT_PATH,
6552                         NULL, 0, _zbl_response_cb, container, _zbl_request_cleanup);
6553
6554         if (0 == sub_id) {
6555                 ERR("g_dbus_connection_signal_subscribe() Fail");
6556                 free(container);
6557                 return ZIGBEE_ERROR_IO_ERROR;
6558         }
6559
6560         container->cb = cb;
6561         container->sid = sub_id;
6562         container->cid = ZBL_ZCL_IDENTIFY_QUERY_REQ;
6563         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
6564         container->userdata = user_data;
6565
6566         variant = g_dbus_proxy_call_sync(zcl_identify_proxy, "query",
6567                 g_variant_new("(qy)", addr16, dst_ep), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6568
6569         if (!variant) {
6570                 ERR("Failed to get 'query' [%s]", dbus_err->message);
6571                 g_error_free(dbus_err);
6572                 return ZIGBEE_ERROR_IO_ERROR;
6573         }
6574
6575         g_variant_get(variant, "(i)", &result);
6576         DBG("ret = [0x%x]", result);
6577         g_variant_unref(variant);
6578
6579         return result;
6580 }
6581
6582 int zbl_add_group(nwk_addr addr16, unsigned char ep, unsigned short group_id,
6583                 const char *group_name, zb_zcl_group_add_group_rsp cb, void *user_data)
6584 {
6585         int result = ZIGBEE_ERROR_NONE;
6586         GVariant *variant = NULL;
6587         GError *dbus_err = NULL;
6588
6589         int sub_id, to;
6590         zbl_req_cb_s *container;
6591
6592         int j = 0;
6593         GVariant *groupname_variant = NULL;
6594         GVariantBuilder *groupname_builder = NULL;
6595
6596         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6597         RETV_IF(NULL == zcl_group_proxy, ZIGBEE_ERROR_IO_ERROR);
6598
6599         DBG("zbl_add_group()");
6600
6601         container = calloc(1, sizeof(zbl_req_cb_s));
6602         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
6603
6604         to = zbl_dbus_get_timeout(zcl_group_proxy);
6605         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
6606                         ZIGBEE_ZCL_GROUP_INTERFACE, "add_group_rsp", ZIGBEE_CONTROL_OBJECT_PATH,
6607                         NULL, 0, _zbl_response_cb, container, _zbl_request_cleanup);
6608
6609         if (0 == sub_id) {
6610                 ERR("g_dbus_connection_signal_subscribe() Fail");
6611                 free(container);
6612                 return ZIGBEE_ERROR_IO_ERROR;
6613         }
6614
6615         container->cb = cb;
6616         container->sid = sub_id;
6617         container->cid = ZBL_ZCL_GROUP_ADD_GROUP_REQ;
6618         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
6619         container->userdata = user_data;
6620
6621         groupname_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
6622         while (group_name[j] != '\0') {
6623                 g_variant_builder_add(groupname_builder, "(y)", (group_name[j]));
6624                 j++;
6625         }
6626         groupname_variant = g_variant_builder_end(groupname_builder);
6627         g_variant_builder_unref(groupname_builder);
6628
6629         variant = g_dbus_proxy_call_sync(zcl_group_proxy, "add_group",
6630                 g_variant_new("(qyq@a(y))", addr16, ep, group_id, groupname_variant),
6631                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6632
6633         if (!variant) {
6634                 ERR("Failed to get 'add_group' [%s]", dbus_err->message);
6635                 g_error_free(dbus_err);
6636                 return ZIGBEE_ERROR_IO_ERROR;
6637         }
6638
6639         g_variant_get(variant, "(i)", &result);
6640         DBG("ret = [0x%x]", result);
6641         g_variant_unref(variant);
6642
6643         return result;
6644 }
6645
6646 int zbl_view_group(nwk_addr addr16, unsigned char ep, unsigned short group_id,
6647                 zb_zcl_group_view_group_rsp cb, void *user_data)
6648 {
6649         int result = ZIGBEE_ERROR_NONE;
6650         GVariant *variant = NULL;
6651         GError *dbus_err = NULL;
6652
6653         int sub_id, to;
6654         zbl_req_cb_s *container;
6655
6656         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6657         RETV_IF(NULL == zcl_group_proxy, ZIGBEE_ERROR_IO_ERROR);
6658
6659         DBG("zbl_view_group()");
6660
6661         container = calloc(1, sizeof(zbl_req_cb_s));
6662         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
6663
6664         to = zbl_dbus_get_timeout(zcl_group_proxy);
6665         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
6666                         ZIGBEE_ZCL_GROUP_INTERFACE,  "view_group_rsp", ZIGBEE_CONTROL_OBJECT_PATH,
6667                         NULL, 0, _zbl_response_cb, container, _zbl_request_cleanup);
6668
6669         if (0 == sub_id) {
6670                 ERR("g_dbus_connection_signal_subscribe() Fail");
6671                 free(container);
6672                 return ZIGBEE_ERROR_IO_ERROR;
6673         }
6674
6675         container->cb = cb;
6676         container->sid = sub_id;
6677         container->cid = ZBL_ZCL_GROUP_VIEW_GROUP_REQ;
6678         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
6679         container->userdata = user_data;
6680
6681         variant = g_dbus_proxy_call_sync(zcl_group_proxy, "view_group",
6682                 g_variant_new("(qyq)", addr16, ep, group_id),
6683                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6684
6685         if (!variant) {
6686                 ERR("Failed to get 'view_group' [%s]", dbus_err->message);
6687                 g_error_free(dbus_err);
6688                 return ZIGBEE_ERROR_IO_ERROR;
6689         }
6690
6691         g_variant_get(variant, "(i)", &result);
6692         DBG("ret = [0x%x]", result);
6693         g_variant_unref(variant);
6694
6695         return result;
6696 }
6697
6698 int zbl_group_get_group_membership(nwk_addr addr16, unsigned char ep,
6699                 unsigned char group_count, unsigned short *group_list,
6700                 zb_zcl_group_get_group_membership_rsp cb, void *user_data)
6701 {
6702         int result = ZIGBEE_ERROR_NONE;
6703         GVariant *variant = NULL;
6704         GError *dbus_err = NULL;
6705
6706         int sub_id, to;
6707         zbl_req_cb_s *container;
6708
6709         int j = 0;
6710         GVariant *grouplist_variant = NULL;
6711         GVariantBuilder *grouplist_builder = NULL;
6712
6713         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6714         RETV_IF(NULL == zcl_group_proxy, ZIGBEE_ERROR_IO_ERROR);
6715
6716         DBG("zbl_group_get_group_membership()");
6717
6718         container = calloc(1, sizeof(zbl_req_cb_s));
6719         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
6720
6721         to = zbl_dbus_get_timeout(zcl_group_proxy);
6722         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
6723                         ZIGBEE_ZCL_GROUP_INTERFACE,  "get_group_membership_rsp",
6724                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0, _zbl_response_cb,
6725                         container, _zbl_request_cleanup);
6726
6727         if (0 == sub_id) {
6728                 ERR("g_dbus_connection_signal_subscribe() Fail");
6729                 free(container);
6730                 return ZIGBEE_ERROR_IO_ERROR;
6731         }
6732
6733         container->cb = cb;
6734         container->sid = sub_id;
6735         container->cid = ZBL_ZCL_GROUP_GET_GROUP_MEMBERSHIP_REQ;
6736         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
6737         container->userdata = user_data;
6738
6739         grouplist_builder = g_variant_builder_new(G_VARIANT_TYPE("aq"));
6740         while (j < group_count) {
6741                 g_variant_builder_add(grouplist_builder, "q", group_list[j]);
6742                 j++;
6743         }
6744         grouplist_variant = g_variant_builder_end(grouplist_builder);
6745         g_variant_builder_unref(grouplist_builder);
6746
6747         variant = g_dbus_proxy_call_sync(zcl_group_proxy, "get_group_membership",
6748                 g_variant_new("(qyy@aq)", addr16, ep, group_count,      grouplist_variant),
6749                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6750
6751         if (!variant) {
6752                 ERR("Failed to get 'get_group_membership' [%s]", dbus_err->message);
6753                 g_error_free(dbus_err);
6754                 return ZIGBEE_ERROR_IO_ERROR;
6755         }
6756
6757         g_variant_get(variant, "(i)", &result);
6758         DBG("ret = [0x%x]", result);
6759         g_variant_unref(variant);
6760
6761         return result;
6762 }
6763
6764 int zbl_remove_group(nwk_addr addr16, unsigned char ep, unsigned short group_id,
6765                 zb_zcl_group_remove_group_rsp cb, void *user_data)
6766 {
6767         int result = ZIGBEE_ERROR_NONE;
6768         GVariant *variant = NULL;
6769         GError *dbus_err = NULL;
6770
6771         int sub_id, to;
6772         zbl_req_cb_s *container;
6773
6774         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6775         RETV_IF(NULL == zcl_group_proxy, ZIGBEE_ERROR_IO_ERROR);
6776
6777         DBG("zbl_group_remove_group()");
6778
6779         container = calloc(1, sizeof(zbl_req_cb_s));
6780         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
6781
6782         to = zbl_dbus_get_timeout(zcl_group_proxy);
6783         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
6784                         ZIGBEE_ZCL_GROUP_INTERFACE,  "remove_group_rsp", ZIGBEE_CONTROL_OBJECT_PATH,
6785                         NULL, 0, _zbl_response_cb, container, _zbl_request_cleanup);
6786
6787         if (0 == sub_id) {
6788                 ERR("g_dbus_connection_signal_subscribe() Fail");
6789                 free(container);
6790                 return ZIGBEE_ERROR_IO_ERROR;
6791         }
6792
6793         container->cb = cb;
6794         container->sid = sub_id;
6795         container->cid = ZBL_ZCL_GROUP_REMOVE_GROUP_REQ;
6796         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
6797         container->userdata = user_data;
6798
6799         variant = g_dbus_proxy_call_sync(zcl_group_proxy, "remove_group", g_variant_new("(qyq)",
6800                 addr16, ep, group_id), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6801
6802         if (!variant) {
6803                 ERR("Failed to get 'remove_group' [%s]", dbus_err->message);
6804                 g_error_free(dbus_err);
6805                 return ZIGBEE_ERROR_IO_ERROR;
6806         }
6807
6808         g_variant_get(variant, "(i)", &result);
6809         DBG("ret = [0x%x]", result);
6810         g_variant_unref(variant);
6811
6812         return result;
6813 }
6814
6815 int zbl_remove_all_group(nwk_addr addr16, unsigned char ep)
6816 {
6817         int result = ZIGBEE_ERROR_NONE;
6818         GVariant *variant = NULL;
6819         GError *dbus_err = NULL;
6820
6821         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6822         RETV_IF(NULL == zcl_group_proxy, ZIGBEE_ERROR_IO_ERROR);
6823
6824         DBG("zbl_group_remove_all_group()");
6825
6826         variant = g_dbus_proxy_call_sync(zcl_group_proxy, "remove_all_group",
6827                 g_variant_new("(qy)", addr16, ep), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6828
6829         if (!variant) {
6830                 ERR("Failed to get 'remove_all_group' [%s]", dbus_err->message);
6831                 g_error_free(dbus_err);
6832                 return ZIGBEE_ERROR_IO_ERROR;
6833         }
6834
6835         g_variant_get(variant, "(i)", &result);
6836         DBG("ret = [0x%x]", result);
6837         g_variant_unref(variant);
6838
6839         return result;
6840 }
6841
6842 int zbl_add_group_if_identifying(nwk_addr addr16, unsigned char ep,
6843                 unsigned short group_id, const char *group_name)
6844 {
6845         int result = ZIGBEE_ERROR_NONE;
6846         GVariant *variant = NULL;
6847         GError *dbus_err = NULL;
6848
6849         int j = 0;
6850         GVariant *groupname_variant = NULL;
6851         GVariantBuilder *groupname_builder = NULL;
6852
6853         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6854         RETV_IF(NULL == zcl_group_proxy, ZIGBEE_ERROR_IO_ERROR);
6855
6856         groupname_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
6857         while (group_name[j] != '\0') {
6858                 g_variant_builder_add(groupname_builder, "(y)", group_name[j]);
6859                 j++;
6860         }
6861         groupname_variant = g_variant_builder_end(groupname_builder);
6862         g_variant_builder_unref(groupname_builder);
6863
6864         variant = g_dbus_proxy_call_sync(zcl_group_proxy, "add_group_if_identifying",
6865                 g_variant_new("(qyq@a(y))", addr16, ep, group_id, groupname_variant),
6866                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6867
6868         if (!variant) {
6869                 ERR("Failed to get 'add_group_if_identifying' [%s]", dbus_err->message);
6870                 g_error_free(dbus_err);
6871                 return ZIGBEE_ERROR_IO_ERROR;
6872         }
6873
6874         g_variant_get(variant, "(i)", &result);
6875         DBG("ret = [0x%x]", result);
6876         g_variant_unref(variant);
6877
6878         return result;
6879 }
6880
6881 int zbl_level_control_move_to_level(nwk_addr addr16, unsigned char ep,
6882                 unsigned char level, unsigned short transition_time)
6883 {
6884         int result = ZIGBEE_ERROR_NONE;
6885         GVariant *variant = NULL;
6886         GError *dbus_err = NULL;
6887
6888         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6889         RETV_IF(NULL == level_control_gproxy, ZIGBEE_ERROR_IO_ERROR);
6890
6891         DBG("zbl_level_control_move_to_level()");
6892
6893         variant = g_dbus_proxy_call_sync(level_control_gproxy, "move_to_level",
6894                 g_variant_new("(qyyq)", addr16, ep, level, transition_time),
6895                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6896
6897         if (!variant) {
6898                 ERR("Failed to get 'move_to_level' [%s]", dbus_err->message);
6899                 g_error_free(dbus_err);
6900                 return ZIGBEE_ERROR_IO_ERROR;
6901         }
6902
6903         g_variant_get(variant, "(i)", &result);
6904         DBG("ret = [0x%x]", result);
6905         g_variant_unref(variant);
6906
6907         return result;
6908 }
6909
6910 int zbl_level_control_move(nwk_addr addr16, unsigned char ep,
6911                 unsigned char move_mode, unsigned char rate)
6912 {
6913         int result = ZIGBEE_ERROR_NONE;
6914         GVariant *variant = NULL;
6915         GError *dbus_err = NULL;
6916
6917         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6918         RETV_IF(NULL == level_control_gproxy, ZIGBEE_ERROR_IO_ERROR);
6919
6920         DBG("zbl_level_control_move()");
6921
6922         variant = g_dbus_proxy_call_sync(level_control_gproxy, "move",
6923                 g_variant_new("(qyyy)", addr16, ep, move_mode, rate),
6924                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6925
6926         if (!variant) {
6927                 ERR("Failed to get 'move' [%s]", dbus_err->message);
6928                 g_error_free(dbus_err);
6929                 return ZIGBEE_ERROR_IO_ERROR;
6930         }
6931
6932         g_variant_get(variant, "(i)", &result);
6933         DBG("ret = [0x%x]", result);
6934         g_variant_unref(variant);
6935
6936         return result;
6937 }
6938
6939 int zbl_level_control_step(nwk_addr addr16, unsigned char ep,
6940                 unsigned char step_mode, unsigned char step_size,
6941                 unsigned short transition_time)
6942 {
6943         int result = ZIGBEE_ERROR_NONE;
6944         GVariant *variant = NULL;
6945         GError *dbus_err = NULL;
6946
6947         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6948         RETV_IF(NULL == level_control_gproxy, ZIGBEE_ERROR_IO_ERROR);
6949
6950         DBG("zbl_level_control_step()");
6951
6952         variant = g_dbus_proxy_call_sync(level_control_gproxy, "step",
6953                 g_variant_new("(qyyyq)", addr16, ep, step_mode, step_size, transition_time),
6954                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6955
6956         if (!variant) {
6957                 ERR("Failed to get 'step' [%s]", dbus_err->message);
6958                 g_error_free(dbus_err);
6959                 return ZIGBEE_ERROR_IO_ERROR;
6960         }
6961
6962         g_variant_get(variant, "(i)", &result);
6963         DBG("ret = [0x%x]", result);
6964         g_variant_unref(variant);
6965
6966         return result;
6967 }
6968
6969 int zbl_level_control_stop(nwk_addr addr16, unsigned char ep)
6970 {
6971         int result = ZIGBEE_ERROR_NONE;
6972         GVariant *variant = NULL;
6973         GError *dbus_err = NULL;
6974
6975         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
6976         RETV_IF(NULL == level_control_gproxy, ZIGBEE_ERROR_IO_ERROR);
6977
6978         DBG("zbl_level_control_stop()");
6979
6980         variant = g_dbus_proxy_call_sync(level_control_gproxy, "stop",
6981                 g_variant_new("(qy)", addr16, ep), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
6982
6983         if (!variant) {
6984                 ERR("Failed to get 'stop' [%s]", dbus_err->message);
6985                 g_error_free(dbus_err);
6986                 return ZIGBEE_ERROR_IO_ERROR;
6987         }
6988
6989         g_variant_get(variant, "(i)", &result);
6990         DBG("ret = [0x%x]", result);
6991         g_variant_unref(variant);
6992
6993         return result;
6994 }
6995
6996 int zbl_level_control_move_to_level_with_on_off(nwk_addr addr16,
6997                 unsigned char ep, unsigned char level, unsigned short transition_time)
6998 {
6999         int result = ZIGBEE_ERROR_NONE;
7000         GVariant *variant = NULL;
7001         GError *dbus_err = NULL;
7002
7003         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
7004         RETV_IF(NULL == level_control_gproxy, ZIGBEE_ERROR_IO_ERROR);
7005
7006         DBG("zbl_level_control_move_to_level_with_on_off()");
7007
7008         variant = g_dbus_proxy_call_sync(level_control_gproxy, "move_to_level_with_on_off",
7009                 g_variant_new("(qyyq)", addr16, ep, level, transition_time),
7010                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
7011
7012         if (!variant) {
7013                 ERR("Failed to get 'move_to_level_with_on_off' [%s]", dbus_err->message);
7014                 g_error_free(dbus_err);
7015                 return ZIGBEE_ERROR_IO_ERROR;
7016         }
7017
7018         g_variant_get(variant, "(i)", &result);
7019         DBG("ret = [0x%x]", result);
7020         g_variant_unref(variant);
7021
7022         return result;
7023 }
7024
7025 int zbl_level_control_move_with_on_off(nwk_addr addr16, unsigned char ep,
7026                 unsigned char move_mode, unsigned char rate)
7027 {
7028         int result = ZIGBEE_ERROR_NONE;
7029         GVariant *variant = NULL;
7030         GError *dbus_err = NULL;
7031
7032         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
7033         RETV_IF(NULL == level_control_gproxy, ZIGBEE_ERROR_IO_ERROR);
7034
7035         DBG("zbl_level_control_move_with_on_off()");
7036
7037         variant = g_dbus_proxy_call_sync(level_control_gproxy, "move_with_on_off",
7038                 g_variant_new("(qyyy)", addr16, ep, move_mode, rate),
7039                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
7040
7041         if (!variant) {
7042                 ERR("Failed to get 'move_with_on_off' [%s]", dbus_err->message);
7043                 g_error_free(dbus_err);
7044                 return ZIGBEE_ERROR_IO_ERROR;
7045         }
7046
7047         g_variant_get(variant, "(i)", &result);
7048         DBG("ret = [0x%x]", result);
7049         g_variant_unref(variant);
7050
7051         return result;
7052 }
7053
7054 int zbl_level_control_step_with_on_off(nwk_addr addr16, unsigned char ep,
7055                 unsigned char step_mode, unsigned char step_size,
7056                 unsigned short transition_time)
7057 {
7058         int result = ZIGBEE_ERROR_NONE;
7059         GVariant *variant = NULL;
7060         GError *dbus_err = NULL;
7061
7062         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
7063         RETV_IF(NULL == level_control_gproxy, ZIGBEE_ERROR_IO_ERROR);
7064
7065         DBG("zbl_level_control_step_with_on_off()");
7066
7067         variant = g_dbus_proxy_call_sync(level_control_gproxy, "step_with_on_off",
7068                 g_variant_new("(qyyyq)", addr16, ep, step_mode, step_size, transition_time),
7069                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
7070
7071         if (!variant) {
7072                 ERR("Failed to get 'step_with_on_off' [%s]", dbus_err->message);
7073                 g_error_free(dbus_err);
7074                 return ZIGBEE_ERROR_IO_ERROR;
7075         }
7076
7077         g_variant_get(variant, "(i)", &result);
7078         DBG("ret = [0x%x]", result);
7079         g_variant_unref(variant);
7080
7081         return result;
7082 }
7083
7084 int zbl_onoff_set(nwk_addr addr16, unsigned char ep, unsigned char on_off_type)
7085 {
7086         int result = ZIGBEE_ERROR_NONE;
7087         GVariant *variant = NULL;
7088         GError *dbus_err = NULL;
7089
7090         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
7091         RETV_IF(NULL == on_off_gproxy, ZIGBEE_ERROR_IO_ERROR);
7092
7093         variant = g_dbus_proxy_call_sync(on_off_gproxy, "set_on_off",
7094                 g_variant_new("(qyy)", addr16, ep, on_off_type), G_DBUS_CALL_FLAGS_NONE,
7095                 -1, NULL, &dbus_err);
7096
7097         if (!variant) {
7098                 ERR("Failed to get 'set_on_off' [%s]", dbus_err->message);
7099                 g_error_free(dbus_err);
7100                 return ZIGBEE_ERROR_IO_ERROR;
7101         }
7102
7103         g_variant_get(variant, "(i)", &result);
7104         DBG("ret = [0x%x]", result);
7105         g_variant_unref(variant);
7106
7107         return result;
7108 }
7109
7110 int zbl_zone_enroll_response(nwk_addr addr16, unsigned char dst_ep,
7111                 unsigned char enroll_response_code, unsigned char zone_id)
7112 {
7113         int result = ZIGBEE_ERROR_NONE;
7114         GVariant *variant = NULL;
7115         GError *dbus_err = NULL;
7116
7117         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
7118         RETV_IF(NULL == zcl_ias_zone_proxy, ZIGBEE_ERROR_IO_ERROR);
7119
7120         variant = g_dbus_proxy_call_sync(zcl_ias_zone_proxy, "enroll_response",
7121                 g_variant_new("(qyyy)", addr16, dst_ep, enroll_response_code, zone_id),
7122                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
7123
7124         if (!variant) {
7125                 ERR("Failed to get 'enroll_response' [%s]", dbus_err->message);
7126                 g_error_free(dbus_err);
7127                 return ZIGBEE_ERROR_IO_ERROR;
7128         }
7129
7130         g_variant_get(variant, "(i)", &result);
7131         DBG("ret = [0x%x]", result);
7132         g_variant_unref(variant);
7133
7134         return result;
7135 }
7136
7137 int zbl_pollcontrol_check_in_response(nwk_addr addr16, unsigned char ep,
7138                 unsigned char start_fast_polling, unsigned short fast_poll_timeout)
7139 {
7140         int result = ZIGBEE_ERROR_NONE;
7141         GVariant *variant = NULL;
7142         GError *dbus_err = NULL;
7143
7144         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
7145         RETV_IF(NULL == zcl_poll_control_proxy, ZIGBEE_ERROR_IO_ERROR);
7146
7147         variant = g_dbus_proxy_call_sync(zcl_poll_control_proxy, "check_in_response",
7148                 g_variant_new("(qyyq)", addr16, ep, start_fast_polling, fast_poll_timeout),
7149                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
7150
7151         if (!variant) {
7152                 ERR("Failed to get 'check_in_response' [%s]", dbus_err->message);
7153                 g_error_free(dbus_err);
7154                 return ZIGBEE_ERROR_IO_ERROR;
7155         }
7156
7157         g_variant_get(variant, "(i)", &result);
7158         DBG("ret = [0x%x]", result);
7159         g_variant_unref(variant);
7160
7161         return result;
7162 }
7163
7164 int zbl_pollcontrol_fast_poll_stop(nwk_addr addr16, unsigned char ep)
7165 {
7166         int result = ZIGBEE_ERROR_NONE;
7167         GVariant *variant = NULL;
7168         GError *dbus_err = NULL;
7169
7170         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
7171         RETV_IF(NULL == zcl_poll_control_proxy, ZIGBEE_ERROR_IO_ERROR);
7172
7173         variant = g_dbus_proxy_call_sync(zcl_poll_control_proxy, "fast_poll_stop",
7174                 g_variant_new("(qy)", addr16, ep), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
7175
7176         if (!variant) {
7177                 ERR("Failed to get 'fast_poll_stop' [%s]", dbus_err->message);
7178                 g_error_free(dbus_err);
7179                 return ZIGBEE_ERROR_IO_ERROR;
7180         }
7181
7182         g_variant_get(variant, "(i)", &result);
7183         DBG("ret = [0x%x]", result);
7184         g_variant_unref(variant);
7185
7186         return result;
7187 }
7188
7189 int zbl_pollcontrol_set_long_poll_interval(nwk_addr addr16, unsigned char ep,
7190         unsigned int new_long_poll_interval, zb_zcl_pollctrl_check_in cb, void *user_data)
7191 {
7192         int sub_id, to;
7193         zbl_req_cb_s *container;
7194
7195         int result = ZIGBEE_ERROR_NONE;
7196         GVariant *variant = NULL;
7197         GError *dbus_err = NULL;
7198
7199         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
7200         RETV_IF(NULL == zcl_poll_control_proxy, ZIGBEE_ERROR_IO_ERROR);
7201
7202         DBG("zbl_pollcontrol_set_long_poll_interval()");
7203
7204         container = calloc(1, sizeof(zbl_req_cb_s));
7205         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
7206
7207         to = zbl_dbus_get_timeout(zcl_poll_control_proxy);
7208         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
7209                         ZIGBEE_ZCL_POLL_CONTROL_INTERFACE,  "checkin_response",
7210                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
7211                         _zbl_response_cb, container, _zbl_request_cleanup);
7212
7213         if (0 == sub_id) {
7214                 ERR("g_dbus_connection_signal_subscribe() Fail");
7215                 free(container);
7216                 return ZIGBEE_ERROR_IO_ERROR;
7217         }
7218
7219         container->cb = cb;
7220         container->sid = sub_id;
7221         container->cid = ZBL_ZCL_POLLCONTROL_SET_POLL_INTERVAL_REQ;
7222         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
7223         container->userdata = user_data;
7224
7225         variant = g_dbus_proxy_call_sync(zcl_poll_control_proxy, "set_long_poll_interval",
7226                         g_variant_new("(qyu)", addr16, ep, new_long_poll_interval),
7227                         G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
7228
7229         if (!variant) {
7230                 ERR("Failed to get 'set_long_poll_interval' [%s]", dbus_err->message);
7231                 g_error_free(dbus_err);
7232                 return ZIGBEE_ERROR_IO_ERROR;
7233         }
7234
7235         g_variant_get(variant, "(i)", &result);
7236         DBG("ret = [0x%x]", result);
7237         g_variant_unref(variant);
7238
7239         return result;
7240 }
7241
7242 int zbl_pollcontrol_set_short_poll_interval(nwk_addr addr16, unsigned char ep,
7243         unsigned int new_short_poll_interval, zb_zcl_pollctrl_check_in cb, void *user_data)
7244 {
7245         int sub_id, to;
7246         zbl_req_cb_s *container;
7247
7248         int result = ZIGBEE_ERROR_NONE;
7249         GVariant *variant = NULL;
7250         GError *dbus_err = NULL;
7251
7252         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
7253         RETV_IF(NULL == zcl_poll_control_proxy, ZIGBEE_ERROR_IO_ERROR);
7254
7255         DBG("zbl_pollcontrol_set_short_poll_interval()");
7256
7257         container = calloc(1, sizeof(zbl_req_cb_s));
7258         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
7259
7260         to = zbl_dbus_get_timeout(zcl_poll_control_proxy);
7261         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
7262                         ZIGBEE_ZCL_POLL_CONTROL_INTERFACE,  "checkin_response",
7263                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
7264                         _zbl_response_cb, container, _zbl_request_cleanup);
7265
7266         if (0 == sub_id) {
7267                 ERR("g_dbus_connection_signal_subscribe() Fail");
7268                 free(container);
7269                 return ZIGBEE_ERROR_IO_ERROR;
7270         }
7271
7272         container->cb = cb;
7273         container->sid = sub_id;
7274         container->cid = ZBL_ZCL_POLLCONTROL_SET_POLL_INTERVAL_REQ;
7275         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
7276         container->userdata = user_data;
7277
7278         variant = g_dbus_proxy_call_sync(zcl_poll_control_proxy, "set_short_poll_interval",
7279                         g_variant_new("(qyu)", addr16, ep, new_short_poll_interval),
7280                         G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
7281
7282         if (!variant) {
7283                 ERR("Failed to get 'set_short_poll_interval' [%s]", dbus_err->message);
7284                 g_error_free(dbus_err);
7285                 return ZIGBEE_ERROR_IO_ERROR;
7286         }
7287
7288         g_variant_get(variant, "(i)", &result);
7289         DBG("ret = [0x%x]", result);
7290         g_variant_unref(variant);
7291
7292         return result;
7293 }
7294
7295 int zbl_add_scene(nwk_addr addr16, unsigned char ep, unsigned short group_id,
7296         unsigned char scene_id, unsigned short transition_time, const char *scene_name,
7297         unsigned short ext_field_len, const char *extension_field_sets,
7298         zb_zcl_scene_add_scene_rsp cb, void *user_data)
7299 {
7300         int sub_id, to;
7301         zbl_req_cb_s *container;
7302
7303         int result = ZIGBEE_ERROR_NONE;
7304         GVariant *variant = NULL;
7305         GError *dbus_err = NULL;
7306
7307         int j = 0;
7308         int index = 0;
7309         GVariant *scenename_variant = NULL;
7310         GVariantBuilder *scenename_builder = NULL;
7311         GVariant *extensionfieldSet_variant = NULL;
7312         GVariantBuilder *extensionfieldSet_builder = NULL;
7313
7314         DBG("zbl_add_scene()");
7315
7316         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
7317         RETV_IF(NULL == zcl_scene_proxy, ZIGBEE_ERROR_IO_ERROR);
7318
7319         container = calloc(1, sizeof(zbl_req_cb_s));
7320         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
7321
7322         to = zbl_dbus_get_timeout(zcl_scene_proxy);
7323         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
7324                         ZIGBEE_ZCL_SCENE_INTERFACE,  "add_scene_rsp", ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
7325                         _zbl_response_cb, container, _zbl_request_cleanup);
7326
7327         if (0 == sub_id) {
7328                 ERR("g_dbus_connection_signal_subscribe() Fail");
7329                 free(container);
7330                 return ZIGBEE_ERROR_IO_ERROR;
7331         }
7332
7333         container->cb = cb;
7334         container->sid = sub_id;
7335         container->cid = ZBL_ZCL_SCENE_ADD_SCENE_REQ;
7336         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
7337         container->userdata = user_data;
7338
7339         scenename_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
7340         while ('\0' != scene_name[j]) {
7341                 g_variant_builder_add(scenename_builder, "(y)", scene_name[j]);
7342                 j++;
7343         }
7344         scenename_variant = g_variant_builder_end(scenename_builder);
7345         g_variant_builder_unref(scenename_builder);
7346
7347         extensionfieldSet_builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
7348
7349         while (index < ext_field_len) {
7350                 INFO("Ext contents 0x%02X", extension_field_sets[index]);
7351                 g_variant_builder_add(extensionfieldSet_builder, "(y)", extension_field_sets[index]);
7352                 index++;
7353         }
7354         extensionfieldSet_variant = g_variant_builder_end(extensionfieldSet_builder);
7355         g_variant_builder_unref(extensionfieldSet_builder);
7356
7357         variant = g_dbus_proxy_call_sync(zcl_scene_proxy, "add_scene",
7358                 g_variant_new("(qyqyqq@a(y)@a(y))", addr16, ep, group_id, scene_id, transition_time,
7359                 ext_field_len, scenename_variant, extensionfieldSet_variant), G_DBUS_CALL_FLAGS_NONE,
7360                 to, NULL, &dbus_err);
7361
7362         if (!variant) {
7363                 ERR("Failed to get 'add_scene' [%s]", dbus_err->message);
7364                 g_error_free(dbus_err);
7365                 return ZIGBEE_ERROR_IO_ERROR;
7366         }
7367
7368         g_variant_get(variant, "(i)", &result);
7369         DBG("ret = [0x%x]", result);
7370         g_variant_unref(variant);
7371
7372         return result;
7373 }
7374
7375 int zbl_view_scene(nwk_addr addr16, unsigned char ep, unsigned short group_id,
7376         unsigned char scene_id, zb_zcl_scene_view_scene_rsp cb, void *user_data)
7377 {
7378         int sub_id, to;
7379         zbl_req_cb_s *container;
7380
7381         int result = ZIGBEE_ERROR_NONE;
7382         GVariant *variant = NULL;
7383         GError *dbus_err = NULL;
7384
7385         DBG("zbl_scene_view_scene()");
7386
7387         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
7388         RETV_IF(NULL == zcl_scene_proxy, ZIGBEE_ERROR_IO_ERROR);
7389
7390         container = calloc(1, sizeof(zbl_req_cb_s));
7391         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
7392
7393         to = zbl_dbus_get_timeout(zcl_scene_proxy);
7394         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
7395                         ZIGBEE_ZCL_SCENE_INTERFACE,  "view_scene_rsp", ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0,
7396                         _zbl_response_cb, container, _zbl_request_cleanup);
7397
7398         if (0 == sub_id) {
7399                 ERR("g_dbus_connection_signal_subscribe() Fail");
7400                 free(container);
7401                 return ZIGBEE_ERROR_IO_ERROR;
7402         }
7403
7404         container->cb = cb;
7405         container->sid = sub_id;
7406         container->cid = ZBL_ZCL_SCENE_VIEW_SCENE_REQ;
7407         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
7408         container->userdata = user_data;
7409
7410         variant = g_dbus_proxy_call_sync(zcl_scene_proxy, "view_scene",
7411                 g_variant_new("(qyqy)", addr16, ep, group_id, scene_id), G_DBUS_CALL_FLAGS_NONE,
7412                 to, NULL, &dbus_err);
7413
7414         if (!variant) {
7415                 ERR("Failed to get 'view_scene' [%s]", dbus_err->message);
7416                 g_error_free(dbus_err);
7417                 return ZIGBEE_ERROR_IO_ERROR;
7418         }
7419
7420         g_variant_get(variant, "(i)", &result);
7421         DBG("ret = [0x%x]", result);
7422         g_variant_unref(variant);
7423
7424         return result;
7425 }
7426
7427 int zbl_remove_scene(nwk_addr addr16, unsigned char ep,
7428         unsigned short group_id, unsigned char scene_id, zb_zcl_scene_remove_scene_rsp cb,
7429         void *user_data)
7430 {
7431         int sub_id, to;
7432         zbl_req_cb_s *container;
7433
7434         int result = ZIGBEE_ERROR_NONE;
7435         GVariant *variant = NULL;
7436         GError *dbus_err = NULL;
7437
7438         DBG("zbl_scene_remove_scene()");
7439
7440         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
7441         RETV_IF(NULL == zcl_scene_proxy, ZIGBEE_ERROR_IO_ERROR);
7442
7443         container = calloc(1, sizeof(zbl_req_cb_s));
7444         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
7445
7446         to = zbl_dbus_get_timeout(zcl_scene_proxy);
7447         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
7448                         ZIGBEE_ZCL_SCENE_INTERFACE,  "remove_scene_rsp", ZIGBEE_CONTROL_OBJECT_PATH,
7449                         NULL, 0, _zbl_response_cb, container, _zbl_request_cleanup);
7450
7451         if (0 == sub_id) {
7452                 ERR("g_dbus_connection_signal_subscribe() Fail");
7453                 free(container);
7454                 return ZIGBEE_ERROR_IO_ERROR;
7455         }
7456
7457         container->cb = cb;
7458         container->sid = sub_id;
7459         container->cid = ZBL_ZCL_SCENE_REMOVE_SCENE_REQ;
7460         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
7461         container->userdata = user_data;
7462
7463         variant = g_dbus_proxy_call_sync(zcl_scene_proxy, "remove_scene",
7464                 g_variant_new("(qyqy)", addr16, ep, group_id, scene_id),
7465                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
7466
7467         if (!variant) {
7468                 ERR("Failed to get 'remove_scene' [%s]", dbus_err->message);
7469                 g_error_free(dbus_err);
7470                 return ZIGBEE_ERROR_IO_ERROR;
7471         }
7472
7473         g_variant_get(variant, "(i)", &result);
7474         DBG("ret = [0x%x]", result);
7475         g_variant_unref(variant);
7476
7477         return result;
7478 }
7479
7480 int zbl_remove_all_scene(nwk_addr addr16, unsigned char ep,
7481         unsigned short group_id, zb_zcl_scene_remove_all_scene_rsp cb, void *user_data)
7482 {
7483         int sub_id, to;
7484         zbl_req_cb_s *container;
7485
7486         int result = ZIGBEE_ERROR_NONE;
7487         GVariant *variant = NULL;
7488         GError *dbus_err = NULL;
7489
7490         DBG("zbl_scene_remove_all_scene()");
7491
7492         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
7493         RETV_IF(NULL == zcl_scene_proxy, ZIGBEE_ERROR_IO_ERROR);
7494
7495         container = calloc(1, sizeof(zbl_req_cb_s));
7496         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
7497
7498         to = zbl_dbus_get_timeout(zcl_scene_proxy);
7499         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
7500                         ZIGBEE_ZCL_SCENE_INTERFACE,  "remove_all_scene_rsp",
7501                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0, _zbl_response_cb, container,
7502                         _zbl_request_cleanup);
7503
7504         if (0 == sub_id) {
7505                 ERR("g_dbus_connection_signal_subscribe() Fail");
7506                 free(container);
7507                 return ZIGBEE_ERROR_IO_ERROR;
7508         }
7509
7510         container->cb = cb;
7511         container->sid = sub_id;
7512         container->cid = ZBL_ZCL_SCENE_REMOVE_ALL_SCENE_REQ;
7513         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
7514         container->userdata = user_data;
7515
7516         variant = g_dbus_proxy_call_sync(zcl_scene_proxy, "remove_all_scene",
7517                 g_variant_new("(qyq)", addr16, ep, group_id),
7518                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
7519
7520         if (!variant) {
7521                 ERR("Failed to get 'remove_all_scene' [%s]", dbus_err->message);
7522                 g_error_free(dbus_err);
7523                 return ZIGBEE_ERROR_IO_ERROR;
7524         }
7525
7526         g_variant_get(variant, "(i)", &result);
7527         DBG("ret = [0x%x]", result);
7528         g_variant_unref(variant);
7529
7530         return result;
7531 }
7532
7533 int zbl_store_scene(nwk_addr addr16, unsigned char ep, unsigned short group_id,
7534         unsigned char scene_id, zb_zcl_scene_store_scene_rsp cb, void *user_data)
7535 {
7536         int sub_id, to;
7537         zbl_req_cb_s *container;
7538
7539         int result = ZIGBEE_ERROR_NONE;
7540         GVariant *variant = NULL;
7541         GError *dbus_err = NULL;
7542
7543         DBG("zbl_scene_store_scene()");
7544
7545         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
7546         RETV_IF(NULL == zcl_scene_proxy, ZIGBEE_ERROR_IO_ERROR);
7547
7548         container = calloc(1, sizeof(zbl_req_cb_s));
7549         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
7550
7551         to = zbl_dbus_get_timeout(zcl_scene_proxy);
7552         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
7553                         ZIGBEE_ZCL_SCENE_INTERFACE,  "store_scene_rsp", ZIGBEE_CONTROL_OBJECT_PATH,
7554                         NULL, 0, _zbl_response_cb, container, _zbl_request_cleanup);
7555
7556         if (0 == sub_id) {
7557                 ERR("g_dbus_connection_signal_subscribe() Fail");
7558                 free(container);
7559                 return ZIGBEE_ERROR_IO_ERROR;
7560         }
7561
7562         container->cb = cb;
7563         container->sid = sub_id;
7564         container->cid = ZBL_ZCL_SCENE_STORE_SCENE_REQ;
7565         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
7566         container->userdata = user_data;
7567
7568         variant = g_dbus_proxy_call_sync(zcl_scene_proxy, "store_scene",
7569                 g_variant_new("(qyqy)", addr16, ep, group_id, scene_id),
7570                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
7571
7572         if (!variant) {
7573                 ERR("Failed to get 'store_scene' [%s]", dbus_err->message);
7574                 g_error_free(dbus_err);
7575                 return ZIGBEE_ERROR_IO_ERROR;
7576         }
7577
7578         g_variant_get(variant, "(i)", &result);
7579         DBG("ret = [0x%x]", result);
7580         g_variant_unref(variant);
7581
7582         return result;
7583 }
7584
7585 int zbl_recall_scene(nwk_addr addr16, unsigned char ep, unsigned short group_id,
7586         unsigned char scene_id)
7587 {
7588         int result = ZIGBEE_ERROR_NONE;
7589         GVariant *variant = NULL;
7590         GError *dbus_err = NULL;
7591
7592         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
7593         RETV_IF(NULL == zcl_scene_proxy, ZIGBEE_ERROR_IO_ERROR);
7594
7595         variant = g_dbus_proxy_call_sync(zcl_scene_proxy, "recall_scene",
7596                 g_variant_new("(qyqy)", addr16, ep, group_id, scene_id), G_DBUS_CALL_FLAGS_NONE,
7597                 -1, NULL, &dbus_err);
7598
7599         if (!variant) {
7600                 ERR("Failed to get 'recall_scene' [%s]", dbus_err->message);
7601                 g_error_free(dbus_err);
7602                 return ZIGBEE_ERROR_IO_ERROR;
7603         }
7604
7605         g_variant_get(variant, "(i)", &result);
7606         DBG("ret = [0x%x]", result);
7607         g_variant_unref(variant);
7608
7609         return result;
7610 }
7611
7612 int zbl_get_scene_membership(nwk_addr addr16, unsigned char ep,
7613         unsigned short group_id, zb_zcl_scene_get_scene_membership_rsp cb, void *user_data)
7614 {
7615         int sub_id, to;
7616         zbl_req_cb_s *container;
7617
7618         int result = ZIGBEE_ERROR_NONE;
7619         GVariant *variant = NULL;
7620         GError *dbus_err = NULL;
7621
7622         DBG("zbl_scene_get_scene_membership()");
7623
7624         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
7625         RETV_IF(NULL == zcl_scene_proxy, ZIGBEE_ERROR_IO_ERROR);
7626
7627         container = calloc(1, sizeof(zbl_req_cb_s));
7628         RETVM_IF(NULL == container, ZIGBEE_ERROR_OUT_OF_MEMORY, "calloc() Fail(%d)", errno);
7629
7630         to = zbl_dbus_get_timeout(zcl_scene_proxy);
7631         sub_id = g_dbus_connection_signal_subscribe((GDBusConnection*)gdbus_conn, NULL,
7632                         ZIGBEE_ZCL_SCENE_INTERFACE, "get_scene_membership_rsp",
7633                         ZIGBEE_CONTROL_OBJECT_PATH, NULL, 0, _zbl_response_cb, container,
7634                         _zbl_request_cleanup);
7635
7636         if (0 == sub_id) {
7637                 ERR("g_dbus_connection_signal_subscribe() Fail");
7638                 free(container);
7639                 return ZIGBEE_ERROR_IO_ERROR;
7640         }
7641
7642         container->cb = cb;
7643         container->sid = sub_id;
7644         container->cid = ZBL_ZCL_SCENE_GET_SCENE_MEMBERSHIP_REQ;
7645         container->tid = g_timeout_add_seconds(to, _zbl_timeout_cb, container);
7646         container->userdata = user_data;
7647
7648         variant = g_dbus_proxy_call_sync(zcl_scene_proxy, "get_scene_membership",
7649                 g_variant_new("(qyq)", addr16, ep, group_id),
7650                 G_DBUS_CALL_FLAGS_NONE, to, NULL, &dbus_err);
7651
7652         if (!variant) {
7653                 ERR("Failed to get get_scene_membership [%s]", dbus_err->message);
7654                 g_error_free(dbus_err);
7655                 return ZIGBEE_ERROR_IO_ERROR;
7656         }
7657
7658         g_variant_get(variant, "(i)", &result);
7659         DBG("ret = [0x%x]", result);
7660         g_variant_unref(variant);
7661
7662         return result;
7663 }
7664
7665 int zbl_thermostat_adjust_setpoint(nwk_addr addr16, unsigned char ep, unsigned char mode,
7666         unsigned char amount)
7667 {
7668         int result = ZIGBEE_ERROR_IO_ERROR;
7669         GVariant *variant = NULL;
7670         GError *dbus_err = NULL;
7671
7672         RETV_IF(NULL == gdbus_conn, ZIGBEE_ERROR_IO_ERROR);
7673         RETV_IF(NULL == thermostat_gproxy, ZIGBEE_ERROR_IO_ERROR);
7674
7675         variant = g_dbus_proxy_call_sync(thermostat_gproxy, "setpoint_raise_lower",
7676                 g_variant_new("(qyyy)", addr16, ep, mode, amount),
7677                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &dbus_err);
7678
7679         if (!variant) {
7680                 ERR("Failed to get 'setpoint_raise_lower' [%s]", dbus_err->message);
7681                 g_error_free(dbus_err);
7682                 return ZIGBEE_ERROR_IO_ERROR;
7683         }
7684
7685         g_variant_get(variant, "(i)", &result);
7686         DBG("ret = [0x%x]", result);
7687         g_variant_unref(variant);
7688
7689         return result;
7690 }
7691
7692 int zbl_dbus_start(zigbee_h handle)
7693 {
7694         FN_CALL;
7695
7696         unsigned int id;
7697
7698         if (gdbus_conn) {
7699                 zbl_ref_count++;
7700                 return ZIGBEE_ERROR_NONE;
7701         }
7702
7703         gdbus_conn = _zbl_get_connection();
7704         if (!gdbus_conn) {
7705                 ERR("Couldn't connect to the System bus");
7706                 return ZIGBEE_ERROR_IO_ERROR;
7707         }
7708
7709         id = g_signal_connect(gdbus_conn, "notify::g-name-owner",
7710                         G_CALLBACK(_zbl_dbus_name_owner_notify), NULL);
7711         if (0 == id) {
7712                 ERR("g_signal_connect() Fail\n");
7713                 return ZIGBEE_ERROR_IO_ERROR;
7714         }
7715
7716         /* Phase 1. Subscribe signals */
7717         _zbl_dbus_subscribe_signal(handle);
7718
7719         /* Phase 2. Make proxies */
7720         service_gproxy = _zbl_get_service_proxy();
7721         RETVM_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get service_gproxy");
7722         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(service_gproxy), ZIGBEE_BROADCAST_TIMEOUT);
7723
7724         on_off_gproxy = _zbl_get_on_off_proxy();
7725         RETVM_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get on_off_gproxy");
7726         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(on_off_gproxy), ZIGBEE_BROADCAST_TIMEOUT);
7727
7728         door_lock_gproxy = _zbl_get_door_lock_proxy();
7729         RETVM_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get door_lock_gproxy");
7730         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(door_lock_gproxy), ZIGBEE_BROADCAST_TIMEOUT);
7731
7732         level_control_gproxy = _zbl_get_level_control_proxy();
7733         RETVM_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get level_control_gproxy");
7734         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(level_control_gproxy), ZIGBEE_BROADCAST_TIMEOUT);
7735
7736         thermostat_gproxy = _zbl_get_thermostat_proxy();
7737         RETVM_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get thermostat_gproxy");
7738         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(thermostat_gproxy), ZIGBEE_BROADCAST_TIMEOUT);
7739
7740         fan_control_gproxy = _zbl_get_fan_control_proxy();
7741         RETVM_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get fan_control_gproxy");
7742         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(fan_control_gproxy), ZIGBEE_BROADCAST_TIMEOUT);
7743
7744         alarm_gproxy = _zbl_get_alarm_proxy();
7745         RETVM_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get alarm_gproxy");
7746         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(alarm_gproxy), ZIGBEE_BROADCAST_TIMEOUT);
7747
7748         mfglib_gproxy = _zbl_get_mfglib_proxy();
7749         RETVM_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get mfglib_gproxy");
7750         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(mfglib_gproxy), ZIGBEE_BROADCAST_TIMEOUT);
7751
7752         zcl_global_proxy = _zbl_get_zcl_global_proxy();
7753         RETVM_IF(NULL == service_gproxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get zcl_global_proxy");
7754         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(zcl_global_proxy), ZIGBEE_BROADCAST_TIMEOUT);
7755
7756         zdo_dev_proxy = _zbl_get_zdo_dev_proxy();
7757         RETVM_IF(NULL == zdo_dev_proxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get zdo_dev_proxy");
7758         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(zdo_dev_proxy), ZIGBEE_BROADCAST_TIMEOUT);
7759
7760         zcl_basic_proxy = _zbl_get_basic_proxy();
7761         RETVM_IF(NULL == zcl_basic_proxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get zcl_basic_proxy");
7762         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(zcl_basic_proxy), ZIGBEE_BROADCAST_TIMEOUT);
7763
7764         zcl_identify_proxy = _zbl_get_identify_proxy();
7765         RETVM_IF(NULL == zcl_identify_proxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get zcl_identify_proxy");
7766         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(zcl_identify_proxy), ZIGBEE_BROADCAST_TIMEOUT);
7767
7768         zcl_ias_zone_proxy = _zbl_get_ias_zone_proxy();
7769         RETVM_IF(NULL == zcl_ias_zone_proxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get zcl_ias_zone_proxy");
7770         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(zcl_ias_zone_proxy), ZIGBEE_BROADCAST_TIMEOUT);
7771
7772         zcl_poll_control_proxy = _zbl_get_poll_control_proxy();
7773         RETVM_IF(NULL == zcl_poll_control_proxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get zcl_poll_control_proxy");
7774         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(zcl_poll_control_proxy), ZIGBEE_BROADCAST_TIMEOUT);
7775
7776         zcl_group_proxy = _zbl_get_group_proxy();
7777         RETVM_IF(NULL == zcl_group_proxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get zcl_group_proxy");
7778         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(zcl_group_proxy), ZIGBEE_BROADCAST_TIMEOUT);
7779
7780         zcl_scene_proxy = _zbl_get_scene_proxy();
7781         RETVM_IF(NULL == zcl_scene_proxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get zcl_scene_proxy");
7782         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(zcl_scene_proxy), ZIGBEE_BROADCAST_TIMEOUT);
7783
7784         zdo_bind_proxy = _zbl_get_zdo_bind_proxy();
7785         RETVM_IF(NULL == zdo_bind_proxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get zdo_bind_proxy");
7786         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(zdo_bind_proxy), ZIGBEE_BROADCAST_TIMEOUT);
7787
7788         zcl_color_control_proxy = _zbl_get_color_control_proxy();
7789         RETVM_IF(NULL == zcl_color_control_proxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get zcl_color_control_proxy");
7790         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(zcl_color_control_proxy), ZIGBEE_BROADCAST_TIMEOUT);
7791
7792         custom_gproxy = _zbl_get_custom_gproxy();
7793         RETVM_IF(NULL == custom_gproxy, ZIGBEE_ERROR_IO_ERROR, "Couldn't get custom_gproxy");
7794         g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(custom_gproxy), ZIGBEE_BROADCAST_TIMEOUT);
7795
7796         zbl_ref_count++;
7797
7798         return ZIGBEE_ERROR_NONE;
7799 }
7800
7801 void zbl_dbus_stop(void)
7802 {
7803         if (0 <= zbl_ref_count) {
7804                 WARN("dbus does not initiaized\n");
7805                 return;
7806         }
7807         if (0 > --zbl_ref_count)
7808                 DBG("all connections closed\n");
7809
7810         g_object_unref(gdbus_conn);
7811         gdbus_conn = NULL;
7812         return;
7813 }
7814
7815 GDBusConnection* zbl_dbus_get_object(void)
7816 {
7817         return gdbus_conn;
7818 }
7819
7820 int zbl_dbus_get_timeout(GDBusProxy *proxy)
7821 {
7822         gint timeout;
7823         RETV_IF(NULL == gdbus_conn, ZIGBEE_BROADCAST_TIMEOUT);
7824         timeout = g_dbus_proxy_get_default_timeout(proxy);
7825         if (timeout <= 0) {
7826                 ERR("Invalid timeout (%d)", timeout);
7827                 return ZIGBEE_BROADCAST_TIMEOUT;
7828         }
7829         return timeout;
7830 }
7831