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 zigbee_on_manager_get_zigbee_state(ZigbeeManager *zigbee_mgr,
38 GDBusMethodInvocation *invocation, gpointer user_data)
48 * Create and send request for processing
54 static void zigbee_service_dbus_interface_initialize_interfaces(ZigBeeServiceInterface *service_interface,
55 ZigbeeObjectSkeleton *zigbee_object)
59 ret = zigbee_service_dbus_interface_zcl_alarm_init(service_interface, zigbee_object);
60 Z_LOGD("ret: %d", ret);
62 ret = zigbee_service_dbus_interface_custom_init(service_interface, zigbee_object);
63 Z_LOGD("ret: %d", ret);
65 ret = zigbee_service_dbus_interface_zcl_door_lock_init(service_interface, zigbee_object);
66 Z_LOGD("ret: %d", ret);
68 ret = zigbee_service_dbus_interface_zcl_fan_control_init(service_interface, zigbee_object);
69 Z_LOGD("ret: %d", ret);
71 ret = zigbee_service_dbus_interface_zcl_level_control_init(service_interface, zigbee_object);
72 Z_LOGD("ret: %d", ret);
74 ret = zigbee_service_dbus_interface_mfglib_control_init(service_interface, zigbee_object);
75 Z_LOGD("ret: %d", ret);
77 ret = zigbee_service_dbus_interface_zcl_on_off_init(service_interface, zigbee_object);
78 Z_LOGD("ret: %d", ret);
80 ret = zigbee_service_dbus_interface_service_init(service_interface, zigbee_object);
81 Z_LOGD("ret: %d", ret);
83 ret = zigbee_service_dbus_interface_zcl_thermostat_init(service_interface, zigbee_object);
84 Z_LOGD("ret: %d", ret);
86 ret = zigbee_service_dbus_interface_zcl_basic_init(service_interface, zigbee_object);
87 Z_LOGD("ret: %d", ret);
89 ret = zigbee_service_dbus_interface_zcl_color_control_init(service_interface, zigbee_object);
90 Z_LOGD("ret: %d", ret);
92 ret = zigbee_service_dbus_interface_zcl_global_control_init(service_interface, zigbee_object);
93 Z_LOGD("ret: %d", ret);
95 ret = zigbee_service_dbus_interface_zcl_group_init(service_interface, zigbee_object);
96 Z_LOGD("ret: %d", ret);
98 ret = zigbee_service_dbus_interface_zcl_ias_zone_init(service_interface, zigbee_object);
99 Z_LOGD("ret: %d", ret);
101 ret = zigbee_service_dbus_interface_zcl_identify_init(service_interface, zigbee_object);
102 Z_LOGD("ret: %d", ret);
104 ret = zigbee_service_dbus_interface_zcl_poll_control_init(service_interface, zigbee_object);
105 Z_LOGD("ret: %d", ret);
107 ret = zigbee_service_dbus_interface_zcl_scene_init(service_interface, zigbee_object);
108 Z_LOGD("ret: %d", ret);
110 ret = zigbee_service_dbus_interface_zdo_bind_init(service_interface, zigbee_object);
111 Z_LOGD("ret: %d", ret);
113 ret = zigbee_service_dbus_interface_zdo_dev_control_init(service_interface, zigbee_object);
114 Z_LOGD("ret: %d", ret);
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)
120 ZblibDriverType_e driver_type;
121 guint notification_id;
123 if (NULL == service_interface) {
124 Z_LOGE("service_interface is NULL");
128 /* Extract driver_type */
129 driver_type = ((noti_id & 0xFF000000) >> 24);
131 /* Extract notification_id */
132 notification_id = (noti_id & 0x000000FF);
134 Z_LOGI("Driver type: [%d] Notification ID: [%d]", driver_type, notification_id);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
251 case ZBLIB_DRIVER_TYPE_NONE: /* Fall through */
253 Z_LOGE("Unhandled driver type: [%d]", driver_type);
259 static void zigbee_on_name_lost(GDBusConnection *connection,
260 const gchar *name, gpointer user_data)
262 ZigbeeCustomData_t *custom_data = user_data;
264 Z_LOGW("'%s' - [Name Lost]", name);
266 NOT_USED(connection);
268 /* Bus name is 'lost' */
269 custom_data->name_acquired = FALSE;
272 static void zigbee_on_name_acquired(GDBusConnection *connection,
273 const gchar *name, gpointer user_data)
275 ZigbeeCustomData_t *custom_data = user_data;
277 Z_LOGI("'%s' - [Name Acquired]", name);
279 NOT_USED(connection);
281 /* Bus name is 'acquired' */
282 custom_data->name_acquired = TRUE;
284 if (TRUE == custom_data->sevice_interface_init_complete) {
285 /* TODO - Emit zigbee_state signal */
289 static void zigbee_on_bus_acquired(GDBusConnection *connection,
290 const gchar *name, gpointer user_data)
292 ZigbeeObjectSkeleton *zigbee_object;
293 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
294 ZigBeeService *service = NULL;
295 ZigbeeCustomData_t *custom_data = NULL;
298 Z_LOGI("'%s' - [BUS Acquired]", name);
300 if (NULL == service_interface) {
301 Z_LOGE("service_interface is NULL!");
305 service = zblib_service_interface_ref_service(service_interface);
306 if (NULL == service) {
307 Z_LOGE("service is NULL!");
311 custom_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
312 if (NULL == custom_data) {
313 Z_LOGE("D-BUS service interface custom_data is NULL!");
318 * Create ZigBee 'manager' D-BUS object
320 custom_data->zigbee_mgr = zigbee_manager_skeleton_new();
323 * Set ZigBee 'manager' D-BUS object method(s)
325 g_signal_connect(custom_data->zigbee_mgr,
326 "handle-get-zigbee-state",
327 G_CALLBACK(zigbee_on_manager_get_zigbee_state),
331 * Export 'manager' interface on ZigBee D-BUS
333 g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(custom_data->zigbee_mgr),
334 connection, ZIGBEE_DBUS_PATH, NULL);
337 * Exports all objects managed by 'manager' on Connection (connection)
339 g_dbus_object_manager_server_set_connection(custom_data->manager, connection);
341 path = g_strdup_printf("%s/service", ZIGBEE_DBUS_PATH);
342 Z_LOGI("dbus object path: [%s]", path);
345 * Create 'object' for specific path only once.
347 zigbee_object = g_hash_table_lookup(custom_data->objects, path);
349 Z_LOGW("ZigBee D-BUS interface object already created (object: %p)", zigbee_object);
354 * Create ZigBee D-BUS object
356 zigbee_object = zigbee_object_skeleton_new(path);
357 Z_LOGI("ZigBee D-BUS object created (zigbee_object: [%p])", zigbee_object);
360 * Insert ZigBee object to HASH table
362 g_hash_table_insert(custom_data->objects, g_strdup(path), zigbee_object);
365 * Initialize interfaces
367 zigbee_service_dbus_interface_initialize_interfaces(service_interface, zigbee_object);
368 Z_LOGI("ZigBee service interfaces initialized!!!");
370 /* Export the Object to Manager */
371 g_dbus_object_manager_server_export(custom_data->manager,
372 G_DBUS_OBJECT_SKELETON(zigbee_object));
374 /* Servcie interface initialization completed */
375 custom_data->sevice_interface_init_complete = TRUE;
377 if (TRUE == custom_data->name_acquired) {
378 /* TODO - Emit zigbee_state signal */
385 /**< Zigbee service dbus interface initialization */
386 gboolean zigbee_service_dbus_interface_init(ZigBeeService *service)
388 ZigBeeServiceInterface *service_interface = NULL;
389 ZigbeeCustomData_t *interface_data = NULL;
392 if (NULL == service) {
393 Z_LOGE("service is NULL");
398 * Create ZigBee service interface object
400 service_interface = zblib_service_interface_new(service,
401 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
402 if (NULL == service_interface) {
403 Z_LOGE("Create D-BUS service interface failed!");
409 * Set Service interface notification callback
411 ret = zblib_service_interface_set_noti_cb(service_interface,
412 zigbee_service_dbus_interface_noti_cb, NULL);
414 Z_LOGE("Set service interface notification callback failed!");
420 * Add Service interface object to 'service'
422 ret = zblib_service_add_service_interface(service,
425 Z_LOGE("Add D-BUS service interface failed!");
431 * ZigBee D-BUS interface custom data
433 interface_data = g_malloc0(sizeof(ZigbeeCustomData_t));
436 * Link interface data to service
438 ret = zblib_service_interface_link_user_data(service_interface,
441 Z_LOGE("Link D-BUS service interface data failed!");
446 /* HASH table for maintaining 'objects' list */
447 interface_data->objects = g_hash_table_new(g_str_hash, g_str_equal);
450 * Acquire "org.tizen.zigbee" named bus on D-BUS SYSTEM bus.
452 interface_data->bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
454 G_BUS_NAME_OWNER_FLAGS_REPLACE,
455 zigbee_on_bus_acquired,
456 zigbee_on_name_acquired,
460 Z_LOGI("ZigBee D-BUS ID: [%d]", interface_data->bus_id);
462 interface_data->manager = g_dbus_object_manager_server_new(ZIGBEE_DBUS_PATH);
467 g_free(interface_data);
470 * Remove Service interface object from 'service'
472 ret = zblib_service_remove_service_interface(service,
475 Z_LOGE("Remove service interface failed!");
479 * Free Service interface object
481 zblib_service_interface_free(service,
487 /**< Zigbee service dbus interface de-initialization */
488 void zigbee_service_dbus_interface_deinit(ZigBeeService *service)
490 ZigBeeServiceInterface *service_interface = NULL;
491 ZigbeeCustomData_t *interface_data = NULL;
494 if (NULL == service) {
495 Z_LOGE("service is NULL");
499 service_interface = zblib_service_ref_service_interface(service,
500 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
501 if (NULL == service_interface) {
502 Z_LOGE("D-BUS service interface not found!");
507 interface_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
508 if (NULL == service_interface) {
509 Z_LOGE("D-BUS service interface not found!");
515 * Unown "org.tizen.zigbee" named bus on D-BUS SYSTEM bus
517 if (interface_data->bus_id > 0) {
518 Z_LOGI("Unowning ZigBee Service interface D-BUS ID: [%d]", interface_data->bus_id);
519 g_bus_unown_name(interface_data->bus_id);
523 g_hash_table_destroy(interface_data->objects);
524 g_free(interface_data);
528 * Remove Service interface object from 'service'
530 ret = zblib_service_remove_service_interface(service,
533 Z_LOGE("Remove service interface failed!");
537 * Free Service interface object
539 zblib_service_interface_free(service,