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