Apply headset connection logic.
[platform/core/connectivity/bluetooth-frwk.git] / bt-service-adaptation / services / audio / bt-service-audio.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:  Anupam Roy <anupam.r@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *              http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <sys/un.h>
23 #include <sys/socket.h>
24 #include <sys/errno.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <gio/gio.h>
28 #include <vconf.h>
29
30 #include "oal-a2dp-sink.h"
31 #include "oal-audio-src.h"
32 #include "oal-device-mgr.h"
33 #include "oal-event.h"
34 #include "oal-hardware.h"
35 #include "oal-hf-client.h"
36
37 #include "bt-request-handler.h"
38 #include "bt-service-a2dp-sink.h"
39 #include "bt-service-a2dp-src.h"
40 #include "bt-service-avrcp-ctrl.h"
41 #include "bt-service-avrcp-tg.h"
42 #include "bt-service-audio-common.h"
43 #include "bt-service-common.h"
44 #include "bt-service-core-device.h"
45 #include "bt-service-headset-connection.h"
46 #include "bt-service-hf.h"
47 #include "bt-service-hf-client.h"
48
49 #ifdef TIZEN_SUPPORT_DUAL_HF
50 #define VCONF_KEY_BT_HOST_BT_MAC_ADDR "db/wms/host_bt_mac"
51 #endif
52
53 /* Static variables and Macros */
54 static GList *g_connected_list;
55 static bt_headset_wait_t *g_wait_data;
56 typedef struct {
57         unsigned int type;
58         int device_state;
59         char device_address[BT_ADDRESS_STRING_SIZE + 1];
60 } bt_connected_headset_data_t;
61
62 /* List for saving device service search info */
63 static GSList *pending_audio_conn_list = NULL;
64
65 static int curr_audio_role = BLUETOOTH_A2DP_SOURCE;
66 static int pending_audio_role = -1;
67
68 static void __bt_remove_device_from_wait_list(char *prev_waiting_device);
69
70 static void __bt_audio_event_handler(int oal_event, gpointer event_data);
71
72 static int __bt_process_audio_connect_all(bt_pending_audio_conn_t *info);
73
74 static int __bt_is_headset_connecting(int type);
75
76 static int __bt_is_headset_disconnecting(int type);
77
78 static void __bt_audio_cleanup_resources(void);
79
80 static gboolean __handle_pending_audio_select_role(gpointer data);
81
82 static void __bt_reply_pending_audio_connect_req(char *address, int result);
83
84 static const char *__convert_audio_type_to_string(bt_audio_type_t type)
85 {
86         switch (type) {
87         case BT_AUDIO_HSP:
88                 return "AUDIO_HSP";
89         case BT_AUDIO_A2DP:
90                 return "AUDIO_A2DP";
91         case BT_AUDIO_ALL:
92                 return "AUDIO_ALL";
93         case BT_AVRCP_TARGET:
94                 return "AVRCP_TARGET";
95         case BT_AVRCP:
96                 return "AVRCP";
97         case BT_AUDIO_A2DP_SOURCE:
98                 return "A2DP_SOURCE";
99         case BT_AUDIO_HFP_SOURCE:
100                 return "HFP_SOURCE";
101         case BT_AUDIO_AG:
102                 return "AUDIO_AG";
103         default:
104                 return "Invalid";
105         }
106 }
107
108 void _bt_set_audio_wait_data_flag(gboolean flag)
109 {
110         BT_DBG("_bt_set_audio_wait_data_flag \n");
111         g_wait_data->ag_flag = flag;
112 }
113
114 bt_headset_wait_t *_bt_get_audio_wait_data(void)
115 {
116         BT_DBG("_bt_get_audio_wait_data \n");
117         return g_wait_data;
118 }
119
120 static void __bt_free_wait_data(void)
121 {
122         if (g_wait_data != NULL) {
123                 g_free(g_wait_data->address);
124                 g_free(g_wait_data);
125                 g_wait_data = NULL;
126         }
127 }
128
129 void _bt_rel_wait_data(void)
130 {
131         BT_DBG("_bt_rel_wait_data \n");
132         __bt_free_wait_data();
133 }
134
135 void _bt_add_headset_to_list(int type, int status, const char *address)
136 {
137         bt_connected_headset_data_t *connected_device;
138         bt_connected_headset_data_t *device;
139         GList *node;
140
141         BT_DBG("_bt_add_headset_to_list \n");
142
143         node = g_list_first(g_connected_list);
144         while (node != NULL) {
145                 device = (bt_connected_headset_data_t *)node->data;
146
147                 if (g_strcmp0(device->device_address, address) == 0) {
148                         BT_DBG("Address match, update connection type \n");
149                         if (status == BT_STATE_CONNECTED)
150                                 device->type |= type;
151                         device->device_state = status;
152                         return;
153                 }
154                 node = g_list_next(node);
155         }
156
157         connected_device = g_malloc0(sizeof(bt_connected_headset_data_t));
158         /* Fix : NULL_RETURNS */
159         if (connected_device == NULL) {
160                 BT_ERR("No memory allocated");
161                 return;
162         }
163
164         connected_device->device_state = status;
165         //if ((status == BT_STATE_CONNECTED) || (status == BT_STATE_CONNECTING))
166         if (status == BT_STATE_CONNECTED)
167                 connected_device->type |= type;
168         g_strlcpy(connected_device->device_address, address,
169                         sizeof(connected_device->device_address));
170         g_connected_list = g_list_append(g_connected_list, connected_device);
171         BT_DBG("Added device[%s] in connected list, device state [%d] Device Type [%d]",
172                                 address, connected_device->device_state, connected_device->type);
173 }
174
175 gboolean _bt_is_headset_type_connected(int type, char *address)
176 {
177         GList *node;
178
179         node = g_list_first(g_connected_list);
180         while (node != NULL) {
181                 bt_connected_headset_data_t *connected_device = node->data;
182
183                 if (connected_device->type & type) {
184                         if (address != NULL)
185                                 g_strlcpy(address, connected_device->device_address,
186                                                 BT_ADDRESS_STRING_SIZE);
187                         return TRUE;
188                 }
189
190                 node = g_list_next(node);
191         }
192         return FALSE;
193 }
194
195
196 gboolean _bt_is_headset_address_type_connected(int type, const char *address)
197 {
198         GList *node;
199
200         node = g_list_first(g_connected_list);
201         while (node != NULL) {
202                 bt_connected_headset_data_t *connected_device = node->data;
203
204                 if (connected_device && (connected_device->type & type)) {
205                         if (memcmp(connected_device->device_address, address, 19) == 0)
206                                 return TRUE;
207                 }
208
209                 node = g_list_next(node);
210         }
211         return FALSE;
212 }
213
214 static void __bt_set_headset_disconnection_type(const char *address)
215 {
216         bt_connected_headset_data_t *connected_device;
217         GList *node;
218
219         node = g_list_first(g_connected_list);
220         while (node != NULL) {
221                 connected_device = node->data;
222                 if (g_strcmp0(connected_device->device_address, address) == 0) {
223                         g_wait_data->disconnection_type = connected_device->type;
224                         return;
225                 }
226                 node = g_list_next(node);
227         }
228 }
229
230 #ifdef TIZEN_SUPPORT_DUAL_HF
231 gboolean __bt_is_companion_device(const char *addr)
232 {
233         if (TIZEN_PROFILE_WEARABLE) {
234                 char *host_device_address = NULL;
235                 host_device_address = vconf_get_str(VCONF_KEY_BT_HOST_BT_MAC_ADDR);
236
237                 if (!host_device_address) {
238                         BT_INFO("Failed to get a companion device address");
239                         return FALSE;
240                 }
241
242                 if (g_strcmp0(host_device_address, addr) == 0) {
243                         BT_INFO("addr[%s] is companion device", addr);
244                         return TRUE;
245                 }
246
247                 return FALSE;
248         } else {
249         /* TODO : Need to add companion device check condition for Phone models */
250         return FALSE;
251         }
252 }
253 #endif
254
255 static int __bt_is_headset_disconnecting(int type)
256 {
257         bt_connected_headset_data_t *connected_device = NULL;
258
259         /* Check if any other headset is connected */
260         GList *node = NULL;
261
262         node = g_list_first(g_connected_list);
263         while (node != NULL) {
264                 connected_device = node->data;
265                 if (connected_device->device_state == BT_STATE_DISCONNECTING)
266                         return BLUETOOTH_ERROR_CONNECTION_BUSY;
267                 node = g_list_next(node);
268         }
269
270         return BLUETOOTH_ERROR_NONE;
271 }
272
273 static int __bt_is_headset_connecting(int type)
274 {
275         bt_connected_headset_data_t *connected_device = NULL;
276
277         /* Check if any other headset is connected */
278         GList *node = NULL;
279
280         node = g_list_first(g_connected_list);
281         while (node != NULL) {
282                 connected_device = node->data;
283                 if (connected_device->device_state == BT_STATE_CONNECTING) {
284                         BT_ERR("@@Device [%s] is already under connecting state", connected_device->device_address);
285                         return BLUETOOTH_ERROR_CONNECTION_BUSY;
286                 }
287                 node = g_list_next(node);
288         }
289
290         return BLUETOOTH_ERROR_NONE;
291 }
292
293 static int __bt_is_headset_connected(int current_conn_type, const char *address)
294 {
295         gboolean connected = FALSE;
296         int disconn_type;
297         char connected_address[BT_ADDRESS_STRING_SIZE + 1];
298         bluetooth_device_address_t device_address;
299         bt_connected_headset_data_t *connected_device = NULL;
300 #ifdef TIZEN_SUPPORT_DUAL_HF
301         gboolean is_companion_device = FALSE;
302 #endif
303
304         /* Check if any other headset is connected */
305         GList *node = NULL;
306
307         BT_DBG("Checking if any Headset connected or not: current device [%s] current audio type [%s]",
308                         address, __convert_audio_type_to_string(current_conn_type));
309         node = g_list_first(g_connected_list);
310         while (node != NULL) {
311                 connected_device = node->data;
312                 BT_DBG("A Device is already connected found in list [%s] audio type [%s]",
313                                 connected_device->device_address, __convert_audio_type_to_string(connected_device->type));
314                 if ((connected_device->type & current_conn_type)) {
315                         g_strlcpy(connected_address, connected_device->device_address,
316                                         BT_ADDRESS_STRING_SIZE + 1);
317 #ifdef TIZEN_SUPPORT_DUAL_HF
318                         is_companion_device = __bt_is_companion_device(connected_address);
319                         BT_INFO("is_companion_device[%d]", is_companion_device);
320
321                         if (!is_companion_device) {
322                                 connected = TRUE;
323                                 break;
324                         }
325 #else
326                         connected = TRUE;
327                         break;
328 #endif
329                 }
330                 node = g_list_next(node);
331         }
332
333         if (!connected) {
334                 BT_DBG("There is no connected device with connection type [%s]",
335                                 __convert_audio_type_to_string(current_conn_type));
336                 return BLUETOOTH_ERROR_NOT_CONNECTED;
337         }
338
339         BT_DBG("connected headset %s", connected_address);
340
341         if (g_strcmp0(connected_address, address) == 0)
342                 return BLUETOOTH_ERROR_ALREADY_CONNECT;
343 #ifdef TIZEN_SUPPORT_DUAL_HF
344         else if (TRUE == __bt_is_companion_device(address))
345                 return BLUETOOTH_ERROR_NOT_CONNECTED;
346 #endif
347
348         /* Convert BD address from string type */
349         _bt_convert_addr_string_to_type(device_address.addr, connected_address);
350         int value = BLUETOOTH_ERROR_NONE;
351         BT_DBG("Already headset connected. addr [%s] connected type [%s] current audio type [%s]",
352                         connected_address, __convert_audio_type_to_string(connected_device->type),
353                         __convert_audio_type_to_string(current_conn_type));
354         disconn_type = connected_device->type & current_conn_type;
355         BT_DBG("Attempt disconnection of Type [%s] of already connected device",
356                         __convert_audio_type_to_string(disconn_type));
357         value = _bt_audio_disconnect(disconn_type, &device_address);
358
359         /* If already one device is waiting, remove current waiting device and add new */
360         if (value == BLUETOOTH_ERROR_NONE) {
361                 if (g_wait_data != NULL) {
362                         if (g_strcmp0(g_wait_data->address, address) != 0) {
363                                 BT_INFO("Already one device was waiting for connection [%s], remove it", g_wait_data->address + 12);
364                                 __bt_remove_device_from_wait_list(g_wait_data->address);
365                                 __bt_free_wait_data();
366                         }
367                 }
368
369                 if (g_wait_data == NULL) {
370                         BT_INFO("Add current device [%s] into waiting list", address + 12);
371                         g_wait_data = g_malloc0(sizeof(bt_headset_wait_t));
372                         g_wait_data->address = g_strdup(address);
373                         g_wait_data->type = current_conn_type;
374                         g_wait_data->ag_flag = FALSE;
375
376                         /* Set disconnection type */
377                         __bt_set_headset_disconnection_type(connected_address);
378                 }
379         }
380
381         return value;
382 }
383
384 static void __bt_remove_device_from_wait_list(char *prev_waiting_device)
385 {
386         /* Before deleting the request update the UI */
387         bluetooth_device_address_t device_address;
388         int result = BLUETOOTH_ERROR_INTERNAL;
389         GArray *out_param;
390         invocation_info_t *req_info;
391         BT_INFO("We are about to DBUS return previous waiting device [%s]", prev_waiting_device);
392
393         _bt_convert_addr_string_to_type(device_address.addr, prev_waiting_device);
394
395         req_info = _bt_get_request_info_data(BT_AV_CONNECT, prev_waiting_device);
396         if (req_info == NULL) {
397                 BT_ERR("req_info == NULL");
398                 return;
399         } else {
400                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
401                 g_array_append_vals(out_param, &device_address,
402                                 sizeof(bluetooth_device_address_t));
403                 _bt_service_method_return(req_info->context,
404                                 out_param, result);
405                 g_array_free(out_param, TRUE);
406                 _bt_free_info_from_invocation_list(req_info);
407         }
408 }
409
410 static int __bt_process_audio_profile_connect(bt_audio_type_t type, bluetooth_device_address_t *address)
411 {
412         char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
413         int result = BLUETOOTH_ERROR_NONE;
414         BT_DBG("type %s", __convert_audio_type_to_string(type));
415
416         _bt_convert_addr_type_to_string(addr,
417                         (unsigned char *)address->addr);
418         /* Attempt profile level connection based on type */
419         switch (type) {
420         case BT_AUDIO_HSP:
421                 result = _bt_connect_remote_hfp(address);
422                 break;
423         case BT_AUDIO_A2DP:
424                 result = _bt_a2dp_connect_remote_sink(address);
425                 break;
426         case BT_AVRCP_TARGET:
427                 result = _bt_avrcp_connect_remote_ctrl(address);
428                 break;
429         case BT_AVRCP:
430                 result = _bt_avrcp_connect_remote_target(address);
431                 break;
432         case BT_AUDIO_A2DP_SOURCE:
433                 return _bt_a2dp_connect_remote_source(address);
434                 break;
435         case BT_AUDIO_AG:
436                 return _bt_connect_remote_ag(address);
437         default:
438                 BT_ERR("Unknown role");
439                 return BLUETOOTH_ERROR_INTERNAL;
440         }
441
442         if (result == BLUETOOTH_ERROR_NONE) {
443                 _bt_headset_set_local_connection(TRUE);
444                 /* Add data to the connected list */
445                 _bt_add_headset_to_list(type, BT_STATE_CONNECTING, addr);
446                 BT_PERMANENT_LOG("Connect %s", __convert_audio_type_to_string(type));
447         } else {
448                 BT_ERR("Profile [%s] connect failed!!", __convert_audio_type_to_string(type));
449         }
450         return result;
451 }
452
453 static int __bt_process_audio_profile_disconnect(bt_audio_type_t type, bluetooth_device_address_t *address)
454 {
455         char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
456         int result = BLUETOOTH_ERROR_NONE;
457         GList *node;
458         BT_DBG("type %s", __convert_audio_type_to_string(type));
459
460         _bt_convert_addr_type_to_string(addr,
461                         (unsigned char *)address->addr);
462         /* Attempt profile level connection based on type */
463         switch (type) {
464         case BT_AUDIO_HSP:
465                 result = _bt_disconnect_remote_hfp(address);
466                 break;
467         case BT_AUDIO_A2DP:
468                 result = _bt_a2dp_disconnect_remote_sink(address);
469                 break;
470         case BT_AVRCP_TARGET:
471                 result = _bt_avrcp_disconnect_remote_ctrl(address);
472                 break;
473         case BT_AVRCP:
474                 result = _bt_avrcp_disconnect_remote_target(address);
475                 break;
476         case BT_AUDIO_A2DP_SOURCE:
477                 return _bt_a2dp_disconnect_remote_source(address);
478                 break;
479         default:
480                 BT_ERR("Unknown role");
481                 return BLUETOOTH_ERROR_INTERNAL;
482         }
483
484         if (result == BLUETOOTH_ERROR_NONE) {
485                 /*
486                  *      This logic is added for dual HF mode issue.
487                  */
488                 node = g_list_first(g_connected_list);
489                 while (node != NULL) {
490                         bt_connected_headset_data_t *connected_device = node->data;
491
492                         if (g_strcmp0(connected_device->device_address, addr) == 0) {
493                                 BT_DBG("Connection type update. old type[%s] -> new type[%s]",
494                                                 __convert_audio_type_to_string(connected_device->type),
495                                                 __convert_audio_type_to_string(type));
496                                 type = connected_device->type;
497                                 break;
498                         }
499                         node = g_list_next(node);
500                 }
501
502                 /* Update device status in connected list */
503                 _bt_add_headset_to_list(type, BT_STATE_DISCONNECTING, addr);
504                 BT_PERMANENT_LOG("Disconnect %s", __convert_audio_type_to_string(type));
505         } else {
506                 BT_ERR("Profile [%s] disconnect failed!!", __convert_audio_type_to_string(type));
507         }
508
509         return result;
510 }
511
512 int _bt_audio_initialize(bt_service_module_t module)
513 {
514         oal_status_t status = OAL_STATUS_SUCCESS;
515         int ret  = BLUETOOTH_ERROR_NONE;
516
517         BT_INFO("_bt_audio_initialize: Module [%d]", module);
518
519         switch (module) {
520         case BT_A2DP_SOURCE_MODULE: {
521                 status = audio_enable(NULL, NULL);
522                 if (OAL_STATUS_SUCCESS != status) {
523                         BT_ERR("Failed to initialize Bluetooth A2DP Source Profile, status: %d", status);
524                         return _bt_convert_oal_status_to_bt_error(status);
525                 }
526                 /* Register Audio module event handler */
527                 _bt_service_register_event_handler_callback(module, _bt_a2dp_source_event_handler);
528                 break;
529         }
530         case BT_A2DP_SINK_MODULE: {
531                 status = a2dp_sink_enable(NULL, NULL);
532                 if (status != OAL_STATUS_SUCCESS) {
533                         BT_ERR("Failed to initialize Bluetooth A2DP Sink Profile, status: %d", status);
534                         return _bt_convert_oal_status_to_bt_error(status);
535                 }
536                 /* Register Audio sink module event handler */
537                 _bt_service_register_event_handler_callback(module, _bt_a2dp_sink_event_handler);
538                 break;
539         }
540         case BT_HFP_MODULE: {
541                 status = hf_client_enable();
542                 if (OAL_STATUS_SUCCESS != status) {
543                         BT_ERR("Failed to initialize Bluetooth HFP client Profile, status: %d", status);
544                         return _bt_convert_oal_status_to_bt_error(status);
545                 }
546                 /* Register Audio module event handler */
547                 _bt_service_register_event_handler_callback(module, _bt_hf_client_event_handler);
548                 break;
549         }
550         case BT_AG_MODULE: {
551                 status = hfp_enable(1);
552                 if (OAL_STATUS_SUCCESS != status) {
553                         BT_ERR("Failed to initialize Bluetooth HFP Audio Gateway Profile, status: %d", status);
554                         return _bt_convert_oal_status_to_bt_error(status);
555                 }
556                 /* Register Audio module event handler */
557                 _bt_service_register_event_handler_callback(module, _bt_hf_event_handler);
558                 break;
559         }
560         case BT_AUDIO_ALL_MODULE: {
561                 /* Register Audio module event handler */
562                 _bt_service_register_event_handler_callback(module, __bt_audio_event_handler);
563                 break;
564         }
565         case BT_AVRCP_CTRL_MODULE: {
566                 status = avrcp_ct_enable();
567                 if (status != OAL_STATUS_SUCCESS) {
568                         BT_ERR("Failed to initialize Bluetooth AVRCP Controller Profile, status: %d", status);
569                         return _bt_convert_oal_status_to_bt_error(status);
570                 }
571                 /* Register Avrcp Controller event handler */
572                 _bt_service_register_event_handler_callback(module, _bt_avrcp_ctrl_event_handler);
573                 break;
574         }
575         case BT_AVRCP_MODULE: {
576                 /* Initialize AVRCP Target */
577                 ret = _bt_service_avrcp_enable();
578                 break;
579         }
580         default:
581                 BT_ERR("Not Supported: Module [%d]", module);
582                 return BLUETOOTH_ERROR_NOT_SUPPORT;
583         }
584
585         BT_INFO("Bluetooth audio interface initialised");
586         return ret;
587 }
588
589 static void __bt_audio_event_handler(int oal_event, gpointer event_data)
590 {
591         switch (oal_event) {
592         case OAL_EVENT_ADAPTER_DISABLED: {
593                 BT_INFO("Adapter Disabled..cleanup resources");
594                 __bt_audio_cleanup_resources();
595                 break;
596         }
597         case OAL_EVENT_ADAPTER_ENABLED: {
598                 /*TODO Currently not handled */
599                 BT_INFO("Adapter Enabled..");
600                 break;
601         }
602         default:
603                 BT_DBG("Unknown event..[%d]", oal_event);
604                 break;
605         }
606 }
607
608 static void __bt_audio_cleanup_resources(void)
609 {
610         GList *node;
611         GSList *l;
612         bt_pending_audio_conn_t *info = NULL;
613
614         /* Remove connected device list */
615         node = g_list_first(g_connected_list);
616         while (node != NULL) {
617                 bt_connected_headset_data_t *connected_device = node->data;
618                 BT_INFO("Data found [%s] in connected device list...remove it..", connected_device->device_address);
619                 g_connected_list = g_list_remove(g_connected_list, connected_device);
620                 node = g_list_next(node);
621         }
622
623         /* Remove pending connection list */
624         for (l = pending_audio_conn_list; l != NULL; l = g_slist_next(l)) {
625                 info = (bt_pending_audio_conn_t*)l->data;
626
627                 if (info) {
628                         BT_INFO("Info found for addr [%s], remove it...", info->address);
629                         pending_audio_conn_list = g_slist_remove(pending_audio_conn_list, info);
630                         g_free(info->address);
631                         g_free(info);
632                         info = NULL;
633                 }
634         }
635 }
636
637 static int __bt_process_audio_connect_all(bt_pending_audio_conn_t *info)
638 {
639         bluetooth_device_address_t device_address;
640         int result = BLUETOOTH_ERROR_NONE;
641         int type = BT_AUDIO_ALL;
642
643         BT_DBG("");
644
645         _bt_convert_addr_string_to_type(device_address.addr, info->address);
646
647         /* Attempt profile level connection */
648         if (info->is_hfp_supported) {
649                 type = BT_AUDIO_HSP;
650                 result = _bt_connect_remote_hfp(&device_address);
651
652                 if (info->is_a2dp_sink_supported)
653                         BT_DBG("A2DP is supported by [%s]", info->address);
654                 else
655                         BT_DBG("A2DP is not supported");
656         } else if (info->is_a2dp_sink_supported) {
657                 type = BT_AUDIO_A2DP;
658                 result = _bt_a2dp_connect_remote_sink(&device_address);
659         } else if (info->is_a2dp_src_supported) {
660                 type = BT_AUDIO_A2DP_SOURCE;
661                 result = _bt_a2dp_connect_remote_source(&device_address);
662         }
663         if (result == BLUETOOTH_ERROR_NONE) {
664                 //_bt_headset_set_local_connection(TRUE);
665                 /* Add data to the connected list */
666                 _bt_add_headset_to_list(type, BT_STATE_CONNECTING, info->address);
667         } else {
668                 BT_ERR("Profile connect failed!!");
669         }
670         return result;
671 }
672
673 bt_pending_audio_conn_t* _bt_get_pending_audio_conn_info(char *address)
674 {
675         bt_pending_audio_conn_t *info = NULL;
676         GSList *l;
677
678         for (l = pending_audio_conn_list; l != NULL; l = g_slist_next(l)) {
679                 info = (bt_pending_audio_conn_t*)l->data;
680
681                 if (g_strcmp0(info->address, address) == 0 && info->search_status == SERVICE_SEARCH_DONE) {
682                         BT_INFO("Pending data found for addr [%s]", info->address + 12);
683                         return info;
684                 }
685         }
686         BT_INFO("Pending data not found!!");
687         return NULL;
688 }
689
690 static void __bt_reply_pending_audio_connect_req(char *address, int result)
691 {
692         GArray *out_param;
693         invocation_info_t *req_info;
694
695         BT_DBG("+");
696         ret_if(NULL == address);
697
698         /* Reply to async request for Audio connect, if any */
699         req_info = _bt_get_request_info_data(BT_AUDIO_CONNECT, address);
700         ret_if(NULL == req_info);
701
702         out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
703         g_array_append_vals(out_param, address, BT_ADDRESS_STRING_SIZE);
704         _bt_service_method_return(req_info->context, out_param, result);
705
706         g_array_free(out_param, TRUE);
707         _bt_free_info_from_invocation_list(req_info);
708
709         if (result != BLUETOOTH_ERROR_NONE)
710                 _bt_headset_set_local_connection(FALSE);
711
712         BT_DBG("-");
713 }
714
715 void _bt_cleanup_audio_pending_conn_info_and_reply_pending_req(bt_pending_audio_conn_t *info, int result)
716 {
717         ret_if(NULL == info);
718
719         /* Reply to async request for Audio connect, if any */
720         __bt_reply_pending_audio_connect_req(info->address, result);
721
722         /* Remove pending audio conn info */
723         pending_audio_conn_list = g_slist_remove(pending_audio_conn_list, info);
724         g_free(info->address);
725         g_free(info);
726 }
727
728 gboolean _bt_audio_check_pending_connection(char *address)
729 {
730         bt_pending_audio_conn_t *data = NULL;
731         bluetooth_device_address_t device_address;
732
733         data = _bt_get_pending_audio_conn_info(address);
734
735         if (data) {
736                 BT_INFO("A2DP Connection is pending..initiate it...");
737                 if (data->is_a2dp_sink_supported && data->conn_req_type == BT_AUDIO_ALL) {
738                         _bt_convert_addr_string_to_type(device_address.addr, address);
739                         if (_bt_audio_connect(BT_AUDIO_A2DP, &device_address) != BLUETOOTH_ERROR_NONE) {
740                                 BT_INFO("A2DP connect triggered for [%s]  but it failed!!", data->address);
741                                 _bt_cleanup_audio_pending_conn_info_and_reply_pending_req(data, BLUETOOTH_ERROR_INTERNAL);
742                         } else {
743                                 BT_INFO("A2DP connect triggered successfully for [%s]", data->address);
744                         }
745                 } else if (data->is_a2dp_src_supported && data->conn_req_type == BT_AUDIO_HFP_SOURCE) {
746                         _bt_convert_addr_string_to_type(device_address.addr, address);
747                         if (_bt_audio_connect(BT_AUDIO_A2DP_SOURCE, &device_address) != BLUETOOTH_ERROR_NONE) {
748                                 BT_INFO("A2DP sink connect triggered for [%s]  but it failed!!", data->address);
749                                 _bt_cleanup_audio_pending_conn_info_and_reply_pending_req(data, BLUETOOTH_ERROR_INTERNAL);
750                         } else {
751                                 BT_INFO("A2DP sink connect triggered successfully for [%s]", data->address);
752                         }
753                 }
754                 return TRUE;
755         } else {
756                 BT_INFO("A2DP Connection is not pending..");
757         }
758         return FALSE;
759 }
760
761 void _bt_audio_check_pending_disconnection(char *address, int type)
762 {
763         int ret = BLUETOOTH_ERROR_NONE;
764         bluetooth_device_address_t device_address;
765
766         if (_bt_is_service_connected(address, type)) {
767                 BT_INFO("Service [%s] is connected with device [%s], disconnect it...",
768                                 __convert_audio_type_to_string(type), address + 12);
769                 _bt_convert_addr_string_to_type(device_address.addr, address);
770                 ret = __bt_process_audio_profile_disconnect(type, &device_address);
771
772                 if (ret != BLUETOOTH_ERROR_NONE)
773                         BT_ERR("Disconnecting service [%s] with device [%s] failed!!",
774                                         __convert_audio_type_to_string(type), address + 12);
775         } else {
776                 BT_INFO("Service [%s] is Not connected with device [%s],..",
777                                 __convert_audio_type_to_string(type), address + 12);
778         }
779 }
780
781 int __bt_handle_audio_all_connect(bt_pending_audio_conn_t *info)
782 {
783         bt_remote_dev_info_t *rem_info;
784         int ret;
785         int indx;
786
787         retv_if(NULL == info, BLUETOOTH_ERROR_INTERNAL);
788         retv_if(NULL == info->address, BLUETOOTH_ERROR_INTERNAL);
789
790         rem_info = _bt_service_get_remote_dev_info(info->address);
791         if (!rem_info) {
792                 BT_ERR("_bt_service_get_remote_dev_info returned NULL");
793                 ret = BLUETOOTH_ERROR_NOT_PAIRED;
794                 goto fail;
795         }
796
797         for (indx = 0; indx < rem_info->uuid_count; indx++) {
798                 BT_INFO("UUID [%s]", rem_info->uuids[indx]);
799                 if (0 == g_strcmp0(A2DP_SINK_UUID, rem_info->uuids[indx])) {
800                         BT_INFO("Device supports A2DP Sink Profile");
801                         info->is_a2dp_sink_supported = TRUE;
802                 } else if (0 == g_strcmp0(A2DP_SOURCE_UUID, rem_info->uuids[indx])) {
803                         BT_INFO("Device supports A2DP Source Profile");
804                         info->is_a2dp_src_supported = TRUE;
805                 } else if ((g_strcmp0(HFP_HS_UUID, rem_info->uuids[indx]) == 0)) {
806                         BT_INFO("Device supports HFP Profile");
807                         info->is_hfp_supported = TRUE;
808                 }
809         }
810
811         if (info->is_a2dp_sink_supported == FALSE &&
812                         info->is_hfp_supported == FALSE &&
813                         info->is_a2dp_src_supported == FALSE) {
814                 BT_ERR("No audio profile is supported");
815                 ret = BLUETOOTH_ERROR_NOT_SUPPORT;
816                 goto fail;
817         }
818
819         BT_INFO("AUDIO_CONNECT_ALL request for [%s]", info->address + 12);
820         info->search_status = SERVICE_SEARCH_DONE;
821
822         /* Give preference to HFP over A2DP for outgoing connection sequence for AUDIO_ALL_CONNECT */
823         if (info->is_hfp_supported)
824                 info->type = BT_AUDIO_HSP;
825         else if (info->is_a2dp_sink_supported)
826                 info->type = BT_AUDIO_A2DP;
827         else if (info->is_a2dp_src_supported)
828                 info->type = BT_AUDIO_A2DP_SOURCE;
829
830         ret = __bt_is_headset_connected(info->type, info->address);
831         if (ret == BLUETOOTH_ERROR_ALREADY_CONNECT) {
832                 BT_ERR("Can't start Audio All connect for [%s], reason: [%s]",
833                                 info->address + 12, "Already connected...");
834                 goto fail;
835         }
836
837         if (ret == BLUETOOTH_ERROR_IN_PROGRESS) {
838                 BT_ERR("Can't start Audio All connect for [%s], reason: [%s]",
839                                 info->address + 12, "Already in progress...");
840                 goto fail;
841         }
842
843         if (ret == BLUETOOTH_ERROR_NOT_CONNECTED) {
844                 BT_ERR("Great, can start Audio All connect for [%s]", info->address + 12);
845                 ret = __bt_is_headset_connecting(info->type);
846                 if (ret != BLUETOOTH_ERROR_NONE) {
847                         BT_ERR("Can't start Audio All connect for [%s], reason: [%s]",
848                                         info->address + 12, "some other device conn in progress");
849                         ret = BLUETOOTH_ERROR_IN_PROGRESS;
850                         goto fail;
851                 }
852
853                 ret = __bt_process_audio_connect_all(info);
854                 if (ret != BLUETOOTH_ERROR_NONE) {
855                         BT_ERR("__bt_process_audio_connect_all failed");
856                         goto fail;
857                 }
858
859                 BT_PERMANENT_LOG("Connect %s", __convert_audio_type_to_string(info->type));
860                 /* If multiple profiles are supported, queue pending connection info */
861                 if ((info->is_hfp_supported && info->is_a2dp_sink_supported) ||
862                                 (info->is_hfp_supported && info->is_a2dp_src_supported)) {
863                         BT_INFO("[%s] Supports HFP and (A2DP_Src or, A2DP_Snk)", info->address + 12);
864                         pending_audio_conn_list = g_slist_append(pending_audio_conn_list, (gpointer)info);
865                 } else {
866                         BT_INFO("[%s] Supports one profile only", info->address + 12);
867                         /*
868                          * It means, we dont need pending connect info as only A2DP (Src/Snk) or
869                          * HFP will be connected for present device, so lets free pending info.
870                          */
871                         g_free(info->address);
872                         g_free(info);
873                 }
874         } else if (ret == BLUETOOTH_ERROR_NONE) {
875                 BT_INFO("Waiting for disconnection...");
876
877                 if ((info->is_hfp_supported && info->is_a2dp_sink_supported) ||
878                                 (info->is_hfp_supported && info->is_a2dp_src_supported)) {
879                         BT_INFO("[%s] Supports HFP and (A2DP_Src or, A2DP_Snk)", info->address + 12);
880                         pending_audio_conn_list = g_slist_append(pending_audio_conn_list, (gpointer)info);
881                 } else {
882                         BT_INFO("[%s] Supports one profile only", info->address + 12);
883                         /*
884                          * It means, we dont need pending connect info as only A2DP (Src/Snk) or
885                          * HFP will be connected for present device, so lets free pending info.
886                          */
887                         g_free(info->address);
888                         g_free(info);
889                 }
890         }
891
892         return BLUETOOTH_ERROR_NONE;
893
894 fail:
895         BT_ERR("Audio connect all failed");
896         g_free(info->address);
897         g_free(info);
898         return ret;
899 }
900
901 static gboolean __audio_get_bonded_info(gpointer data)
902 {
903         bt_pending_audio_conn_t *info = data;
904         char address[BT_ADDRESS_STRING_SIZE];
905
906         retv_if(NULL == info, FALSE);
907         retv_if(NULL == info->address, FALSE);
908
909         if ((info->bonded_info_retries > 0) && !_bt_is_bonded_devices_retrived()) {
910                 info->bonded_info_retries--;
911                 return TRUE;
912         }
913
914         g_strlcpy(address, info->address, BT_ADDRESS_STRING_SIZE);
915         if (info->bonded_info_retries <= 0) {
916                 BT_ERR_C("Even after all retries, bonded devices stil not retrieved");
917                 g_free(info->address);
918                 g_free(info);
919                 goto failed;
920         }
921
922         if (BLUETOOTH_ERROR_NONE != __bt_handle_audio_all_connect(info)) {
923                 BT_ERR("__bt_handle_audio_all_connect failed");
924                 goto failed;
925         }
926
927         return FALSE;
928 failed:
929         __bt_reply_pending_audio_connect_req(address, BLUETOOTH_ERROR_INTERNAL);
930         return FALSE;
931 }
932
933 int _bt_audio_connect(int type, bluetooth_device_address_t *device_address)
934 {
935         int ret = BLUETOOTH_ERROR_NONE;
936         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
937         bt_pending_audio_conn_t *info = NULL;
938
939         BT_CHECK_PARAMETER(device_address, return);
940
941         _bt_convert_addr_type_to_string(address, device_address->addr);
942         BT_INFO("Audio Connect Request: type[%s] address [%s]",
943                         __convert_audio_type_to_string(type), address + 12);
944
945         /*
946          * If type is BT_AUDIO_ALL or BT_AUDIO_HFP_SOURCE, enqueue search info in
947          * order to find out supported services by the remote device.
948          */
949         if (type == BT_AUDIO_ALL || type ==  BT_AUDIO_HFP_SOURCE) {
950                 if (NULL != _bt_get_pending_audio_conn_info(address)) {
951                         BT_ERR("Connection for same device already in progress");
952                         return BLUETOOTH_ERROR_IN_PROGRESS;
953                 }
954
955                 info = g_malloc0(sizeof(bt_pending_audio_conn_t));
956                 info->search_status = SERVICE_SEARCH_STARTED;
957                 info->address = g_strdup(address);
958                 info->type = type;
959                 info->conn_req_type = type;
960
961                 /* Request bonded device info */
962                 if (!_bt_is_bonded_devices_retrived()) {
963                         info->bonded_info_retries = 5;
964                         /* Wait till bonded devices retrival is completed */
965                         g_timeout_add_seconds(1, __audio_get_bonded_info, info);
966                         return BLUETOOTH_ERROR_NONE;
967                 }
968
969                 return __bt_handle_audio_all_connect(info);
970         }
971
972         /* If type is A2DP Sink or HSP/HFP, check further */
973         ret =  __bt_is_headset_connected(type, address);
974         if (ret == BLUETOOTH_ERROR_ALREADY_CONNECT) {
975                 BT_ERR("Failed with BLUETOOTH_ERROR_ALREADY_CONNECT");
976                 return BLUETOOTH_ERROR_ALREADY_CONNECT;
977         }
978
979         if (ret == BLUETOOTH_ERROR_IN_PROGRESS) {
980                 BT_ERR("Failed with BLUETOOTH_ERROR_IN_PROGRESS");
981                 return BLUETOOTH_ERROR_IN_PROGRESS;
982         }
983
984         if (ret == BLUETOOTH_ERROR_NONE) {
985                 BT_INFO("Waiting for disconnection...");
986         } else if (ret == BLUETOOTH_ERROR_NOT_CONNECTED) {
987                 ret = __bt_process_audio_profile_connect(type, device_address);
988                 if (ret != BLUETOOTH_ERROR_NONE) {
989                         BT_ERR("Failed with %d", ret);
990                         return ret;
991                 }
992         }
993
994         return BLUETOOTH_ERROR_NONE;
995 }
996
997 int _bt_audio_disconnect(int type, bluetooth_device_address_t *device_address)
998 {
999         int ret = BLUETOOTH_ERROR_NONE;
1000         int value = BLUETOOTH_ERROR_NONE;
1001         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1002
1003         _bt_convert_addr_type_to_string(address, device_address->addr);
1004         BT_INFO("Audio Diconnect Request: type[%s] address [%s]",
1005                         __convert_audio_type_to_string(type), address + 12);
1006
1007         if (type == BT_AUDIO_ALL) {
1008                 if (_bt_is_service_connected(address, BT_AUDIO_A2DP)) {
1009                         type = BT_AUDIO_A2DP;
1010                 } else if (_bt_is_service_connected(address, BT_AUDIO_HSP)) {
1011                         type = BT_AUDIO_HSP;
1012                 } else {
1013                         BT_ERR("No audio service connected");
1014                         return BLUETOOTH_ERROR_NOT_CONNECTED;
1015                 }
1016         } else if (type == BT_AUDIO_HFP_SOURCE) {
1017                 if (_bt_is_service_connected(address, BT_AUDIO_A2DP_SOURCE)) {
1018                         type = BT_AUDIO_A2DP_SOURCE;
1019                 } else if (_bt_is_service_connected(address, BT_AUDIO_HSP)) {
1020                         type = BT_AUDIO_HSP;
1021                 } else {
1022                         BT_ERR("No audio service connected");
1023                         return BLUETOOTH_ERROR_NOT_CONNECTED;
1024                 }
1025         }
1026
1027         value = __bt_is_headset_disconnecting(type);
1028         if (value != BLUETOOTH_ERROR_NONE) {
1029                 BT_INFO("Disconnect in progress");
1030                 return BLUETOOTH_ERROR_IN_PROGRESS;
1031         }
1032
1033         ret = __bt_process_audio_profile_disconnect(type, device_address);
1034         return ret;
1035 }
1036
1037 gboolean _bt_is_service_connected(char* address, int type)
1038 {
1039         GList *node;
1040         node = g_list_first(g_connected_list);
1041         while (node != NULL) {
1042                 bt_connected_headset_data_t *conn_device = node->data;
1043
1044                 if ((g_strcmp0(conn_device->device_address, address) == 0) &&
1045                                 (conn_device->type & type)) {
1046                         BT_INFO("Service connected");
1047                         return TRUE;
1048                 }
1049
1050                 node = g_list_next(node);
1051         }
1052         BT_INFO("Service not connected");
1053         return FALSE;
1054 }
1055
1056 void _bt_remove_headset_from_list(int type, const char *address)
1057 {
1058         GList *node;
1059
1060         BT_DBG("type %s", __convert_audio_type_to_string(type));
1061
1062         node = g_list_first(g_connected_list);
1063         while (node != NULL) {
1064                 bt_connected_headset_data_t *connected_device = node->data;
1065
1066                 if (g_strcmp0(connected_device->device_address, address) != 0) {
1067                         node = g_list_next(node);
1068                         continue;
1069                 }
1070
1071                 BT_DBG("Address match. Connection type = %s",
1072                                 __convert_audio_type_to_string(connected_device->type));
1073
1074                 switch (type) {
1075                 case BT_AUDIO_A2DP:
1076                         if (connected_device->type & BT_AUDIO_A2DP)
1077                                 connected_device->type &= ~(BT_AUDIO_A2DP);
1078                         break;
1079                 case BT_AUDIO_HSP:
1080                         if (connected_device->type & BT_AUDIO_HSP)
1081                                 connected_device->type &= ~(BT_AUDIO_HSP);
1082                         break;
1083                 case BT_AUDIO_ALL:
1084                         if (connected_device->type & BT_AUDIO_ALL)
1085                                 connected_device->type &= ~(BT_AUDIO_ALL);
1086                         break;
1087                 case BT_AVRCP_TARGET:
1088                         if (connected_device->type & BT_AVRCP_TARGET)
1089                                 connected_device->type &= ~(BT_AVRCP_TARGET);
1090                         break;
1091                 case BT_AVRCP:
1092                         if (connected_device->type & BT_AVRCP)
1093                                 connected_device->type &= ~(BT_AVRCP);
1094                         break;
1095                 case BT_AUDIO_A2DP_SOURCE:
1096                         if (connected_device->type & BT_AUDIO_A2DP_SOURCE)
1097                                 connected_device->type &= ~(BT_AUDIO_A2DP_SOURCE);
1098                         break;
1099                 default:
1100                         break;
1101                 }
1102
1103                 if (connected_device->type == 0x00) {
1104                         BT_INFO("Device will be completely removed from connected list as the only profile connected or connecting got disconnected");
1105                         g_connected_list = g_list_remove(g_connected_list, connected_device);
1106                         g_free(connected_device);
1107                 } else {
1108                         connected_device->device_state = BT_STATE_CONNECTED;
1109                 }
1110
1111                 node = g_list_next(node);
1112         }
1113
1114         /*
1115          * If Audio role selection request is pending (pending_audio_role > 0) then process pending
1116          * audio role select request on BT_AUDIO_A2DP/BT_AUDIO_A2DP_SOURCE device dicaonnection.
1117          */
1118         if (pending_audio_role >= 0 &&
1119                 (type == BT_AUDIO_A2DP || type == BT_AUDIO_A2DP_SOURCE))
1120                 g_idle_add(__handle_pending_audio_select_role, NULL);
1121 }
1122
1123 static void __handle_pending_requests(int result, int service_function, void *user_data, unsigned int size)
1124 {
1125         GSList *l;
1126         GArray *out_param;
1127         invocation_info_t *req_info;
1128
1129         BT_DBG("+");
1130
1131         /* Get method invocation context */
1132         for (l = _bt_get_invocation_list(); l != NULL; ) {
1133                 req_info = l->data;
1134                 l = g_slist_next(l);
1135
1136                 if (req_info == NULL || req_info->service_function != service_function)
1137                         continue;
1138
1139                 /* Create out param */
1140                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
1141
1142                 switch (service_function) {
1143                 case BT_AUDIO_SELECT_ROLE:
1144                         _bt_service_method_return(req_info->context, out_param, result);
1145                         g_array_free(out_param, TRUE);
1146                         _bt_free_info_from_invocation_list(req_info);
1147                         return;
1148                 default:
1149                         BT_ERR("Unknown service function[%d]", service_function);
1150                         return;
1151                 }
1152         }
1153
1154         BT_DBG("-");
1155 }
1156
1157 static gboolean __handle_pending_audio_select_role(gpointer data)
1158 {
1159         int ret;
1160         oal_status_t status;
1161
1162         BT_DBG("+");
1163         if (BLUETOOTH_A2DP_SOURCE == pending_audio_role) {
1164                 /* Disable A2DP Sink role */
1165                 status = a2dp_sink_disable();
1166                 if (status != OAL_STATUS_SUCCESS) {
1167                         BT_ERR("Failed to Disable Bluetooth A2DP Sink Profile, status: %d", status);
1168                         ret = _bt_convert_oal_status_to_bt_error(status);
1169                         goto done;
1170                 }
1171
1172                 /* Disable AVRCP CT role */
1173                 status = avrcp_ct_disable();
1174                 if (status != OAL_STATUS_SUCCESS) {
1175                         BT_ERR("Failed to Disable Bluetooth AVRCP Controller Profile, status: %d", status);
1176                         ret = _bt_convert_oal_status_to_bt_error(status);
1177                         goto done;
1178                 }
1179
1180                 /* Enable A2DP Source role */
1181                 ret = _bt_audio_initialize(BT_A2DP_SOURCE_MODULE);
1182                 if (ret != BLUETOOTH_ERROR_NONE) {
1183                         BT_ERR("Failed to enable Bluetooth A2DP Source Profile");
1184                         goto done;
1185                 }
1186
1187                 /* Enable AVRCP TG role */
1188                 ret = _bt_audio_initialize(BT_AVRCP_MODULE);
1189                 if (ret != BLUETOOTH_ERROR_NONE) {
1190                         BT_ERR("Failed to enable Bluetooth AVRCP Target Profile");
1191                         goto done;
1192                 }
1193         } else {
1194                 /* Disable A2DP Source role */
1195                 status = audio_disable();
1196                 if (OAL_STATUS_SUCCESS != status) {
1197                         BT_ERR("Failed to disable Bluetooth A2DP Source Profile, status: %d", status);
1198                         ret = _bt_convert_oal_status_to_bt_error(status);
1199                         goto done;
1200                 }
1201
1202                 /* Disable AVRCP TG role */
1203                 ret = _bt_service_avrcp_disable();
1204                 if (ret != BLUETOOTH_ERROR_NONE) {
1205                         BT_ERR("Failed to Disable Bluetooth AVRCP Target Profile");
1206                         goto done;
1207                 }
1208
1209                 /* Enable A2DP Sink role */
1210                 ret = _bt_audio_initialize(BT_A2DP_SINK_MODULE);
1211                 if (ret != BLUETOOTH_ERROR_NONE) {
1212                         BT_ERR("Failed to enable Bluetooth A2DP Sink Profile");
1213                         goto done;
1214                 }
1215
1216                 /* Enable AVRCP CT role */
1217                 ret = _bt_audio_initialize(BT_AVRCP_CTRL_MODULE);
1218                 if (ret != BLUETOOTH_ERROR_NONE) {
1219                         BT_ERR("Failed to enable Bluetooth AVRCP Controller Profile");
1220                         goto done;
1221                 }
1222         }
1223
1224 done:
1225         if (ret == BLUETOOTH_ERROR_NONE)
1226                 _bt_audio_set_current_role(pending_audio_role);
1227
1228         __handle_pending_requests(ret, BT_AUDIO_SELECT_ROLE, NULL, 0);
1229         pending_audio_role = -1;
1230         BT_DBG("-");
1231         return FALSE;
1232 }
1233
1234 int _bt_audio_select_role(bluetooth_audio_role_t role)
1235 {
1236         int result = BLUETOOTH_ERROR_NONE;
1237         char address[BT_ADDRESS_STRING_SIZE];
1238         bluetooth_device_address_t dev_addr;
1239
1240         retv_if(BLUETOOTH_A2DP_SINK < role, BLUETOOTH_ERROR_INVALID_PARAM);
1241         retv_if(pending_audio_role >= 0, BLUETOOTH_ERROR_IN_PROGRESS);
1242
1243         BT_DBG("+");
1244
1245         if (curr_audio_role == role) {
1246                 BT_ERR("Desired audio role already enabled, return");
1247                 return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
1248         }
1249
1250         pending_audio_role = role;
1251
1252         if (BLUETOOTH_A2DP_SINK == role) {
1253                 if (_bt_is_headset_type_connected(BT_AUDIO_A2DP, address)) {
1254                         _bt_convert_addr_string_to_type(dev_addr.addr, address);
1255                         result = _bt_audio_disconnect(BT_AUDIO_A2DP, &dev_addr);
1256                         if (result != BLUETOOTH_ERROR_NONE) {
1257                                 BT_ERR("_bt_audio_disconnect(BT_AUDIO_A2DP, %s) Failed", address);
1258                                 result = _bt_convert_oal_status_to_bt_error(result);
1259                         }
1260                 } else {
1261                         BT_INFO("No BT_AUDIO_A2DP device is connected, proceed with role switch");
1262                         g_idle_add(__handle_pending_audio_select_role, NULL);
1263                         result = BLUETOOTH_ERROR_NONE;
1264                 }
1265         } else {
1266                 if (_bt_is_headset_type_connected(BT_AUDIO_A2DP_SOURCE, address)) {
1267                         _bt_convert_addr_string_to_type(dev_addr.addr, address);
1268                         result = _bt_audio_disconnect(BT_AUDIO_A2DP_SOURCE, &dev_addr);
1269                         if (result != BLUETOOTH_ERROR_NONE) {
1270                                 BT_ERR("_bt_audio_disconnect(BT_AUDIO_A2DP_SOURCE, %s) Failed", address);
1271                                 result = _bt_convert_oal_status_to_bt_error(result);
1272                         }
1273                 } else {
1274                         BT_INFO("No BT_AUDIO_A2DP_SOURCE device is connected, proceed with role switch");
1275                         g_idle_add(__handle_pending_audio_select_role, NULL);
1276                         result = BLUETOOTH_ERROR_NONE;
1277                 }
1278         }
1279
1280         BT_DBG("-");
1281         return result;
1282 }
1283
1284 void _bt_audio_set_current_role(bluetooth_audio_role_t role)
1285 {
1286         BT_INFO("role: %s", (role == BLUETOOTH_A2DP_SINK) ? "AUDIO_SINK" : "AUDIO_SOURCE");
1287         curr_audio_role = role;
1288 }
1289
1290 int _bt_hf_connect(bluetooth_device_address_t *device_address)
1291 {
1292         int result = BLUETOOTH_ERROR_NONE;
1293         BT_INFO("+");
1294
1295         result = _bt_connect_remote_ag(device_address);
1296         if (result != BLUETOOTH_ERROR_NONE)
1297                 BT_ERR("HF Client connect to remote AG failed");
1298         else
1299                 BT_PERMANENT_LOG("Connect AG");
1300
1301         return result;
1302 }
1303
1304 int _bt_hf_disconnect(bluetooth_device_address_t *device_address)
1305 {
1306         int result = BLUETOOTH_ERROR_NONE;
1307         BT_INFO("+");
1308
1309         result = _bt_disconnect_remote_ag(device_address);
1310         if (result != BLUETOOTH_ERROR_NONE)
1311                 BT_ERR("HF Client disconnect to remote AG failed");
1312         else
1313                 BT_PERMANENT_LOG("Disconnect AG");
1314
1315         return result;
1316 }