3f729d59a277dcc172a3aab6cb3434fcdec61d27
[platform/core/connectivity/zigbee-manager.git] / zigbee-daemon / zigbee-interface / src / zigbee_service_dbus_interface.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Contact: Suresh Kumar N (suresh.n@samsung.com)
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include <glib.h>
24 #include <dlog.h>
25
26 #include <zblib.h>
27 #include <zblib_service.h>
28 #include <zblib_service_interface.h>
29
30 #include "zigbee_service_interface.h"
31 #include "zigbee_service_interface_common.h"
32 #include "zigbee_service_dbus_interface.h"
33
34 /**< ZigBee D-BUS service interface name */
35 #define ZIGBEE_DBUS_SERVICE_INTERFACE_NAME "zigbee-dbus"
36
37 static gboolean on_manager_enable(ZigbeeManager *zigbee_mgr,
38         GDBusMethodInvocation *invocation,
39         gpointer user_data)
40 {
41         ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
42         ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
43
44         if (NULL == custom_data) {
45                 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
46
47                 return TRUE;
48         }
49
50         zigbee_manager_complete_enable(zigbee_mgr, invocation);
51
52         if (TRUE == custom_data->sevice_interface_init_complete) {
53                 /* Emit zigbee_state - enabled */
54                 zigbee_manager_emit_zigbee_state(zigbee_mgr, TRUE);
55         }
56
57         return TRUE;
58 }
59
60 static gboolean on_manager_disable(ZigbeeManager *zigbee_mgr,
61         GDBusMethodInvocation *invocation,
62         gpointer user_data)
63 {
64         ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
65         ZigBeeService *service = zblib_service_interface_ref_service(service_interface);
66
67         NOT_USED(user_data);
68
69         zigbee_manager_complete_disable(zigbee_mgr, invocation, 0);
70
71         if (service)
72                 zblib_service_exit(service);
73
74         return TRUE;
75 }
76
77 static gboolean on_manager_get_zigbee_state(ZigbeeManager *zigbee_mgr,
78         GDBusMethodInvocation *invocation, gpointer user_data)
79 {
80         ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
81         ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
82
83         Z_LOGI("Entered");
84
85         if (NULL == custom_data) {
86                 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
87
88                 return TRUE;
89         }
90
91         zigbee_manager_complete_get_zigbee_state(zigbee_mgr, invocation,
92                         0, custom_data->sevice_interface_init_complete);
93
94         return TRUE;
95 }
96
97 static void zigbee_service_dbus_interface_initialize_interfaces(ZigBeeServiceInterface *service_interface,
98         ZigbeeObjectSkeleton *zigbee_object)
99 {
100         gboolean ret;
101
102         ret = zigbee_service_dbus_interface_zcl_alarm_init(service_interface, zigbee_object);
103         Z_LOGD("ret: %d", ret);
104
105         ret = zigbee_service_dbus_interface_custom_init(service_interface, zigbee_object);
106         Z_LOGD("ret: %d", ret);
107
108         ret = zigbee_service_dbus_interface_zcl_door_lock_init(service_interface, zigbee_object);
109         Z_LOGD("ret: %d", ret);
110
111         ret = zigbee_service_dbus_interface_zcl_fan_control_init(service_interface, zigbee_object);
112         Z_LOGD("ret: %d", ret);
113
114         ret = zigbee_service_dbus_interface_zcl_level_control_init(service_interface, zigbee_object);
115         Z_LOGD("ret: %d", ret);
116
117         ret = zigbee_service_dbus_interface_mfglib_control_init(service_interface, zigbee_object);
118         Z_LOGD("ret: %d", ret);
119
120         ret = zigbee_service_dbus_interface_zcl_on_off_init(service_interface, zigbee_object);
121         Z_LOGD("ret: %d", ret);
122
123         ret = zigbee_service_dbus_interface_service_init(service_interface, zigbee_object);
124         Z_LOGD("ret: %d", ret);
125
126         ret = zigbee_service_dbus_interface_zcl_thermostat_init(service_interface, zigbee_object);
127         Z_LOGD("ret: %d", ret);
128
129         ret = zigbee_service_dbus_interface_zcl_basic_init(service_interface, zigbee_object);
130         Z_LOGD("ret: %d", ret);
131
132         ret = zigbee_service_dbus_interface_zcl_color_control_init(service_interface, zigbee_object);
133         Z_LOGD("ret: %d", ret);
134
135         ret = zigbee_service_dbus_interface_zcl_global_control_init(service_interface, zigbee_object);
136         Z_LOGD("ret: %d", ret);
137
138         ret = zigbee_service_dbus_interface_zcl_group_init(service_interface, zigbee_object);
139         Z_LOGD("ret: %d", ret);
140
141         ret = zigbee_service_dbus_interface_zcl_ias_zone_init(service_interface, zigbee_object);
142         Z_LOGD("ret: %d", ret);
143
144         ret = zigbee_service_dbus_interface_zcl_identify_init(service_interface, zigbee_object);
145         Z_LOGD("ret: %d", ret);
146
147         ret = zigbee_service_dbus_interface_zcl_poll_control_init(service_interface, zigbee_object);
148         Z_LOGD("ret: %d", ret);
149
150         ret = zigbee_service_dbus_interface_zcl_scene_init(service_interface, zigbee_object);
151         Z_LOGD("ret: %d", ret);
152
153         ret = zigbee_service_dbus_interface_zdo_bind_init(service_interface, zigbee_object);
154         Z_LOGD("ret: %d", ret);
155
156         ret = zigbee_service_dbus_interface_zdo_dev_control_init(service_interface, zigbee_object);
157         Z_LOGD("ret: %d", ret);
158 }
159
160 static void zigbee_service_dbus_interface_noti_cb(ZigBeeServiceInterface *service_interface,
161         guint noti_id, gpointer noti_data, guint noti_data_len, gpointer noti_cb_data)
162 {
163         ZblibDriverType_e driver_type;
164         guint notification_id;
165
166         if (NULL == service_interface) {
167                 Z_LOGE("service_interface is NULL");
168                 return;
169         }
170
171         /* Extract driver_type */
172         driver_type = ((noti_id & 0xFF000000) >> 24);
173
174         /* Extract notification_id */
175         notification_id = (noti_id & 0x000000FF);
176
177         Z_LOGI("Driver type: [%d] Notification ID: [%d]", driver_type, notification_id);
178
179         switch (driver_type) {
180         case ZBLIB_DRIVER_TYPE_ZCL_ALARM: {
181                 zigbee_service_dbus_interface_zcl_alarm_notification(service_interface,
182                         notification_id, noti_data, noti_data_len, noti_cb_data);
183         }
184         break;
185
186         case ZBLIB_DRIVER_TYPE_CUSTOM: {
187                 zigbee_service_dbus_interface_custom_notification(service_interface,
188                         notification_id, noti_data, noti_data_len, noti_cb_data);
189         }
190         break;
191
192         case ZBLIB_DRIVER_TYPE_ZCL_DOOR_LOCK: {
193                 zigbee_service_dbus_interface_zcl_door_lock_notification(service_interface,
194                         notification_id, noti_data, noti_data_len, noti_cb_data);
195         }
196         break;
197
198         case ZBLIB_DRIVER_TYPE_ZCL_FAN_CONTROL: {
199                 zigbee_service_dbus_interface_zcl_fan_control_notification(service_interface,
200                         notification_id, noti_data, noti_data_len, noti_cb_data);
201         }
202         break;
203
204         case ZBLIB_DRIVER_TYPE_ZCL_LEVEL_CONTROL: {
205                 zigbee_service_dbus_interface_zcl_level_control_notification(service_interface,
206                         notification_id, noti_data, noti_data_len, noti_cb_data);
207         }
208         break;
209
210         case ZBLIB_DRIVER_TYPE_MFGLIB_CONTROL: {
211                 zigbee_service_dbus_interface_mfglib_control_notification(service_interface,
212                         notification_id, noti_data, noti_data_len, noti_cb_data);
213         }
214         break;
215
216         case ZBLIB_DRIVER_TYPE_ZCL_ON_OFF: {
217                 zigbee_service_dbus_interface_zcl_on_off_notification(service_interface,
218                         notification_id, noti_data, noti_data_len, noti_cb_data);
219         }
220         break;
221
222         case ZBLIB_DRIVER_TYPE_SERVICE: {
223                 zigbee_service_dbus_interface_service_notification(service_interface,
224                         notification_id, noti_data, noti_data_len, noti_cb_data);
225         }
226         break;
227
228         case ZBLIB_DRIVER_TYPE_ZCL_THERMOSTAT: {
229                 zigbee_service_dbus_interface_zcl_thermostat_notification(service_interface,
230                         notification_id, noti_data, noti_data_len, noti_cb_data);
231         }
232         break;
233
234         case ZBLIB_DRIVER_TYPE_ZCL_BASIC: {
235                 zigbee_service_dbus_interface_zcl_basic_notification(service_interface,
236                         notification_id, noti_data, noti_data_len, noti_cb_data);
237         }
238         break;
239
240         case ZBLIB_DRIVER_TYPE_ZCL_GLOBAL_CONTROL: {
241                 zigbee_service_dbus_interface_zcl_global_control_notification(service_interface,
242                         notification_id, noti_data, noti_data_len, noti_cb_data);
243         }
244         break;
245
246         case ZBLIB_DRIVER_TYPE_ZCL_IAS_ZONE: {
247                 zigbee_service_dbus_interface_zcl_ias_zone_notification(service_interface,
248                         notification_id, noti_data, noti_data_len, noti_cb_data);
249         }
250         break;
251
252         case ZBLIB_DRIVER_TYPE_ZCL_IDENTIFY: {
253                 zigbee_service_dbus_interface_zcl_identify_notification(service_interface,
254                         notification_id, noti_data, noti_data_len, noti_cb_data);
255         }
256         break;
257
258         case ZBLIB_DRIVER_TYPE_ZCL_COLOR_CONTROL: {
259                 zigbee_service_dbus_interface_zcl_color_control_notification(service_interface,
260                         notification_id, noti_data, noti_data_len, noti_cb_data);
261         }
262         break;
263
264         case ZBLIB_DRIVER_TYPE_ZCL_GROUP: {
265                 zigbee_service_dbus_interface_zcl_group_notification(service_interface,
266                         notification_id, noti_data, noti_data_len, noti_cb_data);
267         }
268         break;
269
270         case ZBLIB_DRIVER_TYPE_ZCL_POLL_CONTROL: {
271                 zigbee_service_dbus_interface_zcl_poll_control_notification(service_interface,
272                         notification_id, noti_data, noti_data_len, noti_cb_data);
273         }
274         break;
275
276         case ZBLIB_DRIVER_TYPE_ZCL_SCENE: {
277                 zigbee_service_dbus_interface_zcl_scene_notification(service_interface,
278                         notification_id, noti_data, noti_data_len, noti_cb_data);
279         }
280         break;
281
282         case ZBLIB_DRIVER_TYPE_ZDO_DEV_CONTROL: {
283                 zigbee_service_dbus_interface_zdo_dev_control_notification(service_interface,
284                         notification_id, noti_data, noti_data_len, noti_cb_data);
285         }
286         break;
287
288         case ZBLIB_DRIVER_TYPE_ZDO_BIND: {
289                 zigbee_service_dbus_interface_zdo_bind_notification(service_interface,
290                         notification_id, noti_data, noti_data_len, noti_cb_data);
291         }
292         break;
293
294         case ZBLIB_DRIVER_TYPE_NONE: /* Fall through */
295         default: {
296                 Z_LOGE("Unhandled driver type: [%d]", driver_type);
297         }
298         break;
299         }
300 }
301
302 static void zigbee_on_name_lost(GDBusConnection *connection,
303         const gchar *name, gpointer user_data)
304 {
305         ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
306         ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
307
308         Z_LOGW("'%s' - [Name Lost]", name);
309
310         zblib_check_null_ret("custom_data", custom_data);
311
312         NOT_USED(connection);
313
314         /* Bus name is 'lost' */
315         custom_data->name_acquired = FALSE;
316 }
317
318 static void zigbee_on_name_acquired(GDBusConnection *connection,
319         const gchar *name, gpointer user_data)
320 {
321         ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
322         ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
323
324         Z_LOGI("'%s' - [Name Acquired]", name);
325
326         NOT_USED(connection);
327
328         zblib_check_null_ret("custom_data", custom_data);
329
330         /* Bus name is 'acquired' */
331         custom_data->name_acquired = TRUE;
332
333         if (TRUE == custom_data->sevice_interface_init_complete) {
334                 /* Emit zigbee_state - enabled */
335                 zigbee_manager_emit_zigbee_state(custom_data->zigbee_mgr, TRUE);
336         }
337 }
338
339 static void zigbee_on_bus_acquired(GDBusConnection *connection,
340         const gchar *name, gpointer user_data)
341 {
342         ZigbeeObjectSkeleton *zigbee_object;
343         ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
344         ZigBeeService *service = NULL;
345         ZigbeeCustomData_t *custom_data = NULL;
346         char *path = NULL;
347
348         Z_LOGI("'%s' - [BUS Acquired]", name);
349
350         if (NULL == service_interface) {
351                 Z_LOGE("service_interface is NULL!");
352                 return;
353         }
354
355         service = zblib_service_interface_ref_service(service_interface);
356         if (NULL == service) {
357                 Z_LOGE("service is NULL!");
358                 return;
359         }
360
361         custom_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
362         if (NULL == custom_data) {
363                 Z_LOGE("D-BUS service interface custom_data is NULL!");
364                 return;
365         }
366
367         /*
368          * Create ZigBee 'manager' D-BUS object
369          */
370         custom_data->zigbee_mgr = zigbee_manager_skeleton_new();
371
372         /*
373          * Set ZigBee 'manager' D-BUS object method(s)
374          */
375         g_signal_connect(custom_data->zigbee_mgr,
376                         "handle-get-zigbee-state",
377                         G_CALLBACK(on_manager_get_zigbee_state),
378                         service_interface);
379
380         g_signal_connect(custom_data->zigbee_mgr,
381                         "handle-enable",
382                         G_CALLBACK(on_manager_enable),
383                         service_interface);
384
385         g_signal_connect(custom_data->zigbee_mgr,
386                         "handle-disable",
387                         G_CALLBACK(on_manager_disable),
388                         service_interface);
389
390         /*
391          * Export 'manager' interface on ZigBee D-BUS
392          */
393         g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(custom_data->zigbee_mgr),
394                 connection, ZIGBEE_DBUS_PATH, NULL);
395
396         /*
397          * Exports all objects managed by 'manager' on Connection (connection)
398          */
399         g_dbus_object_manager_server_set_connection(custom_data->manager, connection);
400
401         path = g_strdup_printf("%s", ZIGBEE_SERVICE_PATH);
402         Z_LOGI("dbus object path: [%s]", path);
403
404         /*
405          * Create 'object' for specific path only once.
406          */
407         zigbee_object = g_hash_table_lookup(custom_data->objects, path);
408         if (zigbee_object) {
409                 Z_LOGW("ZigBee D-BUS interface object already created (object: %p)", zigbee_object);
410                 goto OUT;
411         }
412
413         /*
414          * Create ZigBee D-BUS object
415          */
416         zigbee_object = zigbee_object_skeleton_new(path);
417         Z_LOGI("ZigBee D-BUS object created (zigbee_object: [%p])", zigbee_object);
418
419         /*
420          * Insert ZigBee object to HASH table
421          */
422         g_hash_table_insert(custom_data->objects, g_strdup(path), zigbee_object);
423
424         /*
425          * Initialize interfaces
426          */
427         zigbee_service_dbus_interface_initialize_interfaces(service_interface, zigbee_object);
428         Z_LOGI("ZigBee service interfaces initialized!!!");
429
430         /* Export the Object to Manager */
431         g_dbus_object_manager_server_export(custom_data->manager,
432                 G_DBUS_OBJECT_SKELETON(zigbee_object));
433
434         /* Service interface initialization completed */
435         custom_data->sevice_interface_init_complete = TRUE;
436
437         if (TRUE == custom_data->name_acquired) {
438                 /* TODO - Emit zigbee_state signal */
439         }
440
441 OUT:
442         g_free(path);
443 }
444
445 static void zigbee_get_activation_sbus(ZigbeeCustomData_t *interface_data)
446 {
447         /* Get D-Bus owner to activate zigbee-daemon */
448         interface_data->activation_dbus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
449                         ZIGBEE_DBUS_SERVICE".manager",
450                         G_BUS_NAME_OWNER_FLAGS_REPLACE,
451                         NULL,
452                         NULL,
453                         NULL,
454                         NULL,
455                         NULL);
456         Z_LOGI("ZigBee D-BUS activation ID: [%d]", interface_data->activation_dbus_id);
457 }
458
459 /**< Zigbee service dbus interface initialization */
460 gboolean zigbee_service_dbus_interface_init(ZigBeeService *service)
461 {
462         ZigBeeServiceInterface *service_interface = NULL;
463         ZigbeeCustomData_t *interface_data = NULL;
464         gboolean ret;
465
466         if (NULL == service) {
467                 Z_LOGE("service is NULL");
468                 return FALSE;
469         }
470
471         /*
472          * Create ZigBee service interface object
473          */
474         service_interface = zblib_service_interface_new(service,
475                 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
476         if (NULL == service_interface) {
477                 Z_LOGE("Create D-BUS service interface failed!");
478
479                 return FALSE;
480         }
481
482         /*
483          * Set Service interface notification callback
484          */
485         ret = zblib_service_interface_set_noti_cb(service_interface,
486                 zigbee_service_dbus_interface_noti_cb, NULL);
487         if (FALSE == ret) {
488                 Z_LOGE("Set service interface notification callback failed!");
489
490                 goto EXIT;
491         }
492
493         /*
494          * Add Service interface object to 'service'
495          */
496         ret = zblib_service_add_service_interface(service,
497                         service_interface);
498         if (FALSE == ret) {
499                 Z_LOGE("Add D-BUS service interface failed!");
500
501                 goto EXIT;
502         }
503
504         /*
505          * ZigBee D-BUS interface custom data
506          */
507         interface_data = g_malloc0(sizeof(ZigbeeCustomData_t));
508
509         /*
510          * Link interface data to service
511          */
512         ret = zblib_service_interface_link_user_data(service_interface,
513                         interface_data);
514         if (FALSE == ret) {
515                 Z_LOGE("Link D-BUS service interface data failed!");
516
517                 goto EXIT;
518         }
519
520         /* HASH table for maintaining 'objects' list */
521         interface_data->objects = g_hash_table_new_full(g_str_hash, g_str_equal,
522                         g_free, NULL);
523
524         /*
525          * Acquire "org.tizen.zigbee.manager" named bus on D-BUS SYSTEM bus.
526          */
527         zigbee_get_activation_sbus(interface_data);
528
529         /*
530          * Acquire "org.tizen.zigbee" named bus on D-BUS SYSTEM bus.
531          */
532         interface_data->bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
533                         ZIGBEE_DBUS_SERVICE,
534                         G_BUS_NAME_OWNER_FLAGS_REPLACE,
535                         zigbee_on_bus_acquired,
536                         zigbee_on_name_acquired,
537                         zigbee_on_name_lost,
538                         service_interface,
539                         NULL);
540         Z_LOGI("ZigBee D-BUS ID: [%d]", interface_data->bus_id);
541
542         interface_data->manager = g_dbus_object_manager_server_new(ZIGBEE_DBUS_PATH);
543
544         return TRUE;
545
546 EXIT:
547         g_free(interface_data);
548
549         /*
550          * Remove Service interface object from 'service'
551          */
552         ret = zblib_service_remove_service_interface(service,
553                         service_interface);
554         if (FALSE == ret) {
555                 Z_LOGE("Remove service interface failed!");
556         }
557
558         /*
559          * Free Service interface object
560          */
561         zblib_service_interface_free(service,
562                         service_interface);
563
564         return FALSE;
565 }
566
567 /**< Zigbee service dbus interface de-initialization */
568 void zigbee_service_dbus_interface_deinit(ZigBeeService *service)
569 {
570         ZigBeeServiceInterface *service_interface = NULL;
571         ZigbeeCustomData_t *interface_data = NULL;
572         gboolean ret;
573
574         if (NULL == service) {
575                 Z_LOGE("service is NULL");
576                 return;
577         }
578
579         service_interface = zblib_service_ref_service_interface(service,
580                 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
581         if (NULL == service_interface) {
582                 Z_LOGE("D-BUS service interface not found!");
583
584                 return;
585         }
586
587         interface_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
588         if (NULL == interface_data) {
589                 Z_LOGE("D-BUS interface data not found!");
590
591                 goto EXIT;
592         }
593
594         /*
595          * Unown "org.tizen.zigbee.manager" named bus on D-BUS SYSTEM bus
596          */
597         if (interface_data->activation_dbus_id > 0) {
598                 Z_LOGI("Unowning ZigBee Service interface activation D-BUS ID: [%d]",
599                         interface_data->activation_dbus_id);
600                 g_bus_unown_name(interface_data->activation_dbus_id);
601         }
602
603         /*
604          * Unown "org.tizen.zigbee" named bus on D-BUS SYSTEM bus
605          */
606         if (interface_data->bus_id > 0) {
607                 Z_LOGI("Unowning ZigBee Service interface D-BUS ID: [%d]", interface_data->bus_id);
608                 g_bus_unown_name(interface_data->bus_id);
609         }
610
611         /* Free resources */
612         g_hash_table_destroy(interface_data->objects);
613         g_free(interface_data);
614
615 EXIT:
616         /*
617          * Remove Service interface object from 'service'
618          */
619         ret = zblib_service_remove_service_interface(service,
620                         service_interface);
621         if (FALSE == ret) {
622                 Z_LOGE("Remove service interface failed!");
623         }
624
625         /*
626          * Free Service interface object
627          */
628         zblib_service_interface_free(service,
629                         service_interface);
630 }