X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bt-api%2Fbt-hdp.c;h=f8f0fadca12612b78bad5be69b462d02eba54bc6;hb=8a4d6b041afca0b8e0bdc8c3336a3d7d563988fa;hp=23c9cb7b3f4b8f2a9eb063e3d8b7172369ba15be;hpb=5f5b6fa5e56703d0d16409aee366a7701888a583;p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git diff --git a/bt-api/bt-hdp.c b/bt-api/bt-hdp.c old mode 100644 new mode 100755 index 23c9cb7..f8f0fad --- a/bt-api/bt-hdp.c +++ b/bt-api/bt-hdp.c @@ -1,13 +1,11 @@ /* - * bluetooth-frwk - * - * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -19,21 +17,26 @@ #include #include -#include +#include +#include #include +#include #include "bluetooth-api.h" #include "bt-common.h" #include "bt-internal-types.h" +#include "bt-request-sender.h" #define HDP_BUFFER_SIZE 1024 -#define BLUEZ_HDP_MANAGER_INTERFACE "org.bluez.HealthManager" -#define BLUEZ_HDP_DEVICE_INTERFACE "org.bluez.HealthDevice" -#define BLUEZ_HDP_CHANNEL_INTERFACE "org.bluez.HealthChannel" +#define BLUEZ_HDP_MANAGER_INTERFACE "org.bluez.HealthManager1" +#define BLUEZ_HDP_DEVICE_INTERFACE "org.bluez.HealthDevice1" +#define BLUEZ_HDP_CHANNEL_INTERFACE "org.bluez.HealthChannel1" typedef struct { - char *obj_channel_path; int fd; + unsigned int channel_id; + guint watch_id; + void *app_handle; } hdp_obj_info_t; typedef struct { @@ -41,710 +44,29 @@ typedef struct { GSList *obj_info; } hdp_app_list_t; - -/********************************************************************** -* Static Functions declaration * -***********************************************************************/ -static int __bt_hdp_internal_create_application(unsigned int data_type, - int role, - bt_hdp_qos_type_t channel_type, - char **app_handle); - -static DBusHandlerResult __bt_hdp_internal_event_filter(DBusConnection *sys_conn, - DBusMessage *msg, - void *data); - -static void __bt_hdp_internal_handle_connect(DBusMessage *msg); - -static void __bt_hdp_internal_handle_disconnect(DBusMessage *msg); - -static void __bt_hdp_internal_handle_property_changed(DBusMessage *msg); - -static int __bt_hdp_internal_add_filter(void); - -static int __bt_hdp_internal_acquire_fd(const char *path); - -static void __bt_hdp_internal_watch_fd(int file_desc, const char *path); - -static gboolean __bt_hdp_internal_data_received(GIOChannel *gio, - GIOCondition cond, - gpointer data); - -static int __bt_hdp_internal_destroy_application(const char *app_handle); - -static void __bt_hdp_internal_remove_filter(void); - -static hdp_app_list_t *__bt_hdp_internal_gslist_find_app_handler(void *app_handle); - -static hdp_obj_info_t *__bt_hdp_internal_gslist_obj_find_using_fd(int fd); - -static hdp_obj_info_t *__bt_hdp_internal_gslist_obj_find_using_path(const char *obj_channel_path); - -/*Global Variables*/ -static DBusConnection *g_hdp_dus_conn; - static GSList *g_app_list = NULL; -/********************************************************************** -* Health device APIs (HDP) * -***********************************************************************/ - -BT_EXPORT_API int bluetooth_hdp_activate(unsigned short data_type, - bt_hdp_role_type_t role, - bt_hdp_qos_type_t channel_type, - char **app_handle) -{ - int result = BLUETOOTH_ERROR_NONE; - - BT_DBG("+"); - - BT_CHECK_ENABLED(); - - /*For source role is mandatory */ - if (role == HDP_ROLE_SOURCE && channel_type == HDP_QOS_ANY) { - BT_DBG("For source, type is mandatory - Reliable/Streaming"); - return BLUETOOTH_ERROR_INVALID_PARAM; - } - - result = __bt_hdp_internal_create_application(data_type, role, - channel_type, app_handle); - - return result; -} +/* Variable for privilege, only for write API, + * before we should reduce time to bt-service dbus calling + * -1 : Don't have a permission to access API + * 0 : Initial value, not yet check + * 1 : Have a permission to access API + */ +static int privilege_token; static void __bt_hdp_obj_info_free(hdp_obj_info_t *info) { - if (info) { - close(info->fd); - g_free(info->obj_channel_path); - g_free(info); - } -} - -static int __bt_hdp_internal_create_application(unsigned int data_type, - int role, - bt_hdp_qos_type_t channel_type, - char **app_handle) -{ - DBusMessage *msg; - DBusMessage *reply; - const char *svalue; - const char *key_type; - char *app_path; - hdp_app_list_t *list; - DBusError err; - DBusMessageIter iter; - DBusMessageIter array_iter; - DBusMessageIter entry; - DBusMessageIter variant; - guint16 value; - DBusConnection *conn; - int ret = BLUETOOTH_ERROR_NONE; - - BT_DBG("+"); - - conn = _bt_get_system_conn(); - retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); - - msg = dbus_message_new_method_call(BT_BLUEZ_NAME, "/org/bluez", - BLUEZ_HDP_MANAGER_INTERFACE, - "CreateApplication"); - - retv_if(msg == NULL, BLUETOOTH_ERROR_NO_RESOURCES); - - dbus_message_iter_init_append(msg, &iter); - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, - DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING - DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, - &array_iter); - - key_type = "DataType"; - value = (guint16) data_type; - dbus_message_iter_open_container(&array_iter, DBUS_TYPE_DICT_ENTRY, - NULL, &entry); - dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key_type); - dbus_message_iter_open_container(&entry, - DBUS_TYPE_VARIANT, DBUS_TYPE_UINT16_AS_STRING, &variant); - dbus_message_iter_append_basic(&variant, DBUS_TYPE_UINT16, &value); - dbus_message_iter_close_container(&entry, &variant); - dbus_message_iter_close_container(&array_iter, &entry); - - key_type = "Role"; - - /*0-Source,1-Sink*/ - svalue = (role == HDP_ROLE_SINK) ? "Sink" : "Source"; - dbus_message_iter_open_container(&array_iter, DBUS_TYPE_DICT_ENTRY, - NULL, &entry); - dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key_type); - dbus_message_iter_open_container(&entry, - DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &variant); - dbus_message_iter_append_basic(&variant, DBUS_TYPE_STRING, &svalue); - dbus_message_iter_close_container(&entry, &variant); - dbus_message_iter_close_container(&array_iter, &entry); - - key_type = "Description"; - svalue = "Health Device"; - dbus_message_iter_open_container(&array_iter, DBUS_TYPE_DICT_ENTRY, - NULL, &entry); - dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key_type); - dbus_message_iter_open_container(&entry, - DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &variant); - dbus_message_iter_append_basic(&variant, DBUS_TYPE_STRING, &svalue); - dbus_message_iter_close_container(&entry, &variant); - dbus_message_iter_close_container(&array_iter, &entry); - - if (role == HDP_ROLE_SOURCE) { - key_type = "ChannelType"; - if (channel_type == HDP_QOS_RELIABLE) - svalue = "Reliable"; - else if (channel_type == HDP_QOS_STREAMING) - svalue = "Streaming"; - - dbus_message_iter_open_container(&array_iter, - DBUS_TYPE_DICT_ENTRY, NULL, &entry); - dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, - &key_type); - dbus_message_iter_open_container(&entry, - DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, - &variant); - dbus_message_iter_append_basic(&variant, DBUS_TYPE_STRING, - &svalue); - dbus_message_iter_close_container(&entry, &variant); - dbus_message_iter_close_container(&array_iter, &entry); - } - - dbus_message_iter_close_container(&iter, &array_iter); - - dbus_error_init(&err); - - reply = dbus_connection_send_with_reply_and_block( - conn, msg, - -1, &err); - dbus_message_unref(msg); - - if (!reply) { - BT_ERR(" HDP:dbus Can't create application"); - - if (dbus_error_is_set(&err)) { - BT_ERR("%s", err.message); - dbus_error_free(&err); - } - return BLUETOOTH_ERROR_INTERNAL; - } - - if (!dbus_message_get_args(reply, &err, DBUS_TYPE_OBJECT_PATH, - &app_path, DBUS_TYPE_INVALID)) { - - BT_ERR(" HDP: Can't get reply arguments from Dbus"); - - if (dbus_error_is_set(&err)) { - BT_ERR("Error: %s", err.message); - dbus_error_free(&err); - } - - dbus_message_unref(reply); - return BLUETOOTH_ERROR_INTERNAL; - } - - dbus_message_unref(reply); - - BT_DBG("Created health application: %s", (char *)app_path); - - ret = __bt_hdp_internal_add_filter(); - - if (ret != BLUETOOTH_ERROR_NONE) { - BT_ERR("Funtion failed"); - return ret; - } - - list = g_new0(hdp_app_list_t, 1); - list->app_handle = (void *)g_strdup(app_path); - *app_handle = list->app_handle; - - g_app_list = g_slist_append(g_app_list, list); - - return BLUETOOTH_ERROR_NONE; -} - -static int __bt_hdp_internal_add_filter(void) -{ - DBusError dbus_error; - BT_DBG("+"); - /*Single process only one signal registration is required */ - if (g_hdp_dus_conn) { - BT_ERR("g_hdp_dus_conn already exist"); - goto done; - } - - /* Add the filter for HDP client functions */ - dbus_error_init(&dbus_error); - - g_hdp_dus_conn = _bt_get_system_conn(); - retv_if(g_hdp_dus_conn == NULL, BLUETOOTH_ERROR_INTERNAL); + ret_if(NULL == info); - dbus_connection_add_filter(g_hdp_dus_conn, - __bt_hdp_internal_event_filter, NULL, NULL); - - dbus_bus_add_match(g_hdp_dus_conn, - "type='signal',interface=" BLUEZ_HDP_DEVICE_INTERFACE, - &dbus_error); - - if (dbus_error_is_set(&dbus_error)) { - BT_ERR("Fail to add dbus filter signal\n"); - dbus_error_free(&dbus_error); - g_hdp_dus_conn = NULL; - return BLUETOOTH_ERROR_INTERNAL; - } - -done: - BT_DBG("-\n"); - return BLUETOOTH_ERROR_NONE; - -} - -static DBusHandlerResult __bt_hdp_internal_event_filter(DBusConnection *sys_conn, - DBusMessage *msg, void *data) -{ - const char *path = dbus_message_get_path(msg); - - if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - BT_DBG("Path = %s\n", path); - if (path == NULL || g_strcmp0(path, "/") == 0) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - if (dbus_message_is_signal(msg, BLUEZ_HDP_DEVICE_INTERFACE, - "ChannelConnected")) - __bt_hdp_internal_handle_connect(msg); - - else if (dbus_message_is_signal(msg, BLUEZ_HDP_DEVICE_INTERFACE, - "ChannelDeleted")) - __bt_hdp_internal_handle_disconnect(msg); - - else if (dbus_message_is_signal(msg, BLUEZ_HDP_DEVICE_INTERFACE, - "PropertyChanged")) - __bt_hdp_internal_handle_property_changed(msg); - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static void __bt_hdp_internal_handle_connect(DBusMessage *msg) -{ - const char *path = dbus_message_get_path(msg); - const char *obj_channel_path; - bt_user_info_t *user_info; - bt_hdp_connected_t conn_ind; - int ret; - - BT_DBG("+********Signal - ChannelConnected******\n\n"); - BT_DBG("Path = %s", path); - - if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, - &obj_channel_path, DBUS_TYPE_INVALID)) { - BT_ERR("Unexpected parameters in ChannelConnected signal"); - return; - } - - BT_DBG("Channel connected, Path = %s", obj_channel_path); - - ret = __bt_hdp_internal_acquire_fd(obj_channel_path); - if (ret != BLUETOOTH_ERROR_NONE) { - user_info = _bt_get_user_data(BT_COMMON); - if (user_info) { - _bt_common_event_cb(BLUETOOTH_EVENT_HDP_CONNECTED, - BLUETOOTH_ERROR_CONNECTION_ERROR, &conn_ind, - user_info->cb, user_info->user_data); - } - } + g_source_remove(info->watch_id); + close(info->fd); + g_free(info); BT_DBG("-"); } -static void __bt_hdp_internal_handle_disconnect(DBusMessage *msg) -{ - const char *path = dbus_message_get_path(msg); - const char *obj_channel_path; - char address[BT_ADDRESS_STRING_SIZE] = { 0, }; - bluetooth_device_address_t device_addr = { {0} }; - bt_hdp_disconnected_t dis_ind; - hdp_obj_info_t *info; - bt_user_info_t *user_info; - - BT_DBG("+********Signal - ChannelDeleted ******\n\n"); - BT_DBG("Path = %s", path); - - if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, - &obj_channel_path, DBUS_TYPE_INVALID)) { - BT_ERR("Unexpected parameters in ChannelDeleted signal"); - return; - } - - BT_DBG("Channel Deleted, Path = %s", obj_channel_path); - - info = __bt_hdp_internal_gslist_obj_find_using_path(obj_channel_path); - if (!info) { - BT_ERR("No obj info for ob_channel_path [%s]\n", obj_channel_path); - return; - } - - /*Since bluetoothd is not sending the ChannelDeleted signal */ - _bt_device_path_to_address(path, address); - - _bt_convert_addr_string_to_type(device_addr.addr, address); - - dis_ind.channel_id = info->fd; - dis_ind.device_address = device_addr; - - user_info = _bt_get_user_data(BT_COMMON); - - if (user_info) { - _bt_common_event_cb(BLUETOOTH_EVENT_HDP_DISCONNECTED, - BLUETOOTH_ERROR_NONE, &dis_ind, - user_info->cb, user_info->user_data); - } - - BT_DBG(" Removed connection from list\n"); - - __bt_hdp_obj_info_free(info); - -} - -static void __bt_hdp_internal_handle_property_changed(DBusMessage *msg) -{ - const char *path = dbus_message_get_path(msg); - DBusMessageIter item_iter; - DBusMessageIter value_iter; - const char *property; - const char *obj_main_channel_path; - - BT_DBG("+*******Signal - PropertyChanged*******\n"); - BT_DBG("Path = %s", path); - - dbus_message_iter_init(msg, &item_iter); - - if (dbus_message_iter_get_arg_type(&item_iter) != DBUS_TYPE_STRING) { - BT_DBG("This is bad format dbus"); - return; - } - - dbus_message_iter_get_basic(&item_iter, &property); - - ret_if(property == NULL); - - BT_DBG("Property (%s)\n", property); - - if (0 == g_strcmp0(property, "MainChannel")) { - BT_DBG("Property MainChannel received"); - - dbus_message_iter_next(&item_iter); - - dbus_message_iter_recurse(&item_iter, &value_iter); - - dbus_message_iter_get_basic(&value_iter, - &obj_main_channel_path); - BT_DBG("Path = %s", path); - - BT_DBG("Main Channel Path = %s", obj_main_channel_path); - } - BT_DBG("-*************\n"); -} - -static int __bt_hdp_internal_acquire_fd(const char *path) -{ - char address[BT_ADDRESS_STRING_SIZE] = { 0, }; - bluetooth_device_address_t device_addr = { {0} }; - DBusMessageIter reply_iter; - DBusMessageIter reply_iter_entry; - const char *property; - char *type_qos = NULL; - char *device = NULL;; - char *app_handle = NULL;; - hdp_app_list_t *list = NULL;; - DBusMessage *msg; - DBusMessage *reply; - DBusConnection *conn; - bt_hdp_connected_t conn_ind; - DBusError err; - int fd; - bt_user_info_t *user_info; - - BT_DBG("+"); - - conn = _bt_get_system_conn(); - retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); - - msg = dbus_message_new_method_call(BT_BLUEZ_NAME, path, - BLUEZ_HDP_CHANNEL_INTERFACE, - "Acquire"); - - retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL); - - dbus_error_init(&err); - - reply = dbus_connection_send_with_reply_and_block(conn, msg, - -1, &err); - - dbus_message_unref(msg); - - if (!reply) { - BT_ERR(" HDP:****** dbus Can't create application ****"); - - if (dbus_error_is_set(&err)) { - BT_ERR("%s", err.message); - dbus_error_free(&err); - } - - return BLUETOOTH_ERROR_INTERNAL; - } - - if (!dbus_message_get_args(reply, &err, DBUS_TYPE_UNIX_FD, &fd, - DBUS_TYPE_INVALID)) { - BT_ERR(" HDP:dbus Can't get reply arguments"); - - if (dbus_error_is_set(&err)) { - BT_ERR("%s", err.message); - dbus_error_free(&err); - } - goto error; - } - - dbus_message_unref(reply); - - BT_DBG("File Descriptor = %d, Dev_path = %s \n", fd, path); - - msg = dbus_message_new_method_call(BT_BLUEZ_NAME, path, - BLUEZ_HDP_CHANNEL_INTERFACE, "GetProperties"); - - retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL); - - dbus_error_init(&err); - - reply = dbus_connection_send_with_reply_and_block(conn, msg, - -1, &err); - - dbus_message_unref(msg); - - if (!reply) { - BT_ERR(" HDP:dbus Can't get the reply"); - - if (dbus_error_is_set(&err)) { - BT_ERR("%s", err.message); - dbus_error_free(&err); - } - - return BLUETOOTH_ERROR_INTERNAL; - } - dbus_message_iter_init(reply, &reply_iter); - - if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) { - BT_ERR("Can't get reply arguments - DBUS_TYPE_ARRAY\n"); - goto error; - } - - dbus_message_iter_recurse(&reply_iter, &reply_iter_entry); - - /*Parse the dict */ - while (dbus_message_iter_get_arg_type(&reply_iter_entry) == - DBUS_TYPE_DICT_ENTRY) { - DBusMessageIter dict_entry, dict_entry_val; - dbus_message_iter_recurse(&reply_iter_entry, &dict_entry); - dbus_message_iter_get_basic(&dict_entry, &property); - BT_DBG("String received = %s\n", property); - - if (g_strcmp0("Type", property) == 0) { - dbus_message_iter_next(&dict_entry); - dbus_message_iter_recurse(&dict_entry, &dict_entry_val); - if (dbus_message_iter_get_arg_type(&dict_entry_val) != - DBUS_TYPE_STRING) - continue; - - dbus_message_iter_get_basic(&dict_entry_val, &type_qos); - - } else if (g_strcmp0("Device", property) == 0) { - dbus_message_iter_next(&dict_entry); - dbus_message_iter_recurse(&dict_entry, &dict_entry_val); - if (dbus_message_iter_get_arg_type(&dict_entry_val) != - DBUS_TYPE_OBJECT_PATH) - continue; - - dbus_message_iter_get_basic(&dict_entry_val, &device); - - } else if (g_strcmp0("Application", property) == 0) { - dbus_message_iter_next(&dict_entry); - dbus_message_iter_recurse(&dict_entry, &dict_entry_val); - if (dbus_message_iter_get_arg_type(&dict_entry_val) != - DBUS_TYPE_OBJECT_PATH) - continue; - - dbus_message_iter_get_basic(&dict_entry_val, - &app_handle); - } - dbus_message_iter_next(&reply_iter_entry); - } - - BT_DBG("QOS = %s, Device = %s, Apphandler = %s", - type_qos, device, app_handle); - - if (NULL == type_qos || NULL == app_handle) { - BT_ERR("Pasing failed\n"); - goto error; - } - - list = __bt_hdp_internal_gslist_find_app_handler((void *)app_handle); - - /*Only process register with app handle receive the Connected event */ - if (NULL == list) { - BT_DBG("**** Could not locate the list for %s*****\n", app_handle); - goto error; - } - - hdp_obj_info_t *info = g_new0(hdp_obj_info_t, 1); - info->fd = fd; - info->obj_channel_path = g_strdup(path); - list->obj_info = g_slist_append(list->obj_info, info); - - __bt_hdp_internal_watch_fd(fd, info->obj_channel_path); - - _bt_device_path_to_address(path, address); - - _bt_convert_addr_string_to_type(device_addr.addr, address); - - conn_ind.app_handle = app_handle; - conn_ind.channel_id = fd; - conn_ind.device_address = device_addr; - conn_ind.type = (g_strcmp0(type_qos, "Reliable") == 0) ? - HDP_QOS_RELIABLE : HDP_QOS_STREAMING; - - BT_DBG("Going to give callback\n"); - - user_info = _bt_get_user_data(BT_COMMON); - - if (user_info) { - _bt_common_event_cb(BLUETOOTH_EVENT_HDP_CONNECTED, - BLUETOOTH_ERROR_NONE, &conn_ind, - user_info->cb, user_info->user_data); - } - - dbus_message_unref(reply); - - BT_DBG("Updated fd in the list*\n"); - BT_DBG("-\n"); - - return BLUETOOTH_ERROR_NONE; - error: - dbus_message_unref(reply); - return BLUETOOTH_ERROR_INTERNAL; -} - -static void __bt_hdp_internal_watch_fd(int file_desc, const char *path) -{ - GIOChannel *gio; - - BT_DBG("+"); - - gio = g_io_channel_unix_new(file_desc); - - g_io_channel_set_close_on_unref(gio, TRUE); - - g_io_add_watch(gio, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, - __bt_hdp_internal_data_received, (void *)path); - BT_DBG("-"); -} - - -static void __bt_hdp_internal_handle_disconnect_cb(int sk, const char *path) -{ - char address[BT_ADDRESS_STRING_SIZE] = { 0, }; - bluetooth_device_address_t device_addr = { {0} }; - bt_hdp_disconnected_t dis_ind; - hdp_obj_info_t *info; - bt_user_info_t *user_info; - - BT_DBG("******** Socket Error ******\n"); - - info = __bt_hdp_internal_gslist_obj_find_using_path(path); - ret_if(info == NULL); - - /*Since bluetoothd is not sending the ChannelDeleted signal */ - _bt_device_path_to_address(path, address); - - _bt_convert_addr_string_to_type(device_addr.addr, address); - - dis_ind.channel_id = sk; - dis_ind.device_address = device_addr; - - user_info = _bt_get_user_data(BT_COMMON); - - if (user_info) { - _bt_common_event_cb(BLUETOOTH_EVENT_HDP_DISCONNECTED, - BLUETOOTH_ERROR_NONE, &dis_ind, - user_info->cb, user_info->user_data); - } - - BT_DBG(" Removed connection from list\n"); - - __bt_hdp_obj_info_free(info); -} - -static gboolean __bt_hdp_internal_data_received(GIOChannel *gio, - GIOCondition cond, gpointer data) -{ - char buff[HDP_BUFFER_SIZE] = { 0, }; - int sk; - int act_read; - bt_hdp_data_ind_t data_ind = { 0, }; - const char *path = (const char *)data; - bt_user_info_t *user_info; - - BT_DBG("+"); - - sk = g_io_channel_unix_get_fd(gio); - - if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) { - BT_DBG("GIOCondition %d.............path = %s\n", cond, path); - __bt_hdp_internal_handle_disconnect_cb(sk, path); - return FALSE; - } - - act_read = recv(sk, (void *)buff, sizeof(buff), 0); - - if (act_read > 0) { - BT_DBG("Received data of %d\n", act_read); - } else { - BT_DBG("Read failed.....\n"); - return FALSE; - } - - data_ind.channel_id = sk; - data_ind.buffer = buff; - data_ind.size = act_read; - - user_info = _bt_get_user_data(BT_COMMON); - - if (user_info) { - _bt_common_event_cb(BLUETOOTH_EVENT_HDP_DATA_RECEIVED, - BLUETOOTH_ERROR_NONE, &data_ind, - user_info->cb, user_info->user_data); - } - - BT_DBG("-\n"); - - return TRUE; -} - -BT_EXPORT_API int bluetooth_hdp_deactivate(const char *app_handle) -{ - BT_DBG("+"); - - BT_CHECK_ENABLED(); - BT_CHECK_PARAMETER(app_handle); - - return __bt_hdp_internal_destroy_application(app_handle); -} - static hdp_app_list_t *__bt_hdp_internal_gslist_find_app_handler(void *app_handle) { GSList *l; @@ -762,10 +84,11 @@ static hdp_app_list_t *__bt_hdp_internal_gslist_find_app_handler(void *app_handl return list; } } + return NULL; } -static hdp_obj_info_t *__bt_hdp_internal_gslist_obj_find_using_fd(int fd) +static hdp_obj_info_t *__bt_hdp_internal_gslist_obj_find_using_ch_id(unsigned int channel_id) { GSList *l; GSList *iter; @@ -784,397 +107,419 @@ static hdp_obj_info_t *__bt_hdp_internal_gslist_obj_find_using_fd(int fd) if (!info) return NULL; - if (fd == info->fd) + if (channel_id == info->channel_id) return info; } } + return NULL; } -static hdp_obj_info_t *__bt_hdp_internal_gslist_obj_find_using_path(const char *obj_channel_path) +static hdp_obj_info_t *__bt_hdp_internal_gslist_obj_find_using_fd(unsigned int sock_fd) { GSList *l; GSList *iter; - hdp_obj_info_t *info = NULL; retv_if(g_app_list == NULL, NULL); BT_DBG("List length = %d\n", g_slist_length(g_app_list)); + for (l = g_app_list; l != NULL; l = l->next) { hdp_app_list_t *list = l->data; if (!list) return NULL; for (iter = list->obj_info; iter != NULL; iter = iter->next) { - info = iter->data; + hdp_obj_info_t *info = iter->data; if (!info) return NULL; - if (0 == g_strcmp0(info->obj_channel_path, obj_channel_path)) { - list->obj_info = g_slist_remove(list->obj_info, info); + if ((int)sock_fd == info->fd) return info; - } } } + return NULL; } -static gboolean __bt_hdp_internal_destroy_application_cb(gpointer data) +static gboolean __bt_hdp_internal_data_received(GIOChannel *gio, + GIOCondition cond, gpointer data) { - const char *app_handle; - hdp_app_list_t *list = NULL; - app_handle = (const char *)data; + int fd; + gsize len = 0; + bt_user_info_t *user_info; + char buff[HDP_BUFFER_SIZE] = { 0, }; + GError *err = NULL; + GIOStatus status = G_IO_STATUS_NORMAL; + bluetooth_device_address_t *address = data; + hdp_obj_info_t *info; BT_DBG("+"); - list = __bt_hdp_internal_gslist_find_app_handler((void *)app_handle); - if (NULL == list) { - BT_DBG("**** list not found for %s ******\n", app_handle); + fd = g_io_channel_unix_get_fd(gio); + BT_DBG("fd: %d", fd); + + info = __bt_hdp_internal_gslist_obj_find_using_fd(fd); + if (!info) { + BT_INFO("No obj info found for fd: %d", fd); + g_free(address); return FALSE; } - g_app_list = g_slist_remove(g_app_list, list); - - g_free(list->app_handle); - g_slist_foreach(list->obj_info, (GFunc)__bt_hdp_obj_info_free, NULL); - g_free(list); + if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) { + bt_hdp_disconnected_t disconn_info; + hdp_app_list_t *list; - BT_DBG("List length = %d\n", g_slist_length(g_app_list)); + BT_DBG("GIOCondition %d", cond); + disconn_info.channel_id = info->channel_id; + memcpy(&disconn_info.device_address, address, sizeof(bluetooth_device_address_t)); - if (0 == g_slist_length(g_app_list)) - __bt_hdp_internal_remove_filter(); - BT_DBG("-"); - return FALSE; -} + list = __bt_hdp_internal_gslist_find_app_handler(info->app_handle); + if (list) { + list->obj_info = g_slist_remove(list->obj_info, info); + __bt_hdp_obj_info_free(info); + } -static int __bt_hdp_internal_destroy_application(const char *app_handle) -{ - DBusMessage *msg; - DBusMessage *reply; - DBusError err; - DBusConnection *conn; + user_info = _bt_get_user_data(BT_COMMON); + _bt_common_event_cb(BLUETOOTH_EVENT_HDP_DISCONNECTED, + BLUETOOTH_ERROR_NONE, &disconn_info, + user_info->cb, user_info->user_data); + g_free(address); + return FALSE; + } - conn = _bt_get_system_conn(); - retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); + status = g_io_channel_read_chars(gio, buff, HDP_BUFFER_SIZE, &len, &err); + if (status != G_IO_STATUS_NORMAL) { + BT_ERR("IO Channel read is failed with %d", status); + if (err) { + BT_ERR("IO Channel read error [%s]", err->message); + g_error_free(err); + } + g_free(address); + return FALSE; + } - msg = dbus_message_new_method_call(BT_BLUEZ_NAME, "/org/bluez", - BLUEZ_HDP_MANAGER_INTERFACE, "DestroyApplication"); + BT_DBG("fd: %d, len: %zd, buffer: %s", fd, len, buff); - retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL); + user_info = _bt_get_user_data(BT_COMMON); + if (user_info->cb) { + bt_hdp_data_ind_t data_ind = { 0, }; - dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &app_handle, - DBUS_TYPE_INVALID); + data_ind.channel_id = info->channel_id; + data_ind.buffer = buff; + data_ind.size = len; + _bt_common_event_cb(BLUETOOTH_EVENT_HDP_DATA_RECEIVED, + BLUETOOTH_ERROR_NONE, &data_ind, + user_info->cb, user_info->user_data); + } - dbus_error_init(&err); + BT_DBG("-"); + return TRUE; +} - reply = dbus_connection_send_with_reply_and_block(conn, msg, - -1, &err); - dbus_message_unref(msg); - if (!reply) { - BT_ERR(" HDP:dbus Can't Destroy application"); +static void __hdp_handle_new_connection(bt_hdp_connected_t *conn_info, int fd) +{ + hdp_obj_info_t *info; + hdp_app_list_t *list; + bluetooth_device_address_t *address; + GIOChannel *gio; - if (dbus_error_is_set(&err)) { - BT_ERR("%s", err.message); - dbus_error_free(&err); - } + BT_DBG("+"); - return BLUETOOTH_ERROR_INTERNAL; + list = __bt_hdp_internal_gslist_find_app_handler((void *)conn_info->app_handle); + if (NULL == list) { + BT_ERR("**** Could not locate the list for %s*****\n", conn_info->app_handle); + return; } - dbus_message_unref(reply); - - BT_DBG("Destroyed health application: %s", (char *)app_handle); + info = g_new0(hdp_obj_info_t, 1); + info->channel_id = conn_info->channel_id; + info->app_handle = list->app_handle; + info->fd = fd; + address = g_memdup(&(conn_info->device_address), sizeof(bluetooth_device_address_t)); - g_idle_add(__bt_hdp_internal_destroy_application_cb, - (gpointer)app_handle); + gio = g_io_channel_unix_new(fd); + g_io_channel_set_close_on_unref(gio, TRUE); + info->watch_id = g_io_add_watch(gio, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, + __bt_hdp_internal_data_received, (void *)address); + g_io_channel_unref(gio); + list->obj_info = g_slist_append(list->obj_info, info); - return BLUETOOTH_ERROR_NONE; + BT_DBG("-"); } -static void __bt_hdp_internal_remove_filter(void) +void _bt_hdp_app_remove_obj_info(unsigned int channel_id) { + hdp_app_list_t *list; + hdp_obj_info_t *info; + BT_DBG("+"); - ret_if(g_hdp_dus_conn == NULL); + info = __bt_hdp_internal_gslist_obj_find_using_ch_id(channel_id); + ret_if(NULL == info); - dbus_connection_remove_filter(g_hdp_dus_conn, - __bt_hdp_internal_event_filter, NULL); + list = __bt_hdp_internal_gslist_find_app_handler(info->app_handle); + ret_if(NULL == list); - g_hdp_dus_conn = NULL; /*should not unref here, bcz no ++reff */ + list->obj_info = g_slist_remove(list->obj_info, info); + BT_DBG("obj_info length = %d\n", g_slist_length(list->obj_info)); + __bt_hdp_obj_info_free(info); BT_DBG("-"); } -BT_EXPORT_API int bluetooth_hdp_send_data(unsigned int channel_id, - const char *buffer, - unsigned int size) +int _bt_hdp_app_acquire_fd(bt_hdp_connected_t *conn_info) { - int wbytes = 0; - int written = 0; + int result; + GUnixFDList *out_fd_list = NULL; - BT_DBG("+"); + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - BT_CHECK_ENABLED(); + g_array_append_vals(in_param1, &conn_info->channel_id, sizeof(int)); + result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_HDP_GET_FD, + in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list); - if ((channel_id == 0) || (NULL == buffer) || (size == 0)) { - BT_DBG("Invalid arguments..\n"); - return BLUETOOTH_ERROR_INVALID_PARAM; + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + BT_DBG("result: %x", result); + if (result != BLUETOOTH_ERROR_NONE || NULL == out_fd_list) { + BT_ERR("out_fd_list is NULL"); + bluetooth_hdp_disconnect(conn_info->channel_id, &conn_info->device_address); + return BLUETOOTH_ERROR_INTERNAL; } else { - while (wbytes < size) { - written = write(channel_id, buffer + wbytes, size - wbytes); - if (written <= 0) { - BT_DBG("write failed..\n"); - return BLUETOOTH_ERROR_NOT_IN_OPERATION; - } - wbytes += written; - } + int *fd_list_array; + int len = 0; + + fd_list_array = g_unix_fd_list_steal_fds(out_fd_list, &len); + BT_INFO("Num fds in fd_list is : %d, fd_list[0]: %d", len, fd_list_array[0]); + __hdp_handle_new_connection(conn_info, fd_list_array[0]); + g_free(fd_list_array); + g_object_unref(out_fd_list); } + BT_DBG("-"); return BLUETOOTH_ERROR_NONE; } - -static void __bt_hdp_connect_request_cb(DBusGProxy *hdp_proxy, DBusGProxyCall *call, - gpointer user_data) +/********************************************************************** +* Health device APIs (HDP) * +***********************************************************************/ +BT_EXPORT_API int bluetooth_hdp_activate(unsigned short data_type, + bt_hdp_role_type_t role, + bt_hdp_qos_type_t channel_type, + char **app_handle) { - GError *g_error = NULL; - char *obj_connect_path = NULL; - bt_hdp_connected_t *conn_ind = user_data; - bt_user_info_t *user_info; - - dbus_g_proxy_end_call(hdp_proxy, call, &g_error, - DBUS_TYPE_G_OBJECT_PATH, &obj_connect_path, G_TYPE_INVALID); - - g_object_unref(hdp_proxy); + int result = BLUETOOTH_ERROR_NONE; - if (g_error != NULL) { - BT_ERR("HDP connection Dbus Call Error: %s\n", g_error->message); - g_error_free(g_error); + BT_DBG("+"); - user_info = _bt_get_user_data(BT_COMMON); + BT_CHECK_ENABLED(return); - if (user_info) { - _bt_common_event_cb(BLUETOOTH_EVENT_HDP_CONNECTED, - BLUETOOTH_ERROR_CONNECTION_ERROR, conn_ind, - user_info->cb, user_info->user_data); - } - } else { - BT_DBG("Obj Path returned = %s\n", obj_connect_path); - g_free(obj_connect_path); + /*For source role is mandatory */ + if (role == HDP_ROLE_SOURCE && channel_type == HDP_QOS_ANY) { + BT_ERR("For source, type is mandatory - Reliable/Streaming"); + return BLUETOOTH_ERROR_INVALID_PARAM; } - g_free((void *)conn_ind->app_handle); - g_free(conn_ind); -} - -BT_EXPORT_API int bluetooth_hdp_connect(const char *app_handle, - bt_hdp_qos_type_t channel_type, - const bluetooth_device_address_t *device_address) -{ - GError *err = NULL; - DBusGConnection *conn = NULL; - DBusGProxy *hdp_proxy = NULL; - bt_hdp_connected_t *param; - char address[BT_ADDRESS_STRING_SIZE] = { 0 }; - char default_adapter_path[BT_ADAPTER_OBJECT_PATH_MAX + 1] = { 0 }; - char *dev_path = NULL; - char *role; + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - BT_DBG("+"); + g_array_append_vals(in_param1, &data_type, sizeof(short)); + g_array_append_vals(in_param2, &role, sizeof(bt_hdp_role_type_t)); + g_array_append_vals(in_param3, &channel_type, sizeof(bt_hdp_qos_type_t)); - BT_CHECK_ENABLED(); - BT_CHECK_PARAMETER(app_handle); - BT_CHECK_PARAMETER(device_address); + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_HDP_REGISTER_SINK_APP, + in_param1, in_param2, in_param3, in_param4, &out_param); - if (channel_type == HDP_QOS_RELIABLE) { - role = "Reliable"; - } else if (channel_type == HDP_QOS_STREAMING) { - role = "Streaming"; - } else if (channel_type == HDP_QOS_ANY) { - role = "Any"; - } else { - BT_ERR("Invalid channel_type %d", channel_type); - return BLUETOOTH_ERROR_ACCESS_DENIED; - } + if (result == BLUETOOTH_ERROR_NONE) { + char *buf; + hdp_app_list_t *list; - conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &err); + buf = &g_array_index(out_param, char, 0); + BT_DBG("Created app: %s", buf); - if (err != NULL) { - BT_DBG("ERROR: Can't get on system bus [%s]", err->message); - g_error_free(err); - return BLUETOOTH_ERROR_INTERNAL; + list = g_new0(hdp_app_list_t, 1); + list->app_handle = (void *)g_strdup(buf); + *app_handle = list->app_handle; + g_app_list = g_slist_append(g_app_list, list); } - /* If the adapter path is wrong, we can think the BT is not enabled. */ - if (_bt_get_adapter_path(conn, default_adapter_path) < 0) { - BT_ERR("Could not get adapter path\n"); - dbus_g_connection_unref(conn); - return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED; - } + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - _bt_convert_addr_type_to_string(address, - (unsigned char *)device_address->addr); + BT_DBG("-"); + return result; +} - BT_DBG("create conection to %s", address); +BT_EXPORT_API int bluetooth_hdp_deactivate(const char *app_handle) +{ + int result; + hdp_app_list_t *list; + + BT_DBG("+"); - dev_path = g_strdup_printf("%s/dev_%s", default_adapter_path, address); + BT_CHECK_ENABLED(return); + BT_CHECK_PARAMETER(app_handle, return); - if (dev_path == NULL) { - dbus_g_connection_unref(conn); - return BLUETOOTH_ERROR_MEMORY_ALLOCATION; + list = __bt_hdp_internal_gslist_find_app_handler((void *)app_handle); + if (NULL == list) { + BT_ERR("**** list not found for %s ******\n", app_handle); + return BLUETOOTH_ERROR_INVALID_PARAM; } - g_strdelimit(dev_path, ":", '_'); + BT_DBG("app_handle: %s", app_handle); - BT_DBG("path: %s", dev_path); + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - hdp_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME, dev_path, - BLUEZ_HDP_DEVICE_INTERFACE); - dbus_g_connection_unref(conn); + g_array_append_vals(in_param1, app_handle, (strlen(app_handle) + 1)); - if (hdp_proxy == NULL) { - BT_DBG("Failed to get the HDP server proxy\n"); - g_free(dev_path); - return BLUETOOTH_ERROR_NOT_PAIRED; + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_HDP_UNREGISTER_SINK_APP, + in_param1, in_param2, in_param3, in_param4, &out_param); + if (result == BLUETOOTH_ERROR_NONE) { + g_app_list = g_slist_remove(g_app_list, list); + g_free(list->app_handle); + g_slist_foreach(list->obj_info, (GFunc)__bt_hdp_obj_info_free, NULL); + g_free(list); } - BT_DBG("app path %s\n", app_handle); - - param = g_new0(bt_hdp_connected_t, 1); - param->app_handle = g_strdup(app_handle); - memcpy(¶m->device_address, device_address, BLUETOOTH_ADDRESS_LENGTH); - param->type = channel_type; - - if (!dbus_g_proxy_begin_call(hdp_proxy, "CreateChannel", - (DBusGProxyCallNotify) __bt_hdp_connect_request_cb, - param, /* user_data */ - NULL, /* destroy */ - DBUS_TYPE_G_OBJECT_PATH, app_handle, - G_TYPE_STRING, role, - G_TYPE_INVALID)) { - BT_ERR("HDP connection Dbus Call Error"); - g_free(dev_path); - g_free((void *)param->app_handle); - g_free(param); - g_object_unref(hdp_proxy); - return BLUETOOTH_ERROR_INTERNAL; - } + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - g_free(dev_path); - return BLUETOOTH_ERROR_NONE; + return result; } -static void __bt_hdp_disconnect_request_cb(DBusGProxy *hdp_proxy, DBusGProxyCall *call, - gpointer user_data) +BT_EXPORT_API int bluetooth_hdp_send_data(unsigned int channel_id, + const char *buffer, + unsigned int size) { - GError *g_error = NULL; - bt_hdp_disconnected_t *disconn_ind = user_data; - bt_user_info_t *user_info; + unsigned int wbytes = 0; + int written = 0; + hdp_obj_info_t *info; + int result; - dbus_g_proxy_end_call(hdp_proxy, call, &g_error, G_TYPE_INVALID); + BT_DBG("+"); - g_object_unref(hdp_proxy); + BT_CHECK_ENABLED(return); - if (g_error != NULL) { - BT_ERR("HDP disconnection Dbus Call Error: %s\n", g_error->message); - g_error_free(g_error); + retv_if(NULL == buffer, BLUETOOTH_ERROR_INVALID_PARAM); + retv_if(0 == size, BLUETOOTH_ERROR_INVALID_PARAM); - user_info = _bt_get_user_data(BT_COMMON); + info = __bt_hdp_internal_gslist_obj_find_using_ch_id(channel_id); + if (NULL == info) { + BT_ERR("*** Could not locate the info for %d*****", channel_id); + return BLUETOOTH_ERROR_INVALID_PARAM; + } + + switch (privilege_token) { + case 0: + result = _bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HDP_SEND_DATA); - if (user_info) { - _bt_common_event_cb(BLUETOOTH_EVENT_HDP_DISCONNECTED, - BLUETOOTH_ERROR_CONNECTION_ERROR, disconn_ind, - user_info->cb, user_info->user_data); + if (result == BLUETOOTH_ERROR_NONE) { + privilege_token = 1; /* Have a permission */ + } else if (result == BLUETOOTH_ERROR_PERMISSION_DEINED) { + BT_ERR("Don't have a privilege to use this API"); + privilege_token = -1; /* Don't have a permission */ + return BLUETOOTH_ERROR_PERMISSION_DEINED; + } else { + /* Just break - It is not related with permission error */ } - } else { - BT_DBG("HDP disconnection Dbus Call is done\n"); + break; + case 1: + /* Already have a privilege */ + break; + case -1: + return BLUETOOTH_ERROR_PERMISSION_DEINED; + default: + /* Invalid privilge token value */ + return BLUETOOTH_ERROR_INTERNAL; + } + + while (wbytes < size) { + written = write(info->fd, (buffer + wbytes), (size - wbytes)); + if (written <= 0) { + BT_ERR("write failed..\n"); + return BLUETOOTH_ERROR_NOT_IN_OPERATION; + } + wbytes += written; } - g_free(disconn_ind); + return BLUETOOTH_ERROR_NONE; } -BT_EXPORT_API int bluetooth_hdp_disconnect(unsigned int channel_id, +BT_EXPORT_API int bluetooth_hdp_connect(const char *app_handle, + bt_hdp_qos_type_t channel_type, const bluetooth_device_address_t *device_address) { - GError *err = NULL; - DBusGConnection *conn = NULL; - DBusGProxy *hdp_proxy = NULL; - char address[BT_ADDRESS_STRING_SIZE] = { 0 }; - char default_adapter_path[BT_ADAPTER_OBJECT_PATH_MAX + 1] = { 0 }; - char *dev_path = NULL; - bt_hdp_disconnected_t *param; + int result; + hdp_app_list_t *list; + bt_user_info_t *user_info; - BT_DBG("+\n"); + BT_CHECK_ENABLED(return); + BT_CHECK_PARAMETER(app_handle, return); + BT_CHECK_PARAMETER(device_address, return); - BT_CHECK_ENABLED(); - BT_CHECK_PARAMETER(device_address); + user_info = _bt_get_user_data(BT_COMMON); + retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL); - hdp_obj_info_t *info = __bt_hdp_internal_gslist_obj_find_using_fd(channel_id); - if (NULL == info) { - BT_ERR("*** Could not locate the list for %d*****\n", channel_id); + list = __bt_hdp_internal_gslist_find_app_handler((void *)app_handle); + if (NULL == list) { + BT_ERR("**** list not found for %s ******\n", app_handle); return BLUETOOTH_ERROR_INVALID_PARAM; } - conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &err); + BT_DBG("app_handle: %s", app_handle); - if (err != NULL) { - BT_ERR("ERROR: Can't get on system bus [%s]", err->message); - g_error_free(err); - return BLUETOOTH_ERROR_INTERNAL; - } + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - /* If the adapter path is wrong, we can think the BT is not enabled. */ - if (_bt_get_adapter_path(conn, default_adapter_path) < 0) { - BT_ERR("Could not get adapter path\n"); - dbus_g_connection_unref(conn); - return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED; - } + g_array_append_vals(in_param1, app_handle, (strlen(app_handle) + 1)); + g_array_append_vals(in_param2, &channel_type, sizeof(bt_hdp_qos_type_t)); + g_array_append_vals(in_param3, device_address, sizeof(bluetooth_device_address_t)); - _bt_convert_addr_type_to_string(address, - (unsigned char *)device_address->addr); + result = _bt_send_request_async(BT_BLUEZ_SERVICE, + BT_HDP_CONNECT, in_param1, in_param2, in_param3, in_param4, + user_info->cb, user_info->user_data); - BT_DBG("create conection to %s\n", address); + if (result != BLUETOOTH_ERROR_NONE) + BT_ERR("BT_HDP_CONNECT failed"); - dev_path = g_strdup_printf("%s/dev_%s", default_adapter_path, address); + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - if (dev_path == NULL) { - dbus_g_connection_unref(conn); - return BLUETOOTH_ERROR_MEMORY_ALLOCATION; - } - - g_strdelimit(dev_path, ":", '_'); + return result; +} - BT_DBG("path %s\n", dev_path); +BT_EXPORT_API int bluetooth_hdp_disconnect(unsigned int channel_id, + const bluetooth_device_address_t *device_address) +{ + int result; + hdp_obj_info_t *info; + bt_user_info_t *user_info; - hdp_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME, dev_path, - BLUEZ_HDP_DEVICE_INTERFACE); + BT_CHECK_ENABLED(return); + BT_CHECK_PARAMETER(device_address, return); - dbus_g_connection_unref(conn); + user_info = _bt_get_user_data(BT_COMMON); + retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL); - if (hdp_proxy == NULL) { - BT_ERR("Failed to get the HDP proxy\n"); - g_free(dev_path); - return BLUETOOTH_ERROR_NOT_PAIRED; + BT_DBG("channel_id: %d", channel_id); + info = __bt_hdp_internal_gslist_obj_find_using_ch_id(channel_id); + if (NULL == info) { + BT_ERR("*** Could not locate the info for %d*****", channel_id); + return BLUETOOTH_ERROR_INVALID_PARAM; } - param = g_new0(bt_hdp_disconnected_t, 1); - param->channel_id = channel_id; - memcpy(¶m->device_address, device_address, BLUETOOTH_ADDRESS_LENGTH); - - if (!dbus_g_proxy_begin_call(hdp_proxy, "DestroyChannel", - (DBusGProxyCallNotify) __bt_hdp_disconnect_request_cb, - param, /* user_data */ - NULL, /* destroy */ - DBUS_TYPE_G_OBJECT_PATH, info->obj_channel_path, - G_TYPE_INVALID)) { - BT_ERR("HDP connection Dbus Call Error"); - g_free(dev_path); - g_free(param); - g_object_unref(hdp_proxy); - return BLUETOOTH_ERROR_INTERNAL; - } + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); - g_free(dev_path); + g_array_append_vals(in_param1, &channel_id, sizeof(int)); + g_array_append_vals(in_param2, device_address, sizeof(bluetooth_device_address_t)); - return BLUETOOTH_ERROR_NONE; + result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_HDP_DISCONNECT, + in_param1, in_param2, in_param3, in_param4, + user_info->cb, user_info->user_data); + if (result != BLUETOOTH_ERROR_NONE) + BT_ERR("BT_HDP_DISCONNECT failed"); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + return result; }