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