4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * Girishashok Joshi <girish.joshi@samsung.com>
8 * Chanyeol Park <chanyeol.park@samsung.com>
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
14 * http://www.apache.org/licenses/LICENSE-2.0
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.
24 #include <dbus/dbus-glib.h>
25 #include <dbus/dbus.h>
29 #include <syspopup_caller.h>
31 #include "bluetooth-api.h"
32 #include "bt-internal-types.h"
34 #include "bt-service-audio.h"
35 #include "bt-service-adapter.h"
36 #include "bt-service-common.h"
37 #include "bt-service-device.h"
38 #include "bt-service-event.h"
39 #include "bt-service-util.h"
41 #include "bt-service-headset-connection.h"
43 #ifdef TIZEN_SUPPORT_DUAL_HF
45 #define VCONF_KEY_BT_HOST_BT_MAC_ADDR "db/wms/host_bt_mac"
52 char device_address[BT_ADDRESS_STRING_SIZE + 1];
53 } bt_connected_headset_data_t;
55 static GList *g_connected_list;
57 static bt_headset_wait_t *g_wait_data;
59 static bt_audio_function_data_t *pdata;
61 static void __bt_remove_device_from_wait_list();
63 static void __bt_free_wait_data();
65 static gboolean __bt_device_support_uuid(char *remote_address,
66 bt_audio_type_t type);
68 static void __bt_hf_request_cb(DBusGProxy *proxy, DBusGProxyCall *call,
71 GError *g_error = NULL;
72 GArray *out_param1 = NULL;
73 GArray *out_param2 = NULL;
74 int result = BLUETOOTH_ERROR_NONE;
75 bt_function_data_t *func_data;
76 request_info_t *req_info;
78 dbus_g_proxy_end_call(proxy, call, &g_error, G_TYPE_INVALID);
80 g_object_unref(proxy);
82 func_data = user_data;
84 if (func_data == NULL) {
86 BT_ERR("func_data == NULL");
90 req_info = _bt_get_request_info(func_data->req_id);
91 if (req_info == NULL) {
92 BT_ERR("req_info == NULL");
99 BT_ERR("HFG request Dbus Call Error: %s\n", g_error->message);
101 result = BLUETOOTH_ERROR_INTERNAL;
104 if (req_info->context == NULL)
107 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
108 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
110 g_array_append_vals(out_param1, func_data->address,
112 g_array_append_vals(out_param2, &result, sizeof(int));
114 dbus_g_method_return(req_info->context, out_param1, out_param2);
116 g_array_free(out_param1, TRUE);
117 g_array_free(out_param2, TRUE);
119 _bt_delete_request_list(req_info->req_id);
122 g_error_free(g_error);
125 g_free(func_data->address);
130 void _bt_audio_check_pending_connect()
133 bluetooth_device_address_t device_address;
138 if (pdata->pending == BT_PENDING_CONNECT) {
140 _bt_convert_addr_string_to_type(device_address.addr,
143 _bt_audio_connect(pdata->req_id,
148 g_free(pdata->address);
157 static void __bt_audio_request_cb(DBusGProxy *proxy, DBusGProxyCall *call,
160 GError *g_error = NULL;
161 GArray *out_param1 = NULL;
162 GArray *out_param2 = NULL;
163 int result = BLUETOOTH_ERROR_NONE;
165 bt_audio_function_data_t *func_data;
167 request_info_t *req_info;
169 dbus_g_proxy_end_call(proxy, call, &g_error, G_TYPE_INVALID);
171 g_object_unref(proxy);
173 func_data = user_data;
175 if (func_data == NULL) {
177 BT_ERR("func_data == NULL");
181 if (func_data->pending != BT_PENDING_NONE && g_error == NULL) {
183 bluetooth_device_address_t device_address;
184 _bt_convert_addr_string_to_type(device_address.addr,
187 if (func_data->pending == BT_PENDING_CONNECT) {
189 if (__bt_device_support_uuid(func_data->address,
192 pdata = g_new0(bt_audio_function_data_t, 1);
193 pdata->req_id = func_data->req_id;
194 pdata->out_param = func_data->out_param;
195 pdata->address = strdup(func_data->address);
196 pdata->pending = func_data->pending;
202 if (_bt_is_service_connected(func_data->address
204 _bt_audio_disconnect(func_data->req_id,
207 func_data->out_param);
216 req_info = _bt_get_request_info(func_data->req_id);
217 if (req_info == NULL) {
218 BT_ERR("req_info == NULL");
225 BT_ERR("Audio Connect/Disconnect Dbus Call Error: %s\n", g_error->message);
227 result = BLUETOOTH_ERROR_INTERNAL;
229 /* Remove the device from the list */
230 _bt_remove_headset_from_list(func_data->type, func_data->address);
232 /* Error, check if any waiting device is there */
233 if (g_wait_data == NULL)
236 if (g_strcmp0(g_wait_data->address, func_data->address) != 0) {
237 bluetooth_device_address_t device_address;
238 _bt_convert_addr_string_to_type(device_address.addr,
239 g_wait_data->address);
240 _bt_audio_connect(g_wait_data->req_id, g_wait_data->type,
241 &device_address, g_wait_data->out_param1);
244 /* Event will be sent by the event reciever */
246 if (req_info->context == NULL) {
247 BT_DBG("req_info->context is NULL");
251 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
252 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
254 g_array_append_vals(out_param1, func_data->address,
256 g_array_append_vals(out_param2, &result, sizeof(int));
258 dbus_g_method_return(req_info->context, out_param1, out_param2);
260 g_array_free(out_param1, TRUE);
261 g_array_free(out_param2, TRUE);
263 _bt_delete_request_list(req_info->req_id);
266 g_error_free(g_error);
269 g_free(func_data->address);
274 static char *__bt_get_audio_path(bluetooth_device_address_t *address)
277 char *object_path = NULL;
278 char addr_str[BT_ADDRESS_STRING_SIZE + 1] = { 0 };
279 DBusGProxy *audio_proxy;
280 DBusGProxy *adapter_proxy;
281 DBusGConnection *g_conn;
282 GError *error = NULL;
284 retv_if(address == NULL, NULL);
286 g_conn = _bt_get_system_gconn();
287 retv_if(g_conn == NULL, NULL);
289 adapter_proxy = _bt_get_adapter_proxy();
290 retv_if(adapter_proxy == NULL, NULL);
292 _bt_convert_addr_type_to_string(addr_str, address->addr);
294 dbus_g_proxy_call(adapter_proxy, "FindDevice",
295 &error, G_TYPE_STRING, addr_str,
296 G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH,
297 &object_path, G_TYPE_INVALID);
300 BT_ERR("Failed to Find device: %s\n", error->message);
305 retv_if(object_path == NULL, NULL);
307 audio_proxy = dbus_g_proxy_new_for_name(g_conn,
310 BT_HEADSET_INTERFACE);
312 retv_if(audio_proxy == NULL, NULL);
314 g_object_unref(audio_proxy);
319 static char *__bt_get_connected_audio_path(void)
323 char *audio_path = NULL;
325 bluetooth_device_info_t info;
327 /* allocate the g_pointer_array */
328 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
330 if (_bt_get_bonded_devices(&device_list)
331 != BLUETOOTH_ERROR_NONE) {
332 g_array_free(device_list, TRUE);
336 size = device_list->len;
337 size = (device_list->len) / sizeof(bluetooth_device_info_t);
339 for (i = 0; i < size; i++) {
341 info = g_array_index(device_list,
342 bluetooth_device_info_t, i);
344 if (info.connected == TRUE) {
345 audio_path = __bt_get_audio_path(&info.device_address);
351 g_array_free(device_list, TRUE);
356 static void __bt_free_wait_data()
358 if (g_wait_data != NULL) {
359 g_free(g_wait_data->address);
365 static void __bt_remove_device_from_wait_list()
367 /* Before deleting the request update the UI */
368 GArray *out_param_1 = NULL;
369 GArray *out_param_2 = NULL;
370 int result = BLUETOOTH_ERROR_INTERNAL;
371 request_info_t *req_info;
373 req_info = _bt_get_request_info(g_wait_data->req_id);
374 if (req_info == NULL) {
375 BT_ERR("req_info == NULL");
379 out_param_1 = g_array_new(FALSE, FALSE, sizeof(gchar));
380 out_param_2 = g_array_new(FALSE, FALSE, sizeof(gchar));
381 g_array_append_vals(out_param_1, g_wait_data->address,
383 g_array_append_vals(out_param_2, &result, sizeof(int));
384 dbus_g_method_return(req_info->context,
385 out_param_1, out_param_2);
386 g_array_free(out_param_1, TRUE);
387 g_array_free(out_param_2, TRUE);
388 _bt_delete_request_list(g_wait_data->req_id);
391 static void __bt_set_headset_disconnection_type(const char *address)
393 bt_connected_headset_data_t *connected_device;
396 node = g_list_first(g_connected_list);
397 while (node != NULL) {
398 connected_device = node->data;
399 if (g_strcmp0(connected_device->device_address, address) == 0) {
400 g_wait_data->disconnection_type = connected_device->type;
403 node = g_list_next(node);
407 gboolean _bt_is_headset_type_connected(int type, char *address)
411 node = g_list_first(g_connected_list);
412 while (node != NULL) {
413 bt_connected_headset_data_t *connected_device = node->data;
415 if (connected_device->type & type) {
417 g_strlcpy(address, connected_device->device_address,
418 BT_ADDRESS_STRING_SIZE + 1);
422 node = g_list_next(node);
427 #ifdef TIZEN_SUPPORT_DUAL_HF
428 gboolean __bt_is_companion_device(const char *addr)
430 #ifdef TIZEN_WEARABLE
431 char *host_device_address = NULL;
432 host_device_address = vconf_get_str(VCONF_KEY_BT_HOST_BT_MAC_ADDR);
434 if (!host_device_address) {
435 BT_INFO("Failed to get a companion device address");
439 if (g_strcmp0(host_device_address, addr) == 0) {
440 BT_INFO("addr[%s] is companion device", addr);
446 /* TODO : Need to add companion device check condition for Phone models */
452 static int __bt_is_headset_connected(int type, int req_id,
453 const char *address, GArray **out_param1)
455 gboolean connected = FALSE;
456 char connected_address[BT_ADDRESS_STRING_SIZE + 1];
457 bluetooth_device_address_t device_address;
458 bt_connected_headset_data_t *connected_device = NULL;
459 #ifdef TIZEN_SUPPORT_DUAL_HF
460 gboolean is_companion_device = FALSE;
463 /* Check if any other headset is connected */
466 node = g_list_first(g_connected_list);
467 while (node != NULL) {
468 connected_device = node->data;
469 if ((connected_device->type & type) == type) {
470 g_strlcpy(connected_address, connected_device->device_address,
471 BT_ADDRESS_STRING_SIZE + 1);
472 #ifdef TIZEN_SUPPORT_DUAL_HF
473 is_companion_device = __bt_is_companion_device(connected_address);
474 BT_INFO(" is_companion_device[%d]", is_companion_device);
476 if (!is_companion_device) {
485 node = g_list_next(node);
489 return BLUETOOTH_ERROR_NOT_CONNECTED;
491 BT_DBG("connected headset %s", connected_address);
493 if (g_strcmp0(connected_address, address) == 0)
494 return BLUETOOTH_ERROR_ALREADY_CONNECT;
495 #ifdef TIZEN_SUPPORT_DUAL_HF
496 else if (TRUE == __bt_is_companion_device(address))
497 return BLUETOOTH_ERROR_NOT_CONNECTED;
500 /* If already one device is waiting, remove current waiting device and add new */
501 if (g_wait_data != NULL) {
502 if (g_strcmp0(g_wait_data->address, address) != 0) {
503 __bt_remove_device_from_wait_list();
504 __bt_free_wait_data();
508 if (g_wait_data == NULL) {
509 g_wait_data = g_malloc0(sizeof(bt_headset_wait_t));
510 g_wait_data->address = g_strdup(address);
511 g_wait_data->req_id = req_id;
512 g_wait_data->type = type;
513 g_wait_data->ag_flag = FALSE;
514 g_wait_data->out_param1 = out_param1;
516 /* Set disconnection type */
517 __bt_set_headset_disconnection_type(connected_address);
520 /* Convert BD adress from string type */
521 _bt_convert_addr_string_to_type(device_address.addr, connected_address);
522 _bt_audio_disconnect(0, connected_device->type & type, &device_address, NULL);
523 return BLUETOOTH_ERROR_NONE;
526 void _bt_set_audio_wait_data_flag(gboolean flag)
528 BT_DBG("_bt_set_audio_wait_data_flag \n");
529 g_wait_data->ag_flag = flag;
532 bt_headset_wait_t *_bt_get_audio_wait_data(void)
534 BT_DBG("_bt_get_audio_wait_data \n");
538 void _bt_rel_wait_data(void)
540 BT_DBG("_bt_rel_wait_data \n");
541 __bt_free_wait_data();
544 void _bt_add_headset_to_list(int type, int status, const char *address)
546 bt_connected_headset_data_t *connected_device;
547 bt_connected_headset_data_t *device;
550 BT_DBG("_bt_add_headset_to_list \n");
552 node = g_list_first(g_connected_list);
553 while (node != NULL) {
554 device = (bt_connected_headset_data_t *)node->data;
556 if (g_strcmp0(device->device_address, address) == 0) {
557 BT_DBG("Address match, update connection type \n");
558 if (status == BT_STATE_CONNECTED)
559 device->type |= type;
560 device->device_state = status;
563 node = g_list_next(node);
566 connected_device = g_malloc0(sizeof(bt_connected_headset_data_t));
567 connected_device->device_state = status;
568 if (status == BT_STATE_CONNECTED)
569 connected_device->type |= type;
570 g_strlcpy(connected_device->device_address, address,
571 sizeof(connected_device->device_address));
572 g_connected_list = g_list_append(g_connected_list, connected_device);
575 int _bt_get_device_state_from_list(int type, const char *address)
578 bt_connected_headset_data_t *device;
581 node = g_list_first(g_connected_list);
582 while (node != NULL) {
583 device = (bt_connected_headset_data_t *)node->data;
584 if (g_strcmp0(device->device_address, address) == 0) {
585 BT_DBG("Device found");
586 return device->device_state;
588 node = g_list_next(node);
591 BT_DBG("Device not found");
592 return BLUETOOTH_ERROR_INTERNAL;
595 void _bt_remove_headset_from_list(int type, const char *address)
599 BT_DBG("_bt_remove_headset_from_list \n");
601 node = g_list_first(g_connected_list);
602 while (node != NULL) {
603 bt_connected_headset_data_t *connected_device = node->data;
605 if (g_strcmp0(connected_device->device_address, address) != 0) {
606 node = g_list_next(node);
610 BT_DBG("Address match \n");
612 BT_DBG("Connection type = %x\n", connected_device->type);
616 if (connected_device->type & BT_AUDIO_A2DP)
617 connected_device->type &= ~(BT_AUDIO_A2DP);
620 if (connected_device->type & BT_AUDIO_HSP)
621 connected_device->type &= ~(BT_AUDIO_HSP);
624 if (connected_device->type & BT_AUDIO_ALL)
625 connected_device->type &= ~(BT_AUDIO_ALL);
628 if (connected_device->type & BT_AVRCP)
629 connected_device->type &= ~(BT_AVRCP);
633 BT_DBG("Connection type = %x\n", connected_device->type);
635 if (connected_device->type == 0x00) {
636 g_connected_list = g_list_remove(g_connected_list, connected_device);
637 g_free(connected_device);
640 node = g_list_next(node);
644 static gboolean __bt_device_support_uuid(char *remote_address,
645 bt_audio_type_t type)
647 GArray *dev_list = NULL;
649 bluetooth_device_info_t info;
650 char bond_address[BT_ADDRESS_STRING_SIZE] = { 0 };
651 gboolean ret = FALSE;
655 dev_list = g_array_new (FALSE, FALSE, sizeof(gchar));
657 _bt_get_bonded_devices(&dev_list);
658 size = (dev_list->len) / sizeof(bluetooth_device_info_t);
660 for (i=0; i < size; i++) {
661 info = g_array_index(dev_list, bluetooth_device_info_t, i);
662 _bt_convert_addr_type_to_string(bond_address,
663 info.device_address.addr);
664 if (strcmp(bond_address, remote_address) != 0)
667 BT_INFO("Device address Matched");
669 while (j != info.service_index) {
670 if (type == BT_AUDIO_HSP) {
671 if (strcmp(info.uuids[j], HFP_HS_UUID) == 0) {
672 BT_INFO("HFP HS UUID exists");
676 } else if (type == BT_AUDIO_A2DP) {
677 if (strcmp(info.uuids[j], A2DP_SINK_UUID) == 0) {
678 BT_INFO("A2DP SINK UUID exists");
687 g_array_free(dev_list, TRUE);
692 gboolean _bt_is_service_connected(char* address, int type)
696 node = g_list_first(g_connected_list);
697 while (node != NULL) {
698 bt_connected_headset_data_t *conn_device = node->data;
700 if ((g_strcmp0(conn_device->device_address, address) == 0) &&
701 (conn_device->type & type)) {
702 BT_INFO("Service connected");
706 node = g_list_next(node);
708 BT_INFO("Service not connected");
712 int _bt_audio_connect(int request_id, int type,
713 bluetooth_device_address_t *device_address,
716 int result = BLUETOOTH_ERROR_NONE;
717 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
718 DBusGProxy *adapter_proxy;
719 DBusGConnection *g_conn;
722 int value = BLUETOOTH_ERROR_NONE;
723 bt_audio_function_data_t *func_data;
725 BT_CHECK_PARAMETER(device_address, return);
727 adapter_proxy = _bt_get_adapter_proxy();
728 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
730 g_conn = _bt_get_system_gconn();
731 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
733 _bt_convert_addr_type_to_string(address, device_address->addr);
735 func_data = g_malloc0(sizeof(bt_audio_function_data_t));
737 func_data->address = g_strdup(address);
738 func_data->req_id = request_id;
739 func_data->type = type;
740 func_data->pending = BT_PENDING_NONE;
741 func_data->out_param = out_param1;
748 uuid = A2DP_SINK_UUID;
751 uuid = AVRCP_TARGET_UUID;
754 if (__bt_device_support_uuid(address, BT_AUDIO_HSP)) {
756 func_data->pending = BT_PENDING_CONNECT;
757 } else if (__bt_device_support_uuid(address, BT_AUDIO_A2DP)) {
758 uuid = A2DP_SINK_UUID;
760 BT_ERR("No audio role supported");
761 result = BLUETOOTH_ERROR_SERVICE_NOT_FOUND;
766 BT_ERR("Unknown role");
767 result = BLUETOOTH_ERROR_INTERNAL;
770 BT_INFO("Connecting to service %s", uuid);
772 value = __bt_is_headset_connected(type, request_id, address, out_param1);
774 if (value == BLUETOOTH_ERROR_ALREADY_CONNECT) {
775 return BLUETOOTH_ERROR_ALREADY_CONNECT;
776 } else if (value == BLUETOOTH_ERROR_NOT_CONNECTED) {
777 _bt_headset_set_local_connection(TRUE);
778 ret = _bt_connect_profile(address, uuid,
779 __bt_audio_request_cb, func_data);
781 if (ret != BLUETOOTH_ERROR_NONE) {
782 BT_ERR("_bt_connect_profile Error");
783 _bt_headset_set_local_connection(FALSE);
784 g_free(func_data->address);
789 /* Add data to the connected list */
790 _bt_add_headset_to_list(type, BT_STATE_CONNECTING, address);
793 return BLUETOOTH_ERROR_NONE;
795 g_array_append_vals(*out_param1, address,
801 int _bt_audio_disconnect(int request_id, int type,
802 bluetooth_device_address_t *device_address,
805 int result = BLUETOOTH_ERROR_NONE;
806 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
807 bt_audio_function_data_t *func_data;
808 DBusGProxy *adapter_proxy;
809 DBusGConnection *g_conn;
814 BT_CHECK_PARAMETER(device_address, return);
816 adapter_proxy = _bt_get_adapter_proxy();
817 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
819 g_conn = _bt_get_system_gconn();
820 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
822 _bt_convert_addr_type_to_string(address, device_address->addr);
824 func_data = g_malloc0(sizeof(bt_audio_function_data_t));
826 func_data->address = g_strdup(address);
827 func_data->req_id = request_id;
828 func_data->pending = BT_PENDING_NONE;
829 func_data->out_param = out_param1;
830 func_data->type = type;
837 uuid = A2DP_SINK_UUID;
840 uuid = AVRCP_TARGET_UUID;
843 if (_bt_is_service_connected(address, BT_AUDIO_HSP)) {
845 func_data->pending = BT_PENDING_DISCONNECT;
846 } else if (_bt_is_service_connected(address, BT_AUDIO_A2DP)) {
847 uuid = A2DP_SINK_UUID;
849 BT_ERR("No audio service connected");
850 result = BLUETOOTH_ERROR_NOT_CONNECTED;
855 BT_ERR("Unknown role");
856 result = BLUETOOTH_ERROR_INTERNAL;
860 BT_INFO("Disconnecting service %s", uuid);
861 ret = _bt_disconnect_profile(address, uuid,
862 __bt_audio_request_cb, func_data);
864 if (ret != BLUETOOTH_ERROR_NONE) {
865 BT_ERR("_bt_disconnect_profile Error");
866 g_free(func_data->address);
872 * This logic is added for dual HF mode issue.
874 node = g_list_first(g_connected_list);
875 while (node != NULL) {
876 bt_connected_headset_data_t *connected_device = node->data;
878 if (g_strcmp0(connected_device->device_address, address) == 0) {
879 BT_DBG("Connection type update");
880 type = connected_device->type;
883 node = g_list_next(node);
885 _bt_add_headset_to_list(type, BT_STATE_DISCONNECTING, address);
887 return BLUETOOTH_ERROR_NONE;
889 if (out_param1 != NULL)
890 g_array_append_vals(*out_param1, address,
896 void _bt_remove_from_connected_list(const char *address)
898 bt_connected_headset_data_t *connected_device;
901 node = g_list_first(g_connected_list);
902 while (node != NULL) {
903 connected_device = node->data;
904 if (connected_device != NULL &&
905 g_strcmp0(connected_device->device_address, address) == 0) {
906 BT_ERR("Device is removed from the list");
907 g_connected_list = g_list_remove(g_connected_list, connected_device);
908 g_free(connected_device);
911 node = g_list_next(node);
915 int _bt_hf_connect(int request_id,
916 bluetooth_device_address_t *device_address,
919 int result = BLUETOOTH_ERROR_NONE;
920 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
921 bt_function_data_t *func_data;
922 DBusGProxy *adapter_proxy;
923 DBusGConnection *g_conn;
929 BT_CHECK_PARAMETER(device_address, return);
931 _bt_convert_addr_type_to_string(address, device_address->addr);
933 adapter_proxy = _bt_get_adapter_proxy();
934 if (adapter_proxy == NULL) {
935 result = BLUETOOTH_ERROR_INTERNAL;
939 g_conn = _bt_get_system_gconn();
940 if (g_conn == NULL) {
941 result = BLUETOOTH_ERROR_INTERNAL;
945 func_data = g_malloc0(sizeof(bt_function_data_t));
947 func_data->address = g_strdup(address);
948 func_data->req_id = request_id;
949 uuid = g_strdup(HFP_AG_UUID);
951 BT_DBG("Connecting to service %s", uuid);
953 ret = _bt_connect_profile(address, uuid,
954 __bt_hf_request_cb, func_data);
956 if (ret != BLUETOOTH_ERROR_NONE) {
957 BT_ERR("_bt_connect_profile Error");
958 g_free(func_data->address);
964 return BLUETOOTH_ERROR_NONE;
966 if (out_param1 != NULL)
967 g_array_append_vals(*out_param1, address,
973 int _bt_hf_disconnect(int request_id,
974 bluetooth_device_address_t *device_address,
977 int result = BLUETOOTH_ERROR_NONE;
978 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
979 bt_function_data_t *func_data;
980 DBusGProxy *adapter_proxy;
981 DBusGConnection *g_conn;
986 BT_CHECK_PARAMETER(device_address, return);
988 _bt_convert_addr_type_to_string(address, device_address->addr);
990 adapter_proxy = _bt_get_adapter_proxy();
991 if (adapter_proxy == NULL) {
992 result = BLUETOOTH_ERROR_INTERNAL;
996 g_conn = _bt_get_system_gconn();
997 if (g_conn == NULL) {
998 result = BLUETOOTH_ERROR_INTERNAL;
1002 func_data = g_malloc0(sizeof(bt_function_data_t));
1004 func_data->address = g_strdup(address);
1005 func_data->req_id = request_id;
1006 uuid = g_strdup(HFP_AG_UUID);
1008 BT_DBG("Disconnecting service %s", uuid);
1009 ret = _bt_disconnect_profile(address, uuid,
1010 __bt_hf_request_cb, func_data);
1012 if (ret != BLUETOOTH_ERROR_NONE) {
1013 BT_ERR("_bt_disconnect_profile Error");
1014 g_free(func_data->address);
1020 return BLUETOOTH_ERROR_NONE;
1022 if (out_param1 != NULL)
1023 g_array_append_vals(*out_param1, address,
1024 BT_ADDRESS_STR_LEN);
1029 int _bt_audio_get_speaker_gain(unsigned int *gain)
1031 char *device_path = NULL;
1032 DBusGProxy *adapter_proxy;
1033 DBusGProxy *profile_proxy;
1034 DBusGConnection *g_conn;
1035 GHashTable *hash = NULL;
1038 adapter_proxy = _bt_get_adapter_proxy();
1039 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1041 g_conn = _bt_get_system_gconn();
1042 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1044 device_path = __bt_get_connected_audio_path();
1045 retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
1047 profile_proxy = dbus_g_proxy_new_for_name(g_conn, BT_BLUEZ_NAME,
1048 device_path, BT_HEADSET_INTERFACE);
1050 g_free(device_path);
1052 retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1054 dbus_g_proxy_call(profile_proxy, "GetProperties", NULL,
1056 dbus_g_type_get_map("GHashTable",
1057 G_TYPE_STRING, G_TYPE_VALUE),
1058 &hash, G_TYPE_INVALID);
1060 g_object_unref(profile_proxy);
1062 retv_if(hash == NULL, BLUETOOTH_ERROR_INTERNAL);
1064 value = g_hash_table_lookup(hash, "SpeakerGain");
1065 *gain = value ? g_value_get_uint(value) : 0;
1066 g_hash_table_destroy(hash);
1067 return BLUETOOTH_ERROR_NONE;
1070 int _bt_audio_set_speaker_gain(unsigned int gain)
1072 char *device_path = NULL;
1073 char *gain_str = "SpeakerGain";
1074 char sig[2] = {DBUS_TYPE_UINT16, '\0'};
1075 int ret = BLUETOOTH_ERROR_NONE;
1077 DBusMessageIter iter;
1078 DBusMessageIter value;
1079 DBusConnection *conn;
1081 conn = _bt_get_system_conn();
1082 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1084 device_path = __bt_get_connected_audio_path();
1085 retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
1087 msg = dbus_message_new_method_call(BT_BLUEZ_NAME,
1088 device_path, BT_HEADSET_INTERFACE,
1091 g_free(device_path);
1093 retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
1095 dbus_message_iter_init_append(msg, &iter);
1096 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
1098 dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
1100 dbus_message_iter_append_basic(&value, DBUS_TYPE_UINT16,
1102 dbus_message_iter_close_container(&iter, &value);
1104 if (dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_METHOD_CALL)
1105 dbus_message_set_no_reply(msg, TRUE);
1107 if (!dbus_connection_send(conn, msg, NULL)) {
1108 BT_ERR("Dbus sending failed\n");
1109 ret = BLUETOOTH_ERROR_INTERNAL;
1111 dbus_message_unref(msg);
1116 int _bt_audio_set_content_protect(gboolean status)
1118 DBusConnection *conn;
1119 DBusMessage *signal;
1123 conn = _bt_get_system_conn();
1124 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1126 BT_DBG("Content Protection status = [%d] \n", status);
1128 /*Emit Content protection Status change signal with value*/
1129 signal = dbus_message_new_signal(BT_CONTENT_PROTECTION_PATH,
1130 BT_CONTENT_PROTECTION_INTERFACE,
1131 "ProtectionRequired");
1135 if (!dbus_message_append_args(signal,
1136 DBUS_TYPE_BOOLEAN, &status,
1137 DBUS_TYPE_INVALID)) {
1138 BT_ERR("Signal appending failed\n");
1139 dbus_message_unref(signal);
1143 dbus_connection_send(conn, signal, NULL);
1144 dbus_message_unref(signal);
1147 return BLUETOOTH_ERROR_NONE;
1150 return BLUETOOTH_ERROR_INTERNAL;