Fix SVace warnings
[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 zigbee_on_manager_get_zigbee_state(ZigbeeManager *zigbee_mgr,
38         GDBusMethodInvocation *invocation, gpointer user_data)
39 {
40         Z_LOGI("Entered");
41
42         NOT_USED(zigbee_mgr);
43         NOT_USED(invocation);
44         NOT_USED(user_data);
45
46         /*
47          * TODO -
48          * Create and send request for processing
49          */
50
51         return TRUE;
52 }
53
54 static void zigbee_service_dbus_interface_initialize_interfaces(ZigBeeServiceInterface *service_interface,
55         ZigbeeObjectSkeleton *zigbee_object)
56 {
57         gboolean ret;
58
59         ret = zigbee_service_dbus_interface_zcl_alarm_init(service_interface, zigbee_object);
60         Z_LOGD("ret: %d", ret);
61
62         ret = zigbee_service_dbus_interface_custom_init(service_interface, zigbee_object);
63         Z_LOGD("ret: %d", ret);
64
65         ret = zigbee_service_dbus_interface_zcl_door_lock_init(service_interface, zigbee_object);
66         Z_LOGD("ret: %d", ret);
67
68         ret = zigbee_service_dbus_interface_zcl_fan_control_init(service_interface, zigbee_object);
69         Z_LOGD("ret: %d", ret);
70
71         ret = zigbee_service_dbus_interface_zcl_level_control_init(service_interface, zigbee_object);
72         Z_LOGD("ret: %d", ret);
73
74         ret = zigbee_service_dbus_interface_mfglib_control_init(service_interface, zigbee_object);
75         Z_LOGD("ret: %d", ret);
76
77         ret = zigbee_service_dbus_interface_zcl_on_off_init(service_interface, zigbee_object);
78         Z_LOGD("ret: %d", ret);
79
80         ret = zigbee_service_dbus_interface_service_init(service_interface, zigbee_object);
81         Z_LOGD("ret: %d", ret);
82
83         ret = zigbee_service_dbus_interface_zcl_thermostat_init(service_interface, zigbee_object);
84         Z_LOGD("ret: %d", ret);
85
86         ret = zigbee_service_dbus_interface_zcl_basic_init(service_interface, zigbee_object);
87         Z_LOGD("ret: %d", ret);
88
89         ret = zigbee_service_dbus_interface_zcl_color_control_init(service_interface, zigbee_object);
90         Z_LOGD("ret: %d", ret);
91
92         ret = zigbee_service_dbus_interface_zcl_global_control_init(service_interface, zigbee_object);
93         Z_LOGD("ret: %d", ret);
94
95         ret = zigbee_service_dbus_interface_zcl_group_init(service_interface, zigbee_object);
96         Z_LOGD("ret: %d", ret);
97
98         ret = zigbee_service_dbus_interface_zcl_ias_zone_init(service_interface, zigbee_object);
99         Z_LOGD("ret: %d", ret);
100
101         ret = zigbee_service_dbus_interface_zcl_identify_init(service_interface, zigbee_object);
102         Z_LOGD("ret: %d", ret);
103
104         ret = zigbee_service_dbus_interface_zcl_poll_control_init(service_interface, zigbee_object);
105         Z_LOGD("ret: %d", ret);
106
107         ret = zigbee_service_dbus_interface_zcl_scene_init(service_interface, zigbee_object);
108         Z_LOGD("ret: %d", ret);
109
110         ret = zigbee_service_dbus_interface_zdo_bind_init(service_interface, zigbee_object);
111         Z_LOGD("ret: %d", ret);
112
113         ret = zigbee_service_dbus_interface_zdo_dev_control_init(service_interface, zigbee_object);
114         Z_LOGD("ret: %d", ret);
115 }
116
117 static void zigbee_service_dbus_interface_noti_cb(ZigBeeServiceInterface *service_interface,
118         guint noti_id, gpointer noti_data, guint noti_data_len, gpointer noti_cb_data)
119 {
120         ZblibDriverType_e driver_type;
121         guint notification_id;
122
123         if (NULL == service_interface) {
124                 Z_LOGE("service_interface is NULL");
125                 return;
126         }
127
128         /* Extract driver_type */
129         driver_type = ((noti_id & 0xFF000000) >> 24);
130
131         /* Extract notification_id */
132         notification_id = (noti_id & 0x000000FF);
133
134         Z_LOGI("Driver type: [%d] Notification ID: [%d]", driver_type, notification_id);
135
136         switch (driver_type) {
137         case ZBLIB_DRIVER_TYPE_ZCL_ALARM: {
138                 zigbee_service_dbus_interface_zcl_alarm_notification(service_interface,
139                         notification_id, noti_data, noti_data_len, noti_cb_data);
140         }
141         break;
142
143         case ZBLIB_DRIVER_TYPE_CUSTOM: {
144                 zigbee_service_dbus_interface_custom_notification(service_interface,
145                         notification_id, noti_data, noti_data_len, noti_cb_data);
146         }
147         break;
148
149         case ZBLIB_DRIVER_TYPE_ZCL_DOOR_LOCK: {
150                 zigbee_service_dbus_interface_zcl_door_lock_notification(service_interface,
151                         notification_id, noti_data, noti_data_len, noti_cb_data);
152         }
153         break;
154
155         case ZBLIB_DRIVER_TYPE_ZCL_FAN_CONTROL: {
156                 zigbee_service_dbus_interface_zcl_fan_control_notification(service_interface,
157                         notification_id, noti_data, noti_data_len, noti_cb_data);
158         }
159         break;
160
161         case ZBLIB_DRIVER_TYPE_ZCL_LEVEL_CONTROL: {
162                 zigbee_service_dbus_interface_zcl_level_control_notification(service_interface,
163                         notification_id, noti_data, noti_data_len, noti_cb_data);
164         }
165         break;
166
167         case ZBLIB_DRIVER_TYPE_MFGLIB_CONTROL: {
168                 zigbee_service_dbus_interface_mfglib_control_notification(service_interface,
169                         notification_id, noti_data, noti_data_len, noti_cb_data);
170         }
171         break;
172
173         case ZBLIB_DRIVER_TYPE_ZCL_ON_OFF: {
174                 zigbee_service_dbus_interface_zcl_on_off_notification(service_interface,
175                         notification_id, noti_data, noti_data_len, noti_cb_data);
176         }
177         break;
178
179         case ZBLIB_DRIVER_TYPE_SERVICE: {
180                 zigbee_service_dbus_interface_service_notification(service_interface,
181                         notification_id, noti_data, noti_data_len, noti_cb_data);
182         }
183         break;
184
185         case ZBLIB_DRIVER_TYPE_ZCL_THERMOSTAT: {
186                 zigbee_service_dbus_interface_zcl_thermostat_notification(service_interface,
187                         notification_id, noti_data, noti_data_len, noti_cb_data);
188         }
189         break;
190
191         case ZBLIB_DRIVER_TYPE_ZCL_BASIC: {
192                 zigbee_service_dbus_interface_zcl_basic_notification(service_interface,
193                         notification_id, noti_data, noti_data_len, noti_cb_data);
194         }
195         break;
196
197         case ZBLIB_DRIVER_TYPE_ZCL_GLOBAL_CONTROL: {
198                 zigbee_service_dbus_interface_zcl_global_control_notification(service_interface,
199                         notification_id, noti_data, noti_data_len, noti_cb_data);
200         }
201         break;
202
203         case ZBLIB_DRIVER_TYPE_ZCL_IAS_ZONE: {
204                 zigbee_service_dbus_interface_zcl_ias_zone_notification(service_interface,
205                         notification_id, noti_data, noti_data_len, noti_cb_data);
206         }
207         break;
208
209         case ZBLIB_DRIVER_TYPE_ZCL_IDENTIFY: {
210                 zigbee_service_dbus_interface_zcl_identify_notification(service_interface,
211                         notification_id, noti_data, noti_data_len, noti_cb_data);
212         }
213         break;
214
215         case ZBLIB_DRIVER_TYPE_ZCL_COLOR_CONTROL: {
216                 zigbee_service_dbus_interface_zcl_color_control_notification(service_interface,
217                         notification_id, noti_data, noti_data_len, noti_cb_data);
218         }
219         break;
220
221         case ZBLIB_DRIVER_TYPE_ZCL_GROUP: {
222                 zigbee_service_dbus_interface_zcl_group_notification(service_interface,
223                         notification_id, noti_data, noti_data_len, noti_cb_data);
224         }
225         break;
226
227         case ZBLIB_DRIVER_TYPE_ZCL_POLL_CONTROL: {
228                 zigbee_service_dbus_interface_zcl_poll_control_notification(service_interface,
229                         notification_id, noti_data, noti_data_len, noti_cb_data);
230         }
231         break;
232
233         case ZBLIB_DRIVER_TYPE_ZCL_SCENE: {
234                 zigbee_service_dbus_interface_zcl_scene_notification(service_interface,
235                         notification_id, noti_data, noti_data_len, noti_cb_data);
236         }
237         break;
238
239         case ZBLIB_DRIVER_TYPE_ZDO_DEV_CONTROL: {
240                 zigbee_service_dbus_interface_zdo_dev_control_notification(service_interface,
241                         notification_id, noti_data, noti_data_len, noti_cb_data);
242         }
243         break;
244
245         case ZBLIB_DRIVER_TYPE_ZDO_BIND: {
246                 zigbee_service_dbus_interface_zdo_bind_notification(service_interface,
247                         notification_id, noti_data, noti_data_len, noti_cb_data);
248         }
249         break;
250
251         case ZBLIB_DRIVER_TYPE_NONE: /* Fall through */
252         default: {
253                 Z_LOGE("Unhandled driver type: [%d]", driver_type);
254         }
255         break;
256         }
257 }
258
259 static void zigbee_on_name_lost(GDBusConnection *connection,
260         const gchar *name, gpointer user_data)
261 {
262         ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
263         ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
264
265         Z_LOGW("'%s' - [Name Lost]", name);
266
267         zblib_check_null_ret("custom_data", custom_data);
268
269         NOT_USED(connection);
270
271         /* Bus name is 'lost' */
272         custom_data->name_acquired = FALSE;
273 }
274
275 static void zigbee_on_name_acquired(GDBusConnection *connection,
276         const gchar *name, gpointer user_data)
277 {
278         ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
279         ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
280
281         Z_LOGI("'%s' - [Name Acquired]", name);
282
283         NOT_USED(connection);
284
285         zblib_check_null_ret("custom_data", custom_data);
286
287         /* Bus name is 'acquired' */
288         custom_data->name_acquired = TRUE;
289
290         if (TRUE == custom_data->sevice_interface_init_complete) {
291                 /* TODO - Emit zigbee_state signal */
292         }
293 }
294
295 static void zigbee_on_bus_acquired(GDBusConnection *connection,
296         const gchar *name, gpointer user_data)
297 {
298         ZigbeeObjectSkeleton *zigbee_object;
299         ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
300         ZigBeeService *service = NULL;
301         ZigbeeCustomData_t *custom_data = NULL;
302         char *path = NULL;
303
304         Z_LOGI("'%s' - [BUS Acquired]", name);
305
306         if (NULL == service_interface) {
307                 Z_LOGE("service_interface is NULL!");
308                 return;
309         }
310
311         service = zblib_service_interface_ref_service(service_interface);
312         if (NULL == service) {
313                 Z_LOGE("service is NULL!");
314                 return;
315         }
316
317         custom_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
318         if (NULL == custom_data) {
319                 Z_LOGE("D-BUS service interface custom_data is NULL!");
320                 return;
321         }
322
323         /*
324          * Create ZigBee 'manager' D-BUS object
325          */
326         custom_data->zigbee_mgr = zigbee_manager_skeleton_new();
327
328         /*
329          * Set ZigBee 'manager' D-BUS object method(s)
330          */
331         g_signal_connect(custom_data->zigbee_mgr,
332                         "handle-get-zigbee-state",
333                         G_CALLBACK(zigbee_on_manager_get_zigbee_state),
334                         custom_data);
335
336         /*
337          * Export 'manager' interface on ZigBee D-BUS
338          */
339         g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(custom_data->zigbee_mgr),
340                 connection, ZIGBEE_DBUS_PATH, NULL);
341
342         /*
343          * Exports all objects managed by 'manager' on Connection (connection)
344          */
345         g_dbus_object_manager_server_set_connection(custom_data->manager, connection);
346
347         path = g_strdup_printf("%s", ZIGBEE_SERVICE_PATH);
348         Z_LOGI("dbus object path: [%s]", path);
349
350         /*
351          * Create 'object' for specific path only once.
352          */
353         zigbee_object = g_hash_table_lookup(custom_data->objects, path);
354         if (zigbee_object) {
355                 Z_LOGW("ZigBee D-BUS interface object already created (object: %p)", zigbee_object);
356                 goto OUT;
357         }
358
359         /*
360          * Create ZigBee D-BUS object
361          */
362         zigbee_object = zigbee_object_skeleton_new(path);
363         Z_LOGI("ZigBee D-BUS object created (zigbee_object: [%p])", zigbee_object);
364
365         /*
366          * Insert ZigBee object to HASH table
367          */
368         g_hash_table_insert(custom_data->objects, g_strdup(path), zigbee_object);
369
370         /*
371          * Initialize interfaces
372          */
373         zigbee_service_dbus_interface_initialize_interfaces(service_interface, zigbee_object);
374         Z_LOGI("ZigBee service interfaces initialized!!!");
375
376         /* Export the Object to Manager */
377         g_dbus_object_manager_server_export(custom_data->manager,
378                 G_DBUS_OBJECT_SKELETON(zigbee_object));
379
380         /* Servcie interface initialization completed */
381         custom_data->sevice_interface_init_complete = TRUE;
382
383         if (TRUE == custom_data->name_acquired) {
384                 /* TODO - Emit zigbee_state signal */
385         }
386
387 OUT:
388         g_free(path);
389 }
390
391 /**< Zigbee service dbus interface initialization */
392 gboolean zigbee_service_dbus_interface_init(ZigBeeService *service)
393 {
394         ZigBeeServiceInterface *service_interface = NULL;
395         ZigbeeCustomData_t *interface_data = NULL;
396         gboolean ret;
397
398         if (NULL == service) {
399                 Z_LOGE("service is NULL");
400                 return FALSE;
401         }
402
403         /*
404          * Create ZigBee service interface object
405          */
406         service_interface = zblib_service_interface_new(service,
407                 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
408         if (NULL == service_interface) {
409                 Z_LOGE("Create D-BUS service interface failed!");
410
411                 return FALSE;
412         }
413
414         /*
415          * Set Service interface notification callback
416          */
417         ret = zblib_service_interface_set_noti_cb(service_interface,
418                 zigbee_service_dbus_interface_noti_cb, NULL);
419         if (FALSE == ret) {
420                 Z_LOGE("Set service interface notification callback failed!");
421
422                 goto EXIT;
423         }
424
425         /*
426          * Add Service interface object to 'service'
427          */
428         ret = zblib_service_add_service_interface(service,
429                         service_interface);
430         if (FALSE == ret) {
431                 Z_LOGE("Add D-BUS service interface failed!");
432
433                 goto EXIT;
434         }
435
436         /*
437          * ZigBee D-BUS interface custom data
438          */
439         interface_data = g_malloc0(sizeof(ZigbeeCustomData_t));
440
441         /*
442          * Link interface data to service
443          */
444         ret = zblib_service_interface_link_user_data(service_interface,
445                         interface_data);
446         if (FALSE == ret) {
447                 Z_LOGE("Link D-BUS service interface data failed!");
448
449                 goto EXIT;
450         }
451
452         /* HASH table for maintaining 'objects' list */
453         interface_data->objects = g_hash_table_new_full(g_str_hash, g_str_equal,
454                         g_free, NULL);
455
456         /*
457          * Acquire "org.tizen.zigbee" named bus on D-BUS SYSTEM bus.
458          */
459         interface_data->bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
460                         ZIGBEE_DBUS_SERVICE,
461                         G_BUS_NAME_OWNER_FLAGS_REPLACE,
462                         zigbee_on_bus_acquired,
463                         zigbee_on_name_acquired,
464                         zigbee_on_name_lost,
465                         service_interface,
466                         NULL);
467         Z_LOGI("ZigBee D-BUS ID: [%d]", interface_data->bus_id);
468
469         interface_data->manager = g_dbus_object_manager_server_new(ZIGBEE_DBUS_PATH);
470
471         return TRUE;
472
473 EXIT:
474         g_free(interface_data);
475
476         /*
477          * Remove Service interface object from 'service'
478          */
479         ret = zblib_service_remove_service_interface(service,
480                         service_interface);
481         if (FALSE == ret) {
482                 Z_LOGE("Remove service interface failed!");
483         }
484
485         /*
486          * Free Service interface object
487          */
488         zblib_service_interface_free(service,
489                         service_interface);
490
491         return FALSE;
492 }
493
494 /**< Zigbee service dbus interface de-initialization */
495 void zigbee_service_dbus_interface_deinit(ZigBeeService *service)
496 {
497         ZigBeeServiceInterface *service_interface = NULL;
498         ZigbeeCustomData_t *interface_data = NULL;
499         gboolean ret;
500
501         if (NULL == service) {
502                 Z_LOGE("service is NULL");
503                 return;
504         }
505
506         service_interface = zblib_service_ref_service_interface(service,
507                 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
508         if (NULL == service_interface) {
509                 Z_LOGE("D-BUS service interface not found!");
510
511                 return;
512         }
513
514         interface_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
515         if (NULL == interface_data) {
516                 Z_LOGE("D-BUS interface data not found!");
517
518                 goto EXIT;
519         }
520
521         /*
522          * Unown "org.tizen.zigbee" named bus on D-BUS SYSTEM bus
523          */
524         if (interface_data->bus_id > 0) {
525                 Z_LOGI("Unowning ZigBee Service interface D-BUS ID: [%d]", interface_data->bus_id);
526                 g_bus_unown_name(interface_data->bus_id);
527         }
528
529         /* Free resources */
530         g_hash_table_destroy(interface_data->objects);
531         g_free(interface_data);
532
533 EXIT:
534         /*
535          * Remove Service interface object from 'service'
536          */
537         ret = zblib_service_remove_service_interface(service,
538                         service_interface);
539         if (FALSE == ret) {
540                 Z_LOGE("Remove service interface failed!");
541         }
542
543         /*
544          * Free Service interface object
545          */
546         zblib_service_interface_free(service,
547                         service_interface);
548 }