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)
366 GError *error = NULL;
367 ZigbeeObjectSkeleton *zigbee_object;
368 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
369 ZigBeeService *service = NULL;
370 ZigbeeCustomData_t *custom_data = NULL;
373 Z_LOGI("'%s' - [BUS Acquired]", name);
375 if (NULL == service_interface) {
376 Z_LOGE("service_interface is NULL!");
380 service = zblib_service_interface_ref_service(service_interface);
381 if (NULL == service) {
382 Z_LOGE("service is NULL!");
386 custom_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
387 if (NULL == custom_data) {
388 Z_LOGE("D-BUS service interface custom_data is NULL!");
393 * Create ZigBee 'manager' D-BUS object
395 custom_data->zigbee_mgr = zigbee_manager_skeleton_new();
398 * Set ZigBee 'manager' D-BUS object method(s)
400 g_signal_connect(custom_data->zigbee_mgr,
401 "handle-get-zigbee-state",
402 G_CALLBACK(on_manager_get_zigbee_state),
405 g_signal_connect(custom_data->zigbee_mgr,
407 G_CALLBACK(on_manager_enable),
410 g_signal_connect(custom_data->zigbee_mgr,
412 G_CALLBACK(on_manager_disable),
416 * Export 'manager' interface on ZigBee D-BUS
418 ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(custom_data->zigbee_mgr),
419 connection, ZIGBEE_DBUS_PATH, &error);
421 /* LCOV_EXCL_START */
422 Z_LOGW("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
427 * Exports all objects managed by 'manager' on Connection (connection)
429 g_dbus_object_manager_server_set_connection(custom_data->manager, connection);
431 path = g_strdup_printf("%s", ZIGBEE_SERVICE_PATH);
432 Z_LOGI("dbus object path: [%s]", path);
435 * Create 'object' for specific path only once.
437 zigbee_object = g_hash_table_lookup(custom_data->objects, path);
439 Z_LOGW("ZigBee D-BUS interface object already created (object: %p)", zigbee_object);
444 * Create ZigBee D-BUS object
446 zigbee_object = zigbee_object_skeleton_new(path);
447 Z_LOGI("ZigBee D-BUS object created (zigbee_object: [%p])", zigbee_object);
450 * Insert ZigBee object to HASH table
452 g_hash_table_insert(custom_data->objects, g_strdup(path), zigbee_object);
455 * Initialize interfaces
457 zigbee_service_dbus_interface_initialize_interfaces(service_interface, zigbee_object);
458 Z_LOGI("ZigBee service interfaces initialized!!!");
460 /* Export the Object to Manager */
461 g_dbus_object_manager_server_export(custom_data->manager,
462 G_DBUS_OBJECT_SKELETON(zigbee_object));
464 /* Service interface initialization completed */
465 custom_data->sevice_interface_init_complete = TRUE;
471 static void zigbee_get_activation_sbus(ZigbeeCustomData_t *interface_data)
473 /* Get D-Bus owner to activate zigbee-daemon */
474 interface_data->activation_dbus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
475 ZIGBEE_DBUS_SERVICE".manager",
476 G_BUS_NAME_OWNER_FLAGS_REPLACE,
482 Z_LOGI("ZigBee D-BUS activation ID: [%d]", interface_data->activation_dbus_id);
485 /**< Zigbee service dbus interface initialization */
486 gboolean zigbee_service_dbus_interface_init(ZigBeeService *service)
488 ZigBeeServiceInterface *service_interface = NULL;
489 ZigbeeCustomData_t *interface_data = NULL;
492 if (NULL == service) {
493 Z_LOGE("service is NULL");
498 * Create ZigBee service interface object
500 service_interface = zblib_service_interface_new(service,
501 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
502 if (NULL == service_interface) {
503 Z_LOGE("Create D-BUS service interface failed!");
509 * Set Service interface notification callback
511 ret = zblib_service_interface_set_noti_cb(service_interface,
512 zigbee_service_dbus_interface_noti_cb, NULL);
514 Z_LOGE("Set service interface notification callback failed!");
520 * Add Service interface object to 'service'
522 ret = zblib_service_add_service_interface(service,
525 Z_LOGE("Add D-BUS service interface failed!");
531 * ZigBee D-BUS interface custom data
533 interface_data = g_malloc0(sizeof(ZigbeeCustomData_t));
536 * Link interface data to service
538 ret = zblib_service_interface_link_user_data(service_interface,
541 Z_LOGE("Link D-BUS service interface data failed!");
546 /* HASH table for maintaining 'objects' list */
547 interface_data->objects = g_hash_table_new_full(g_str_hash, g_str_equal,
551 * Acquire "org.tizen.zigbee.manager" named bus on D-BUS SYSTEM bus.
553 zigbee_get_activation_sbus(interface_data);
556 * Acquire "org.tizen.zigbee" named bus on D-BUS SYSTEM bus.
558 interface_data->bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
560 G_BUS_NAME_OWNER_FLAGS_REPLACE,
561 zigbee_on_bus_acquired,
562 zigbee_on_name_acquired,
566 Z_LOGI("ZigBee D-BUS ID: [%d]", interface_data->bus_id);
568 interface_data->manager = g_dbus_object_manager_server_new(ZIGBEE_DBUS_PATH);
573 g_free(interface_data);
576 * Remove Service interface object from 'service'
578 ret = zblib_service_remove_service_interface(service,
581 Z_LOGE("Remove service interface failed!");
584 * Free Service interface object
586 zblib_service_interface_free(service,
592 /**< Zigbee service dbus interface de-initialization */
593 void zigbee_service_dbus_interface_deinit(ZigBeeService *service)
595 ZigBeeServiceInterface *service_interface = NULL;
596 ZigbeeCustomData_t *interface_data = NULL;
599 if (NULL == service) {
600 Z_LOGE("service is NULL");
604 service_interface = zblib_service_ref_service_interface(service,
605 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
606 if (NULL == service_interface) {
607 Z_LOGE("D-BUS service interface not found!");
612 interface_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
613 if (NULL == interface_data) {
614 Z_LOGE("D-BUS interface data not found!");
619 /* Emit zigbee_state - disabled */
620 Z_LOGD("Update zigbee_state ----");
621 zigbee_manager_emit_zigbee_state(interface_data->zigbee_mgr, FALSE);
624 * Unown "org.tizen.zigbee.manager" named bus on D-BUS SYSTEM bus
626 if (interface_data->activation_dbus_id > 0) {
627 Z_LOGI("Unowning ZigBee Service interface activation D-BUS ID: [%d]",
628 interface_data->activation_dbus_id);
629 g_bus_unown_name(interface_data->activation_dbus_id);
633 * Unown "org.tizen.zigbee" named bus on D-BUS SYSTEM bus
635 if (interface_data->bus_id > 0) {
636 Z_LOGI("Unowning ZigBee Service interface D-BUS ID: [%d]", interface_data->bus_id);
637 g_bus_unown_name(interface_data->bus_id);
641 g_hash_table_destroy(interface_data->objects);
642 g_free(interface_data);
646 * Remove Service interface object from 'service'
648 ret = zblib_service_remove_service_interface(service,
651 Z_LOGE("Remove service interface failed!");
654 * Free Service interface object
656 zblib_service_interface_free(service,