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 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
30 #include <syspopup_caller.h>
33 #include "bluetooth-api.h"
34 #include "bt-internal-types.h"
36 #include "bt-service-audio.h"
37 #include "bt-service-adapter.h"
38 #include "bt-service-common.h"
39 #include "bt-service-device.h"
40 #include "bt-service-event.h"
41 #include "bt-service-util.h"
43 #include "bt-service-headset-connection.h"
45 #ifdef TIZEN_SUPPORT_DUAL_HF
47 #define VCONF_KEY_BT_HOST_BT_MAC_ADDR "db/wms/host_bt_mac"
54 char device_address[BT_ADDRESS_STRING_SIZE + 1];
55 } bt_connected_headset_data_t;
57 static GList *g_connected_list;
59 static bt_headset_wait_t *g_wait_data;
61 static bt_audio_function_data_t *pdata;
63 static void __bt_remove_device_from_wait_list();
65 static void __bt_free_wait_data();
67 static gboolean __bt_device_support_uuid(char *remote_address,
68 bt_audio_type_t type);
70 static void __bt_hf_request_cb(DBusGProxy *proxy, DBusGProxyCall *call,
73 GError *g_error = NULL;
74 GArray *out_param1 = NULL;
75 GArray *out_param2 = NULL;
76 int result = BLUETOOTH_ERROR_NONE;
77 bt_function_data_t *func_data;
78 request_info_t *req_info;
80 dbus_g_proxy_end_call(proxy, call, &g_error, G_TYPE_INVALID);
82 g_object_unref(proxy);
84 func_data = user_data;
86 if (func_data == NULL) {
88 BT_ERR("func_data == NULL");
92 req_info = _bt_get_request_info(func_data->req_id);
93 if (req_info == NULL) {
94 BT_ERR("req_info == NULL");
101 BT_ERR("HFG request Dbus Call Error: %s\n", g_error->message);
103 result = BLUETOOTH_ERROR_INTERNAL;
106 if (req_info->context == NULL)
109 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
110 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
112 g_array_append_vals(out_param1, func_data->address,
114 g_array_append_vals(out_param2, &result, sizeof(int));
116 dbus_g_method_return(req_info->context, out_param1, out_param2);
118 g_array_free(out_param1, TRUE);
119 g_array_free(out_param2, TRUE);
121 _bt_delete_request_list(req_info->req_id);
124 g_error_free(g_error);
127 g_free(func_data->address);
132 void _bt_audio_check_pending_connect()
135 bluetooth_device_address_t device_address;
140 if (pdata->pending == BT_PENDING_CONNECT) {
142 _bt_convert_addr_string_to_type(device_address.addr,
145 _bt_audio_connect(pdata->req_id,
150 g_free(pdata->address);
159 static void __bt_audio_request_cb(DBusGProxy *proxy, DBusGProxyCall *call,
162 GError *g_error = NULL;
163 GArray *out_param1 = NULL;
164 GArray *out_param2 = NULL;
165 int result = BLUETOOTH_ERROR_NONE;
167 bt_audio_function_data_t *func_data;
169 request_info_t *req_info;
171 dbus_g_proxy_end_call(proxy, call, &g_error, G_TYPE_INVALID);
173 g_object_unref(proxy);
175 func_data = user_data;
177 if (func_data == NULL) {
179 BT_ERR("func_data == NULL");
183 if (func_data->pending != BT_PENDING_NONE && g_error == NULL) {
185 bluetooth_device_address_t device_address;
186 _bt_convert_addr_string_to_type(device_address.addr,
189 if (func_data->pending == BT_PENDING_CONNECT) {
191 if (__bt_device_support_uuid(func_data->address,
194 pdata = g_new0(bt_audio_function_data_t, 1);
195 pdata->req_id = func_data->req_id;
196 pdata->out_param = func_data->out_param;
197 pdata->address = strdup(func_data->address);
198 pdata->pending = func_data->pending;
204 if (_bt_is_service_connected(func_data->address
206 _bt_audio_disconnect(func_data->req_id,
209 func_data->out_param);
218 req_info = _bt_get_request_info(func_data->req_id);
219 if (req_info == NULL) {
220 BT_ERR("req_info == NULL");
227 BT_ERR("Audio Connect/Disconnect Dbus Call Error: %s\n", g_error->message);
229 result = BLUETOOTH_ERROR_INTERNAL;
231 /* Remove the device from the list */
232 _bt_remove_headset_from_list(func_data->type, func_data->address);
234 /* Error, check if any waiting device is there */
235 if (g_wait_data == NULL)
238 if (g_strcmp0(g_wait_data->address, func_data->address) != 0) {
239 bluetooth_device_address_t device_address;
240 _bt_convert_addr_string_to_type(device_address.addr,
241 g_wait_data->address);
242 _bt_audio_connect(g_wait_data->req_id, g_wait_data->type,
243 &device_address, g_wait_data->out_param1);
246 /* Event will be sent by the event reciever */
248 if (req_info->context == NULL) {
249 BT_DBG("req_info->context is NULL");
253 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
254 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
256 g_array_append_vals(out_param1, func_data->address,
258 g_array_append_vals(out_param2, &result, sizeof(int));
260 dbus_g_method_return(req_info->context, out_param1, out_param2);
262 g_array_free(out_param1, TRUE);
263 g_array_free(out_param2, TRUE);
265 _bt_delete_request_list(req_info->req_id);
268 g_error_free(g_error);
271 g_free(func_data->address);
276 static char *__bt_get_audio_path(bluetooth_device_address_t *address)
279 char *object_path = NULL;
280 char addr_str[BT_ADDRESS_STRING_SIZE + 1] = { 0 };
281 DBusGProxy *audio_proxy;
282 DBusGProxy *adapter_proxy;
283 DBusGConnection *g_conn;
285 retv_if(address == NULL, NULL);
287 g_conn = _bt_get_system_gconn();
288 retv_if(g_conn == NULL, NULL);
290 adapter_proxy = _bt_get_adapter_proxy();
291 retv_if(adapter_proxy == NULL, NULL);
293 _bt_convert_addr_type_to_string(addr_str, address->addr);
295 object_path = _bt_get_device_object_path(addr_str);
297 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_FOUND);
299 audio_proxy = dbus_g_proxy_new_for_name(g_conn,
302 BT_HFP_AGENT_INTERFACE);
304 retv_if(audio_proxy == NULL, NULL);
306 g_object_unref(audio_proxy);
311 static char *__bt_get_connected_audio_path(void)
315 char *audio_path = NULL;
317 bluetooth_device_info_t info;
319 /* allocate the g_pointer_array */
320 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
322 if (_bt_get_bonded_devices(&device_list)
323 != BLUETOOTH_ERROR_NONE) {
324 g_array_free(device_list, TRUE);
328 size = device_list->len;
329 size = (device_list->len) / sizeof(bluetooth_device_info_t);
331 for (i = 0; i < size; i++) {
333 info = g_array_index(device_list,
334 bluetooth_device_info_t, i);
336 if (info.connected == TRUE) {
337 audio_path = __bt_get_audio_path(&info.device_address);
343 g_array_free(device_list, TRUE);
348 static void __bt_free_wait_data()
350 if (g_wait_data != NULL) {
351 g_free(g_wait_data->address);
357 static void __bt_remove_device_from_wait_list()
359 /* Before deleting the request update the UI */
360 GArray *out_param_1 = NULL;
361 GArray *out_param_2 = NULL;
362 int result = BLUETOOTH_ERROR_INTERNAL;
363 request_info_t *req_info;
365 req_info = _bt_get_request_info(g_wait_data->req_id);
366 if (req_info == NULL) {
367 BT_ERR("req_info == NULL");
371 out_param_1 = g_array_new(FALSE, FALSE, sizeof(gchar));
372 out_param_2 = g_array_new(FALSE, FALSE, sizeof(gchar));
373 g_array_append_vals(out_param_1, g_wait_data->address,
375 g_array_append_vals(out_param_2, &result, sizeof(int));
376 dbus_g_method_return(req_info->context,
377 out_param_1, out_param_2);
378 g_array_free(out_param_1, TRUE);
379 g_array_free(out_param_2, TRUE);
380 _bt_delete_request_list(g_wait_data->req_id);
383 static void __bt_set_headset_disconnection_type(const char *address)
385 bt_connected_headset_data_t *connected_device;
388 node = g_list_first(g_connected_list);
389 while (node != NULL) {
390 connected_device = node->data;
391 if (g_strcmp0(connected_device->device_address, address) == 0) {
392 g_wait_data->disconnection_type = connected_device->type;
395 node = g_list_next(node);
399 gboolean _bt_is_headset_type_connected(int type, char *address)
403 node = g_list_first(g_connected_list);
404 while (node != NULL) {
405 bt_connected_headset_data_t *connected_device = node->data;
407 if (connected_device->type & type) {
409 g_strlcpy(address, connected_device->device_address,
410 BT_ADDRESS_STRING_SIZE + 1);
414 node = g_list_next(node);
419 #ifdef TIZEN_SUPPORT_DUAL_HF
420 gboolean __bt_is_companion_device(const char *addr)
422 #ifdef TIZEN_WEARABLE
423 char *host_device_address = NULL;
424 host_device_address = vconf_get_str(VCONF_KEY_BT_HOST_BT_MAC_ADDR);
426 if (!host_device_address) {
427 BT_INFO("Failed to get a companion device address");
431 if (g_strcmp0(host_device_address, addr) == 0) {
432 BT_INFO("addr[%s] is companion device", addr);
438 /* TODO : Need to add companion device check condition for Phone models */
444 static int __bt_is_headset_connected(int type, int req_id,
445 const char *address, GArray **out_param1)
447 gboolean connected = FALSE;
448 char connected_address[BT_ADDRESS_STRING_SIZE + 1];
449 bluetooth_device_address_t device_address;
450 bt_connected_headset_data_t *connected_device = NULL;
451 #ifdef TIZEN_SUPPORT_DUAL_HF
452 gboolean is_companion_device = FALSE;
455 /* Check if any other headset is connected */
458 node = g_list_first(g_connected_list);
459 while (node != NULL) {
460 connected_device = node->data;
461 if ((connected_device->type & type) == type) {
462 g_strlcpy(connected_address, connected_device->device_address,
463 BT_ADDRESS_STRING_SIZE + 1);
464 #ifdef TIZEN_SUPPORT_DUAL_HF
465 is_companion_device = __bt_is_companion_device(connected_address);
466 BT_INFO(" is_companion_device[%d]", is_companion_device);
468 if (!is_companion_device) {
477 node = g_list_next(node);
481 return BLUETOOTH_ERROR_NOT_CONNECTED;
483 BT_DBG("connected headset %s", connected_address);
485 if (g_strcmp0(connected_address, address) == 0)
486 return BLUETOOTH_ERROR_ALREADY_CONNECT;
487 #ifdef TIZEN_SUPPORT_DUAL_HF
488 else if (TRUE == __bt_is_companion_device(address))
489 return BLUETOOTH_ERROR_NOT_CONNECTED;
492 /* If already one device is waiting, remove current waiting device and add new */
493 if (g_wait_data != NULL) {
494 if (g_strcmp0(g_wait_data->address, address) != 0) {
495 __bt_remove_device_from_wait_list();
496 __bt_free_wait_data();
500 if (g_wait_data == NULL) {
501 g_wait_data = g_malloc0(sizeof(bt_headset_wait_t));
502 g_wait_data->address = g_strdup(address);
503 g_wait_data->req_id = req_id;
504 g_wait_data->type = type;
505 g_wait_data->ag_flag = FALSE;
506 g_wait_data->out_param1 = out_param1;
508 /* Set disconnection type */
509 __bt_set_headset_disconnection_type(connected_address);
512 /* Convert BD adress from string type */
513 _bt_convert_addr_string_to_type(device_address.addr, connected_address);
514 _bt_audio_disconnect(0, connected_device->type & type, &device_address, NULL);
515 return BLUETOOTH_ERROR_NONE;
518 void _bt_set_audio_wait_data_flag(gboolean flag)
520 BT_DBG("_bt_set_audio_wait_data_flag \n");
521 g_wait_data->ag_flag = flag;
524 bt_headset_wait_t *_bt_get_audio_wait_data(void)
526 BT_DBG("_bt_get_audio_wait_data \n");
530 void _bt_rel_wait_data(void)
532 BT_DBG("_bt_rel_wait_data \n");
533 __bt_free_wait_data();
536 void _bt_add_headset_to_list(int type, int status, const char *address)
538 bt_connected_headset_data_t *connected_device;
539 bt_connected_headset_data_t *device;
542 BT_DBG("_bt_add_headset_to_list \n");
544 node = g_list_first(g_connected_list);
545 while (node != NULL) {
546 device = (bt_connected_headset_data_t *)node->data;
548 if (g_strcmp0(device->device_address, address) == 0) {
549 BT_DBG("Address match, update connection type \n");
550 if (status == BT_STATE_CONNECTED)
551 device->type |= type;
552 device->device_state = status;
555 node = g_list_next(node);
558 connected_device = g_malloc0(sizeof(bt_connected_headset_data_t));
559 connected_device->device_state = status;
560 if (status == BT_STATE_CONNECTED)
561 connected_device->type |= type;
562 g_strlcpy(connected_device->device_address, address,
563 sizeof(connected_device->device_address));
564 g_connected_list = g_list_append(g_connected_list, connected_device);
567 int _bt_get_device_state_from_list(int type, const char *address)
570 bt_connected_headset_data_t *device;
573 node = g_list_first(g_connected_list);
574 while (node != NULL) {
575 device = (bt_connected_headset_data_t *)node->data;
576 if (g_strcmp0(device->device_address, address) == 0) {
577 BT_DBG("Device found");
578 return device->device_state;
580 node = g_list_next(node);
583 BT_DBG("Device not found");
584 return BLUETOOTH_ERROR_INTERNAL;
587 void _bt_remove_headset_from_list(int type, const char *address)
591 BT_DBG("_bt_remove_headset_from_list \n");
593 node = g_list_first(g_connected_list);
594 while (node != NULL) {
595 bt_connected_headset_data_t *connected_device = node->data;
597 if (g_strcmp0(connected_device->device_address, address) != 0) {
598 node = g_list_next(node);
602 BT_DBG("Address match \n");
604 BT_DBG("Connection type = %x\n", connected_device->type);
608 if (connected_device->type & BT_AUDIO_A2DP)
609 connected_device->type &= ~(BT_AUDIO_A2DP);
612 if (connected_device->type & BT_AUDIO_HSP)
613 connected_device->type &= ~(BT_AUDIO_HSP);
616 if (connected_device->type & BT_AUDIO_ALL)
617 connected_device->type &= ~(BT_AUDIO_ALL);
620 if (connected_device->type & BT_AVRCP)
621 connected_device->type &= ~(BT_AVRCP);
625 BT_DBG("Connection type = %x\n", connected_device->type);
627 if (connected_device->type == 0x00) {
628 g_connected_list = g_list_remove(g_connected_list, connected_device);
629 g_free(connected_device);
632 node = g_list_next(node);
636 static gboolean __bt_device_support_uuid(char *remote_address,
637 bt_audio_type_t type)
639 GArray *dev_list = NULL;
641 bluetooth_device_info_t info;
642 char bond_address[BT_ADDRESS_STRING_SIZE] = { 0 };
643 gboolean ret = FALSE;
647 dev_list = g_array_new (FALSE, FALSE, sizeof(gchar));
649 _bt_get_bonded_devices(&dev_list);
650 size = (dev_list->len) / sizeof(bluetooth_device_info_t);
652 for (i=0; i < size; i++) {
653 info = g_array_index(dev_list, bluetooth_device_info_t, i);
654 _bt_convert_addr_type_to_string(bond_address,
655 info.device_address.addr);
656 if (strcmp(bond_address, remote_address) != 0)
659 BT_INFO("Device address Matched");
661 while (j != info.service_index) {
662 if (type == BT_AUDIO_HSP) {
663 if (strcmp(info.uuids[j], HFP_HS_UUID) == 0) {
664 BT_INFO("HFP HS UUID exists");
668 } else if (type == BT_AUDIO_A2DP) {
669 if (strcmp(info.uuids[j], A2DP_SINK_UUID) == 0) {
670 BT_INFO("A2DP SINK UUID exists");
679 g_array_free(dev_list, TRUE);
684 gboolean _bt_is_service_connected(char* address, int type)
688 node = g_list_first(g_connected_list);
689 while (node != NULL) {
690 bt_connected_headset_data_t *conn_device = node->data;
692 if ((g_strcmp0(conn_device->device_address, address) == 0) &&
693 (conn_device->type & type)) {
694 BT_INFO("Service connected");
698 node = g_list_next(node);
700 BT_INFO("Service not connected");
704 int _bt_audio_connect(int request_id, int type,
705 bluetooth_device_address_t *device_address,
708 int result = BLUETOOTH_ERROR_NONE;
709 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
710 DBusGProxy *adapter_proxy;
711 DBusGConnection *g_conn;
714 int value = BLUETOOTH_ERROR_NONE;
715 bt_audio_function_data_t *func_data;
717 BT_CHECK_PARAMETER(device_address, return);
719 adapter_proxy = _bt_get_adapter_proxy();
720 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
722 g_conn = _bt_get_system_gconn();
723 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
725 _bt_convert_addr_type_to_string(address, device_address->addr);
727 func_data = g_malloc0(sizeof(bt_audio_function_data_t));
729 func_data->address = g_strdup(address);
730 func_data->req_id = request_id;
731 func_data->type = type;
732 func_data->pending = BT_PENDING_NONE;
733 func_data->out_param = out_param1;
740 uuid = A2DP_SINK_UUID;
743 uuid = AVRCP_TARGET_UUID;
746 if (__bt_device_support_uuid(address, BT_AUDIO_HSP)) {
748 func_data->pending = BT_PENDING_CONNECT;
749 } else if (__bt_device_support_uuid(address, BT_AUDIO_A2DP)) {
750 uuid = A2DP_SINK_UUID;
752 BT_ERR("No audio role supported");
753 result = BLUETOOTH_ERROR_SERVICE_NOT_FOUND;
758 BT_ERR("Unknown role");
759 result = BLUETOOTH_ERROR_INTERNAL;
762 BT_INFO("Connecting to service %s", uuid);
764 value = __bt_is_headset_connected(type, request_id, address, out_param1);
766 if (value == BLUETOOTH_ERROR_ALREADY_CONNECT) {
767 return BLUETOOTH_ERROR_ALREADY_CONNECT;
768 } else if (value == BLUETOOTH_ERROR_NOT_CONNECTED) {
769 _bt_headset_set_local_connection(TRUE);
770 ret = _bt_connect_profile(address, uuid,
771 __bt_audio_request_cb, func_data);
773 if (ret != BLUETOOTH_ERROR_NONE) {
774 BT_ERR("_bt_connect_profile Error");
775 _bt_headset_set_local_connection(FALSE);
776 g_free(func_data->address);
781 /* Add data to the connected list */
782 _bt_add_headset_to_list(type, BT_STATE_CONNECTING, address);
785 return BLUETOOTH_ERROR_NONE;
787 g_array_append_vals(*out_param1, address,
793 int _bt_audio_disconnect(int request_id, int type,
794 bluetooth_device_address_t *device_address,
797 int result = BLUETOOTH_ERROR_NONE;
798 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
799 bt_audio_function_data_t *func_data;
800 DBusGProxy *adapter_proxy;
801 DBusGConnection *g_conn;
806 BT_CHECK_PARAMETER(device_address, return);
808 adapter_proxy = _bt_get_adapter_proxy();
809 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
811 g_conn = _bt_get_system_gconn();
812 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
814 _bt_convert_addr_type_to_string(address, device_address->addr);
816 func_data = g_malloc0(sizeof(bt_audio_function_data_t));
818 func_data->address = g_strdup(address);
819 func_data->req_id = request_id;
820 func_data->pending = BT_PENDING_NONE;
821 func_data->out_param = out_param1;
822 func_data->type = type;
829 uuid = A2DP_SINK_UUID;
832 uuid = AVRCP_TARGET_UUID;
835 if (_bt_is_service_connected(address, BT_AUDIO_HSP)) {
837 func_data->pending = BT_PENDING_DISCONNECT;
838 } else if (_bt_is_service_connected(address, BT_AUDIO_A2DP)) {
839 uuid = A2DP_SINK_UUID;
841 BT_ERR("No audio service connected");
842 result = BLUETOOTH_ERROR_NOT_CONNECTED;
847 BT_ERR("Unknown role");
848 result = BLUETOOTH_ERROR_INTERNAL;
852 BT_INFO("Disconnecting service %s", uuid);
853 ret = _bt_disconnect_profile(address, uuid,
854 __bt_audio_request_cb, func_data);
856 if (ret != BLUETOOTH_ERROR_NONE) {
857 BT_ERR("_bt_disconnect_profile Error");
858 g_free(func_data->address);
864 * This logic is added for dual HF mode issue.
866 node = g_list_first(g_connected_list);
867 while (node != NULL) {
868 bt_connected_headset_data_t *connected_device = node->data;
870 if (g_strcmp0(connected_device->device_address, address) == 0) {
871 BT_DBG("Connection type update");
872 type = connected_device->type;
875 node = g_list_next(node);
877 _bt_add_headset_to_list(type, BT_STATE_DISCONNECTING, address);
879 return BLUETOOTH_ERROR_NONE;
881 if (out_param1 != NULL)
882 g_array_append_vals(*out_param1, address,
888 void _bt_remove_from_connected_list(const char *address)
890 bt_connected_headset_data_t *connected_device;
893 node = g_list_first(g_connected_list);
894 while (node != NULL) {
895 connected_device = node->data;
896 if (connected_device != NULL &&
897 g_strcmp0(connected_device->device_address, address) == 0) {
898 BT_ERR("Device is removed from the list");
899 g_connected_list = g_list_remove(g_connected_list, connected_device);
900 g_free(connected_device);
903 node = g_list_next(node);
907 int _bt_hf_connect(int request_id,
908 bluetooth_device_address_t *device_address,
911 int result = BLUETOOTH_ERROR_NONE;
912 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
913 bt_function_data_t *func_data;
914 DBusGProxy *adapter_proxy;
915 DBusGConnection *g_conn;
921 BT_CHECK_PARAMETER(device_address, return);
923 _bt_convert_addr_type_to_string(address, device_address->addr);
925 adapter_proxy = _bt_get_adapter_proxy();
926 if (adapter_proxy == NULL) {
927 result = BLUETOOTH_ERROR_INTERNAL;
931 g_conn = _bt_get_system_gconn();
932 if (g_conn == NULL) {
933 result = BLUETOOTH_ERROR_INTERNAL;
937 func_data = g_malloc0(sizeof(bt_function_data_t));
939 func_data->address = g_strdup(address);
940 func_data->req_id = request_id;
941 uuid = g_strdup(HFP_AG_UUID);
943 BT_DBG("Connecting to service %s", uuid);
945 ret = _bt_connect_profile(address, uuid,
946 __bt_hf_request_cb, func_data);
948 if (ret != BLUETOOTH_ERROR_NONE) {
949 BT_ERR("_bt_connect_profile Error");
950 g_free(func_data->address);
956 return BLUETOOTH_ERROR_NONE;
958 if (out_param1 != NULL)
959 g_array_append_vals(*out_param1, address,
965 int _bt_hf_disconnect(int request_id,
966 bluetooth_device_address_t *device_address,
969 int result = BLUETOOTH_ERROR_NONE;
970 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
971 bt_function_data_t *func_data;
972 DBusGProxy *adapter_proxy;
973 DBusGConnection *g_conn;
978 BT_CHECK_PARAMETER(device_address, return);
980 _bt_convert_addr_type_to_string(address, device_address->addr);
982 adapter_proxy = _bt_get_adapter_proxy();
983 if (adapter_proxy == NULL) {
984 result = BLUETOOTH_ERROR_INTERNAL;
988 g_conn = _bt_get_system_gconn();
989 if (g_conn == NULL) {
990 result = BLUETOOTH_ERROR_INTERNAL;
994 func_data = g_malloc0(sizeof(bt_function_data_t));
996 func_data->address = g_strdup(address);
997 func_data->req_id = request_id;
998 uuid = g_strdup(HFP_AG_UUID);
1000 BT_DBG("Disconnecting service %s", uuid);
1001 ret = _bt_disconnect_profile(address, uuid,
1002 __bt_hf_request_cb, func_data);
1004 if (ret != BLUETOOTH_ERROR_NONE) {
1005 BT_ERR("_bt_disconnect_profile Error");
1006 g_free(func_data->address);
1012 return BLUETOOTH_ERROR_NONE;
1014 if (out_param1 != NULL)
1015 g_array_append_vals(*out_param1, address,
1016 BT_ADDRESS_STR_LEN);
1021 int _bt_audio_get_speaker_gain(unsigned int *gain)
1023 char *device_path = NULL;
1024 DBusGProxy *adapter_proxy;
1025 DBusGProxy *profile_proxy;
1026 DBusGConnection *g_conn;
1027 GHashTable *hash = NULL;
1030 adapter_proxy = _bt_get_adapter_proxy();
1031 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1033 g_conn = _bt_get_system_gconn();
1034 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1036 device_path = __bt_get_connected_audio_path();
1037 retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
1039 profile_proxy = dbus_g_proxy_new_for_name(g_conn, BT_BLUEZ_NAME,
1040 device_path, BT_HEADSET_INTERFACE);
1042 g_free(device_path);
1044 retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1046 dbus_g_proxy_call(profile_proxy, "GetProperties", NULL,
1048 dbus_g_type_get_map("GHashTable",
1049 G_TYPE_STRING, G_TYPE_VALUE),
1050 &hash, G_TYPE_INVALID);
1052 g_object_unref(profile_proxy);
1054 retv_if(hash == NULL, BLUETOOTH_ERROR_INTERNAL);
1056 value = g_hash_table_lookup(hash, "SpeakerGain");
1057 *gain = value ? g_value_get_uint(value) : 0;
1058 g_hash_table_destroy(hash);
1059 return BLUETOOTH_ERROR_NONE;
1062 int _bt_audio_set_speaker_gain(unsigned int gain)
1064 char *device_path = NULL;
1065 char *gain_str = "SpeakerGain";
1066 char sig[2] = {DBUS_TYPE_UINT16, '\0'};
1067 int ret = BLUETOOTH_ERROR_NONE;
1069 DBusMessageIter iter;
1070 DBusMessageIter value;
1071 DBusConnection *conn;
1073 conn = _bt_get_system_conn();
1074 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1076 device_path = __bt_get_connected_audio_path();
1077 retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
1079 msg = dbus_message_new_method_call(BT_BLUEZ_NAME,
1080 device_path, BT_HEADSET_INTERFACE,
1083 g_free(device_path);
1085 retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
1087 dbus_message_iter_init_append(msg, &iter);
1088 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
1090 dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
1092 dbus_message_iter_append_basic(&value, DBUS_TYPE_UINT16,
1094 dbus_message_iter_close_container(&iter, &value);
1096 if (dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_METHOD_CALL)
1097 dbus_message_set_no_reply(msg, TRUE);
1099 if (!dbus_connection_send(conn, msg, NULL)) {
1100 BT_ERR("Dbus sending failed\n");
1101 ret = BLUETOOTH_ERROR_INTERNAL;
1103 dbus_message_unref(msg);
1108 int _bt_audio_set_content_protect(gboolean status)
1110 DBusConnection *conn;
1111 DBusMessage *signal;
1115 conn = _bt_get_system_conn();
1116 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1118 BT_DBG("Content Protection status = [%d] \n", status);
1120 /*Emit Content protection Status change signal with value*/
1121 signal = dbus_message_new_signal(BT_CONTENT_PROTECTION_PATH,
1122 BT_CONTENT_PROTECTION_INTERFACE,
1123 "ProtectionRequired");
1127 if (!dbus_message_append_args(signal,
1128 DBUS_TYPE_BOOLEAN, &status,
1129 DBUS_TYPE_INVALID)) {
1130 BT_ERR("Signal appending failed\n");
1131 dbus_message_unref(signal);
1135 dbus_connection_send(conn, signal, NULL);
1136 dbus_message_unref(signal);
1139 return BLUETOOTH_ERROR_NONE;
1142 return BLUETOOTH_ERROR_INTERNAL;