2 * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
4 * Contact: Suresh Kumar N (suresh.n@samsung.com)
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
27 #include <zblib_service.h>
28 #include <zblib_service_interface.h>
30 #include "zigbee_service_interface.h"
31 #include "zigbee_service_interface_common.h"
32 #include "zigbee_service_dbus_interface.h"
34 /**< ZigBee D-BUS service interface name */
35 #define ZIGBEE_DBUS_SERVICE_INTERFACE_NAME "zigbee-dbus"
37 static gboolean on_manager_enable(ZigbeeManager *zigbee_mgr,
38 GDBusMethodInvocation *invocation,
41 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
42 ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
44 if (NULL == custom_data) {
45 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
50 zigbee_manager_complete_enable(zigbee_mgr, invocation);
52 if (TRUE == custom_data->sevice_interface_init_complete) {
53 /* Emit zigbee_state - enabled */
54 zigbee_manager_emit_zigbee_state(zigbee_mgr, TRUE);
60 static gboolean on_manager_disable(ZigbeeManager *zigbee_mgr,
61 GDBusMethodInvocation *invocation,
64 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
65 ZigBeeService *service = zblib_service_interface_ref_service(service_interface);
69 zigbee_manager_complete_disable(zigbee_mgr, invocation, 0);
72 zblib_service_exit(service);
77 static gboolean on_manager_get_zigbee_state(ZigbeeManager *zigbee_mgr,
78 GDBusMethodInvocation *invocation, gpointer user_data)
80 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
81 ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
85 if (NULL == custom_data) {
86 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
91 zigbee_manager_complete_get_zigbee_state(zigbee_mgr, invocation,
92 0, custom_data->sevice_interface_init_complete);
97 static void zigbee_service_dbus_interface_initialize_interfaces(ZigBeeServiceInterface *service_interface,
98 ZigbeeObjectSkeleton *zigbee_object)
102 ret = zigbee_service_dbus_interface_zcl_alarm_init(service_interface, zigbee_object);
103 Z_LOGD("ret: %d", ret);
105 ret = zigbee_service_dbus_interface_custom_init(service_interface, zigbee_object);
106 Z_LOGD("ret: %d", ret);
108 ret = zigbee_service_dbus_interface_zcl_door_lock_init(service_interface, zigbee_object);
109 Z_LOGD("ret: %d", ret);
111 ret = zigbee_service_dbus_interface_zcl_fan_control_init(service_interface, zigbee_object);
112 Z_LOGD("ret: %d", ret);
114 ret = zigbee_service_dbus_interface_zcl_level_control_init(service_interface, zigbee_object);
115 Z_LOGD("ret: %d", ret);
117 ret = zigbee_service_dbus_interface_mfglib_control_init(service_interface, zigbee_object);
118 Z_LOGD("ret: %d", ret);
120 ret = zigbee_service_dbus_interface_zcl_on_off_init(service_interface, zigbee_object);
121 Z_LOGD("ret: %d", ret);
123 ret = zigbee_service_dbus_interface_service_init(service_interface, zigbee_object);
124 Z_LOGD("ret: %d", ret);
126 ret = zigbee_service_dbus_interface_zcl_thermostat_init(service_interface, zigbee_object);
127 Z_LOGD("ret: %d", ret);
129 ret = zigbee_service_dbus_interface_zcl_basic_init(service_interface, zigbee_object);
130 Z_LOGD("ret: %d", ret);
132 ret = zigbee_service_dbus_interface_zcl_color_control_init(service_interface, zigbee_object);
133 Z_LOGD("ret: %d", ret);
135 ret = zigbee_service_dbus_interface_zcl_global_control_init(service_interface, zigbee_object);
136 Z_LOGD("ret: %d", ret);
138 ret = zigbee_service_dbus_interface_zcl_group_init(service_interface, zigbee_object);
139 Z_LOGD("ret: %d", ret);
141 ret = zigbee_service_dbus_interface_zcl_ias_zone_init(service_interface, zigbee_object);
142 Z_LOGD("ret: %d", ret);
144 ret = zigbee_service_dbus_interface_zcl_identify_init(service_interface, zigbee_object);
145 Z_LOGD("ret: %d", ret);
147 ret = zigbee_service_dbus_interface_zcl_poll_control_init(service_interface, zigbee_object);
148 Z_LOGD("ret: %d", ret);
150 ret = zigbee_service_dbus_interface_zcl_scene_init(service_interface, zigbee_object);
151 Z_LOGD("ret: %d", ret);
153 ret = zigbee_service_dbus_interface_zdo_bind_init(service_interface, zigbee_object);
154 Z_LOGD("ret: %d", ret);
156 ret = zigbee_service_dbus_interface_zdo_dev_control_init(service_interface, zigbee_object);
157 Z_LOGD("ret: %d", ret);
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)
163 ZblibDriverType_e driver_type;
164 guint notification_id;
166 if (NULL == service_interface) {
167 Z_LOGE("service_interface is NULL");
171 /* Extract driver_type */
172 driver_type = ((noti_id & 0xFF000000) >> 24);
174 /* Extract notification_id */
175 notification_id = (noti_id & 0x000000FF);
177 Z_LOGI("Driver type: [%d] Notification ID: [%d]", driver_type, notification_id);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
294 case ZBLIB_DRIVER_TYPE_NONE: /* Fall through */
296 Z_LOGE("Unhandled driver type: [%d]", driver_type);
302 static void zigbee_on_name_lost(GDBusConnection *connection,
303 const gchar *name, gpointer user_data)
305 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
306 ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
308 Z_LOGW("'%s' - [Name Lost]", name);
310 zblib_check_null_ret("custom_data", custom_data);
312 NOT_USED(connection);
314 /* Bus name is 'lost' */
315 custom_data->name_acquired = FALSE;
318 static void zigbee_on_name_acquired(GDBusConnection *connection,
319 const gchar *name, gpointer user_data)
321 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
322 ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
324 Z_LOGI("'%s' - [Name Acquired]", name);
326 NOT_USED(connection);
328 zblib_check_null_ret("custom_data", custom_data);
330 /* Bus name is 'acquired' */
331 custom_data->name_acquired = TRUE;
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);
339 static void zigbee_on_bus_acquired(GDBusConnection *connection,
340 const gchar *name, gpointer user_data)
342 ZigbeeObjectSkeleton *zigbee_object;
343 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
344 ZigBeeService *service = NULL;
345 ZigbeeCustomData_t *custom_data = NULL;
348 Z_LOGI("'%s' - [BUS Acquired]", name);
350 if (NULL == service_interface) {
351 Z_LOGE("service_interface is NULL!");
355 service = zblib_service_interface_ref_service(service_interface);
356 if (NULL == service) {
357 Z_LOGE("service is NULL!");
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!");
368 * Create ZigBee 'manager' D-BUS object
370 custom_data->zigbee_mgr = zigbee_manager_skeleton_new();
373 * Set ZigBee 'manager' D-BUS object method(s)
375 g_signal_connect(custom_data->zigbee_mgr,
376 "handle-get-zigbee-state",
377 G_CALLBACK(on_manager_get_zigbee_state),
380 g_signal_connect(custom_data->zigbee_mgr,
382 G_CALLBACK(on_manager_enable),
385 g_signal_connect(custom_data->zigbee_mgr,
387 G_CALLBACK(on_manager_disable),
391 * Export 'manager' interface on ZigBee D-BUS
393 g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(custom_data->zigbee_mgr),
394 connection, ZIGBEE_DBUS_PATH, NULL);
397 * Exports all objects managed by 'manager' on Connection (connection)
399 g_dbus_object_manager_server_set_connection(custom_data->manager, connection);
401 path = g_strdup_printf("%s", ZIGBEE_SERVICE_PATH);
402 Z_LOGI("dbus object path: [%s]", path);
405 * Create 'object' for specific path only once.
407 zigbee_object = g_hash_table_lookup(custom_data->objects, path);
409 Z_LOGW("ZigBee D-BUS interface object already created (object: %p)", zigbee_object);
414 * Create ZigBee D-BUS object
416 zigbee_object = zigbee_object_skeleton_new(path);
417 Z_LOGI("ZigBee D-BUS object created (zigbee_object: [%p])", zigbee_object);
420 * Insert ZigBee object to HASH table
422 g_hash_table_insert(custom_data->objects, g_strdup(path), zigbee_object);
425 * Initialize interfaces
427 zigbee_service_dbus_interface_initialize_interfaces(service_interface, zigbee_object);
428 Z_LOGI("ZigBee service interfaces initialized!!!");
430 /* Export the Object to Manager */
431 g_dbus_object_manager_server_export(custom_data->manager,
432 G_DBUS_OBJECT_SKELETON(zigbee_object));
434 /* Service interface initialization completed */
435 custom_data->sevice_interface_init_complete = TRUE;
437 if (TRUE == custom_data->name_acquired) {
438 /* TODO - Emit zigbee_state signal */
445 static void zigbee_get_activation_sbus(ZigbeeCustomData_t *interface_data)
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,
456 Z_LOGI("ZigBee D-BUS activation ID: [%d]", interface_data->activation_dbus_id);
459 /**< Zigbee service dbus interface initialization */
460 gboolean zigbee_service_dbus_interface_init(ZigBeeService *service)
462 ZigBeeServiceInterface *service_interface = NULL;
463 ZigbeeCustomData_t *interface_data = NULL;
466 if (NULL == service) {
467 Z_LOGE("service is NULL");
472 * Create ZigBee service interface object
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!");
483 * Set Service interface notification callback
485 ret = zblib_service_interface_set_noti_cb(service_interface,
486 zigbee_service_dbus_interface_noti_cb, NULL);
488 Z_LOGE("Set service interface notification callback failed!");
494 * Add Service interface object to 'service'
496 ret = zblib_service_add_service_interface(service,
499 Z_LOGE("Add D-BUS service interface failed!");
505 * ZigBee D-BUS interface custom data
507 interface_data = g_malloc0(sizeof(ZigbeeCustomData_t));
510 * Link interface data to service
512 ret = zblib_service_interface_link_user_data(service_interface,
515 Z_LOGE("Link D-BUS service interface data failed!");
520 /* HASH table for maintaining 'objects' list */
521 interface_data->objects = g_hash_table_new_full(g_str_hash, g_str_equal,
525 * Acquire "org.tizen.zigbee.manager" named bus on D-BUS SYSTEM bus.
527 zigbee_get_activation_sbus(interface_data);
530 * Acquire "org.tizen.zigbee" named bus on D-BUS SYSTEM bus.
532 interface_data->bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
534 G_BUS_NAME_OWNER_FLAGS_REPLACE,
535 zigbee_on_bus_acquired,
536 zigbee_on_name_acquired,
540 Z_LOGI("ZigBee D-BUS ID: [%d]", interface_data->bus_id);
542 interface_data->manager = g_dbus_object_manager_server_new(ZIGBEE_DBUS_PATH);
547 g_free(interface_data);
550 * Remove Service interface object from 'service'
552 ret = zblib_service_remove_service_interface(service,
555 Z_LOGE("Remove service interface failed!");
559 * Free Service interface object
561 zblib_service_interface_free(service,
567 /**< Zigbee service dbus interface de-initialization */
568 void zigbee_service_dbus_interface_deinit(ZigBeeService *service)
570 ZigBeeServiceInterface *service_interface = NULL;
571 ZigbeeCustomData_t *interface_data = NULL;
574 if (NULL == service) {
575 Z_LOGE("service is NULL");
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!");
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!");
595 * Unown "org.tizen.zigbee.manager" named bus on D-BUS SYSTEM bus
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);
604 * Unown "org.tizen.zigbee" named bus on D-BUS SYSTEM bus
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);
612 g_hash_table_destroy(interface_data->objects);
613 g_free(interface_data);
617 * Remove Service interface object from 'service'
619 ret = zblib_service_remove_service_interface(service,
622 Z_LOGE("Remove service interface failed!");
626 * Free Service interface object
628 zblib_service_interface_free(service,