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 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
263 ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
265 Z_LOGW("'%s' - [Name Lost]", name);
267 NOT_USED(connection);
269 /* Bus name is 'lost' */
270 custom_data->name_acquired = FALSE;
273 static void zigbee_on_name_acquired(GDBusConnection *connection,
274 const gchar *name, gpointer user_data)
276 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
277 ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
279 Z_LOGI("'%s' - [Name Acquired]", name);
281 NOT_USED(connection);
283 /* Bus name is 'acquired' */
284 custom_data->name_acquired = TRUE;
286 if (TRUE == custom_data->sevice_interface_init_complete) {
287 /* TODO - Emit zigbee_state signal */
291 static void zigbee_on_bus_acquired(GDBusConnection *connection,
292 const gchar *name, gpointer user_data)
294 ZigbeeObjectSkeleton *zigbee_object;
295 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
296 ZigBeeService *service = NULL;
297 ZigbeeCustomData_t *custom_data = NULL;
300 Z_LOGI("'%s' - [BUS Acquired]", name);
302 if (NULL == service_interface) {
303 Z_LOGE("service_interface is NULL!");
307 service = zblib_service_interface_ref_service(service_interface);
308 if (NULL == service) {
309 Z_LOGE("service is NULL!");
313 custom_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
314 if (NULL == custom_data) {
315 Z_LOGE("D-BUS service interface custom_data is NULL!");
320 * Create ZigBee 'manager' D-BUS object
322 custom_data->zigbee_mgr = zigbee_manager_skeleton_new();
325 * Set ZigBee 'manager' D-BUS object method(s)
327 g_signal_connect(custom_data->zigbee_mgr,
328 "handle-get-zigbee-state",
329 G_CALLBACK(zigbee_on_manager_get_zigbee_state),
333 * Export 'manager' interface on ZigBee D-BUS
335 g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(custom_data->zigbee_mgr),
336 connection, ZIGBEE_DBUS_PATH, NULL);
339 * Exports all objects managed by 'manager' on Connection (connection)
341 g_dbus_object_manager_server_set_connection(custom_data->manager, connection);
343 path = g_strdup_printf("%s", ZIGBEE_SERVICE_PATH);
344 Z_LOGI("dbus object path: [%s]", path);
347 * Create 'object' for specific path only once.
349 zigbee_object = g_hash_table_lookup(custom_data->objects, path);
351 Z_LOGW("ZigBee D-BUS interface object already created (object: %p)", zigbee_object);
356 * Create ZigBee D-BUS object
358 zigbee_object = zigbee_object_skeleton_new(path);
359 Z_LOGI("ZigBee D-BUS object created (zigbee_object: [%p])", zigbee_object);
362 * Insert ZigBee object to HASH table
364 g_hash_table_insert(custom_data->objects, g_strdup(path), zigbee_object);
367 * Initialize interfaces
369 zigbee_service_dbus_interface_initialize_interfaces(service_interface, zigbee_object);
370 Z_LOGI("ZigBee service interfaces initialized!!!");
372 /* Export the Object to Manager */
373 g_dbus_object_manager_server_export(custom_data->manager,
374 G_DBUS_OBJECT_SKELETON(zigbee_object));
376 /* Servcie interface initialization completed */
377 custom_data->sevice_interface_init_complete = TRUE;
379 if (TRUE == custom_data->name_acquired) {
380 /* TODO - Emit zigbee_state signal */
387 /**< Zigbee service dbus interface initialization */
388 gboolean zigbee_service_dbus_interface_init(ZigBeeService *service)
390 ZigBeeServiceInterface *service_interface = NULL;
391 ZigbeeCustomData_t *interface_data = NULL;
394 if (NULL == service) {
395 Z_LOGE("service is NULL");
400 * Create ZigBee service interface object
402 service_interface = zblib_service_interface_new(service,
403 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
404 if (NULL == service_interface) {
405 Z_LOGE("Create D-BUS service interface failed!");
411 * Set Service interface notification callback
413 ret = zblib_service_interface_set_noti_cb(service_interface,
414 zigbee_service_dbus_interface_noti_cb, NULL);
416 Z_LOGE("Set service interface notification callback failed!");
422 * Add Service interface object to 'service'
424 ret = zblib_service_add_service_interface(service,
427 Z_LOGE("Add D-BUS service interface failed!");
433 * ZigBee D-BUS interface custom data
435 interface_data = g_malloc0(sizeof(ZigbeeCustomData_t));
438 * Link interface data to service
440 ret = zblib_service_interface_link_user_data(service_interface,
443 Z_LOGE("Link D-BUS service interface data failed!");
448 /* HASH table for maintaining 'objects' list */
449 interface_data->objects = g_hash_table_new(g_str_hash, g_str_equal);
452 * Acquire "org.tizen.zigbee" named bus on D-BUS SYSTEM bus.
454 interface_data->bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
456 G_BUS_NAME_OWNER_FLAGS_REPLACE,
457 zigbee_on_bus_acquired,
458 zigbee_on_name_acquired,
462 Z_LOGI("ZigBee D-BUS ID: [%d]", interface_data->bus_id);
464 interface_data->manager = g_dbus_object_manager_server_new(ZIGBEE_DBUS_PATH);
469 g_free(interface_data);
472 * Remove Service interface object from 'service'
474 ret = zblib_service_remove_service_interface(service,
477 Z_LOGE("Remove service interface failed!");
481 * Free Service interface object
483 zblib_service_interface_free(service,
489 /**< Zigbee service dbus interface de-initialization */
490 void zigbee_service_dbus_interface_deinit(ZigBeeService *service)
492 ZigBeeServiceInterface *service_interface = NULL;
493 ZigbeeCustomData_t *interface_data = NULL;
496 if (NULL == service) {
497 Z_LOGE("service is NULL");
501 service_interface = zblib_service_ref_service_interface(service,
502 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
503 if (NULL == service_interface) {
504 Z_LOGE("D-BUS service interface not found!");
509 interface_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
510 if (NULL == service_interface) {
511 Z_LOGE("D-BUS service interface not found!");
517 * Unown "org.tizen.zigbee" named bus on D-BUS SYSTEM bus
519 if (interface_data->bus_id > 0) {
520 Z_LOGI("Unowning ZigBee Service interface D-BUS ID: [%d]", interface_data->bus_id);
521 g_bus_unown_name(interface_data->bus_id);
525 g_hash_table_destroy(interface_data->objects);
526 g_free(interface_data);
530 * Remove Service interface object from 'service'
532 ret = zblib_service_remove_service_interface(service,
535 Z_LOGE("Remove service interface failed!");
539 * Free Service interface object
541 zblib_service_interface_free(service,