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