Fix unref issue
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-audio.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <gio/gio.h>
19 #include <glib.h>
20 #include <dlog.h>
21 #include <string.h>
22 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
23 #include <vconf.h>
24 #endif
25 #include <syspopup_caller.h>
26
27 #include "bluetooth-api.h"
28 #include "bt-internal-types.h"
29
30 #include "bt-service-audio.h"
31 #include "bt-service-adapter.h"
32 #include "bt-service-common.h"
33 #include "bt-service-device.h"
34 #include "bt-service-event.h"
35 #include "bt-service-util.h"
36
37 #include "bt-service-headset-connection.h"
38
39 #ifdef TIZEN_SUPPORT_DUAL_HF
40 #define VCONF_KEY_BT_HOST_BT_MAC_ADDR "db/wms/host_bt_mac"
41 #endif
42
43 typedef struct {
44         unsigned int type;
45         int device_state;
46         char device_address[BT_ADDRESS_STRING_SIZE + 1];
47 } bt_connected_headset_data_t;
48
49 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
50 typedef struct {
51         int alarm_id;
52         int retry_count;
53 } bt_auto_connect_timer_t;
54
55 bt_auto_connect_timer_t auto_connect_timer = {0, };
56 #endif
57
58 static GList *g_connected_list;
59
60 static bt_headset_wait_t *g_wait_data;
61
62 static bt_audio_function_data_t *pdata;
63
64 static void __bt_remove_device_from_wait_list();
65
66 static void __bt_free_wait_data();
67
68 static gboolean __bt_device_support_uuid(char *remote_address,
69                                 bt_audio_type_t type);
70
71 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
72 static int __bt_auto_connect_alarm_cb(alarm_id_t alarm_id, void* user_param);
73 #endif
74
75 static void __bt_hf_request_cb(GDBusProxy *proxy, GAsyncResult *res,
76                                     gpointer user_data)
77 {
78         GError *g_error = NULL;
79         GVariant *out_param1 = NULL;
80         GVariant *reply = NULL;
81         int result = BLUETOOTH_ERROR_NONE;
82         bt_function_data_t *func_data;
83         request_info_t *req_info;
84
85         reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
86         g_object_unref(proxy);
87
88         func_data = user_data;
89
90         if (func_data == NULL) {
91                 /* Send reply */
92                 BT_ERR("func_data == NULL");
93                 goto done;
94         }
95
96         req_info = _bt_get_request_info(func_data->req_id);
97         if (req_info == NULL) {
98                 BT_ERR("req_info == NULL");
99                 goto done;
100         }
101
102         if (reply == NULL) {
103                 BT_ERR("HF Connect Dbus Call Error");
104                 result = _bt_convert_gerror(g_error);
105                 if (g_error) {
106                         BT_ERR("Error: %s\n", g_error->message);
107                         g_clear_error(&g_error);
108                 }
109         } else {
110                 g_variant_unref(reply);
111         }
112
113         if (req_info->context == NULL)
114                 goto done;
115
116         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
117                 func_data->address, BT_ADDRESS_STR_LEN, TRUE, NULL, NULL);
118
119         g_dbus_method_invocation_return_value(req_info->context,
120                         g_variant_new("(iv)", result, out_param1));
121
122         _bt_delete_request_list(req_info->req_id);
123
124 done:
125         if (func_data) {
126                 g_free(func_data->address);
127                 g_free(func_data);
128         }
129 }
130
131 void _bt_audio_check_pending_connect()
132 {
133         BT_DBG("+");
134         bluetooth_device_address_t device_address;
135
136         if (pdata == NULL)
137                 return;
138
139         if (pdata->pending == BT_PENDING_CONNECT) {
140
141                 _bt_convert_addr_string_to_type(device_address.addr,
142                                 pdata->address);
143                 _bt_audio_connect(pdata->req_id,
144                                 BT_AUDIO_A2DP,
145                                 &device_address,
146                                 NULL);
147
148                 g_free(pdata->address);
149                 g_free(pdata);
150                 pdata = NULL;
151         }
152
153         BT_DBG("-");
154         return;
155 }
156
157 static void __bt_audio_request_cb(GDBusProxy *proxy, GAsyncResult *res,
158                                     gpointer user_data)
159 {
160         GError *g_error = NULL;
161         GVariant *out_param1 = NULL;
162         GVariant *reply = NULL;
163         int result = BLUETOOTH_ERROR_NONE;
164         bt_audio_function_data_t *func_data;
165         request_info_t *req_info;
166
167         reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
168         g_object_unref(proxy);
169
170     if (reply)
171         g_variant_unref(reply);
172
173         func_data = user_data;
174
175         if (func_data == NULL) {
176                 /* Send reply */
177                 BT_ERR("func_data == NULL");
178                 goto done;
179         }
180
181         if (func_data->pending != BT_PENDING_NONE && g_error == NULL) {
182                 bluetooth_device_address_t device_address;
183                 _bt_convert_addr_string_to_type(device_address.addr,
184                                         func_data->address);
185
186                 if (func_data->pending == BT_PENDING_CONNECT) {
187
188                         if (__bt_device_support_uuid(func_data->address,
189                                                         BT_AUDIO_A2DP)) {
190
191                                 pdata = g_new0(bt_audio_function_data_t, 1);
192                                 pdata->req_id = func_data->req_id;
193                                 pdata->address = strdup(func_data->address);
194                                 pdata->pending = func_data->pending;
195                         } else
196                                 goto check_req_info;
197
198                 } else {
199                         if (_bt_is_service_connected(func_data->address
200                                                         , BT_AUDIO_HSP)) {
201                                 _bt_audio_disconnect(func_data->req_id,
202                                         BT_AUDIO_HSP, &device_address, NULL);
203                         } else
204                                 goto check_req_info;
205                 }
206
207                 goto done;
208         }
209
210 check_req_info:
211         if (g_error == NULL)
212                 goto dbus_return;
213
214         BT_ERR("Audio Connect/Disconnect Dbus Call Error: %s\n", g_error->message);
215
216         result = BLUETOOTH_ERROR_INTERNAL;
217         /* If there is error then we need to set local initiated connection as false
218           * If don't do this then when headset initiate connection for HFP then we don't
219           * initiate connection for A2dp to headset as this flag was set to true in first
220           * connection failure attempt and not set in error case.*/
221         _bt_headset_set_local_connection(FALSE);
222
223         /* Remove the device from the list */
224         _bt_remove_headset_from_list(func_data->type, func_data->address);
225
226         /* Error, check if any waiting device is there */
227         if (g_wait_data == NULL)
228                 goto dbus_return;
229
230         if (g_strcmp0(g_wait_data->address, func_data->address) != 0) {
231                 bluetooth_device_address_t device_address;
232                 _bt_convert_addr_string_to_type(device_address.addr,
233                                 g_wait_data->address);
234                 _bt_audio_connect(g_wait_data->req_id, g_wait_data->type,
235                                 &device_address, NULL);
236         }
237
238         /* Event will be sent by the event reciever */
239 dbus_return:
240         req_info = _bt_get_request_info(func_data->req_id);
241         if (req_info == NULL) {
242                 BT_ERR("req_info == NULL");
243                 goto done;
244         } else if (req_info->context == NULL) {
245                 BT_ERR("req_info->context is NULL");
246                 goto done;
247         }
248
249         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
250                 func_data->address, BT_ADDRESS_STR_LEN, TRUE, NULL, NULL);
251
252         g_dbus_method_invocation_return_value(req_info->context,
253                         g_variant_new("(iv)", result, out_param1));
254
255         _bt_delete_request_list(req_info->req_id);
256 done:
257         g_clear_error(&g_error);
258
259         if (func_data) {
260                 g_free(func_data->address);
261                 g_free(func_data);
262         }
263 }
264
265 static void __bt_free_wait_data()
266 {
267         if (g_wait_data != NULL) {
268                 g_free(g_wait_data->address);
269                 g_free(g_wait_data);
270                 g_wait_data = NULL;
271         }
272 }
273
274 static void __bt_remove_device_from_wait_list()
275 {
276         /* Before deleting the request update the UI */
277         GVariant *out_param_1 = NULL;
278         int result = BLUETOOTH_ERROR_INTERNAL;
279         request_info_t *req_info;
280
281         req_info = _bt_get_request_info(g_wait_data->req_id);
282         if (req_info == NULL) {
283                 BT_ERR("req_info == NULL");
284                 return;
285         }
286
287         out_param_1 = g_variant_new_from_data((const GVariantType *)"ay",
288                 g_wait_data->address, BT_ADDRESS_STR_LEN, TRUE, NULL, NULL);
289
290         g_dbus_method_invocation_return_value(req_info->context,
291                         g_variant_new("(iv)", result, out_param_1));
292
293         _bt_delete_request_list(g_wait_data->req_id);
294 }
295
296 static void __bt_set_headset_disconnection_type(const char *address)
297 {
298         bt_connected_headset_data_t *connected_device;
299         GList *node;
300
301         node = g_list_first(g_connected_list);
302         while (node != NULL) {
303                 connected_device = node->data;
304                 if (g_strcmp0(connected_device->device_address, address) == 0) {
305                         g_wait_data->disconnection_type = connected_device->type;
306                         return;
307                 }
308                 node = g_list_next(node);
309         }
310 }
311
312 #ifdef TIZEN_BT_DUAL_HEADSET_CONNECT
313 void _bt_check_already_connected_headset(int type, char *address)
314 {
315         GList *node;
316         char connected_address[BT_ADDRESS_STRING_SIZE + 1];
317         bluetooth_device_address_t device_address;
318         int device_count = 0;
319
320         if (address != NULL) {
321                 node = g_list_first(g_connected_list);
322                 while (node != NULL) {
323                         bt_connected_headset_data_t *connected_device = node->data;
324                         if ((connected_device->type & type) &&
325                                 (g_strcmp0(connected_device->device_address, address) != 0)) {
326                                 device_count++;
327                                 /* Disconnect the earliest(1st) connected headset */
328                                 if (device_count == 1) {
329                                         g_strlcpy(connected_address,
330                                                 connected_device->device_address,
331                                                 BT_ADDRESS_STRING_SIZE + 1);
332                                         BT_DBG("Earliest/First Connected headset %s",
333                                                 connected_address);
334                                 } else if (device_count == MAX_CONNECTED_HEADSET) {
335                                         _bt_convert_addr_string_to_type(device_address.addr,
336                                                 connected_address);
337                                         _bt_audio_disconnect(0, type, &device_address, NULL);
338                                         return;
339                                 }
340                         }
341                         node = g_list_next(node);
342                 }
343         }
344 }
345 #endif
346
347 gboolean _bt_is_headset_type_connected(int type, char *address)
348 {
349         GList *node;
350
351         node = g_list_first(g_connected_list);
352         while (node != NULL) {
353                 bt_connected_headset_data_t *connected_device = node->data;
354
355                 if (connected_device->type & type) {
356                         if (address != NULL)
357                                 g_strlcpy(address, connected_device->device_address,
358                                                 BT_ADDRESS_STRING_SIZE + 1);
359                         return TRUE;
360                 }
361
362                 node = g_list_next(node);
363         }
364         return FALSE;
365 }
366
367 #ifdef TIZEN_SUPPORT_DUAL_HF
368 gboolean __bt_is_companion_device(const char *addr)
369 {
370         if (TIZEN_PROFILE_WEARABLE) {
371                 char *host_device_address = NULL;
372                 host_device_address = vconf_get_str(VCONF_KEY_BT_HOST_BT_MAC_ADDR);
373
374                 if (!host_device_address) {
375                         BT_INFO("Failed to get a companion device address");
376                         return FALSE;
377                 }
378
379                 if (g_strcmp0(host_device_address, addr) == 0) {
380                         BT_INFO("Found companion device");
381                         free(host_device_address);
382                         return TRUE;
383                 }
384
385                 free(host_device_address);
386                 return FALSE;
387         } else {
388                 /* TODO : Need to add companion device check condition for Phone models */
389                 return FALSE;
390         }
391 }
392 #endif
393
394 static int __bt_is_headset_connected(int type, int req_id,
395                                 const char *address)
396 {
397         gboolean connected = FALSE;
398         char connected_address[BT_ADDRESS_STRING_SIZE + 1];
399         bluetooth_device_address_t device_address;
400         bt_connected_headset_data_t *connected_device = NULL;
401 #ifdef TIZEN_SUPPORT_DUAL_HF
402         gboolean is_companion_device = FALSE;
403 #endif
404
405         /* Check if any other headset is connected */
406         GList *node = NULL;;
407
408         node = g_list_first(g_connected_list);
409         while (node != NULL) {
410                 connected_device = node->data;
411                 if ((connected_device->type & type)) {
412 #ifdef TIZEN_BT_DUAL_HEADSET_CONNECT
413                         device_count++;
414                         /* Disconnect the earliest(1st) connected headset */
415                         if (device_count == 1)
416                                 g_strlcpy(connected_address, connected_device->device_address,
417                                         BT_ADDRESS_STRING_SIZE + 1);
418
419                         if (g_strcmp0(connected_device->device_address, address) == 0)
420                                 return BLUETOOTH_ERROR_ALREADY_CONNECT;
421 #else
422                         g_strlcpy(connected_address, connected_device->device_address,
423                                         BT_ADDRESS_STRING_SIZE + 1);
424 #endif
425 #ifdef TIZEN_SUPPORT_DUAL_HF
426                         is_companion_device = __bt_is_companion_device(connected_address);
427                         BT_INFO(" is_companion_device[%d]", is_companion_device);
428
429                         if (!is_companion_device) {
430                                 connected = TRUE;
431                                 break;
432                         }
433 #else
434 #ifdef TIZEN_BT_DUAL_HEADSET_CONNECT
435                         if (device_count == MAX_CONNECTED_HEADSET) {
436                                 connected = TRUE;
437                                 break;
438                         }
439 #else
440                         connected = TRUE;
441                         break;
442 #endif
443 #endif
444                 }
445                 node = g_list_next(node);
446         }
447
448         if (!connected) {
449                 __bt_free_wait_data();
450                 return BLUETOOTH_ERROR_NOT_CONNECTED;
451         }
452
453         BT_DBG("connected headset %s", connected_address);
454
455         if (g_strcmp0(connected_address, address) == 0)
456                 return BLUETOOTH_ERROR_ALREADY_CONNECT;
457 #ifdef TIZEN_SUPPORT_DUAL_HF
458         else if (TRUE == __bt_is_companion_device(address))
459                 return BLUETOOTH_ERROR_NOT_CONNECTED;
460 #endif
461
462         /* Convert BD adress from string type */
463         _bt_convert_addr_string_to_type(device_address.addr, connected_address);
464         int value = BLUETOOTH_ERROR_NONE;
465         value = _bt_audio_disconnect(0, connected_device->type & type, &device_address, NULL);
466
467         /* If already one device is waiting, remove current waiting device and add new */
468         if (value == BLUETOOTH_ERROR_NONE) {
469                 if (g_wait_data != NULL) {
470                         if (g_strcmp0(g_wait_data->address, address) != 0) {
471                                 __bt_remove_device_from_wait_list();
472                                 __bt_free_wait_data();
473                         }
474                 }
475
476                 if (g_wait_data == NULL) {
477                         g_wait_data = g_malloc0(sizeof(bt_headset_wait_t));
478                         g_wait_data->address = g_strdup(address);
479                         g_wait_data->req_id = req_id;
480                         g_wait_data->type = type;
481                         g_wait_data->ag_flag = FALSE;
482
483                         /* Set disconnection type */
484                         __bt_set_headset_disconnection_type(connected_address);
485                 }
486         }
487
488         return value;
489 }
490
491 static int __bt_is_headset_connecting(int type)
492 {
493         bt_connected_headset_data_t *connected_device = NULL;
494
495         /* Check if any other headset is connected */
496         GList *node = NULL;
497
498         node = g_list_first(g_connected_list);
499         while (node != NULL) {
500                 connected_device = node->data;
501                 if (connected_device->device_state == BT_STATE_CONNECTING)
502                         return BLUETOOTH_ERROR_CONNECTION_BUSY;
503                 node = g_list_next(node);
504         }
505
506         return BLUETOOTH_ERROR_NONE;
507 }
508
509 int __bt_is_headset_disconnecting(int type)
510 {
511         bt_connected_headset_data_t *connected_device = NULL;
512
513         /* Check if any other headset is connected */
514         GList *node = NULL;
515
516         node = g_list_first(g_connected_list);
517         while (node != NULL) {
518                 connected_device = node->data;
519                 if (connected_device->device_state == BT_STATE_DISCONNECTING)
520                         return BLUETOOTH_ERROR_CONNECTION_BUSY;
521
522                 node = g_list_next(node);
523         }
524
525         return BLUETOOTH_ERROR_NONE;
526 }
527
528 void _bt_set_audio_wait_data_flag(gboolean flag)
529 {
530         BT_DBG("_bt_set_audio_wait_data_flag \n");
531         g_wait_data->ag_flag = flag;
532 }
533
534 bt_headset_wait_t *_bt_get_audio_wait_data(void)
535 {
536         BT_DBG("_bt_get_audio_wait_data \n");
537         return g_wait_data;
538 }
539
540 void _bt_rel_wait_data(void)
541 {
542         BT_DBG("_bt_rel_wait_data \n");
543         __bt_free_wait_data();
544 }
545
546 void _bt_add_headset_to_list(int type, int status, const char *address)
547 {
548         bt_connected_headset_data_t *connected_device;
549         bt_connected_headset_data_t *device;
550         GList *node;
551
552         BT_DBG("_bt_add_headset_to_list \n");
553
554         node = g_list_first(g_connected_list);
555         while (node != NULL) {
556                 device = (bt_connected_headset_data_t *)node->data;
557
558                 if (g_strcmp0(device->device_address, address) == 0) {
559                         BT_DBG("Address match, update connection type \n");
560                         if (status == BT_STATE_CONNECTED)
561                                 device->type |= type;
562                         device->device_state = status;
563                         return;
564                 }
565                 node = g_list_next(node);
566         }
567
568         connected_device = g_malloc0(sizeof(bt_connected_headset_data_t));
569         connected_device->device_state = status;
570         if ((status == BT_STATE_CONNECTED) || (status == BT_STATE_CONNECTING))
571                 connected_device->type |= type;
572         g_strlcpy(connected_device->device_address, address,
573                         sizeof(connected_device->device_address));
574         g_connected_list = g_list_append(g_connected_list, connected_device);
575 }
576
577 int _bt_get_device_state_from_list(int type, const char *address)
578 {
579         GList *node;
580         bt_connected_headset_data_t *device;
581
582         BT_DBG("+");
583         node = g_list_first(g_connected_list);
584         while (node != NULL) {
585                 device = (bt_connected_headset_data_t *)node->data;
586                 if (g_strcmp0(device->device_address, address) == 0) {
587                         BT_DBG("Device found");
588                         return device->device_state;
589                 }
590                 node = g_list_next(node);
591         }
592
593         BT_DBG("Device not found");
594         return BLUETOOTH_ERROR_INTERNAL;
595 }
596
597 void _bt_remove_headset_from_list(int type, const char *address)
598 {
599         GList *node;
600
601         BT_DBG("_bt_remove_headset_from_list \n");
602
603         node = g_list_first(g_connected_list);
604         while (node != NULL) {
605                 bt_connected_headset_data_t *connected_device = node->data;
606
607                 if (g_strcmp0(connected_device->device_address, address) != 0) {
608                         node = g_list_next(node);
609                         continue;
610                 }
611
612                 BT_DBG("Address match \n");
613
614                 BT_DBG("Connection type = %x\n", connected_device->type);
615
616                 switch (type) {
617                 case BT_AUDIO_A2DP:
618                         if (connected_device->type & BT_AUDIO_A2DP)
619                                 connected_device->type &= ~(BT_AUDIO_A2DP);
620                         break;
621                 case BT_AUDIO_HSP:
622                         if (connected_device->type & BT_AUDIO_HSP)
623                                 connected_device->type &= ~(BT_AUDIO_HSP);
624                         break;
625                 case BT_AUDIO_ALL:
626                         if (connected_device->type & BT_AUDIO_ALL)
627                                 connected_device->type &= ~(BT_AUDIO_ALL);
628                         break;
629                 case BT_AVRCP:
630                         if (connected_device->type & BT_AVRCP)
631                                 connected_device->type &= ~(BT_AVRCP);
632                         break;
633                 case BT_AUDIO_A2DP_SOURCE:
634                         if (connected_device->type & BT_AUDIO_A2DP_SOURCE)
635                                 connected_device->type &= ~(BT_AUDIO_A2DP_SOURCE);
636                 }
637
638                 BT_DBG("Connection type = %x\n", connected_device->type);
639
640                 if (connected_device->type == 0x00) {
641                         g_connected_list = g_list_remove(g_connected_list, connected_device);
642                         g_free(connected_device);
643                 } else {
644                         connected_device->device_state = BT_STATE_CONNECTED;
645                 }
646
647                 node = g_list_next(node);
648         }
649 }
650
651 static gboolean __bt_device_support_uuid(char *remote_address,
652                                 bt_audio_type_t type)
653 {
654         GArray *dev_list = NULL;
655         int size;
656         int i;
657         int j;
658         bluetooth_device_info_t info;
659         char bond_address[BT_ADDRESS_STRING_SIZE] = { 0 };
660         gboolean ret = FALSE;
661
662         BT_DBG("+");
663
664         dev_list = g_array_new(FALSE, FALSE, sizeof(gchar));
665
666         _bt_get_bonded_devices(&dev_list);
667         size = (dev_list->len) / sizeof(bluetooth_device_info_t);
668
669         for (i = 0; i < size; i++) {
670                 info = g_array_index(dev_list, bluetooth_device_info_t, i);
671                 _bt_convert_addr_type_to_string(bond_address,
672                                 info.device_address.addr);
673                 if (strcmp(bond_address, remote_address) != 0)
674                         continue;
675
676                 BT_INFO("Device address Matched");
677                 j = 0;
678                 while (j != info.service_index) {
679                         if (type == BT_AUDIO_HSP) {
680                                 if (strcmp(info.uuids[j], HFP_HS_UUID) == 0) {
681                                         BT_INFO("HFP HS UUID exists");
682                                         ret = TRUE;
683                                         goto end;
684                                 }
685                         } else if (type == BT_AUDIO_A2DP) {
686                                 if (strcmp(info.uuids[j], A2DP_SINK_UUID) == 0) {
687                                         BT_INFO("A2DP SINK UUID exists");
688                                         ret = TRUE;
689                                         goto end;
690                                 }
691                         }
692                         j++;
693                 }
694         }
695 end:
696         g_array_free(dev_list, TRUE);
697         BT_DBG("-");
698         return ret;
699 }
700
701 gboolean _bt_is_service_connected(char* address, int type)
702 {
703         GList *node;
704
705         node = g_list_first(g_connected_list);
706         while (node != NULL) {
707                 bt_connected_headset_data_t *conn_device = node->data;
708
709                 if ((g_strcmp0(conn_device->device_address, address) == 0) &&
710                         (conn_device->type & type)) {
711                                 BT_INFO("Service connected");
712                                 return TRUE;
713                 }
714
715                 node = g_list_next(node);
716         }
717         BT_INFO("Service not connected");
718         return FALSE;
719 }
720
721 int _bt_audio_connect(int request_id, int type,
722                 bluetooth_device_address_t *device_address,
723                 GArray *out_param1)
724 {
725         int result = BLUETOOTH_ERROR_NONE;
726         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
727         GDBusProxy *adapter_proxy;
728         GDBusConnection *g_conn;
729         int ret;
730         char *uuid = NULL;
731         int value = BLUETOOTH_ERROR_NONE;
732         bt_audio_function_data_t *func_data;
733         guint hfp_hs_trusted = TRUE; /* set default "allowed" */
734         guint a2dp_trusted = TRUE;
735
736         BT_CHECK_PARAMETER(device_address, return);
737
738         adapter_proxy = _bt_get_adapter_proxy();
739         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
740
741         g_conn = _bt_gdbus_get_system_gconn();
742         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
743
744         _bt_convert_addr_type_to_string(address, device_address->addr);
745
746         func_data = g_malloc0(sizeof(bt_audio_function_data_t));
747         func_data->address = g_strdup(address);
748         func_data->req_id = request_id;
749         func_data->type = type;
750         func_data->pending = BT_PENDING_NONE;
751
752         result = _bt_get_trust_profile(device_address, TRUSTED_PROFILE_HFP_HF, &hfp_hs_trusted);
753         if (result != BLUETOOTH_ERROR_NONE)
754                 BT_ERR("Can't get hfp_hs restriction info");
755
756         result = _bt_get_trust_profile(device_address, TRUSTED_PROFILE_A2DP, &a2dp_trusted);
757         if (result != BLUETOOTH_ERROR_NONE)
758                 BT_ERR("Can't get a2dp restriction info");
759
760         switch (type) {
761         case BT_AUDIO_HSP:
762                 uuid = HFP_HS_UUID;
763                 break;
764         case BT_AUDIO_A2DP:
765                 uuid = A2DP_SINK_UUID;
766                 break;
767         case BT_AVRCP:
768                 uuid = AVRCP_TARGET_UUID;
769                 break;
770         case BT_AUDIO_A2DP_SOURCE:
771                 uuid = A2DP_SOURCE_UUID;
772                 break;
773         case BT_AUDIO_ALL:
774                 if ((hfp_hs_trusted == TRUE) && (a2dp_trusted == TRUE)) { /* in case of both profiles are not restricted */
775                         if (__bt_device_support_uuid(address, BT_AUDIO_HSP)) {
776                                 uuid = HFP_HS_UUID;
777                                 func_data->pending = BT_PENDING_CONNECT;
778                                 type = BT_AUDIO_HSP;
779                         } else if (__bt_device_support_uuid(address, BT_AUDIO_A2DP)) {
780                                 uuid = A2DP_SINK_UUID;
781                                 type = BT_AUDIO_A2DP;
782                         } else {
783                                 BT_ERR("No audio role supported");
784                                 result = BLUETOOTH_ERROR_SERVICE_NOT_FOUND;
785                                 goto fail;
786                         }
787                 } else if ((hfp_hs_trusted == FALSE) && (a2dp_trusted == FALSE)) { /* in case of both profiles are restricted */
788                         BT_ERR("All profiles are restricted");
789                         result = BLUETOOTH_ERROR_INTERNAL;
790                         goto fail;
791                 } else if (a2dp_trusted == FALSE) { /* in case of a2dp is restricted, only connection for hfp_hs */
792                         if (__bt_device_support_uuid(address, BT_AUDIO_HSP)) {
793                                 uuid = HFP_HS_UUID;
794                                 type = BT_AUDIO_HSP;
795                         } else {
796                                 BT_ERR("HFP_HS role is not supported");
797                                 result = BLUETOOTH_ERROR_SERVICE_NOT_FOUND;
798                                 goto fail;
799                         }
800                 } else if (hfp_hs_trusted == FALSE) { /* in case of hfp_hs is restricted, only connection for a2dp */
801                         if (__bt_device_support_uuid(address, BT_AUDIO_A2DP)) {
802                                 uuid = A2DP_SINK_UUID;
803                                 type = BT_AUDIO_A2DP;
804                         } else {
805                                 BT_ERR("A2DP role is not supported");
806                                 result = BLUETOOTH_ERROR_SERVICE_NOT_FOUND;
807                                 goto fail;
808                         }
809                 }
810                 break;
811         case BT_AVRCP_TARGET:
812                 uuid = AVRCP_REMOTE_UUID;
813                 break;
814         default:
815                 BT_ERR("Unknown role");
816                 result = BLUETOOTH_ERROR_INTERNAL;
817                 goto fail;
818         }
819         BT_INFO("Connecting to service %s", uuid);
820         /* First Check if device is in connecting state if it than return error */
821         value = __bt_is_headset_connecting(type);
822         if (value != BLUETOOTH_ERROR_NONE) {
823                 result = BLUETOOTH_ERROR_IN_PROGRESS;
824                 goto fail;
825         }
826
827         value = __bt_is_headset_connected(type, request_id, address);
828
829         if (value == BLUETOOTH_ERROR_ALREADY_CONNECT) {
830                 result = BLUETOOTH_ERROR_ALREADY_CONNECT;
831                 goto fail;
832         } else if (value == BLUETOOTH_ERROR_NOT_CONNECTED) {
833                 _bt_headset_set_local_connection(TRUE);
834                 ret = _bt_connect_profile(address, uuid,
835                                 __bt_audio_request_cb, func_data);
836
837                 if (ret != BLUETOOTH_ERROR_NONE) {
838                         BT_ERR("_bt_connect_profile Error");
839                         _bt_headset_set_local_connection(FALSE);
840                         g_free(func_data->address);
841                         g_free(func_data);
842                         return ret;
843                 }
844
845                 /* Add data to the connected list */
846                 _bt_add_headset_to_list(type, BT_STATE_CONNECTING, address);
847         } else if (value == BLUETOOTH_ERROR_IN_PROGRESS) {
848                 result = BLUETOOTH_ERROR_IN_PROGRESS;
849                 goto fail;
850         }
851
852         return BLUETOOTH_ERROR_NONE;
853 fail:
854         if (out_param1 != NULL)
855                 g_array_append_vals(out_param1, address,
856                                 BT_ADDRESS_STR_LEN);
857
858         g_free(func_data->address);
859         g_free(func_data);
860
861         return result;
862 }
863
864 int _bt_audio_disconnect(int request_id, int type,
865                 bluetooth_device_address_t *device_address,
866                 GArray *out_param1)
867 {
868         int result = BLUETOOTH_ERROR_NONE;
869         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
870         bt_audio_function_data_t *func_data;
871         GDBusProxy *adapter_proxy;
872         GDBusConnection *g_conn;
873         GList *node;
874         int ret;
875         char *uuid;
876         int value = BLUETOOTH_ERROR_NONE;
877
878         BT_CHECK_PARAMETER(device_address, return);
879
880         adapter_proxy = _bt_get_adapter_proxy();
881         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
882
883         g_conn = _bt_gdbus_get_system_gconn();
884         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
885
886         _bt_convert_addr_type_to_string(address, device_address->addr);
887
888         func_data = g_malloc0(sizeof(bt_audio_function_data_t));
889         func_data->address = g_strdup(address);
890         func_data->req_id = request_id;
891         func_data->pending = BT_PENDING_NONE;
892         func_data->type = type;
893
894         switch (type) {
895         case BT_AUDIO_HSP:
896                 uuid = HFP_HS_UUID;
897                 break;
898         case BT_AUDIO_A2DP:
899                 uuid = A2DP_SINK_UUID;
900                 break;
901         case BT_AVRCP:
902                 uuid = AVRCP_TARGET_UUID;
903                 break;
904         case BT_AUDIO_A2DP_SOURCE:
905                 uuid = A2DP_SOURCE_UUID;
906                 break;
907         case BT_AUDIO_ALL:
908                 if (_bt_is_service_connected(address, BT_AUDIO_A2DP)) {
909                         uuid = A2DP_SINK_UUID;
910                         func_data->pending = BT_PENDING_DISCONNECT;
911                 } else if (_bt_is_service_connected(address, BT_AUDIO_HSP)) {
912                         uuid = HFP_HS_UUID;
913                 } else {
914                         BT_ERR("No audio service connected");
915                         result = BLUETOOTH_ERROR_NOT_CONNECTED;
916                         goto fail;
917                 }
918                 break;
919         case BT_AVRCP_TARGET:
920                 uuid = AVRCP_REMOTE_UUID;
921                 break;
922         default:
923                 BT_ERR("Unknown role");
924                 result = BLUETOOTH_ERROR_INTERNAL;
925                 goto fail;
926         }
927         value = __bt_is_headset_disconnecting(type);
928         if (value != BLUETOOTH_ERROR_NONE) {
929                 BT_INFO("Disconnect in progress");
930                 result = BLUETOOTH_ERROR_IN_PROGRESS;
931                 goto fail;
932         }
933         BT_INFO("Disconnecting service %s", uuid);
934         ret = _bt_disconnect_profile(address, uuid,
935                         __bt_audio_request_cb, func_data);
936
937         if (ret != BLUETOOTH_ERROR_NONE) {
938                 BT_ERR("_bt_disconnect_profile Error");
939                 g_free(func_data->address);
940                 g_free(func_data);
941                 return ret;
942         }
943
944         /*
945          *      This logic is added for dual HF mode issue.
946          */
947         node = g_list_first(g_connected_list);
948         while (node != NULL) {
949                 bt_connected_headset_data_t *connected_device = node->data;
950
951                 if (g_strcmp0(connected_device->device_address, address) == 0) {
952                         BT_DBG("Connection type update");
953                         type = connected_device->type;
954                         break;
955                 }
956                 node = g_list_next(node);
957         }
958         _bt_add_headset_to_list(type, BT_STATE_DISCONNECTING, address);
959
960         return BLUETOOTH_ERROR_NONE;
961 fail:
962         if (out_param1 != NULL)
963                 g_array_append_vals(out_param1, address,
964                                 BT_ADDRESS_STR_LEN);
965
966         g_free(func_data->address);
967         g_free(func_data);
968
969         return result;
970 }
971
972 void _bt_remove_from_connected_list(const char *address)
973 {
974         bt_connected_headset_data_t *connected_device;
975         GList *node;
976
977         node = g_list_first(g_connected_list);
978         while (node != NULL) {
979                 connected_device = node->data;
980                 if (connected_device != NULL &&
981                 g_strcmp0(connected_device->device_address, address) == 0) {
982                         BT_ERR("Device is removed from the list");
983                         g_connected_list = g_list_remove(g_connected_list, connected_device);
984                         g_free(connected_device);
985                         return;
986                 }
987                 node = g_list_next(node);
988         }
989 }
990
991 int _bt_hf_connect(int request_id,
992                 bluetooth_device_address_t *device_address,
993                 GArray *out_param1)
994 {
995         int result = BLUETOOTH_ERROR_NONE;
996         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
997         bt_function_data_t *func_data;
998         GDBusProxy *adapter_proxy;
999         GDBusConnection *g_conn;
1000         gboolean connected = FALSE;
1001         int ret;
1002         char *uuid;
1003
1004         BT_CHECK_PARAMETER(device_address, return);
1005
1006         _bt_convert_addr_type_to_string(address, device_address->addr);
1007
1008         adapter_proxy = _bt_get_adapter_proxy();
1009         if (adapter_proxy == NULL) {
1010                 result = BLUETOOTH_ERROR_INTERNAL;
1011                 goto fail;
1012         }
1013
1014         g_conn = _bt_gdbus_get_system_gconn();
1015         if (g_conn == NULL) {
1016                 result = BLUETOOTH_ERROR_INTERNAL;
1017                 goto fail;
1018         }
1019
1020         /* Check if HF is connected or not */
1021         result = _bt_is_device_connected(device_address, BT_PROFILE_CONN_HFG, &connected);
1022         if (connected == TRUE) {
1023                 BT_ERR("HF is already connected");
1024                 result = BLUETOOTH_ERROR_ALREADY_CONNECT;
1025                 goto fail;
1026         }
1027
1028         func_data = g_malloc0(sizeof(bt_function_data_t));
1029         func_data->address = g_strdup(address);
1030         func_data->req_id = request_id;
1031         uuid = g_strdup(HFP_AG_UUID);
1032
1033         BT_DBG("Connecting to service %s", uuid);
1034
1035         ret = _bt_connect_profile(address, uuid,
1036                         __bt_hf_request_cb, func_data);
1037
1038         if (ret != BLUETOOTH_ERROR_NONE) {
1039                 BT_ERR("_bt_connect_profile Error");
1040                 g_free(func_data->address);
1041                 g_free(func_data);
1042                 g_free(uuid);
1043                 return ret;
1044         }
1045         g_free(uuid);
1046         if (out_param1)
1047                 g_array_free(out_param1, TRUE);
1048
1049         return BLUETOOTH_ERROR_NONE;
1050 fail:
1051         if (out_param1 != NULL)
1052                 g_array_append_vals(out_param1, address,
1053                                 BT_ADDRESS_STR_LEN);
1054
1055         return result;
1056 }
1057
1058 int _bt_hf_disconnect(int request_id,
1059                 bluetooth_device_address_t *device_address,
1060                 GArray *out_param1)
1061 {
1062         int result = BLUETOOTH_ERROR_NONE;
1063         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1064         bt_function_data_t *func_data;
1065         GDBusProxy *adapter_proxy;
1066         GDBusConnection *g_conn;
1067
1068         int ret;
1069         char *uuid;
1070
1071         BT_CHECK_PARAMETER(device_address, return);
1072
1073         _bt_convert_addr_type_to_string(address, device_address->addr);
1074
1075         adapter_proxy = _bt_get_adapter_proxy();
1076         if (adapter_proxy == NULL) {
1077                 result = BLUETOOTH_ERROR_INTERNAL;
1078                 goto fail;
1079         }
1080
1081         g_conn = _bt_gdbus_get_system_gconn();
1082         if (g_conn == NULL) {
1083                 result = BLUETOOTH_ERROR_INTERNAL;
1084                 goto fail;
1085         }
1086
1087         func_data = g_malloc0(sizeof(bt_function_data_t));
1088         func_data->address = g_strdup(address);
1089         func_data->req_id = request_id;
1090         uuid = g_strdup(HFP_AG_UUID);
1091
1092         BT_DBG("Disconnecting service %s", uuid);
1093         ret = _bt_disconnect_profile(address, uuid,
1094                         __bt_hf_request_cb, func_data);
1095
1096         if (ret != BLUETOOTH_ERROR_NONE) {
1097                 BT_ERR("_bt_disconnect_profile Error");
1098                 g_free(func_data->address);
1099                 g_free(func_data);
1100                 g_free(uuid);
1101                 return ret;
1102         }
1103         g_free(uuid);
1104
1105         return BLUETOOTH_ERROR_NONE;
1106 fail:
1107         if (out_param1 != NULL)
1108                 g_array_append_vals(out_param1, address,
1109                                 BT_ADDRESS_STR_LEN);
1110
1111         return result;
1112 }
1113
1114 int _bt_audio_set_content_protect(gboolean status)
1115 {
1116         GDBusConnection *conn;
1117         GError *error = NULL;
1118
1119         BT_DBG("+\n");
1120
1121         conn = _bt_gdbus_get_system_gconn();
1122         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1123
1124         BT_DBG("Content Protection status = [%d]", status);
1125
1126         g_dbus_connection_emit_signal(conn,
1127                         NULL, BT_CONTENT_PROTECTION_PATH,
1128                         BT_CONTENT_PROTECTION_INTERFACE,
1129                         "ProtectionRequired",
1130                         g_variant_new("(b)", status),
1131                         &error);
1132
1133         if (error) {
1134                 /* dBUS gives error cause */
1135                 ERR("Could not Emit Signal: errCode[%x], message[%s]",
1136                         error->code, error->message);
1137                 g_clear_error(&error);
1138                 return BLUETOOTH_ERROR_INTERNAL;
1139         }
1140
1141         BT_DBG("Emit Signal done = [ProtectionRequired]");
1142         return BLUETOOTH_ERROR_NONE;
1143 }
1144
1145 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
1146 static void __bt_auto_connect_request_cb(GDBusProxy *proxy, GAsyncResult *res,
1147                                     gpointer user_data)
1148 {
1149         GError *err = NULL;
1150         GVariant *reply = NULL;
1151
1152         reply = g_dbus_proxy_call_finish(proxy, res, &err);
1153         g_object_unref(proxy);
1154         g_variant_unref(reply);
1155
1156         BT_DBG("+");
1157         if (err != NULL) {
1158                 g_dbus_error_strip_remote_error(err);
1159                 BT_INFO("Auto_connect_request Dbus Call Error: %s", err->message);
1160
1161                 if (strcmp("Host is down", err->message)) {
1162                         BT_INFO("Fail reason is not 'Host Down'. Terminate auto connect");
1163                         _bt_audio_stop_auto_connect();
1164                         vconf_set_str(BT_LAST_CONNECTED_DEVICE, "");
1165                 }
1166         }
1167         g_clear_error(&err);
1168 }
1169
1170
1171 // It is the function that retry to create alarm.
1172 // Sometimes alarm mgr service is created later than bluetooth-frwk service in booting time.
1173 // So, in this case, we have to retry alarmmgr_add_alarm.
1174 static gboolean __bt_audio_alarm_retry_cb(gpointer data)
1175 {
1176         int result;
1177         alarm_id_t alarm_id;
1178
1179         BT_DBG("__bt_audio_alarm_retry_cb called.");
1180         result = _bt_service_set_alarm(BT_AUTO_CONNECT_TIMEOUT_AFTER_LINKLOSS,
1181                                                 __bt_auto_connect_alarm_cb, NULL, &alarm_id);
1182
1183         if (result != BLUETOOTH_ERROR_NONE)
1184                 return TRUE;
1185         else
1186                 auto_connect_timer.alarm_id = alarm_id;
1187
1188         return FALSE;
1189 }
1190
1191 static int __bt_auto_connect_alarm_cb(alarm_id_t alarm_id, void* user_param)
1192 {
1193         int result = BLUETOOTH_ERROR_NONE;
1194         char *address = NULL;
1195         alarm_id_t new_alarm_id;
1196
1197         BT_INFO("alram id = [%d] , retry_count [%d] ",
1198                                                 alarm_id, auto_connect_timer.retry_count);
1199
1200         if (alarm_id != auto_connect_timer.alarm_id)
1201                 return 0;
1202
1203         address = vconf_get_str(BT_LAST_CONNECTED_DEVICE);
1204
1205         if (address == NULL) {
1206                 BT_ERR("Address vconf is null");
1207                 auto_connect_timer.alarm_id = 0;
1208                 return 0;
1209         }
1210
1211         BT_DBG("ADDRESS [%s]", address);
1212
1213         result = _bt_connect_profile(address, A2DP_SOURCE_UUID,
1214                         __bt_auto_connect_request_cb, NULL);
1215
1216         auto_connect_timer.retry_count--;
1217
1218         BT_DBG("result [%d]", result);
1219
1220         if (auto_connect_timer.retry_count <= 0) {
1221                 BT_INFO("Stopping Auto connect retry");
1222                 auto_connect_timer.alarm_id = 0;
1223         } else {
1224                 result = _bt_service_set_alarm(BT_AUTO_CONNECT_TIMEOUT_AFTER_LINKLOSS,
1225                                                 __bt_auto_connect_alarm_cb, NULL, &new_alarm_id);
1226                 if (result == BLUETOOTH_ERROR_NONE)
1227                         auto_connect_timer.alarm_id = new_alarm_id;
1228         }
1229
1230         free(address);
1231         return 0;
1232 }
1233
1234 static void __bt_auto_connect_alarm_remove()
1235 {
1236         BT_DBG("");
1237         if (auto_connect_timer.alarm_id > 0) {
1238                 _bt_service_remove_alarm(auto_connect_timer.alarm_id);
1239                 auto_connect_timer.alarm_id = 0;
1240         }
1241         auto_connect_timer.retry_count = 0;
1242 }
1243
1244 int _bt_audio_start_auto_connect(gboolean linkloss_flag)
1245 {
1246         int result = BLUETOOTH_ERROR_NONE;
1247         char *address = NULL;
1248         alarm_id_t alarm_id = 0;
1249
1250         BT_DBG("");
1251
1252         address = vconf_get_str(BT_LAST_CONNECTED_DEVICE);
1253
1254         if (address == NULL) {
1255                 BT_ERR("No target device");
1256                 return 0;
1257         }
1258
1259         __bt_auto_connect_alarm_remove();
1260
1261         auto_connect_timer.retry_count =  BT_AUTO_CONNECT_TIMEOUT_RETRY_TIME /
1262                                                 BT_AUTO_CONNECT_TIMEOUT_AFTER_LINKLOSS;
1263
1264         if (linkloss_flag) {
1265                 BT_INFO("Start auto connection after linkloss");
1266                 result = _bt_service_set_alarm(BT_AUTO_CONNECT_TIMEOUT_AFTER_LINKLOSS,
1267                                                 __bt_auto_connect_alarm_cb, NULL, &alarm_id);
1268                 if (result != BLUETOOTH_ERROR_NONE)
1269                         g_timeout_add(500, (GSourceFunc)__bt_audio_alarm_retry_cb, NULL);
1270                 else
1271                         auto_connect_timer.alarm_id = alarm_id;
1272
1273         } else {
1274                 BT_INFO("Start auto connection after BT activated");
1275                 result = _bt_service_set_alarm(BT_AUTO_CONNECT_TIMEOUT_AFTER_BT_ACTIVATED,
1276                                                 __bt_auto_connect_alarm_cb, NULL, &alarm_id);
1277                 if (result == BLUETOOTH_ERROR_NONE)
1278                         auto_connect_timer.alarm_id = alarm_id;
1279         }
1280
1281         free(address);
1282         return BLUETOOTH_ERROR_NONE;
1283 }
1284
1285 int _bt_audio_stop_auto_connect(void)
1286 {
1287         BT_DBG("");
1288         __bt_auto_connect_alarm_remove();
1289
1290         return BLUETOOTH_ERROR_NONE;
1291 }
1292
1293 void _bt_audio_set_auto_connect_device_addr(const char *address)
1294 {
1295         if (address == NULL) {
1296                 BT_ERR("address is null");
1297                 return;
1298         }
1299
1300         BT_INFO("Last connected device is [%s]", address);
1301         vconf_set_str(BT_LAST_CONNECTED_DEVICE, address);
1302 }
1303 #endif /*TIZEN_BT_A2DP_SINK_AUTO_CONNECT */
1304
1305 int _bt_audio_select_role(bluetooth_audio_role_t role)
1306 {
1307
1308         GDBusProxy *proxy;
1309         GVariant *ret;
1310         GError *error = NULL;
1311         GDBusConnection *g_conn = _bt_gdbus_get_system_gconn();
1312         gchar *adapter_path = _bt_get_adapter_path();
1313
1314         BT_INFO("_bt_audio_select_role called [%d]", role);
1315
1316         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
1317         BT_INFO("Adapter Path = %s", adapter_path);
1318
1319         proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
1320                 BT_BLUEZ_NAME, adapter_path, BT_MEDIA_INTERFACE, NULL, &error);
1321
1322         g_free(adapter_path);
1323
1324         if (proxy == NULL) {
1325                 BT_ERR("Unable to create proxy");
1326
1327                 if (error) {
1328                         BT_ERR("Error: %s", error->message);
1329                         g_clear_error(&error);
1330                 }
1331
1332                 return BLUETOOTH_ERROR_INTERNAL;
1333         }
1334
1335         if (role == BLUETOOTH_A2DP_SOURCE)
1336                 ret = g_dbus_proxy_call_sync(proxy, "SelectRole", g_variant_new("(s)", "source"),
1337                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1338         else
1339                 ret = g_dbus_proxy_call_sync(proxy, "SelectRole", g_variant_new("(s)", "sink"),
1340                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1341
1342         g_object_unref(proxy);
1343
1344         if (ret == NULL) {
1345                 BT_ERR("Call SelectRole Failed");
1346                 if (error) {
1347                         BT_ERR("errCode[%x], message[%s]", error->code, error->message);
1348                         g_clear_error(&error);
1349                 }
1350
1351                 return BLUETOOTH_ERROR_INTERNAL;
1352         }
1353
1354         g_variant_unref(ret);
1355         return BLUETOOTH_ERROR_NONE;
1356 }