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>
29 #include <zblib_driver_manager.h>
31 #include "zigbee_service_interface.h"
32 #include "zigbee_service_interface_common.h"
33 #include "zigbee_service_dbus_interface.h"
35 /**< ZigBee D-BUS service interface name */
36 #define ZIGBEE_DBUS_SERVICE_INTERFACE_NAME "zigbee-dbus"
38 static void _notify_zigbee_state(ZigBeeServiceInterface *service_interface,
41 ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
42 ZigBeeService *service = zblib_service_interface_ref_service(service_interface);
44 if (NULL == custom_data) {
45 Z_LOGE("Unexpected invalid parameter !");
50 /* Notify zigbee service manually here (Enabled) */
51 zigbee_manager_emit_zigbee_state(custom_data->zigbee_mgr, result);
53 /* ZigBee state will be emitted on bus termination */
54 zblib_service_exit(service);
58 static gboolean on_manager_enable(ZigbeeManager *zigbee_mgr,
59 GDBusMethodInvocation *invocation,
62 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
63 ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
65 if (NULL == custom_data) {
66 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
71 zigbee_manager_complete_enable(zigbee_mgr, invocation);
76 static gboolean on_manager_disable(ZigbeeManager *zigbee_mgr,
77 GDBusMethodInvocation *invocation,
80 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
81 ZigBeeService *service = zblib_service_interface_ref_service(service_interface);
85 zigbee_manager_complete_disable(zigbee_mgr, invocation, 0);
88 zblib_service_exit(service);
93 static gboolean on_manager_get_zigbee_state(ZigbeeManager *zigbee_mgr,
94 GDBusMethodInvocation *invocation, gpointer user_data)
96 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
97 ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
101 if (NULL == custom_data) {
102 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
107 zigbee_manager_complete_get_zigbee_state(zigbee_mgr, invocation,
108 0, custom_data->sevice_interface_init_complete);
113 static void zigbee_service_dbus_interface_initialize_interfaces(ZigBeeServiceInterface *service_interface,
114 ZigbeeObjectSkeleton *zigbee_object)
118 ret = zigbee_service_dbus_interface_zcl_alarm_init(service_interface, zigbee_object);
119 Z_LOGD("ret: %d", ret);
121 ret = zigbee_service_dbus_interface_custom_init(service_interface, zigbee_object);
122 Z_LOGD("ret: %d", ret);
124 ret = zigbee_service_dbus_interface_zcl_door_lock_init(service_interface, zigbee_object);
125 Z_LOGD("ret: %d", ret);
127 ret = zigbee_service_dbus_interface_zcl_fan_control_init(service_interface, zigbee_object);
128 Z_LOGD("ret: %d", ret);
130 ret = zigbee_service_dbus_interface_zcl_level_control_init(service_interface, zigbee_object);
131 Z_LOGD("ret: %d", ret);
133 ret = zigbee_service_dbus_interface_mfglib_control_init(service_interface, zigbee_object);
134 Z_LOGD("ret: %d", ret);
136 ret = zigbee_service_dbus_interface_zcl_on_off_init(service_interface, zigbee_object);
137 Z_LOGD("ret: %d", ret);
139 ret = zigbee_service_dbus_interface_service_init(service_interface, zigbee_object);
140 Z_LOGD("ret: %d", ret);
142 ret = zigbee_service_dbus_interface_zcl_thermostat_init(service_interface, zigbee_object);
143 Z_LOGD("ret: %d", ret);
145 ret = zigbee_service_dbus_interface_zcl_basic_init(service_interface, zigbee_object);
146 Z_LOGD("ret: %d", ret);
148 ret = zigbee_service_dbus_interface_zcl_color_control_init(service_interface, zigbee_object);
149 Z_LOGD("ret: %d", ret);
151 ret = zigbee_service_dbus_interface_zcl_global_control_init(service_interface, zigbee_object);
152 Z_LOGD("ret: %d", ret);
154 ret = zigbee_service_dbus_interface_zcl_group_init(service_interface, zigbee_object);
155 Z_LOGD("ret: %d", ret);
157 ret = zigbee_service_dbus_interface_zcl_ias_zone_init(service_interface, zigbee_object);
158 Z_LOGD("ret: %d", ret);
160 ret = zigbee_service_dbus_interface_zcl_identify_init(service_interface, zigbee_object);
161 Z_LOGD("ret: %d", ret);
163 ret = zigbee_service_dbus_interface_zcl_poll_control_init(service_interface, zigbee_object);
164 Z_LOGD("ret: %d", ret);
166 ret = zigbee_service_dbus_interface_zcl_scene_init(service_interface, zigbee_object);
167 Z_LOGD("ret: %d", ret);
169 ret = zigbee_service_dbus_interface_zdo_bind_init(service_interface, zigbee_object);
170 Z_LOGD("ret: %d", ret);
172 ret = zigbee_service_dbus_interface_zdo_dev_control_init(service_interface, zigbee_object);
173 Z_LOGD("ret: %d", ret);
176 static void zigbee_service_dbus_interface_noti_cb(ZigBeeServiceInterface *service_interface,
177 guint noti_id, gpointer noti_data, guint noti_data_len, gpointer noti_cb_data)
179 ZblibDriverType_e driver_type;
180 guint notification_id;
182 if (NULL == service_interface) {
183 Z_LOGE("service_interface is NULL");
187 /* Extract driver_type */
188 driver_type = ((noti_id & 0xFF000000) >> 24);
190 /* Extract notification_id */
191 notification_id = (noti_id & 0x000000FF);
193 Z_LOGI("Driver type: [%d] Notification ID: [%d]", driver_type, notification_id);
195 switch (driver_type) {
196 case ZBLIB_DRIVER_TYPE_ZCL_ALARM: {
197 zigbee_service_dbus_interface_zcl_alarm_notification(service_interface,
198 notification_id, noti_data, noti_data_len, noti_cb_data);
202 case ZBLIB_DRIVER_TYPE_CUSTOM: {
203 zigbee_service_dbus_interface_custom_notification(service_interface,
204 notification_id, noti_data, noti_data_len, noti_cb_data);
208 case ZBLIB_DRIVER_TYPE_ZCL_DOOR_LOCK: {
209 zigbee_service_dbus_interface_zcl_door_lock_notification(service_interface,
210 notification_id, noti_data, noti_data_len, noti_cb_data);
214 case ZBLIB_DRIVER_TYPE_ZCL_FAN_CONTROL: {
215 zigbee_service_dbus_interface_zcl_fan_control_notification(service_interface,
216 notification_id, noti_data, noti_data_len, noti_cb_data);
220 case ZBLIB_DRIVER_TYPE_ZCL_LEVEL_CONTROL: {
221 zigbee_service_dbus_interface_zcl_level_control_notification(service_interface,
222 notification_id, noti_data, noti_data_len, noti_cb_data);
226 case ZBLIB_DRIVER_TYPE_MFGLIB_CONTROL: {
227 zigbee_service_dbus_interface_mfglib_control_notification(service_interface,
228 notification_id, noti_data, noti_data_len, noti_cb_data);
232 case ZBLIB_DRIVER_TYPE_ZCL_ON_OFF: {
233 zigbee_service_dbus_interface_zcl_on_off_notification(service_interface,
234 notification_id, noti_data, noti_data_len, noti_cb_data);
238 case ZBLIB_DRIVER_TYPE_SERVICE: {
239 zigbee_service_dbus_interface_service_notification(service_interface,
240 notification_id, noti_data, noti_data_len, noti_cb_data);
244 case ZBLIB_DRIVER_TYPE_ZCL_THERMOSTAT: {
245 zigbee_service_dbus_interface_zcl_thermostat_notification(service_interface,
246 notification_id, noti_data, noti_data_len, noti_cb_data);
250 case ZBLIB_DRIVER_TYPE_ZCL_BASIC: {
251 zigbee_service_dbus_interface_zcl_basic_notification(service_interface,
252 notification_id, noti_data, noti_data_len, noti_cb_data);
256 case ZBLIB_DRIVER_TYPE_ZCL_GLOBAL_CONTROL: {
257 zigbee_service_dbus_interface_zcl_global_control_notification(service_interface,
258 notification_id, noti_data, noti_data_len, noti_cb_data);
262 case ZBLIB_DRIVER_TYPE_ZCL_IAS_ZONE: {
263 zigbee_service_dbus_interface_zcl_ias_zone_notification(service_interface,
264 notification_id, noti_data, noti_data_len, noti_cb_data);
268 case ZBLIB_DRIVER_TYPE_ZCL_IDENTIFY: {
269 zigbee_service_dbus_interface_zcl_identify_notification(service_interface,
270 notification_id, noti_data, noti_data_len, noti_cb_data);
274 case ZBLIB_DRIVER_TYPE_ZCL_COLOR_CONTROL: {
275 zigbee_service_dbus_interface_zcl_color_control_notification(service_interface,
276 notification_id, noti_data, noti_data_len, noti_cb_data);
280 case ZBLIB_DRIVER_TYPE_ZCL_GROUP: {
281 zigbee_service_dbus_interface_zcl_group_notification(service_interface,
282 notification_id, noti_data, noti_data_len, noti_cb_data);
286 case ZBLIB_DRIVER_TYPE_ZCL_POLL_CONTROL: {
287 zigbee_service_dbus_interface_zcl_poll_control_notification(service_interface,
288 notification_id, noti_data, noti_data_len, noti_cb_data);
292 case ZBLIB_DRIVER_TYPE_ZCL_SCENE: {
293 zigbee_service_dbus_interface_zcl_scene_notification(service_interface,
294 notification_id, noti_data, noti_data_len, noti_cb_data);
298 case ZBLIB_DRIVER_TYPE_ZDO_DEV_CONTROL: {
299 zigbee_service_dbus_interface_zdo_dev_control_notification(service_interface,
300 notification_id, noti_data, noti_data_len, noti_cb_data);
304 case ZBLIB_DRIVER_TYPE_ZDO_BIND: {
305 zigbee_service_dbus_interface_zdo_bind_notification(service_interface,
306 notification_id, noti_data, noti_data_len, noti_cb_data);
310 case ZBLIB_DRIVER_TYPE_MANAGER: {
311 /* Handle 'enabled' notification here */
312 if (notification_id == ZBLIB_MANAGER_NOTI_ZIGBEE_ENABLED) {
313 gboolean *rsp = (gboolean*)noti_data;
315 Z_LOGD("Firmware update result : [%s]", ((*rsp) ? "Succeed" : "Failed"));
316 _notify_zigbee_state(service_interface, *rsp);
318 Z_LOGE("Unhandled notification id: [%d]", notification_id);
322 case ZBLIB_DRIVER_TYPE_NONE: /* Fall through */
324 Z_LOGE("Unhandled driver type: [%d]", driver_type);
330 static void zigbee_on_name_lost(GDBusConnection *connection,
331 const gchar *name, gpointer user_data)
333 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
334 ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
336 Z_LOGW("'%s' - [Name Lost]", name);
338 zblib_check_null_ret("custom_data", custom_data);
340 NOT_USED(connection);
342 /* Bus name is 'lost' */
343 custom_data->name_acquired = FALSE;
346 static void zigbee_on_name_acquired(GDBusConnection *connection,
347 const gchar *name, gpointer user_data)
349 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
350 ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
352 Z_LOGI("'%s' - [Name Acquired]", name);
354 NOT_USED(connection);
356 zblib_check_null_ret("custom_data", custom_data);
358 /* Bus name is 'acquired' */
359 custom_data->name_acquired = TRUE;
362 static void zigbee_on_bus_acquired(GDBusConnection *connection,
363 const gchar *name, gpointer user_data)
365 ZigbeeObjectSkeleton *zigbee_object;
366 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
367 ZigBeeService *service = NULL;
368 ZigbeeCustomData_t *custom_data = NULL;
371 Z_LOGI("'%s' - [BUS Acquired]", name);
373 if (NULL == service_interface) {
374 Z_LOGE("service_interface is NULL!");
378 service = zblib_service_interface_ref_service(service_interface);
379 if (NULL == service) {
380 Z_LOGE("service is NULL!");
384 custom_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
385 if (NULL == custom_data) {
386 Z_LOGE("D-BUS service interface custom_data is NULL!");
391 * Create ZigBee 'manager' D-BUS object
393 custom_data->zigbee_mgr = zigbee_manager_skeleton_new();
396 * Set ZigBee 'manager' D-BUS object method(s)
398 g_signal_connect(custom_data->zigbee_mgr,
399 "handle-get-zigbee-state",
400 G_CALLBACK(on_manager_get_zigbee_state),
403 g_signal_connect(custom_data->zigbee_mgr,
405 G_CALLBACK(on_manager_enable),
408 g_signal_connect(custom_data->zigbee_mgr,
410 G_CALLBACK(on_manager_disable),
414 * Export 'manager' interface on ZigBee D-BUS
416 g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(custom_data->zigbee_mgr),
417 connection, ZIGBEE_DBUS_PATH, NULL);
420 * Exports all objects managed by 'manager' on Connection (connection)
422 g_dbus_object_manager_server_set_connection(custom_data->manager, connection);
424 path = g_strdup_printf("%s", ZIGBEE_SERVICE_PATH);
425 Z_LOGI("dbus object path: [%s]", path);
428 * Create 'object' for specific path only once.
430 zigbee_object = g_hash_table_lookup(custom_data->objects, path);
432 Z_LOGW("ZigBee D-BUS interface object already created (object: %p)", zigbee_object);
437 * Create ZigBee D-BUS object
439 zigbee_object = zigbee_object_skeleton_new(path);
440 Z_LOGI("ZigBee D-BUS object created (zigbee_object: [%p])", zigbee_object);
443 * Insert ZigBee object to HASH table
445 g_hash_table_insert(custom_data->objects, g_strdup(path), zigbee_object);
448 * Initialize interfaces
450 zigbee_service_dbus_interface_initialize_interfaces(service_interface, zigbee_object);
451 Z_LOGI("ZigBee service interfaces initialized!!!");
453 /* Export the Object to Manager */
454 g_dbus_object_manager_server_export(custom_data->manager,
455 G_DBUS_OBJECT_SKELETON(zigbee_object));
457 /* Service interface initialization completed */
458 custom_data->sevice_interface_init_complete = TRUE;
464 static void zigbee_get_activation_sbus(ZigbeeCustomData_t *interface_data)
466 /* Get D-Bus owner to activate zigbee-daemon */
467 interface_data->activation_dbus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
468 ZIGBEE_DBUS_SERVICE".manager",
469 G_BUS_NAME_OWNER_FLAGS_REPLACE,
475 Z_LOGI("ZigBee D-BUS activation ID: [%d]", interface_data->activation_dbus_id);
478 /**< Zigbee service dbus interface initialization */
479 gboolean zigbee_service_dbus_interface_init(ZigBeeService *service)
481 ZigBeeServiceInterface *service_interface = NULL;
482 ZigbeeCustomData_t *interface_data = NULL;
485 if (NULL == service) {
486 Z_LOGE("service is NULL");
491 * Create ZigBee service interface object
493 service_interface = zblib_service_interface_new(service,
494 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
495 if (NULL == service_interface) {
496 Z_LOGE("Create D-BUS service interface failed!");
502 * Set Service interface notification callback
504 ret = zblib_service_interface_set_noti_cb(service_interface,
505 zigbee_service_dbus_interface_noti_cb, NULL);
507 Z_LOGE("Set service interface notification callback failed!");
513 * Add Service interface object to 'service'
515 ret = zblib_service_add_service_interface(service,
518 Z_LOGE("Add D-BUS service interface failed!");
524 * ZigBee D-BUS interface custom data
526 interface_data = g_malloc0(sizeof(ZigbeeCustomData_t));
529 * Link interface data to service
531 ret = zblib_service_interface_link_user_data(service_interface,
534 Z_LOGE("Link D-BUS service interface data failed!");
539 /* HASH table for maintaining 'objects' list */
540 interface_data->objects = g_hash_table_new_full(g_str_hash, g_str_equal,
544 * Acquire "org.tizen.zigbee.manager" named bus on D-BUS SYSTEM bus.
546 zigbee_get_activation_sbus(interface_data);
549 * Acquire "org.tizen.zigbee" named bus on D-BUS SYSTEM bus.
551 interface_data->bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
553 G_BUS_NAME_OWNER_FLAGS_REPLACE,
554 zigbee_on_bus_acquired,
555 zigbee_on_name_acquired,
559 Z_LOGI("ZigBee D-BUS ID: [%d]", interface_data->bus_id);
561 interface_data->manager = g_dbus_object_manager_server_new(ZIGBEE_DBUS_PATH);
566 g_free(interface_data);
569 * Remove Service interface object from 'service'
571 ret = zblib_service_remove_service_interface(service,
574 Z_LOGE("Remove service interface failed!");
577 * Free Service interface object
579 zblib_service_interface_free(service,
585 /**< Zigbee service dbus interface de-initialization */
586 void zigbee_service_dbus_interface_deinit(ZigBeeService *service)
588 ZigBeeServiceInterface *service_interface = NULL;
589 ZigbeeCustomData_t *interface_data = NULL;
592 if (NULL == service) {
593 Z_LOGE("service is NULL");
597 service_interface = zblib_service_ref_service_interface(service,
598 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
599 if (NULL == service_interface) {
600 Z_LOGE("D-BUS service interface not found!");
605 interface_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
606 if (NULL == interface_data) {
607 Z_LOGE("D-BUS interface data not found!");
612 /* Emit zigbee_state - disabled */
613 Z_LOGD("Update zigbee_state ----");
614 zigbee_manager_emit_zigbee_state(interface_data->zigbee_mgr, FALSE);
617 * Unown "org.tizen.zigbee.manager" named bus on D-BUS SYSTEM bus
619 if (interface_data->activation_dbus_id > 0) {
620 Z_LOGI("Unowning ZigBee Service interface activation D-BUS ID: [%d]",
621 interface_data->activation_dbus_id);
622 g_bus_unown_name(interface_data->activation_dbus_id);
626 * Unown "org.tizen.zigbee" named bus on D-BUS SYSTEM bus
628 if (interface_data->bus_id > 0) {
629 Z_LOGI("Unowning ZigBee Service interface D-BUS ID: [%d]", interface_data->bus_id);
630 g_bus_unown_name(interface_data->bus_id);
634 g_hash_table_destroy(interface_data->objects);
635 g_free(interface_data);
639 * Remove Service interface object from 'service'
641 ret = zblib_service_remove_service_interface(service,
644 Z_LOGE("Remove service interface failed!");
647 * Free Service interface object
649 zblib_service_interface_free(service,