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 zblib_check_null_ret("custom_data", custom_data);
269 NOT_USED(connection);
271 /* Bus name is 'lost' */
272 custom_data->name_acquired = FALSE;
275 static void zigbee_on_name_acquired(GDBusConnection *connection,
276 const gchar *name, gpointer user_data)
278 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
279 ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
281 Z_LOGI("'%s' - [Name Acquired]", name);
283 NOT_USED(connection);
285 zblib_check_null_ret("custom_data", custom_data);
287 /* Bus name is 'acquired' */
288 custom_data->name_acquired = TRUE;
290 if (TRUE == custom_data->sevice_interface_init_complete) {
291 /* TODO - Emit zigbee_state signal */
295 static void zigbee_on_bus_acquired(GDBusConnection *connection,
296 const gchar *name, gpointer user_data)
298 ZigbeeObjectSkeleton *zigbee_object;
299 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
300 ZigBeeService *service = NULL;
301 ZigbeeCustomData_t *custom_data = NULL;
304 Z_LOGI("'%s' - [BUS Acquired]", name);
306 if (NULL == service_interface) {
307 Z_LOGE("service_interface is NULL!");
311 service = zblib_service_interface_ref_service(service_interface);
312 if (NULL == service) {
313 Z_LOGE("service is NULL!");
317 custom_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
318 if (NULL == custom_data) {
319 Z_LOGE("D-BUS service interface custom_data is NULL!");
324 * Create ZigBee 'manager' D-BUS object
326 custom_data->zigbee_mgr = zigbee_manager_skeleton_new();
329 * Set ZigBee 'manager' D-BUS object method(s)
331 g_signal_connect(custom_data->zigbee_mgr,
332 "handle-get-zigbee-state",
333 G_CALLBACK(zigbee_on_manager_get_zigbee_state),
337 * Export 'manager' interface on ZigBee D-BUS
339 g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(custom_data->zigbee_mgr),
340 connection, ZIGBEE_DBUS_PATH, NULL);
343 * Exports all objects managed by 'manager' on Connection (connection)
345 g_dbus_object_manager_server_set_connection(custom_data->manager, connection);
347 path = g_strdup_printf("%s", ZIGBEE_SERVICE_PATH);
348 Z_LOGI("dbus object path: [%s]", path);
351 * Create 'object' for specific path only once.
353 zigbee_object = g_hash_table_lookup(custom_data->objects, path);
355 Z_LOGW("ZigBee D-BUS interface object already created (object: %p)", zigbee_object);
360 * Create ZigBee D-BUS object
362 zigbee_object = zigbee_object_skeleton_new(path);
363 Z_LOGI("ZigBee D-BUS object created (zigbee_object: [%p])", zigbee_object);
366 * Insert ZigBee object to HASH table
368 g_hash_table_insert(custom_data->objects, g_strdup(path), zigbee_object);
371 * Initialize interfaces
373 zigbee_service_dbus_interface_initialize_interfaces(service_interface, zigbee_object);
374 Z_LOGI("ZigBee service interfaces initialized!!!");
376 /* Export the Object to Manager */
377 g_dbus_object_manager_server_export(custom_data->manager,
378 G_DBUS_OBJECT_SKELETON(zigbee_object));
380 /* Servcie interface initialization completed */
381 custom_data->sevice_interface_init_complete = TRUE;
383 if (TRUE == custom_data->name_acquired) {
384 /* TODO - Emit zigbee_state signal */
391 /**< Zigbee service dbus interface initialization */
392 gboolean zigbee_service_dbus_interface_init(ZigBeeService *service)
394 ZigBeeServiceInterface *service_interface = NULL;
395 ZigbeeCustomData_t *interface_data = NULL;
398 if (NULL == service) {
399 Z_LOGE("service is NULL");
404 * Create ZigBee service interface object
406 service_interface = zblib_service_interface_new(service,
407 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
408 if (NULL == service_interface) {
409 Z_LOGE("Create D-BUS service interface failed!");
415 * Set Service interface notification callback
417 ret = zblib_service_interface_set_noti_cb(service_interface,
418 zigbee_service_dbus_interface_noti_cb, NULL);
420 Z_LOGE("Set service interface notification callback failed!");
426 * Add Service interface object to 'service'
428 ret = zblib_service_add_service_interface(service,
431 Z_LOGE("Add D-BUS service interface failed!");
437 * ZigBee D-BUS interface custom data
439 interface_data = g_malloc0(sizeof(ZigbeeCustomData_t));
442 * Link interface data to service
444 ret = zblib_service_interface_link_user_data(service_interface,
447 Z_LOGE("Link D-BUS service interface data failed!");
452 /* HASH table for maintaining 'objects' list */
453 interface_data->objects = g_hash_table_new_full(g_str_hash, g_str_equal,
457 * Acquire "org.tizen.zigbee" named bus on D-BUS SYSTEM bus.
459 interface_data->bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
461 G_BUS_NAME_OWNER_FLAGS_REPLACE,
462 zigbee_on_bus_acquired,
463 zigbee_on_name_acquired,
467 Z_LOGI("ZigBee D-BUS ID: [%d]", interface_data->bus_id);
469 interface_data->manager = g_dbus_object_manager_server_new(ZIGBEE_DBUS_PATH);
474 g_free(interface_data);
477 * Remove Service interface object from 'service'
479 ret = zblib_service_remove_service_interface(service,
482 Z_LOGE("Remove service interface failed!");
486 * Free Service interface object
488 zblib_service_interface_free(service,
494 /**< Zigbee service dbus interface de-initialization */
495 void zigbee_service_dbus_interface_deinit(ZigBeeService *service)
497 ZigBeeServiceInterface *service_interface = NULL;
498 ZigbeeCustomData_t *interface_data = NULL;
501 if (NULL == service) {
502 Z_LOGE("service is NULL");
506 service_interface = zblib_service_ref_service_interface(service,
507 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
508 if (NULL == service_interface) {
509 Z_LOGE("D-BUS service interface not found!");
514 interface_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
515 if (NULL == interface_data) {
516 Z_LOGE("D-BUS interface data not found!");
522 * Unown "org.tizen.zigbee" named bus on D-BUS SYSTEM bus
524 if (interface_data->bus_id > 0) {
525 Z_LOGI("Unowning ZigBee Service interface D-BUS ID: [%d]", interface_data->bus_id);
526 g_bus_unown_name(interface_data->bus_id);
530 g_hash_table_destroy(interface_data->objects);
531 g_free(interface_data);
535 * Remove Service interface object from 'service'
537 ret = zblib_service_remove_service_interface(service,
540 Z_LOGE("Remove service interface failed!");
544 * Free Service interface object
546 zblib_service_interface_free(service,