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 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
276 ZigbeeCustomData_t *custom_data = zblib_service_interface_ref_user_data(service_interface);
278 Z_LOGI("'%s' - [Name Acquired]", name);
280 NOT_USED(connection);
282 /* Bus name is 'acquired' */
283 custom_data->name_acquired = TRUE;
285 if (TRUE == custom_data->sevice_interface_init_complete) {
286 /* TODO - Emit zigbee_state signal */
290 static void zigbee_on_bus_acquired(GDBusConnection *connection,
291 const gchar *name, gpointer user_data)
293 ZigbeeObjectSkeleton *zigbee_object;
294 ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
295 ZigBeeService *service = NULL;
296 ZigbeeCustomData_t *custom_data = NULL;
299 Z_LOGI("'%s' - [BUS Acquired]", name);
301 if (NULL == service_interface) {
302 Z_LOGE("service_interface is NULL!");
306 service = zblib_service_interface_ref_service(service_interface);
307 if (NULL == service) {
308 Z_LOGE("service is NULL!");
312 custom_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
313 if (NULL == custom_data) {
314 Z_LOGE("D-BUS service interface custom_data is NULL!");
319 * Create ZigBee 'manager' D-BUS object
321 custom_data->zigbee_mgr = zigbee_manager_skeleton_new();
324 * Set ZigBee 'manager' D-BUS object method(s)
326 g_signal_connect(custom_data->zigbee_mgr,
327 "handle-get-zigbee-state",
328 G_CALLBACK(zigbee_on_manager_get_zigbee_state),
332 * Export 'manager' interface on ZigBee D-BUS
334 g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(custom_data->zigbee_mgr),
335 connection, ZIGBEE_DBUS_PATH, NULL);
338 * Exports all objects managed by 'manager' on Connection (connection)
340 g_dbus_object_manager_server_set_connection(custom_data->manager, connection);
342 path = g_strdup_printf("%s/service", ZIGBEE_DBUS_PATH);
343 Z_LOGI("dbus object path: [%s]", path);
346 * Create 'object' for specific path only once.
348 zigbee_object = g_hash_table_lookup(custom_data->objects, path);
350 Z_LOGW("ZigBee D-BUS interface object already created (object: %p)", zigbee_object);
355 * Create ZigBee D-BUS object
357 zigbee_object = zigbee_object_skeleton_new(path);
358 Z_LOGI("ZigBee D-BUS object created (zigbee_object: [%p])", zigbee_object);
361 * Insert ZigBee object to HASH table
363 g_hash_table_insert(custom_data->objects, g_strdup(path), zigbee_object);
366 * Initialize interfaces
368 zigbee_service_dbus_interface_initialize_interfaces(service_interface, zigbee_object);
369 Z_LOGI("ZigBee service interfaces initialized!!!");
371 /* Export the Object to Manager */
372 g_dbus_object_manager_server_export(custom_data->manager,
373 G_DBUS_OBJECT_SKELETON(zigbee_object));
375 /* Servcie interface initialization completed */
376 custom_data->sevice_interface_init_complete = TRUE;
378 if (TRUE == custom_data->name_acquired) {
379 /* TODO - Emit zigbee_state signal */
386 /**< Zigbee service dbus interface initialization */
387 gboolean zigbee_service_dbus_interface_init(ZigBeeService *service)
389 ZigBeeServiceInterface *service_interface = NULL;
390 ZigbeeCustomData_t *interface_data = NULL;
393 if (NULL == service) {
394 Z_LOGE("service is NULL");
399 * Create ZigBee service interface object
401 service_interface = zblib_service_interface_new(service,
402 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
403 if (NULL == service_interface) {
404 Z_LOGE("Create D-BUS service interface failed!");
410 * Set Service interface notification callback
412 ret = zblib_service_interface_set_noti_cb(service_interface,
413 zigbee_service_dbus_interface_noti_cb, NULL);
415 Z_LOGE("Set service interface notification callback failed!");
421 * Add Service interface object to 'service'
423 ret = zblib_service_add_service_interface(service,
426 Z_LOGE("Add D-BUS service interface failed!");
432 * ZigBee D-BUS interface custom data
434 interface_data = g_malloc0(sizeof(ZigbeeCustomData_t));
437 * Link interface data to service
439 ret = zblib_service_interface_link_user_data(service_interface,
442 Z_LOGE("Link D-BUS service interface data failed!");
447 /* HASH table for maintaining 'objects' list */
448 interface_data->objects = g_hash_table_new(g_str_hash, g_str_equal);
451 * Acquire "org.tizen.zigbee" named bus on D-BUS SYSTEM bus.
453 interface_data->bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
455 G_BUS_NAME_OWNER_FLAGS_REPLACE,
456 zigbee_on_bus_acquired,
457 zigbee_on_name_acquired,
461 Z_LOGI("ZigBee D-BUS ID: [%d]", interface_data->bus_id);
463 interface_data->manager = g_dbus_object_manager_server_new(ZIGBEE_DBUS_PATH);
468 g_free(interface_data);
471 * Remove Service interface object from 'service'
473 ret = zblib_service_remove_service_interface(service,
476 Z_LOGE("Remove service interface failed!");
480 * Free Service interface object
482 zblib_service_interface_free(service,
488 /**< Zigbee service dbus interface de-initialization */
489 void zigbee_service_dbus_interface_deinit(ZigBeeService *service)
491 ZigBeeServiceInterface *service_interface = NULL;
492 ZigbeeCustomData_t *interface_data = NULL;
495 if (NULL == service) {
496 Z_LOGE("service is NULL");
500 service_interface = zblib_service_ref_service_interface(service,
501 ZIGBEE_DBUS_SERVICE_INTERFACE_NAME);
502 if (NULL == service_interface) {
503 Z_LOGE("D-BUS service interface not found!");
508 interface_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
509 if (NULL == service_interface) {
510 Z_LOGE("D-BUS service interface not found!");
516 * Unown "org.tizen.zigbee" named bus on D-BUS SYSTEM bus
518 if (interface_data->bus_id > 0) {
519 Z_LOGI("Unowning ZigBee Service interface D-BUS ID: [%d]", interface_data->bus_id);
520 g_bus_unown_name(interface_data->bus_id);
524 g_hash_table_destroy(interface_data->objects);
525 g_free(interface_data);
529 * Remove Service interface object from 'service'
531 ret = zblib_service_remove_service_interface(service,
534 Z_LOGE("Remove service interface failed!");
538 * Free Service interface object
540 zblib_service_interface_free(service,