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