98dffc659451e1bf13e11764e9b14d63478dfce0
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-hdp.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
7  *               Girishashok Joshi <girish.joshi@samsung.com>
8  *               Chanyeol Park <chanyeol.park@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *              http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <dbus/dbus.h>
27 #include <dbus/dbus-glib-lowlevel.h>
28 #include <string.h>
29
30 #include "bluetooth-api.h"
31 #include "bt-common.h"
32 #include "bt-internal-types.h"
33
34 #define HDP_BUFFER_SIZE 1024
35 #define BLUEZ_HDP_MANAGER_INTERFACE  "org.bluez.HealthManager1"
36 #define BLUEZ_HDP_DEVICE_INTERFACE  "org.bluez.HealthDevice1"
37 #define BLUEZ_HDP_CHANNEL_INTERFACE  "org.bluez.HealthChannel1"
38
39 typedef struct {
40         char *obj_channel_path;
41         int fd;
42         guint watch_id;
43 } hdp_obj_info_t;
44
45 typedef struct {
46         void *app_handle;
47         GSList *obj_info;
48 } hdp_app_list_t;
49
50 /* Variable for privilege, only for write API,
51   before we should reduce time to bt-service dbus calling
52   -1 : Don't have a permission to access API
53   0 : Initial value, not yet check
54   1 : Have a permission to access API
55 */
56 static int privilege_token;
57
58
59 /**********************************************************************
60 *               Static Functions declaration                            *
61 ***********************************************************************/
62 static int __bt_hdp_internal_create_application(unsigned int data_type,
63                                                 int role,
64                                                 bt_hdp_qos_type_t channel_type,
65                                                 char **app_handle);
66
67 static DBusHandlerResult __bt_hdp_internal_event_filter(DBusConnection *sys_conn,
68                                                         DBusMessage *msg,
69                                                         void *data);
70
71 static void __bt_hdp_internal_handle_connect(DBusMessage *msg);
72
73 static void __bt_hdp_internal_handle_disconnect(DBusMessage *msg);
74
75 static void __bt_hdp_internal_handle_property_changed(DBusMessage *msg);
76
77 static int __bt_hdp_internal_add_filter(void);
78
79 static int __bt_hdp_internal_acquire_fd(const char *path);
80
81 static guint __bt_hdp_internal_watch_fd(int file_desc, const char *path);
82
83 static gboolean __bt_hdp_internal_data_received(GIOChannel *gio,
84                                                 GIOCondition cond,
85                                                 gpointer data);
86
87 static int __bt_hdp_internal_destroy_application(const char *app_handle);
88
89 static void __bt_hdp_internal_remove_filter(void);
90
91 static hdp_app_list_t *__bt_hdp_internal_gslist_find_app_handler(void *app_handle);
92
93 static hdp_obj_info_t *__bt_hdp_internal_gslist_obj_find_using_fd(int fd);
94
95 static hdp_obj_info_t *__bt_hdp_internal_gslist_obj_find_using_path(const char *obj_channel_path);
96
97 /*Global Variables*/
98 static DBusConnection *g_hdp_dus_conn;
99
100 static GSList *g_app_list = NULL;
101
102 /**********************************************************************
103 *                       Health device APIs (HDP)                        *
104 ***********************************************************************/
105
106 BT_EXPORT_API int bluetooth_hdp_activate(unsigned short data_type,
107                                         bt_hdp_role_type_t role,
108                                         bt_hdp_qos_type_t channel_type,
109                                         char **app_handle)
110 {
111         int result = BLUETOOTH_ERROR_NONE;
112
113         BT_DBG("+");
114
115         BT_CHECK_ENABLED(return);
116
117         /*For source role is mandatory */
118         if (role == HDP_ROLE_SOURCE && channel_type == HDP_QOS_ANY) {
119                 BT_ERR("For source, type is mandatory - Reliable/Streaming");
120                 return BLUETOOTH_ERROR_INVALID_PARAM;
121         }
122
123         result = __bt_hdp_internal_create_application(data_type, role,
124                                                 channel_type, app_handle);
125
126         return result;
127 }
128
129 static void __bt_hdp_obj_info_free(hdp_obj_info_t *info)
130 {
131         if (info) {
132                 g_source_remove(info->watch_id);
133                 close(info->fd);
134                 g_free(info->obj_channel_path);
135                 g_free(info);
136         }
137 }
138
139 static int __bt_hdp_internal_create_application(unsigned int data_type,
140                                         int role,
141                                         bt_hdp_qos_type_t channel_type,
142                                         char **app_handle)
143 {
144         DBusMessage *msg;
145         DBusMessage *reply;
146         const char *svalue;
147         const char *key_type;
148         char *app_path;
149         hdp_app_list_t *list;
150         DBusError err;
151         DBusMessageIter iter;
152         DBusMessageIter array_iter;
153         DBusMessageIter entry;
154         DBusMessageIter variant;
155         guint16 value;
156         DBusConnection *conn;
157         int ret = BLUETOOTH_ERROR_NONE;
158
159         BT_DBG("+");
160
161         conn = _bt_get_system_conn();
162         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
163
164         msg = dbus_message_new_method_call(BT_BLUEZ_NAME, "/org/bluez",
165                                           BLUEZ_HDP_MANAGER_INTERFACE,
166                                           "CreateApplication");
167
168         retv_if(msg == NULL, BLUETOOTH_ERROR_NO_RESOURCES);
169
170         dbus_message_iter_init_append(msg, &iter);
171         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
172                 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING
173                 DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
174                 &array_iter);
175
176         key_type = "DataType";
177         value = (guint16) data_type;
178         dbus_message_iter_open_container(&array_iter, DBUS_TYPE_DICT_ENTRY,
179                                         NULL, &entry);
180         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key_type);
181         dbus_message_iter_open_container(&entry,
182                 DBUS_TYPE_VARIANT, DBUS_TYPE_UINT16_AS_STRING, &variant);
183         dbus_message_iter_append_basic(&variant, DBUS_TYPE_UINT16, &value);
184         dbus_message_iter_close_container(&entry, &variant);
185         dbus_message_iter_close_container(&array_iter, &entry);
186
187         key_type = "Role";
188
189         /*0-Source,1-Sink*/
190         svalue = (role == HDP_ROLE_SINK) ? "Sink" : "Source";
191         dbus_message_iter_open_container(&array_iter, DBUS_TYPE_DICT_ENTRY,
192                                         NULL, &entry);
193         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key_type);
194         dbus_message_iter_open_container(&entry,
195                 DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &variant);
196         dbus_message_iter_append_basic(&variant, DBUS_TYPE_STRING, &svalue);
197         dbus_message_iter_close_container(&entry, &variant);
198         dbus_message_iter_close_container(&array_iter, &entry);
199
200         key_type = "Description";
201         svalue = "Health Device";
202         dbus_message_iter_open_container(&array_iter, DBUS_TYPE_DICT_ENTRY,
203                                         NULL, &entry);
204         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key_type);
205         dbus_message_iter_open_container(&entry,
206                 DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &variant);
207         dbus_message_iter_append_basic(&variant, DBUS_TYPE_STRING, &svalue);
208         dbus_message_iter_close_container(&entry, &variant);
209         dbus_message_iter_close_container(&array_iter, &entry);
210
211         if (role == HDP_ROLE_SOURCE) {
212                 key_type = "ChannelType";
213                 if (channel_type == HDP_QOS_RELIABLE)
214                         svalue = "reliable";
215                 else if (channel_type == HDP_QOS_STREAMING)
216                         svalue = "streaming";
217
218                 dbus_message_iter_open_container(&array_iter,
219                         DBUS_TYPE_DICT_ENTRY, NULL, &entry);
220                 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
221                                                 &key_type);
222                 dbus_message_iter_open_container(&entry,
223                         DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING,
224                         &variant);
225                 dbus_message_iter_append_basic(&variant, DBUS_TYPE_STRING,
226                                                 &svalue);
227                 dbus_message_iter_close_container(&entry, &variant);
228                 dbus_message_iter_close_container(&array_iter, &entry);
229         }
230
231         dbus_message_iter_close_container(&iter, &array_iter);
232
233         dbus_error_init(&err);
234
235         reply = dbus_connection_send_with_reply_and_block(
236                                         conn, msg,
237                                         -1, &err);
238         dbus_message_unref(msg);
239
240         if (!reply) {
241                 BT_ERR(" HDP:dbus Can't create application");
242
243                 if (dbus_error_is_set(&err)) {
244                         BT_ERR("%s", err.message);
245
246                         if (g_strrstr(err.message, BT_ACCESS_DENIED_MSG))
247                                 ret = BLUETOOTH_ERROR_ACCESS_DENIED;
248                         else
249                                 ret = BLUETOOTH_ERROR_INTERNAL;
250
251                         dbus_error_free(&err);
252                 }
253                 return ret;
254         }
255
256         if (!dbus_message_get_args(reply, &err, DBUS_TYPE_OBJECT_PATH,
257                                 &app_path, DBUS_TYPE_INVALID)) {
258
259                 BT_ERR(" HDP: Can't get reply arguments from Dbus");
260
261                 if (dbus_error_is_set(&err)) {
262                         BT_ERR("Error: %s", err.message);
263                         dbus_error_free(&err);
264                 }
265
266                 dbus_message_unref(reply);
267                 return BLUETOOTH_ERROR_INTERNAL;
268         }
269
270         dbus_message_unref(reply);
271
272         BT_DBG("Created health application: %s", (char *)app_path);
273
274         ret = __bt_hdp_internal_add_filter();
275
276         if (ret != BLUETOOTH_ERROR_NONE) {
277                 BT_ERR("Funtion failed");
278                 return ret;
279         }
280
281         list = g_new0(hdp_app_list_t, 1);
282         list->app_handle = (void *)g_strdup(app_path);
283         *app_handle = list->app_handle;
284
285         g_app_list = g_slist_append(g_app_list, list);
286
287         return BLUETOOTH_ERROR_NONE;
288 }
289
290 static int __bt_hdp_internal_add_filter(void)
291 {
292         DBusError dbus_error;
293
294         BT_DBG("+");
295
296         /*Single process only one signal registration is required */
297         if (g_hdp_dus_conn) {
298                 BT_ERR("g_hdp_dus_conn already exist");
299                 goto done;
300         }
301
302         /* Add the filter for HDP client functions */
303         dbus_error_init(&dbus_error);
304
305         g_hdp_dus_conn = _bt_get_system_conn();
306         retv_if(g_hdp_dus_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
307
308         dbus_connection_add_filter(g_hdp_dus_conn,
309                                 __bt_hdp_internal_event_filter, NULL, NULL);
310
311         dbus_bus_add_match(g_hdp_dus_conn,
312                         "type='signal',interface=" BLUEZ_HDP_DEVICE_INTERFACE,
313                         &dbus_error);
314
315         if (dbus_error_is_set(&dbus_error)) {
316                 BT_ERR("Fail to add dbus filter signal\n");
317                 dbus_error_free(&dbus_error);
318                 g_hdp_dus_conn = NULL;
319                 return BLUETOOTH_ERROR_INTERNAL;
320         }
321
322 done:
323         BT_DBG("-\n");
324         return BLUETOOTH_ERROR_NONE;
325
326 }
327
328 static DBusHandlerResult __bt_hdp_internal_event_filter(DBusConnection *sys_conn,
329                                         DBusMessage *msg, void *data)
330 {
331         const char *path = dbus_message_get_path(msg);
332
333         if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
334                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
335
336         BT_DBG("Path = %s\n", path);
337         if (path == NULL || g_strcmp0(path, "/") == 0)
338                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
339
340         if (dbus_message_is_signal(msg, BLUEZ_HDP_DEVICE_INTERFACE,
341                                         "ChannelConnected"))
342                 __bt_hdp_internal_handle_connect(msg);
343
344         else if (dbus_message_is_signal(msg, BLUEZ_HDP_DEVICE_INTERFACE,
345                                         "ChannelDeleted"))
346                 __bt_hdp_internal_handle_disconnect(msg);
347
348         else if (dbus_message_is_signal(msg, BLUEZ_HDP_DEVICE_INTERFACE,
349                                         "PropertyChanged"))
350                 __bt_hdp_internal_handle_property_changed(msg);
351
352         return DBUS_HANDLER_RESULT_HANDLED;
353 }
354
355 static void __bt_hdp_internal_handle_connect(DBusMessage *msg)
356 {
357         const char *path = dbus_message_get_path(msg);
358         const char *obj_channel_path;
359         bt_user_info_t *user_info;
360         int ret;
361
362         BT_INFO("+********Signal - ChannelConnected******\n\n");
363         BT_DBG("Path = %s", path);
364
365         if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH,
366                                 &obj_channel_path, DBUS_TYPE_INVALID)) {
367                 BT_ERR("Unexpected parameters in ChannelConnected signal");
368                 return;
369         }
370
371         BT_INFO("Channel connected, Path = %s", obj_channel_path);
372
373         user_info = _bt_get_user_data(BT_COMMON);
374         if (user_info == NULL || user_info->cb == NULL)
375                 return;
376
377         ret = __bt_hdp_internal_acquire_fd(obj_channel_path);
378         if (ret != BLUETOOTH_ERROR_NONE) {
379                 _bt_common_event_cb(BLUETOOTH_EVENT_HDP_CONNECTED,
380                                 BLUETOOTH_ERROR_CONNECTION_ERROR, NULL,
381                                 user_info->cb, user_info->user_data);
382         } else {
383                 if (user_info->cb) {
384                         _bt_common_event_cb(BLUETOOTH_EVENT_HDP_CONNECTED,
385                                         BLUETOOTH_ERROR_NONE, NULL,
386                                         user_info->cb, user_info->user_data);
387                 }
388         }
389
390         BT_DBG("-");
391 }
392
393 static void __bt_hdp_internal_handle_disconnect(DBusMessage *msg)
394 {
395         const char *path = dbus_message_get_path(msg);
396         const char *obj_channel_path;
397         char address[BT_ADDRESS_STRING_SIZE] = { 0, };
398         bluetooth_device_address_t device_addr = { {0} };
399         bt_hdp_disconnected_t dis_ind;
400         hdp_obj_info_t *info;
401         bt_user_info_t *user_info;
402
403         BT_INFO("+********Signal - ChannelDeleted ******\n\n");
404         BT_DBG("Path = %s", path);
405
406         if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH,
407                                 &obj_channel_path, DBUS_TYPE_INVALID)) {
408                 BT_ERR("Unexpected parameters in ChannelDeleted signal");
409                 return;
410         }
411
412         BT_INFO("Channel Deleted, Path = %s", obj_channel_path);
413
414         info = __bt_hdp_internal_gslist_obj_find_using_path(obj_channel_path);
415         if (!info) {
416                 BT_ERR("No obj info for ob_channel_path [%s]\n", obj_channel_path);
417                 return;
418         }
419
420         /*Since bluetoothd is not sending the ChannelDeleted signal */
421         _bt_device_path_to_address(path, address);
422
423         _bt_convert_addr_string_to_type(device_addr.addr, address);
424
425         dis_ind.channel_id = info->fd;
426         dis_ind.device_address = device_addr;
427
428         user_info = _bt_get_user_data(BT_COMMON);
429
430         if (user_info->cb) {
431                 _bt_common_event_cb(BLUETOOTH_EVENT_HDP_DISCONNECTED,
432                                 BLUETOOTH_ERROR_NONE, &dis_ind,
433                                 user_info->cb, user_info->user_data);
434         }
435
436         BT_DBG(" Removed connection from list\n");
437
438         __bt_hdp_obj_info_free(info);
439
440 }
441
442 static void __bt_hdp_internal_handle_property_changed(DBusMessage *msg)
443 {
444         const char *path = dbus_message_get_path(msg);
445         DBusMessageIter item_iter;
446         DBusMessageIter value_iter;
447         const char *property;
448         const char *obj_main_channel_path;
449
450         BT_DBG("+*******Signal - PropertyChanged*******\n");
451         BT_DBG("Path = %s", path);
452
453         dbus_message_iter_init(msg, &item_iter);
454
455         if (dbus_message_iter_get_arg_type(&item_iter) != DBUS_TYPE_STRING) {
456                 BT_ERR("This is bad format dbus");
457                 return;
458         }
459
460         dbus_message_iter_get_basic(&item_iter, &property);
461
462         ret_if(property == NULL);
463
464         BT_DBG("Property (%s)\n", property);
465
466         if (0 == g_strcmp0(property, "MainChannel")) {
467                 BT_INFO("Property MainChannel received");
468
469                 dbus_message_iter_next(&item_iter);
470
471                 dbus_message_iter_recurse(&item_iter, &value_iter);
472
473                 dbus_message_iter_get_basic(&value_iter,
474                                                 &obj_main_channel_path);
475                 BT_DBG("Path = %s", path);
476
477                 BT_DBG("Main Channel  Path = %s", obj_main_channel_path);
478         }
479         BT_DBG("-*************\n");
480 }
481
482 static int __bt_hdp_internal_acquire_fd(const char *path)
483 {
484         char address[BT_ADDRESS_STRING_SIZE] = { 0, };
485         bluetooth_device_address_t device_addr = { {0} };
486         DBusMessageIter reply_iter;
487         DBusMessageIter reply_iter_entry;
488         const char *property;
489         char *type_qos = NULL;
490         char *device = NULL;;
491         char *app_handle = NULL;;
492         hdp_app_list_t *list = NULL;;
493         DBusMessage *msg;
494         DBusMessage *reply;
495         DBusConnection *conn;
496         bt_hdp_connected_t conn_ind;
497         DBusError err;
498         int fd;
499         bt_user_info_t *user_info;
500         char *dev_path;
501
502         BT_DBG("+");
503
504         conn = _bt_get_system_conn();
505         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
506
507         msg = dbus_message_new_method_call(BT_BLUEZ_NAME, path,
508                                           BLUEZ_HDP_CHANNEL_INTERFACE,
509                                           "Acquire");
510
511         retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
512
513         dbus_error_init(&err);
514
515         reply = dbus_connection_send_with_reply_and_block(conn, msg,
516                                                         -1, &err);
517
518         dbus_message_unref(msg);
519
520         if (!reply) {
521                 BT_ERR(" HDP:****** dbus Can't create application ****");
522
523                 if (dbus_error_is_set(&err)) {
524                         BT_ERR("%s", err.message);
525                         dbus_error_free(&err);
526                 }
527
528                 return BLUETOOTH_ERROR_INTERNAL;
529         }
530
531         if (!dbus_message_get_args(reply, &err, DBUS_TYPE_UNIX_FD, &fd,
532                                 DBUS_TYPE_INVALID)) {
533                 BT_ERR(" HDP:dbus Can't get reply arguments");
534
535                 if (dbus_error_is_set(&err)) {
536                         BT_ERR("%s", err.message);
537                         dbus_error_free(&err);
538                 }
539                 goto error;
540         }
541
542         dbus_message_unref(reply);
543
544         BT_DBG("File Descriptor = %d, Dev_path = %s \n", fd, path);
545
546         msg = dbus_message_new_method_call(BT_BLUEZ_NAME, path,
547                         BT_PROPERTIES_INTERFACE, "GetAll");
548         dev_path = g_strdup(BLUEZ_HDP_CHANNEL_INTERFACE);
549         dbus_message_append_args(msg, DBUS_TYPE_STRING, &dev_path,
550                                         DBUS_TYPE_INVALID);
551         g_free(dev_path);
552
553         retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
554
555         dbus_error_init(&err);
556
557         reply = dbus_connection_send_with_reply_and_block(conn, msg,
558                                                         -1, &err);
559
560         dbus_message_unref(msg);
561
562         if (!reply) {
563                 BT_ERR(" HDP:dbus Can't get the reply");
564
565                 if (dbus_error_is_set(&err)) {
566                         BT_ERR("%s", err.message);
567                         dbus_error_free(&err);
568                 }
569
570                 return BLUETOOTH_ERROR_INTERNAL;
571         }
572         dbus_message_iter_init(reply, &reply_iter);
573
574         if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) {
575                 BT_ERR("Can't get reply arguments - DBUS_TYPE_ARRAY\n");
576                 goto error;
577         }
578
579         dbus_message_iter_recurse(&reply_iter, &reply_iter_entry);
580
581         /*Parse the dict */
582         while (dbus_message_iter_get_arg_type(&reply_iter_entry) ==
583                                                 DBUS_TYPE_DICT_ENTRY) {
584                 DBusMessageIter dict_entry, dict_entry_val;
585                 dbus_message_iter_recurse(&reply_iter_entry, &dict_entry);
586                 dbus_message_iter_get_basic(&dict_entry, &property);
587                 BT_DBG("String received = %s\n", property);
588
589                 if (g_strcmp0("Type", property) == 0) {
590                         dbus_message_iter_next(&dict_entry);
591                         dbus_message_iter_recurse(&dict_entry, &dict_entry_val);
592                         if (dbus_message_iter_get_arg_type(&dict_entry_val) !=
593                                                 DBUS_TYPE_STRING)
594                                 continue;
595
596                         dbus_message_iter_get_basic(&dict_entry_val, &type_qos);
597
598                 } else if (g_strcmp0("Device", property) == 0) {
599                         dbus_message_iter_next(&dict_entry);
600                         dbus_message_iter_recurse(&dict_entry, &dict_entry_val);
601                         if (dbus_message_iter_get_arg_type(&dict_entry_val) !=
602                                                 DBUS_TYPE_OBJECT_PATH)
603                                 continue;
604
605                         dbus_message_iter_get_basic(&dict_entry_val, &device);
606
607                 } else if (g_strcmp0("Application", property) == 0) {
608                         dbus_message_iter_next(&dict_entry);
609                         dbus_message_iter_recurse(&dict_entry, &dict_entry_val);
610                         if (dbus_message_iter_get_arg_type(&dict_entry_val) !=
611                                                 DBUS_TYPE_OBJECT_PATH)
612                                 continue;
613
614                         dbus_message_iter_get_basic(&dict_entry_val,
615                                                         &app_handle);
616                 }
617                 dbus_message_iter_next(&reply_iter_entry);
618         }
619
620         BT_DBG("QOS = %s, Device = %s, Apphandler = %s",
621                         type_qos, device, app_handle);
622
623         if (NULL == type_qos || NULL == app_handle) {
624                 BT_ERR("Pasing failed\n");
625                 goto error;
626         }
627
628         list = __bt_hdp_internal_gslist_find_app_handler((void *)app_handle);
629
630         /*Only process register with app handle receive the Connected event */
631         if (NULL == list) {
632                 BT_ERR("**** Could not locate the list for %s*****\n", app_handle);
633                 goto error;
634         }
635
636         hdp_obj_info_t *info = g_new0(hdp_obj_info_t, 1);
637         info->fd = fd;
638         info->obj_channel_path = g_strdup(path);
639         info->watch_id = __bt_hdp_internal_watch_fd(fd, info->obj_channel_path);
640         list->obj_info = g_slist_append(list->obj_info, info);
641
642         _bt_device_path_to_address(path, address);
643
644         _bt_convert_addr_string_to_type(device_addr.addr, address);
645
646         conn_ind.app_handle = app_handle;
647         conn_ind.channel_id = fd;
648         conn_ind.device_address = device_addr;
649         conn_ind.type = (g_strcmp0(type_qos, "Reliable") == 0) ?
650                         HDP_QOS_RELIABLE : HDP_QOS_STREAMING;
651
652         BT_DBG("Going to give callback\n");
653
654         user_info = _bt_get_user_data(BT_COMMON);
655
656         if (user_info->cb) {
657                 _bt_common_event_cb(BLUETOOTH_EVENT_HDP_CONNECTED,
658                                 BLUETOOTH_ERROR_NONE, &conn_ind,
659                                 user_info->cb, user_info->user_data);
660         }
661
662         dbus_message_unref(reply);
663
664         BT_DBG("Updated fd in the list*\n");
665         BT_DBG("-\n");
666
667         return BLUETOOTH_ERROR_NONE;
668  error:
669         dbus_message_unref(reply);
670         return BLUETOOTH_ERROR_INTERNAL;
671 }
672
673 static guint __bt_hdp_internal_watch_fd(int file_desc, const char *path)
674 {
675         GIOChannel *gio;
676         guint id;
677
678         BT_DBG("+");
679
680         gio = g_io_channel_unix_new(file_desc);
681
682         g_io_channel_set_close_on_unref(gio, TRUE);
683
684         id = g_io_add_watch(gio, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
685                         __bt_hdp_internal_data_received, (void *)path);
686         BT_DBG("-");
687         return id;
688 }
689
690
691 static void __bt_hdp_internal_handle_disconnect_cb(int sk, const char *path)
692 {
693         char address[BT_ADDRESS_STRING_SIZE] = { 0, };
694         bluetooth_device_address_t device_addr = { {0} };
695         bt_hdp_disconnected_t dis_ind;
696         hdp_obj_info_t *info;
697         bt_user_info_t *user_info;
698
699         BT_INFO("******** Socket Error  ******\n");
700
701         info = __bt_hdp_internal_gslist_obj_find_using_path(path);
702         ret_if(info == NULL);
703
704         /*Since bluetoothd is not sending the ChannelDeleted signal */
705         _bt_device_path_to_address(path, address);
706
707         _bt_convert_addr_string_to_type(device_addr.addr, address);
708
709         dis_ind.channel_id = sk;
710         dis_ind.device_address = device_addr;
711
712         user_info = _bt_get_user_data(BT_COMMON);
713
714         if (user_info->cb) {
715                 _bt_common_event_cb(BLUETOOTH_EVENT_HDP_DISCONNECTED,
716                                 BLUETOOTH_ERROR_NONE, &dis_ind,
717                                 user_info->cb, user_info->user_data);
718         }
719
720         BT_DBG(" Removed connection from list\n");
721
722         __bt_hdp_obj_info_free(info);
723 }
724
725 static gboolean __bt_hdp_internal_data_received(GIOChannel *gio,
726                                         GIOCondition cond, gpointer data)
727 {
728         char buff[HDP_BUFFER_SIZE] = { 0, };
729         int sk;
730         int act_read;
731         bt_hdp_data_ind_t data_ind = { 0, };
732         const char *path = (const char *)data;
733         bt_user_info_t *user_info;
734
735         BT_DBG("+");
736
737         sk = g_io_channel_unix_get_fd(gio);
738
739         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
740                 BT_DBG("GIOCondition %d.............path = %s\n", cond, path);
741                  __bt_hdp_internal_handle_disconnect_cb(sk, path);
742                 return FALSE;
743         }
744
745         act_read = recv(sk, (void *)buff, sizeof(buff), 0);
746
747         if (act_read > 0) {
748                 BT_DBG("Received data of %d\n", act_read);
749         } else {
750                 BT_ERR("Read failed.....\n");
751                 return FALSE;
752         }
753
754         data_ind.channel_id = sk;
755         data_ind.buffer = buff;
756         data_ind.size = act_read;
757
758         user_info = _bt_get_user_data(BT_COMMON);
759
760         if (user_info->cb) {
761                 _bt_common_event_cb(BLUETOOTH_EVENT_HDP_DATA_RECEIVED,
762                                 BLUETOOTH_ERROR_NONE, &data_ind,
763                                 user_info->cb, user_info->user_data);
764         }
765
766         BT_DBG("-\n");
767
768         return TRUE;
769 }
770
771 BT_EXPORT_API int bluetooth_hdp_deactivate(const char *app_handle)
772 {
773         BT_DBG("+");
774
775         BT_CHECK_ENABLED(return);
776         BT_CHECK_PARAMETER(app_handle, return);
777
778         return __bt_hdp_internal_destroy_application(app_handle);
779 }
780
781 static hdp_app_list_t *__bt_hdp_internal_gslist_find_app_handler(void *app_handle)
782 {
783         GSList *l;
784
785         retv_if(g_app_list == NULL, NULL);
786
787         BT_DBG("List length = %d\n", g_slist_length(g_app_list));
788
789         for (l = g_app_list; l != NULL; l = l->next) {
790                 hdp_app_list_t *list = l->data;
791
792                 if (list) {
793                         if (0 == g_strcmp0((char *)list->app_handle,
794                                                 (char *)app_handle))
795                                 return list;
796                 }
797         }
798         return NULL;
799 }
800
801 static hdp_obj_info_t *__bt_hdp_internal_gslist_obj_find_using_fd(int fd)
802 {
803         GSList *l;
804         GSList *iter;
805
806         retv_if(g_app_list == NULL, NULL);
807
808         BT_DBG("List length = %d\n", g_slist_length(g_app_list));
809
810         for (l = g_app_list; l != NULL; l = l->next) {
811                 hdp_app_list_t *list = l->data;
812                 if (!list)
813                         return NULL;
814
815                 for (iter = list->obj_info; iter != NULL; iter = iter->next) {
816                         hdp_obj_info_t *info = iter->data;
817                         if (!info)
818                                 return NULL;
819
820                         if (fd == info->fd)
821                                 return info;
822                 }
823         }
824         return NULL;
825 }
826
827 static hdp_obj_info_t *__bt_hdp_internal_gslist_obj_find_using_path(const char *obj_channel_path)
828 {
829         GSList *l;
830         GSList *iter;
831         hdp_obj_info_t *info = NULL;
832
833         retv_if(g_app_list == NULL, NULL);
834
835         BT_DBG("List length = %d\n", g_slist_length(g_app_list));
836         for (l = g_app_list; l != NULL; l = l->next) {
837                 hdp_app_list_t *list = l->data;
838                 if (!list)
839                         return NULL;
840
841                 for (iter = list->obj_info; iter != NULL; iter = iter->next) {
842                          info = iter->data;
843                         if (!info)
844                                 return NULL;
845
846                         if (0 == g_strcmp0(info->obj_channel_path, obj_channel_path)) {
847                                 list->obj_info = g_slist_remove(list->obj_info, info);
848                                 return info;
849                         }
850                 }
851         }
852         return NULL;
853 }
854
855 static gboolean  __bt_hdp_internal_destroy_application_cb(gpointer data)
856 {
857         const char *app_handle;
858         hdp_app_list_t *list = NULL;
859         app_handle = (const char *)data;
860
861         BT_DBG("+");
862
863         list = __bt_hdp_internal_gslist_find_app_handler((void *)app_handle);
864         if (NULL == list) {
865                 BT_ERR("**** list not found for %s ******\n", app_handle);
866                 return FALSE;
867         }
868
869         g_app_list = g_slist_remove(g_app_list, list);
870
871         g_free(list->app_handle);
872         g_slist_foreach(list->obj_info, (GFunc)__bt_hdp_obj_info_free, NULL);
873         g_free(list);
874
875         BT_DBG("List length = %d\n", g_slist_length(g_app_list));
876
877         if (0 == g_slist_length(g_app_list))
878                 __bt_hdp_internal_remove_filter();
879         BT_DBG("-");
880         return FALSE;
881 }
882
883 static int __bt_hdp_internal_destroy_application(const char *app_handle)
884 {
885         DBusMessage *msg;
886         DBusMessage *reply;
887         DBusError err;
888         DBusConnection *conn;
889         int result = BLUETOOTH_ERROR_NONE;
890
891         conn = _bt_get_system_conn();
892         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
893
894         msg = dbus_message_new_method_call(BT_BLUEZ_NAME, "/org/bluez",
895                         BLUEZ_HDP_MANAGER_INTERFACE, "DestroyApplication");
896
897         retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
898
899         dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &app_handle,
900                                         DBUS_TYPE_INVALID);
901
902         dbus_error_init(&err);
903
904         reply = dbus_connection_send_with_reply_and_block(conn, msg,
905                                                         -1, &err);
906         dbus_message_unref(msg);
907         if (!reply) {
908                 BT_ERR(" HDP:dbus Can't Destroy application");
909
910                 if (dbus_error_is_set(&err)) {
911                         BT_ERR("%s", err.message);
912
913                         if (g_strrstr(err.message, BT_ACCESS_DENIED_MSG))
914                                 result  = BLUETOOTH_ERROR_ACCESS_DENIED;
915                         else
916                                 result  = BLUETOOTH_ERROR_INTERNAL;
917
918                         dbus_error_free(&err);
919                 }
920
921                 return result ;
922         }
923
924         dbus_message_unref(reply);
925
926         BT_DBG("Destroyed health application: %s", (char *)app_handle);
927
928         g_idle_add(__bt_hdp_internal_destroy_application_cb,
929                         (gpointer)app_handle);
930
931         return BLUETOOTH_ERROR_NONE;
932 }
933
934 static void __bt_hdp_internal_remove_filter(void)
935 {
936         BT_DBG("+");
937
938         ret_if(g_hdp_dus_conn == NULL);
939
940         dbus_connection_remove_filter(g_hdp_dus_conn,
941                                         __bt_hdp_internal_event_filter, NULL);
942
943         g_hdp_dus_conn = NULL;  /*should not unref here, bcz no ++reff */
944
945         BT_DBG("-");
946 }
947
948 BT_EXPORT_API int bluetooth_hdp_send_data(unsigned int channel_id,
949                                             const char *buffer,
950                                             unsigned int size)
951 {
952         int wbytes = 0;
953         int written = 0;
954         int result;
955
956         BT_DBG("+");
957
958         BT_CHECK_ENABLED(return);
959
960         if ((channel_id == 0) || (NULL == buffer) || (size == 0)) {
961                 BT_ERR("Invalid arguments..\n");
962                 return BLUETOOTH_ERROR_INVALID_PARAM;
963         }
964
965         switch (privilege_token) {
966         case 0:
967                 result = _bt_check_privilege(BT_BLUEZ_SERVICE, BT_HDP_SEND_DATA);
968
969                 if (result == BLUETOOTH_ERROR_NONE) {
970                         privilege_token = 1; /* Have a permission */
971                 } else if (result == BLUETOOTH_ERROR_PERMISSION_DEINED) {
972                         BT_ERR("Don't have a privilege to use this API");
973                         privilege_token = -1; /* Don't have a permission */
974                         return BLUETOOTH_ERROR_PERMISSION_DEINED;
975                 } else {
976                         /* Just break - It is not related with permission error */
977                 }
978                 break;
979         case 1:
980                 /* Already have a privilege */
981                 break;
982         case -1:
983                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
984         default:
985                 /* Invalid privilge token value */
986                 return BLUETOOTH_ERROR_INTERNAL;
987         }
988
989         while (wbytes < size) {
990                 written = write(channel_id, buffer + wbytes, size - wbytes);
991                 if (written <= 0) {
992                         BT_ERR("write failed..\n");
993                         return BLUETOOTH_ERROR_NOT_IN_OPERATION;
994                 }
995                 wbytes += written;
996         }
997
998         return BLUETOOTH_ERROR_NONE;
999 }
1000
1001
1002 static void __bt_hdp_connect_request_cb(DBusGProxy *hdp_proxy, DBusGProxyCall *call,
1003                                                  gpointer user_data)
1004 {
1005         GError *g_error = NULL;
1006         char *obj_connect_path = NULL;
1007         bt_hdp_connected_t *conn_ind = user_data;
1008         bt_user_info_t *user_info;
1009
1010         dbus_g_proxy_end_call(hdp_proxy, call, &g_error,
1011                 DBUS_TYPE_G_OBJECT_PATH, &obj_connect_path, G_TYPE_INVALID);
1012
1013         g_object_unref(hdp_proxy);
1014
1015         if (g_error != NULL) {
1016                 BT_ERR("HDP connection  Dbus Call Error: %s\n", g_error->message);
1017                 g_error_free(g_error);
1018
1019                 user_info = _bt_get_user_data(BT_COMMON);
1020
1021                 if (user_info->cb) {
1022                         _bt_common_event_cb(BLUETOOTH_EVENT_HDP_CONNECTED,
1023                                         BLUETOOTH_ERROR_CONNECTION_ERROR, conn_ind,
1024                                         user_info->cb, user_info->user_data);
1025                 }
1026         } else {
1027                 BT_DBG("Obj Path returned = %s\n", obj_connect_path);
1028                 user_info = _bt_get_user_data(BT_COMMON);
1029
1030                 if (user_info->cb) {
1031                         _bt_common_event_cb(BLUETOOTH_EVENT_HDP_CONNECTED,
1032                                         BLUETOOTH_ERROR_NONE, conn_ind,
1033                                         user_info->cb, user_info->user_data);
1034                 }
1035                 g_free(obj_connect_path);
1036         }
1037         g_free((void *)conn_ind->app_handle);
1038         g_free(conn_ind);
1039 }
1040
1041
1042 BT_EXPORT_API int bluetooth_hdp_connect(const char *app_handle,
1043                         bt_hdp_qos_type_t channel_type,
1044                         const bluetooth_device_address_t *device_address)
1045 {
1046         GError *err = NULL;
1047         DBusGConnection *conn = NULL;
1048         DBusGProxy *hdp_proxy = NULL;
1049         bt_hdp_connected_t *param;
1050         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1051         char default_adapter_path[BT_ADAPTER_OBJECT_PATH_MAX + 1] = { 0 };
1052         char *dev_path = NULL;
1053         char *role;
1054
1055         BT_DBG("+");
1056
1057         BT_CHECK_ENABLED(return);
1058         BT_CHECK_PARAMETER(app_handle, return);
1059         BT_CHECK_PARAMETER(device_address, return);
1060
1061         if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_HDP_CONNECT)
1062              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
1063                 BT_ERR("Don't have a privilege to use this API");
1064                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
1065         }
1066
1067         if (channel_type == HDP_QOS_RELIABLE) {
1068                 role = "Reliable";
1069         } else if (channel_type == HDP_QOS_STREAMING) {
1070                 role = "Streaming";
1071         } else if (channel_type == HDP_QOS_ANY) {
1072                 role = "Any";
1073         } else {
1074                 BT_ERR("Invalid channel_type %d", channel_type);
1075                 return BLUETOOTH_ERROR_ACCESS_DENIED;
1076         }
1077
1078         conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &err);
1079
1080         if (err != NULL) {
1081                 BT_ERR("ERROR: Can't get on system bus [%s]", err->message);
1082                 g_error_free(err);
1083                 return BLUETOOTH_ERROR_INTERNAL;
1084         }
1085
1086         /* If the adapter path is wrong, we can think the BT is not enabled. */
1087         if (_bt_get_adapter_path(_bt_gdbus_get_system_gconn(),
1088                                         default_adapter_path) < 0) {
1089                 BT_ERR("Could not get adapter path\n");
1090                 dbus_g_connection_unref(conn);
1091                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1092         }
1093
1094         _bt_convert_addr_type_to_string(address,
1095                                 (unsigned char *)device_address->addr);
1096
1097         BT_DBG("create conection to %s", address);
1098
1099         dev_path = g_strdup_printf("%s/dev_%s", default_adapter_path, address);
1100
1101         if (dev_path == NULL) {
1102                 dbus_g_connection_unref(conn);
1103                 return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
1104         }
1105
1106         g_strdelimit(dev_path, ":", '_');
1107
1108         BT_DBG("path: %s", dev_path);
1109
1110         hdp_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME, dev_path,
1111                                                BLUEZ_HDP_DEVICE_INTERFACE);
1112         dbus_g_connection_unref(conn);
1113
1114         if (hdp_proxy == NULL) {
1115                 BT_ERR("Failed to get the HDP server proxy\n");
1116                 g_free(dev_path);
1117                 return BLUETOOTH_ERROR_NOT_PAIRED;
1118         }
1119
1120         BT_DBG("app path %s\n", app_handle);
1121
1122         param = g_new0(bt_hdp_connected_t, 1);
1123         param->app_handle = g_strdup(app_handle);
1124         memcpy(&param->device_address, device_address, BLUETOOTH_ADDRESS_LENGTH);
1125         param->type = channel_type;
1126
1127         if (!dbus_g_proxy_begin_call(hdp_proxy, "CreateChannel",
1128                                 (DBusGProxyCallNotify) __bt_hdp_connect_request_cb,
1129                                 param,  /* user_data */
1130                                 NULL,   /* destroy */
1131                                 DBUS_TYPE_G_OBJECT_PATH, app_handle,
1132                                 G_TYPE_STRING, role,
1133                                 G_TYPE_INVALID)) {
1134                 BT_ERR("HDP connection Dbus Call Error");
1135                 g_free(dev_path);
1136                 g_free((void *)param->app_handle);
1137                 g_free(param);
1138                 g_object_unref(hdp_proxy);
1139                 return BLUETOOTH_ERROR_INTERNAL;
1140         }
1141
1142         g_free(dev_path);
1143         return BLUETOOTH_ERROR_NONE;
1144 }
1145
1146 static void __bt_hdp_disconnect_request_cb(DBusGProxy *hdp_proxy, DBusGProxyCall *call,
1147                                                     gpointer user_data)
1148 {
1149         GError *g_error = NULL;
1150         bt_hdp_disconnected_t *disconn_ind = user_data;
1151         bt_user_info_t *user_info;
1152
1153         dbus_g_proxy_end_call(hdp_proxy, call, &g_error, G_TYPE_INVALID);
1154
1155         g_object_unref(hdp_proxy);
1156
1157         user_info = _bt_get_user_data(BT_COMMON);
1158         if (user_info == NULL || user_info->cb == NULL) {
1159                 g_free(disconn_ind);
1160                 if (g_error)
1161                         g_error_free(g_error);
1162                 return;
1163         }
1164
1165         if (g_error != NULL) {
1166                 BT_ERR("HDP disconnection Dbus Call Error: %s\n", g_error->message);
1167                 g_error_free(g_error);
1168
1169                 _bt_common_event_cb(BLUETOOTH_EVENT_HDP_DISCONNECTED,
1170                                 BLUETOOTH_ERROR_CONNECTION_ERROR, disconn_ind,
1171                                 user_info->cb, user_info->user_data);
1172         } else {
1173                 if (user_info->cb) {
1174                         _bt_common_event_cb(BLUETOOTH_EVENT_HDP_DISCONNECTED,
1175                                         BLUETOOTH_ERROR_NONE, disconn_ind,
1176                                         user_info->cb, user_info->user_data);
1177                 }
1178                 BT_INFO("HDP disconnection Dbus Call is done\n");
1179         }
1180
1181         g_free(disconn_ind);
1182 }
1183
1184 BT_EXPORT_API int bluetooth_hdp_disconnect(unsigned int channel_id,
1185                         const bluetooth_device_address_t *device_address)
1186 {
1187         GError *err = NULL;
1188         DBusGConnection *conn = NULL;
1189         DBusGProxy *hdp_proxy = NULL;
1190         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1191         char default_adapter_path[BT_ADAPTER_OBJECT_PATH_MAX + 1] = { 0 };
1192         char *dev_path = NULL;
1193         bt_hdp_disconnected_t *param;
1194
1195         BT_DBG("+\n");
1196
1197         BT_CHECK_ENABLED(return);
1198         BT_CHECK_PARAMETER(device_address, return);
1199
1200         if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_HDP_DISCONNECT)
1201              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
1202                 BT_ERR("Don't have a privilege to use this API");
1203                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
1204         }
1205
1206         hdp_obj_info_t *info = __bt_hdp_internal_gslist_obj_find_using_fd(channel_id);
1207         if (NULL == info) {
1208                 BT_ERR("*** Could not locate the list for %d*****\n", channel_id);
1209                 return BLUETOOTH_ERROR_INVALID_PARAM;
1210         }
1211
1212         conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &err);
1213
1214         if (err != NULL) {
1215                 BT_ERR("ERROR: Can't get on system bus [%s]", err->message);
1216                 g_error_free(err);
1217                 return BLUETOOTH_ERROR_INTERNAL;
1218         }
1219
1220         /* If the adapter path is wrong, we can think the BT is not enabled. */
1221         if (_bt_get_adapter_path(_bt_gdbus_get_system_gconn(),
1222                                         default_adapter_path) < 0) {
1223                 BT_ERR("Could not get adapter path\n");
1224                 dbus_g_connection_unref(conn);
1225                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1226         }
1227
1228         _bt_convert_addr_type_to_string(address,
1229                                 (unsigned char *)device_address->addr);
1230
1231         BT_DBG("create conection to  %s\n", address);
1232
1233         dev_path = g_strdup_printf("%s/dev_%s", default_adapter_path, address);
1234
1235         if (dev_path == NULL) {
1236                 dbus_g_connection_unref(conn);
1237                 return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
1238         }
1239
1240         g_strdelimit(dev_path, ":", '_');
1241
1242         BT_DBG("path  %s\n", dev_path);
1243
1244         hdp_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME, dev_path,
1245                                                BLUEZ_HDP_DEVICE_INTERFACE);
1246
1247         dbus_g_connection_unref(conn);
1248
1249         if (hdp_proxy == NULL) {
1250                 BT_ERR("Failed to get the HDP proxy\n");
1251                 g_free(dev_path);
1252                 return BLUETOOTH_ERROR_NOT_PAIRED;
1253         }
1254
1255         param = g_new0(bt_hdp_disconnected_t, 1);
1256         param->channel_id = channel_id;
1257         memcpy(&param->device_address, device_address, BLUETOOTH_ADDRESS_LENGTH);
1258
1259         if (!dbus_g_proxy_begin_call(hdp_proxy, "DestroyChannel",
1260                                 (DBusGProxyCallNotify) __bt_hdp_disconnect_request_cb,
1261                                 param,  /* user_data */
1262                                 NULL,   /* destroy */
1263                                 DBUS_TYPE_G_OBJECT_PATH, info->obj_channel_path,
1264                                 G_TYPE_INVALID)) {
1265                 BT_ERR("HDP connection Dbus Call Error");
1266                 g_free(dev_path);
1267                 g_free(param);
1268                 g_object_unref(hdp_proxy);
1269                 return BLUETOOTH_ERROR_INTERNAL;
1270         }
1271
1272         g_free(dev_path);
1273
1274         return BLUETOOTH_ERROR_NONE;
1275 }