b7e4f802571bf05d07f022e4533fec331b87745a
[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         ZigbeeCustomData_t *custom_data = user_data;
263
264         Z_LOGW("'%s' - [Name Lost]", name);
265
266         NOT_USED(connection);
267
268         /* Bus name is 'lost' */
269         custom_data->name_acquired = FALSE;
270 }
271
272 static void zigbee_on_name_acquired(GDBusConnection *connection,
273         const gchar *name, gpointer user_data)
274 {
275         ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
276         ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
277
278         Z_LOGI("'%s' - [Name Acquired]", name);
279
280         NOT_USED(connection);
281
282         /* Bus name is 'acquired' */
283         custom_data->name_acquired = TRUE;
284
285         if (TRUE == custom_data->sevice_interface_init_complete) {
286                 /* TODO - Emit zigbee_state signal */
287         }
288 }
289
290 static void zigbee_on_bus_acquired(GDBusConnection *connection,
291         const gchar *name, gpointer user_data)
292 {
293         ZigbeeObjectSkeleton *zigbee_object;
294         ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
295         ZigBeeService *service = NULL;
296         ZigbeeCustomData_t *custom_data = NULL;
297         char *path = NULL;
298
299         Z_LOGI("'%s' - [BUS Acquired]", name);
300
301         if (NULL == service_interface) {
302                 Z_LOGE("service_interface is NULL!");
303                 return;
304         }
305
306         service = zblib_service_interface_ref_service(service_interface);
307         if (NULL == service) {
308                 Z_LOGE("service is NULL!");
309                 return;
310         }
311
312         custom_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
313         if (NULL == custom_data) {
314                 Z_LOGE("D-BUS service interface custom_data is NULL!");
315                 return;
316         }
317
318         /*
319          * Create ZigBee 'manager' D-BUS object
320          */
321         custom_data->zigbee_mgr = zigbee_manager_skeleton_new();
322
323         /*
324          * Set ZigBee 'manager' D-BUS object method(s)
325          */
326         g_signal_connect(custom_data->zigbee_mgr,
327                         "handle-get-zigbee-state",
328                         G_CALLBACK(zigbee_on_manager_get_zigbee_state),
329                         custom_data);
330
331         /*
332          * Export 'manager' interface on ZigBee D-BUS
333          */
334         g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(custom_data->zigbee_mgr),
335                 connection, ZIGBEE_DBUS_PATH, NULL);
336
337         /*
338          * Exports all objects managed by 'manager' on Connection (connection)
339          */
340         g_dbus_object_manager_server_set_connection(custom_data->manager, connection);
341
342         path = g_strdup_printf("%s/service", ZIGBEE_DBUS_PATH);
343         Z_LOGI("dbus object path: [%s]", path);
344
345         /*
346          * Create 'object' for specific path only once.
347          */
348         zigbee_object = g_hash_table_lookup(custom_data->objects, path);
349         if (zigbee_object) {
350                 Z_LOGW("ZigBee D-BUS interface object already created (object: %p)", zigbee_object);
351                 goto OUT;
352         }
353
354         /*
355          * Create ZigBee D-BUS object
356          */
357         zigbee_object = zigbee_object_skeleton_new(path);
358         Z_LOGI("ZigBee D-BUS object created (zigbee_object: [%p])", zigbee_object);
359
360         /*
361          * Insert ZigBee object to HASH table
362          */
363         g_hash_table_insert(custom_data->objects, g_strdup(path), zigbee_object);
364
365         /*
366          * Initialize interfaces
367          */
368         zigbee_service_dbus_interface_initialize_interfaces(service_interface, zigbee_object);
369         Z_LOGI("ZigBee service interfaces initialized!!!");
370
371         /* Export the Object to Manager */
372         g_dbus_object_manager_server_export(custom_data->manager,
373                 G_DBUS_OBJECT_SKELETON(zigbee_object));
374
375         /* Servcie interface initialization completed */
376         custom_data->sevice_interface_init_complete = TRUE;
377
378         if (TRUE == custom_data->name_acquired) {
379                 /* TODO - Emit zigbee_state signal */
380         }
381
382 OUT:
383         g_free(path);
384 }
385
386 /**< Zigbee service dbus interface initialization */
387 gboolean zigbee_service_dbus_interface_init(ZigBeeService *service)
388 {
389         ZigBeeServiceInterface *service_interface = NULL;
390         ZigbeeCustomData_t *interface_data = NULL;
391         gboolean ret;
392
393         if (NULL == service) {
394                 Z_LOGE("service is NULL");
395                 return FALSE;
396         }
397
398         /*
399          * Create ZigBee service interface object
400          */
401         service_interface = zblib_service_interface_new(service,
402                 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
403         if (NULL == service_interface) {
404                 Z_LOGE("Create D-BUS service interface failed!");
405
406                 return FALSE;
407         }
408
409         /*
410          * Set Service interface notification callback
411          */
412         ret = zblib_service_interface_set_noti_cb(service_interface,
413                 zigbee_service_dbus_interface_noti_cb, NULL);
414         if (FALSE == ret) {
415                 Z_LOGE("Set service interface notification callback failed!");
416
417                 goto EXIT;
418         }
419
420         /*
421          * Add Service interface object to 'service'
422          */
423         ret = zblib_service_add_service_interface(service,
424                         service_interface);
425         if (FALSE == ret) {
426                 Z_LOGE("Add D-BUS service interface failed!");
427
428                 goto EXIT;
429         }
430
431         /*
432          * ZigBee D-BUS interface custom data
433          */
434         interface_data = g_malloc0(sizeof(ZigbeeCustomData_t));
435
436         /*
437          * Link interface data to service
438          */
439         ret = zblib_service_interface_link_user_data(service_interface,
440                         interface_data);
441         if (FALSE == ret) {
442                 Z_LOGE("Link D-BUS service interface data failed!");
443
444                 goto EXIT;
445         }
446
447         /* HASH table for maintaining 'objects' list */
448         interface_data->objects = g_hash_table_new(g_str_hash, g_str_equal);
449
450         /*
451          * Acquire "org.tizen.zigbee" named bus on D-BUS SYSTEM bus.
452          */
453         interface_data->bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
454                         ZIGBEE_DBUS_SERVICE,
455                         G_BUS_NAME_OWNER_FLAGS_REPLACE,
456                         zigbee_on_bus_acquired,
457                         zigbee_on_name_acquired,
458                         zigbee_on_name_lost,
459                         service_interface,
460                         NULL);
461         Z_LOGI("ZigBee D-BUS ID: [%d]", interface_data->bus_id);
462
463         interface_data->manager = g_dbus_object_manager_server_new(ZIGBEE_DBUS_PATH);
464
465         return TRUE;
466
467 EXIT:
468         g_free(interface_data);
469
470         /*
471          * Remove Service interface object from 'service'
472          */
473         ret = zblib_service_remove_service_interface(service,
474                         service_interface);
475         if (FALSE == ret) {
476                 Z_LOGE("Remove service interface failed!");
477         }
478
479         /*
480          * Free Service interface object
481          */
482         zblib_service_interface_free(service,
483                         service_interface);
484
485         return FALSE;
486 }
487
488 /**< Zigbee service dbus interface de-initialization */
489 void zigbee_service_dbus_interface_deinit(ZigBeeService *service)
490 {
491         ZigBeeServiceInterface *service_interface = NULL;
492         ZigbeeCustomData_t *interface_data = NULL;
493         gboolean ret;
494
495         if (NULL == service) {
496                 Z_LOGE("service is NULL");
497                 return;
498         }
499
500         service_interface = zblib_service_ref_service_interface(service,
501                 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
502         if (NULL == service_interface) {
503                 Z_LOGE("D-BUS service interface not found!");
504
505                 return;
506         }
507
508         interface_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
509         if (NULL == service_interface) {
510                 Z_LOGE("D-BUS service interface not found!");
511
512                 goto EXIT;
513         }
514
515         /*
516          * Unown "org.tizen.zigbee" named bus on D-BUS SYSTEM bus
517          */
518         if (interface_data->bus_id > 0) {
519                 Z_LOGI("Unowning ZigBee Service interface D-BUS ID: [%d]", interface_data->bus_id);
520                 g_bus_unown_name(interface_data->bus_id);
521         }
522
523         /* Free resources */
524         g_hash_table_destroy(interface_data->objects);
525         g_free(interface_data);
526
527 EXIT:
528         /*
529          * Remove Service interface object from 'service'
530          */
531         ret = zblib_service_remove_service_interface(service,
532                         service_interface);
533         if (FALSE == ret) {
534                 Z_LOGE("Remove service interface failed!");
535         }
536
537         /*
538          * Free Service interface object
539          */
540         zblib_service_interface_free(service,
541                         service_interface);
542 }