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