Fix issue where server mtu changed callback ws not called
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-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 <stdio.h>
19
20 #include "bluetooth-api.h"
21 #include "bluetooth-audio-api.h"
22 #include "bt-internal-types.h"
23
24 #include "bt-common.h"
25 #include "bt-request-sender.h"
26 #include "bt-event-handler.h"
27 #include "bt-dpm.h"
28
29 BT_EXPORT_API int bluetooth_audio_init(bt_audio_func_ptr cb, void *user_data)
30 {
31         int ret;
32
33         if (cb == NULL) {
34                 BT_ERR("callback is NULL");
35                 return BLUETOOTH_ERROR_INVALID_PARAM;
36         }
37         ret = _bt_init_event_handler();
38
39         if (ret != BLUETOOTH_ERROR_NONE &&
40              ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
41                 BT_ERR("Fail to init the event handler");
42                 return ret;
43         }
44
45         _bt_set_user_data(BT_AUDIO, (void *)cb, user_data);
46
47         /* Register All events */
48         ret = _bt_register_event(BT_HEADSET_EVENT, (void *)cb, user_data);
49         if (ret != BLUETOOTH_ERROR_NONE &&
50             ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
51                 _bt_deinit_event_handler();
52                 return ret;
53         }
54
55         ret = _bt_register_event(BT_A2DP_SOURCE_EVENT, (void *)cb, user_data);
56         if (ret != BLUETOOTH_ERROR_NONE &&
57                         ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
58                 _bt_deinit_event_handler();
59                 return ret;
60         }
61
62         return BLUETOOTH_ERROR_NONE;
63 }
64
65 BT_EXPORT_API int bluetooth_audio_deinit(void)
66 {
67         _bt_unregister_event(BT_HEADSET_EVENT);
68         _bt_unregister_event(BT_A2DP_SOURCE_EVENT);
69         _bt_set_user_data(BT_AUDIO, NULL, NULL);
70
71         return BLUETOOTH_ERROR_NONE;
72 }
73
74 BT_EXPORT_API int bluetooth_audio_connect(bluetooth_device_address_t *remote_address)
75 {
76         int service_function = BT_AUDIO_CONNECT;
77         int result;
78         bt_user_info_t *user_info;
79
80         BT_CHECK_PARAMETER(remote_address, return);
81         BT_CHECK_ENABLED(return);
82
83         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AUDIO_CONNECT)
84              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
85                 BT_ERR("Don't have a privilege to use this API");
86                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
87         }
88
89         if (_bt_check_dpm(BT_DPM_ADDRESS, (void *)remote_address) == BT_DPM_RESTRICTED) {
90                 BT_ERR("Blocklist device");
91                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
92         }
93
94         if (_bt_check_dpm(BT_DPM_HSP, NULL) == BT_DPM_RESTRICTED &&
95                  _bt_check_dpm(BT_DPM_A2DP, NULL) == BT_DPM_RESTRICTED) {
96                 BT_ERR("Not allow to use HSP / A2DP profile");
97                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
98         } else if (_bt_check_dpm(BT_DPM_HSP, NULL) == BT_DPM_RESTRICTED) {
99                 BT_ERR("Not allow to use HSP profile");
100                 service_function = BT_AV_CONNECT;
101         } else if (_bt_check_dpm(BT_DPM_A2DP, NULL) == BT_DPM_RESTRICTED) {
102                 BT_ERR("Not allow to use A2DP profile");
103                 service_function = BT_AG_CONNECT;
104         }
105
106         if (_bt_check_dpm(BT_DPM_DESKTOP, NULL) == BT_DPM_RESTRICTED) {
107                 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
108                 bluetooth_device_class_t dev_class;
109
110                 _bt_convert_addr_type_to_string(address, remote_address->addr);
111                 _bt_get_cod_by_address(address, &dev_class);
112
113                 if (dev_class.major_class == BLUETOOTH_DEVICE_MAJOR_CLASS_COMPUTER) {
114                         BT_ERR("Reject a authorization due to MDM Policy");
115                         return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
116                 }
117         }
118
119         user_info = _bt_get_user_data(BT_AUDIO);
120         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
121
122         BT_INIT_PARAMS();
123         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
124
125         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
126
127         if (service_function == BT_AV_CONNECT)
128                 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AV_CONNECT,
129                                 in_param1, in_param2, in_param3, in_param4,
130                                 user_info->cb, user_info->user_data);
131         else if (service_function == BT_AG_CONNECT)
132                 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AG_CONNECT,
133                                 in_param1, in_param2, in_param3, in_param4,
134                                 user_info->cb, user_info->user_data);
135         else /* default case - with or without DPM enabled */
136
137                 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AUDIO_CONNECT,
138                                 in_param1, in_param2, in_param3, in_param4,
139                                 user_info->cb, user_info->user_data);
140
141         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
142
143         return result;
144 }
145
146 BT_EXPORT_API int bluetooth_audio_disconnect(bluetooth_device_address_t *remote_address)
147 {
148         int result;
149         bt_user_info_t *user_info;
150
151         BT_CHECK_PARAMETER(remote_address, return);
152         BT_CHECK_ENABLED(return);
153
154         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AUDIO_DISCONNECT)
155              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
156                 BT_ERR("Don't have a privilege to use this API");
157                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
158         }
159
160         user_info = _bt_get_user_data(BT_AUDIO);
161         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
162
163         BT_INIT_PARAMS();
164         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
165
166         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
167
168         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AUDIO_DISCONNECT,
169                 in_param1, in_param2, in_param3, in_param4,
170                 user_info->cb, user_info->user_data);
171
172         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
173
174         return result;
175 }
176
177 BT_EXPORT_API int bluetooth_ag_connect(bluetooth_device_address_t *remote_address)
178 {
179         int result;
180         bt_user_info_t *user_info;
181
182         BT_CHECK_PARAMETER(remote_address, return);
183         BT_CHECK_ENABLED(return);
184
185         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AG_CONNECT)
186              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
187                 BT_ERR("Don't have a privilege to use this API");
188                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
189         }
190
191         if (_bt_check_dpm(BT_DPM_ADDRESS, (void *)remote_address) == BT_DPM_RESTRICTED) {
192                 BT_ERR("Blocklist device");
193                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
194         }
195
196         if (_bt_check_dpm(BT_DPM_HSP, NULL) == BT_DPM_RESTRICTED) {
197                 BT_ERR("Not allow to use HSP profile");
198                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
199         }
200
201         if (_bt_check_dpm(BT_DPM_DESKTOP, NULL) == BT_DPM_RESTRICTED) {
202                 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
203                 bluetooth_device_class_t dev_class;
204
205                 _bt_convert_addr_type_to_string(address, remote_address->addr);
206                 _bt_get_cod_by_address(address, &dev_class);
207
208                 if (dev_class.major_class == BLUETOOTH_DEVICE_MAJOR_CLASS_COMPUTER) {
209                         BT_ERR("Reject a authorization due to MDM Policy");
210                         return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
211                 }
212         }
213
214         user_info = _bt_get_user_data(BT_AUDIO);
215         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
216
217         BT_INIT_PARAMS();
218         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
219
220         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
221
222         BT_INFO_C("### Connect AG");
223         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AG_CONNECT,
224                 in_param1, in_param2, in_param3, in_param4,
225                 user_info->cb, user_info->user_data);
226
227         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
228
229         return result;
230 }
231
232 BT_EXPORT_API int bluetooth_ag_disconnect(bluetooth_device_address_t *remote_address)
233 {
234         int result;
235         bt_user_info_t *user_info;
236
237         BT_CHECK_PARAMETER(remote_address, return);
238         BT_CHECK_ENABLED(return);
239
240         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AG_DISCONNECT)
241              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
242                 BT_ERR("Don't have a privilege to use this API");
243                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
244         }
245
246         user_info = _bt_get_user_data(BT_AUDIO);
247         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
248
249         BT_INIT_PARAMS();
250         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
251
252         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
253
254         BT_INFO_C("### Disconnect AG");
255         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AG_DISCONNECT,
256                 in_param1, in_param2, in_param3, in_param4,
257                 user_info->cb, user_info->user_data);
258
259         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
260
261         return result;
262 }
263
264 BT_EXPORT_API int bluetooth_av_connect(bluetooth_device_address_t *remote_address)
265 {
266         int result;
267         bt_user_info_t *user_info;
268
269         BT_CHECK_PARAMETER(remote_address, return);
270         BT_CHECK_ENABLED(return);
271
272         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AV_CONNECT)
273              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
274                 BT_ERR("Don't have a privilege to use this API");
275                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
276         }
277
278         if (_bt_check_dpm(BT_DPM_ADDRESS, (void *)remote_address) == BT_DPM_RESTRICTED) {
279                 BT_ERR("Blocklist device");
280                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
281         }
282
283         if (_bt_check_dpm(BT_DPM_A2DP, NULL) == BT_DPM_RESTRICTED) {
284                 BT_ERR("Not allow to use A2DP profile");
285                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
286         }
287
288         if (_bt_check_dpm(BT_DPM_DESKTOP, NULL) == BT_DPM_RESTRICTED) {
289                 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
290                 bluetooth_device_class_t dev_class;
291
292                 _bt_convert_addr_type_to_string(address, remote_address->addr);
293                 _bt_get_cod_by_address(address, &dev_class);
294
295                 if (dev_class.major_class == BLUETOOTH_DEVICE_MAJOR_CLASS_COMPUTER) {
296                         BT_ERR("Reject a authorization due to MDM Policy");
297                         return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
298                 }
299         }
300
301         user_info = _bt_get_user_data(BT_AUDIO);
302         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
303
304         BT_INIT_PARAMS();
305         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
306
307         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
308
309         BT_INFO_C("### Connect AV");
310         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AV_CONNECT,
311                 in_param1, in_param2, in_param3, in_param4,
312                 user_info->cb, user_info->user_data);
313
314         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
315
316         return result;
317 }
318
319 BT_EXPORT_API int bluetooth_av_source_connect(bluetooth_device_address_t *remote_address)
320 {
321         int result;
322         bt_user_info_t *user_info;
323
324         BT_CHECK_PARAMETER(remote_address, return);
325         BT_CHECK_ENABLED(return);
326
327         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AV_SOURCE_CONNECT)
328                  == BLUETOOTH_ERROR_PERMISSION_DEINED) {
329                 BT_ERR("Don't have a privilege to use this API");
330                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
331         }
332
333         if (_bt_check_dpm(BT_DPM_ADDRESS, (void *)remote_address) == BT_DPM_RESTRICTED) {
334                 BT_ERR("Blocklist device");
335                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
336         }
337
338         if (_bt_check_dpm(BT_DPM_A2DP, NULL) == BT_DPM_RESTRICTED) {
339                 BT_ERR("Not allow to use A2DP profile");
340                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
341         }
342
343         user_info = _bt_get_user_data(BT_AUDIO);
344         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
345
346         BT_INIT_PARAMS();
347         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
348
349         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
350
351         BT_INFO_C("### Connect AV Source");
352         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AV_SOURCE_CONNECT,
353                 in_param1, in_param2, in_param3, in_param4,
354                 user_info->cb, user_info->user_data);
355
356         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
357
358         return result;
359 }
360
361 BT_EXPORT_API int bluetooth_av_disconnect(bluetooth_device_address_t *remote_address)
362 {
363         int result;
364         bt_user_info_t *user_info;
365
366         BT_CHECK_PARAMETER(remote_address, return);
367         BT_CHECK_ENABLED(return);
368
369         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AV_DISCONNECT)
370              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
371                 BT_ERR("Don't have a privilege to use this API");
372                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
373         }
374
375         user_info = _bt_get_user_data(BT_AUDIO);
376         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
377
378         BT_INIT_PARAMS();
379         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
380
381         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
382
383         BT_INFO_C("### Disconnect AV");
384         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AV_DISCONNECT,
385                 in_param1, in_param2, in_param3, in_param4,
386                 user_info->cb, user_info->user_data);
387
388         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
389
390         return result;
391 }
392
393 BT_EXPORT_API int bluetooth_av_source_disconnect(bluetooth_device_address_t *remote_address)
394 {
395         int result;
396         bt_user_info_t *user_info;
397
398         BT_CHECK_PARAMETER(remote_address, return);
399         BT_CHECK_ENABLED(return);
400
401         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AV_SOURCE_DISCONNECT)
402              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
403                 BT_ERR("Don't have a privilege to use this API");
404                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
405         }
406
407         user_info = _bt_get_user_data(BT_AUDIO);
408         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
409
410         BT_INIT_PARAMS();
411         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
412
413         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
414
415         BT_INFO_C("### Disconnect AV Source");
416         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AV_SOURCE_DISCONNECT,
417                 in_param1, in_param2, in_param3, in_param4,
418                 user_info->cb, user_info->user_data);
419
420         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
421
422         return result;
423 }
424
425 BT_EXPORT_API int bluetooth_audio_select_role(bluetooth_audio_role_t role)
426 {
427         int result;
428
429         BT_CHECK_ENABLED(return);
430
431         BT_INIT_PARAMS();
432         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
433
434         g_array_append_vals(in_param1, &role, sizeof(bluetooth_audio_role_t));
435
436         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_AUDIO_SELECT_ROLE,
437                 in_param1, in_param2, in_param3, in_param4, &out_param);
438
439         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
440         return result;
441 }
442
443 BT_EXPORT_API int bluetooth_audio_set_absolute_volume(unsigned int volume)
444 {
445         int result;
446
447         BT_CHECK_ENABLED(return);
448
449         BT_INIT_PARAMS();
450         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
451
452         g_array_append_vals(in_param1, &volume, sizeof(unsigned int));
453
454         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_AUDIO_SET_ABSOLUTE_VOLUME,
455                 in_param1, in_param2, in_param3, in_param4, &out_param);
456
457         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
458         return result;
459 }
460
461 BT_EXPORT_API int bluetooth_audio_get_absolute_volume(unsigned int *volume)
462 {
463         int result;
464
465         BT_CHECK_PARAMETER(volume, return);
466         BT_CHECK_ENABLED(return);
467
468         BT_INIT_PARAMS();
469         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
470
471         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_AUDIO_GET_ABSOLUTE_VOLUME,
472                 in_param1, in_param2, in_param3, in_param4, &out_param);
473
474         if (result == BLUETOOTH_ERROR_NONE) {
475                 *volume = g_array_index(out_param,
476                                 unsigned int, 0);
477         }
478
479         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
480
481         return result;
482 }
483
484 BT_EXPORT_API int bluetooth_audio_is_avc_activated(bool *activated)
485 {
486         int result;
487
488         BT_CHECK_PARAMETER(activated, return);
489
490         if (bluetooth_check_adapter() == BLUETOOTH_ADAPTER_DISABLED) {
491                 BT_DBG("BT is not enabled. So activated value is false");
492                 *activated = false;
493                 return BLUETOOTH_ERROR_NONE;
494         }
495
496         BT_INIT_PARAMS();
497         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
498
499         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_AUDIO_IS_AVC_ACTIVATED,
500                 in_param1, in_param2, in_param3, in_param4, &out_param);
501
502         if (result == BLUETOOTH_ERROR_NONE) {
503                 *activated = g_array_index(out_param,
504                                 bool, 0);
505         }
506
507         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
508
509         return result;
510 }
511
512 BT_EXPORT_API int bluetooth_ag_get_headset_volume(unsigned int *speaker_gain)
513 {
514         int result;
515
516         BT_CHECK_PARAMETER(speaker_gain, return);
517         BT_CHECK_ENABLED(return);
518
519         BT_INIT_PARAMS();
520         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
521
522         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GET_SPEAKER_GAIN,
523                 in_param1, in_param2, in_param3, in_param4, &out_param);
524
525         if (result == BLUETOOTH_ERROR_NONE) {
526                 *speaker_gain = g_array_index(out_param,
527                                 unsigned int, 0);
528         }
529
530         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
531
532         return result;
533 }
534
535 BT_EXPORT_API int bluetooth_ag_set_speaker_gain(unsigned int speaker_gain)
536 {
537         int result;
538
539         BT_CHECK_ENABLED(return);
540
541         if (_bt_check_dpm(BT_DPM_HSP, NULL) == BT_DPM_RESTRICTED) {
542                 BT_ERR("Not allow to use HSP profile");
543                 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
544         }
545
546         BT_INIT_PARAMS();
547         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
548
549         g_array_append_vals(in_param1, &speaker_gain, sizeof(unsigned int));
550
551         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_SET_SPEAKER_GAIN,
552                 in_param1, in_param2, in_param3, in_param4, &out_param);
553
554         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
555
556         return result;
557 }
558
559 #define BT_HF_SERVICE_NAME "org.bluez.hf_agent"
560 #define BT_HF_OBJECT_PATH "/org/bluez/handsfree_agent"
561 #define BT_HF_INTERFACE "org.tizen.HfApp"
562
563
564 static GVariant* __bt_hf_agent_dbus_send(const char *path, const char *interface,
565                                 const char *method, GError **err, GVariant *parameters)
566 {
567         GVariant *reply = NULL;
568         GDBusProxy *proxy = NULL;
569         GDBusConnection *conn = NULL;
570
571         conn = _bt_get_system_common_conn();
572         retv_if(conn == NULL, NULL);
573
574         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
575                 NULL, BT_HF_SERVICE_NAME, path, interface, NULL, err);
576         if (proxy == NULL) {
577                 BT_ERR("Unable to allocate new proxy");
578                 return NULL;
579         }
580
581         reply = g_dbus_proxy_call_sync(proxy, method, parameters,
582                                 G_DBUS_CALL_FLAGS_NONE, -1, NULL, err);
583
584         g_object_unref(proxy);
585         return reply;
586 }
587
588 static int __bt_hf_agent_read_call_list(GVariant *reply,
589                                 bt_hf_call_list_s **call_list) {
590
591         GVariantIter iter;
592         GVariant *var_temp = NULL;
593         int32_t call_count;
594         gchar *num = NULL;
595         int dir, status, mpart, idx;
596
597         BT_DBG("+");
598
599         g_variant_get(reply, "(i@a(siiii))", &call_count, &var_temp);
600
601         if (call_count <= 0) {
602                 *call_list = NULL;
603                 return BLUETOOTH_ERROR_NOT_FOUND;
604         }
605         BT_DBG("Call count = %d", call_count);
606
607         *call_list = g_malloc0(sizeof(bt_hf_call_list_s));
608         (*call_list)->count = call_count;
609
610         g_variant_iter_init(&iter, var_temp);
611         while (g_variant_iter_loop(&iter, "(siiii)", &num, &dir, &status, &mpart, &idx)) {
612                 bt_hf_call_status_info_t *call_info;
613
614                 call_info = g_malloc0(sizeof(bt_hf_call_status_info_t));
615                 call_info->number = g_strdup(num);
616                 call_info->direction = dir;
617                 call_info->status = status;
618                 call_info->mpart = mpart;
619                 call_info->idx = idx;
620
621                 (*call_list)->list = g_list_append((*call_list)->list,
622                                                         (gpointer)call_info);
623         }
624
625         g_variant_unref(var_temp);
626         BT_DBG("-");
627         return BLUETOOTH_ERROR_NONE;
628 }
629
630 static int __bluetooth_hf_get_error(const char *error_message)
631 {
632         if (error_message == NULL) {
633                 BT_ERR("Error message NULL");
634                 return BLUETOOTH_ERROR_INTERNAL;
635         }
636
637         BT_ERR("Error message = %s", error_message);
638
639         if (g_strcmp0(error_message, "NotConnected") == 0)
640                 return BLUETOOTH_ERROR_NOT_CONNECTED;
641         else
642                 return BLUETOOTH_ERROR_INTERNAL;
643 }
644
645 BT_EXPORT_API int bluetooth_hf_init(bt_hf_func_ptr cb, void *user_data)
646 {
647         int ret;
648
649         if (cb == NULL) {
650                 BT_ERR("callback is NULL");
651                 return BLUETOOTH_ERROR_INVALID_PARAM;
652         }
653
654         ret = _bt_init_event_handler();
655
656         if (ret != BLUETOOTH_ERROR_NONE &&
657              ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
658                 BT_ERR("Fail to init the event handler");
659                 return ret;
660         }
661
662         _bt_set_user_data(BT_HF, (void *)cb, user_data);
663
664         /* Register All events */
665         ret = _bt_register_event(BT_HF_AGENT_EVENT, (void *)cb, user_data);
666         if (ret != BLUETOOTH_ERROR_NONE &&
667              ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
668                 _bt_deinit_event_handler();
669                 return ret;
670         }
671
672         return BLUETOOTH_ERROR_NONE;
673 }
674
675 BT_EXPORT_API int bluetooth_hf_deinit(void)
676 {
677         int ret;
678
679         ret = _bt_unregister_event(BT_HF_AGENT_EVENT);
680         if (ret != BLUETOOTH_ERROR_NONE)
681                 BT_ERR("_bt_unregister_event failed");
682
683         _bt_set_user_data(BT_HF, NULL, NULL);
684
685         return BLUETOOTH_ERROR_NONE;
686 }
687
688 BT_EXPORT_API int bluetooth_hf_connect(bluetooth_device_address_t *remote_address)
689 {
690         int result;
691         bt_user_info_t *user_info;
692
693         BT_CHECK_ENABLED(return);
694         BT_CHECK_PARAMETER(remote_address, return);
695
696         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HF_CONNECT)
697              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
698                 BT_ERR("Don't have a privilege to use this API");
699                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
700         }
701
702         user_info = _bt_get_user_data(BT_HF);
703         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
704
705         BT_INIT_PARAMS();
706         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
707
708         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
709
710         BT_INFO_C("### Connect HF");
711         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_HF_CONNECT,
712                 in_param1, in_param2, in_param3, in_param4,
713                 user_info->cb, user_info->user_data);
714
715         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
716
717         return result;
718 }
719
720 BT_EXPORT_API int bluetooth_hf_disconnect(bluetooth_device_address_t *remote_address)
721 {
722         int result;
723         bt_user_info_t *user_info;
724
725         BT_CHECK_PARAMETER(remote_address, return);
726         BT_CHECK_ENABLED(return);
727
728         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HF_DISCONNECT)
729              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
730                 BT_ERR("Don't have a privilege to use this API");
731                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
732         }
733
734         user_info = _bt_get_user_data(BT_HF);
735         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
736
737         BT_INIT_PARAMS();
738         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
739
740         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
741
742         BT_INFO_C("### Disconnect HF");
743         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_HF_DISCONNECT,
744                 in_param1, in_param2, in_param3, in_param4,
745                 user_info->cb, user_info->user_data);
746
747         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
748
749         return result;
750 }
751
752 BT_EXPORT_API int bluetooth_hf_answer_call()
753 {
754         GVariant *reply = NULL;
755         GError *err = NULL;
756         int ret = BLUETOOTH_ERROR_INTERNAL;
757
758         BT_CHECK_ENABLED(return);
759
760         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
761                         "AnswerCall", &err, NULL);
762         if (!reply) {
763                 BT_ERR("Error returned in method call\n");
764                 if (err) {
765                         BT_ERR("Error = %s", err->message);
766                         g_dbus_error_strip_remote_error(err);
767                         ret = _bt_get_error_value_from_message(err->message);
768                         g_clear_error(&err);
769                 }
770                 return ret;
771         }
772
773         g_variant_unref(reply);
774         return BLUETOOTH_ERROR_NONE;
775
776 }
777
778 BT_EXPORT_API int bluetooth_hf_terminate_call()
779 {
780         GVariant *reply = NULL;
781         GError *err = NULL;
782         int ret = BLUETOOTH_ERROR_INTERNAL;
783
784         BT_CHECK_ENABLED(return);
785
786         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
787                         "TerminateCall", &err, NULL);
788         if (!reply) {
789                 BT_ERR("Error returned in method call\n");
790                 if (err) {
791                         BT_ERR("Error = %s", err->message);
792                         g_dbus_error_strip_remote_error(err);
793                         ret = _bt_get_error_value_from_message(err->message);
794                         g_clear_error(&err);
795                 }
796                 return ret;
797         }
798
799         g_variant_unref(reply);
800         return BLUETOOTH_ERROR_NONE;
801 }
802
803 BT_EXPORT_API int bluetooth_hf_initiate_call(char *number)
804 {
805         GVariant *reply = NULL;
806         GError *err = NULL;
807         GVariant *param = NULL;
808         int ret = BLUETOOTH_ERROR_INTERNAL;
809
810         BT_CHECK_ENABLED(return);
811
812         if (!number)
813                 number = "";
814
815         param = g_variant_new("(s)", number);
816         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
817                         "InitiateCall", &err, param);
818         if (!reply) {
819                 BT_ERR("Error returned in method call");
820                 if (err) {
821                         BT_ERR("Error = %s", err->message);
822                         g_dbus_error_strip_remote_error(err);
823                         ret = _bt_get_error_value_from_message(err->message);
824                         g_clear_error(&err);
825                 }
826                 return ret;
827         }
828
829         g_variant_unref(reply);
830         return BLUETOOTH_ERROR_NONE;
831 }
832
833 BT_EXPORT_API int bluetooth_hf_voice_recognition(unsigned int status)
834 {
835         GVariant *reply = NULL;
836         GError *err = NULL;
837         GVariant *param = NULL;
838         int ret = BLUETOOTH_ERROR_INTERNAL;
839
840         BT_CHECK_ENABLED(return);
841
842         param = g_variant_new("(i)", status);
843         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
844                         "VoiceRecognition", &err, param);
845         if (!reply) {
846                 BT_ERR("Error returned in method call\n");
847                 if (err) {
848                         BT_ERR("Error = %s", err->message);
849                         g_dbus_error_strip_remote_error(err);
850                         ret = _bt_get_error_value_from_message(err->message);
851                         g_clear_error(&err);
852                 }
853                 return ret;
854         }
855
856         g_variant_unref(reply);
857         return BLUETOOTH_ERROR_NONE;
858 }
859
860 BT_EXPORT_API int bluetooth_hf_audio_disconnect(void)
861 {
862         GVariant *reply = NULL;
863         GError *err = NULL;
864         int ret = BLUETOOTH_ERROR_INTERNAL;
865
866         BT_CHECK_ENABLED(return);
867
868         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
869                         "ScoDisconnect", &err, NULL);
870         if (!reply) {
871                 BT_ERR("Error returned in method call\n");
872                 if (err) {
873                         BT_ERR("Error = %s", err->message);
874                         g_dbus_error_strip_remote_error(err);
875                         ret = _bt_get_error_value_from_message(err->message);
876                         g_clear_error(&err);
877                 }
878                 return ret;
879         }
880
881         g_variant_unref(reply);
882         return BLUETOOTH_ERROR_NONE;
883 }
884
885 BT_EXPORT_API int bluetooth_hf_set_speaker_gain(unsigned int speaker_gain)
886 {
887         GVariant *reply = NULL;
888         GError *err = NULL;
889         GVariant *param = NULL;
890         int ret = BLUETOOTH_ERROR_INTERNAL;
891
892         BT_CHECK_ENABLED(return);
893
894         param = g_variant_new("(u)", speaker_gain);
895         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
896                         "SpeakerGain", &err, param);
897         if (!reply) {
898                 BT_ERR("Error returned in method call\n");
899                 if (err) {
900                         BT_ERR("Error = %s", err->message);
901                         g_dbus_error_strip_remote_error(err);
902                         ret = _bt_get_error_value_from_message(err->message);
903                         g_clear_error(&err);
904                 }
905                 return ret;
906         }
907
908         g_variant_unref(reply);
909         return BLUETOOTH_ERROR_NONE;
910 }
911
912 BT_EXPORT_API int bluetooth_hf_send_dtmf(char *dtmf)
913 {
914         GVariant *reply = NULL;
915         GError *err = NULL;
916         GVariant *param = NULL;
917         int ret = BLUETOOTH_ERROR_INTERNAL;
918
919         BT_CHECK_ENABLED(return);
920
921         param = g_variant_new("(s)", dtmf);
922         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
923                         "SendDtmf", &err, param);
924         if (!reply) {
925                 BT_ERR("Error returned in method call\n");
926                 if (err) {
927                         BT_ERR("Error = %s", err->message);
928                         g_dbus_error_strip_remote_error(err);
929                         ret = _bt_get_error_value_from_message(err->message);
930                         g_clear_error(&err);
931                 }
932                 return ret;
933         }
934
935         g_variant_unref(reply);
936         return BLUETOOTH_ERROR_NONE;
937 }
938
939 BT_EXPORT_API int bluetooth_hf_send_xsat_cmd(int app_id, char *xsat_cmd)
940 {
941         GVariant *reply = NULL;
942         GError *err = NULL;
943         GVariant *param = NULL;
944         char buffer[200] = {0,};
945         char *ptr = buffer;
946         int ret = BLUETOOTH_ERROR_INTERNAL;
947
948         BT_CHECK_ENABLED(return);
949
950         strncpy(buffer, "AT+XSAT=\0", 200);
951         snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer),
952                 "%d,", app_id);
953         strncat(buffer, xsat_cmd, (sizeof(buffer) - 1) - strlen(buffer));
954         BT_DBG("Xsat cmd received = %s", buffer);
955
956         param = g_variant_new("(s)", ptr);
957
958         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
959                                         "SendAtCmd", &err, param);
960         if (!reply) {
961                 BT_ERR("Error returned in method call\n");
962                 if (err) {
963                         BT_ERR("Error = %s", err->message);
964                         g_dbus_error_strip_remote_error(err);
965                         ret = _bt_get_error_value_from_message(err->message);
966                         g_clear_error(&err);
967                 }
968                 return ret;
969         }
970
971         g_variant_unref(reply);
972         return BLUETOOTH_ERROR_NONE;
973 }
974
975 BT_EXPORT_API int bluetooth_hf_release_and_accept(void)
976 {
977         GVariant *reply = NULL;
978         GError *err = NULL;
979         int ret = BLUETOOTH_ERROR_INTERNAL;
980
981         BT_CHECK_ENABLED(return);
982
983         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
984                         "ReleaseAndAccept", &err, NULL);
985         if (!reply) {
986                 BT_ERR("Error returned in method call\n");
987                 if (err) {
988                         BT_ERR("Error = %s", err->message);
989                         g_dbus_error_strip_remote_error(err);
990                         ret = _bt_get_error_value_from_message(err->message);
991                         g_clear_error(&err);
992                 }
993                 return ret;
994         }
995
996         g_variant_unref(reply);
997         return BLUETOOTH_ERROR_NONE;
998 }
999
1000 BT_EXPORT_API int bluetooth_hf_swap_call(void)
1001 {
1002         GVariant *reply = NULL;
1003         GError *err = NULL;
1004         int ret = BLUETOOTH_ERROR_INTERNAL;
1005
1006         BT_CHECK_ENABLED(return);
1007
1008         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1009                         "CallSwap", &err, NULL);
1010         if (!reply) {
1011                 BT_ERR("Error returned in method call\n");
1012                 if (err) {
1013                         BT_ERR("Error = %s", err->message);
1014                         g_dbus_error_strip_remote_error(err);
1015                         ret = _bt_get_error_value_from_message(err->message);
1016                         g_clear_error(&err);
1017                 }
1018                 return ret;
1019         }
1020
1021         g_variant_unref(reply);
1022         return BLUETOOTH_ERROR_NONE;
1023 }
1024
1025 BT_EXPORT_API int bluetooth_hf_release_all_call(void)
1026 {
1027         GVariant *reply = NULL;
1028         GError *err = NULL;
1029         int ret = BLUETOOTH_ERROR_INTERNAL;
1030
1031         BT_CHECK_ENABLED(return);
1032
1033         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1034                         "ReleaseAllCall", &err, NULL);
1035         if (!reply) {
1036                 BT_ERR("Error returned in method call\n");
1037                 if (err) {
1038                         BT_ERR("Error = %s", err->message);
1039                         g_dbus_error_strip_remote_error(err);
1040                         ret = _bt_get_error_value_from_message(err->message);
1041                         g_clear_error(&err);
1042                 }
1043                 return ret;
1044         }
1045
1046         g_variant_unref(reply);
1047         return BLUETOOTH_ERROR_NONE;
1048 }
1049
1050 BT_EXPORT_API int bluetooth_hf_join_call(void)
1051 {
1052         GVariant *reply = NULL;
1053         GError *err = NULL;
1054         int ret = BLUETOOTH_ERROR_INTERNAL;
1055
1056         BT_CHECK_ENABLED(return);
1057
1058         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1059                         "JoinCall", &err, NULL);
1060         if (!reply) {
1061                 BT_ERR("Error returned in method call\n");
1062                 if (err) {
1063                         BT_ERR("Error = %s", err->message);
1064                         g_dbus_error_strip_remote_error(err);
1065                         ret = _bt_get_error_value_from_message(err->message);
1066                         g_clear_error(&err);
1067                 }
1068                 return ret;
1069         }
1070
1071         g_variant_unref(reply);
1072         return BLUETOOTH_ERROR_NONE;
1073 }
1074
1075 BT_EXPORT_API int bluetooth_hf_get_call_list(void *call_list,
1076                                                                 bt_hf_call_status_info_t **call_status)
1077 {
1078         int i;
1079         GList *list = call_list;
1080         int call_count;
1081         bt_hf_call_status_info_t * call_info;
1082
1083         BT_CHECK_ENABLED(return);
1084         retv_if(list == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1085         retv_if(call_status == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1086
1087         call_count = g_list_length(list);
1088
1089         BT_DBG(" call_count = [%d]", call_count);
1090
1091         for (i = 0; i < call_count; i++) {
1092                 call_info = g_list_nth_data(list, i);
1093                 BT_DBG(" direction = [%d]", call_info->direction);
1094                 BT_DBG(" status = [%d]", call_info->status);
1095                 BT_DBG(" mpart = [%d]", call_info->mpart);
1096                 BT_DBG(" number = [%s]", call_info->number);
1097                 BT_DBG(" idx = [%d]", call_info->idx);
1098                 call_status[i] = call_info;
1099         }
1100
1101         return BLUETOOTH_ERROR_NONE;
1102 }
1103
1104 BT_EXPORT_API int bluetooth_hf_free_call_list(bt_hf_call_list_s *call_list)
1105 {
1106         bt_hf_call_list_s *handle;
1107         bt_hf_call_status_info_t *call_status;
1108
1109         retv_if(call_list == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1110
1111         handle = (bt_hf_call_list_s *)call_list;
1112         do  {
1113                 call_status = (bt_hf_call_status_info_t *)g_list_nth_data(
1114                                                         handle->list, 0);
1115                 if (call_status == NULL)
1116                         break;
1117                 handle->list = g_list_remove(handle->list, call_status);
1118                 g_free(call_status->number);
1119                 g_free(call_status);
1120         } while (1);
1121         g_free(handle);
1122         return BLUETOOTH_ERROR_NONE;
1123 }
1124
1125 BT_EXPORT_API int bluetooth_hf_request_call_list(
1126                                         bt_hf_call_list_s **call_list)
1127 {
1128         GVariant *reply = NULL;
1129         GError *err = NULL;
1130
1131         BT_CHECK_ENABLED(return);
1132
1133         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1134                         "RequestCallList", &err, NULL);
1135         if (!reply) {
1136                 BT_ERR("dbus Error or call list is null\n");
1137                 if (err) {
1138                         BT_ERR("Error = %s", err->message);
1139                         g_clear_error(&err);
1140                 }
1141                 *call_list = NULL;
1142                 return BLUETOOTH_ERROR_INTERNAL;
1143         }
1144         __bt_hf_agent_read_call_list(reply, call_list);
1145
1146         g_variant_unref(reply);
1147         return BLUETOOTH_ERROR_NONE;
1148 }
1149
1150 BT_EXPORT_API int bluetooth_hf_request_call_list_async(void)
1151 {
1152         GVariant *reply = NULL;
1153         GError *err = NULL;
1154         int ret = BLUETOOTH_ERROR_INTERNAL;
1155
1156         BT_CHECK_ENABLED(return);
1157
1158         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1159                         "RequestCallListAsync", &err, NULL);
1160         if (!reply) {
1161                 BT_ERR("Error returned in method call\n");
1162                 if (err) {
1163                         BT_ERR("Error = %s", err->message);
1164                         if (strstr(err->message, "No data"))
1165                                 ret = BLUETOOTH_ERROR_NO_DATA;
1166                         else if (strstr(err->message, "NotConnected"))
1167                                 ret = BLUETOOTH_ERROR_NOT_CONNECTED;
1168                         g_clear_error(&err);
1169                 }
1170                 return ret;
1171         }
1172
1173         g_variant_unref(reply);
1174         return BLUETOOTH_ERROR_NONE;
1175 }
1176
1177 BT_EXPORT_API int bluetooth_hf_get_codec(unsigned int *codec_id)
1178 {
1179         GVariant *reply = NULL;
1180         GError *err = NULL;
1181         int32_t current_codec;
1182
1183         BT_CHECK_ENABLED(return);
1184
1185         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1186                         "GetCurrentCodec", &err, NULL);
1187         if (!reply) {
1188                 BT_ERR("Error returned in method call\n");
1189                 if (err) {
1190                         BT_ERR("Error = %s", err->message);
1191                         g_clear_error(&err);
1192                 }
1193                 return BLUETOOTH_ERROR_INTERNAL;
1194         }
1195
1196         g_variant_get(reply, "(i)", &current_codec);
1197         *codec_id = current_codec;
1198         BT_DBG(" Codec ID is : %d", *codec_id);
1199
1200         g_variant_unref(reply);
1201         return BLUETOOTH_ERROR_NONE;
1202 }
1203
1204 BT_EXPORT_API int bluetooth_hf_get_audio_connected(unsigned int *audio_connected)
1205 {
1206         GVariant *reply = NULL;
1207         GError *err = NULL;
1208         int32_t sco_audio_connected_from_bt_agent;
1209
1210         BT_CHECK_ENABLED(return);
1211
1212         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1213                         "GetAudioConnected", &err, NULL);
1214         if (!reply) {
1215                 BT_ERR("Error returned in method call\n");
1216                 if (err) {
1217                         BT_ERR("Error = %s", err->message);
1218                         g_clear_error(&err);
1219                 }
1220                 return BLUETOOTH_ERROR_INTERNAL;
1221         }
1222
1223         g_variant_get(reply, "(i)", &sco_audio_connected_from_bt_agent);
1224         *audio_connected = sco_audio_connected_from_bt_agent;
1225
1226         if (*audio_connected == BLUETOOTH_HF_AUDIO_CONNECTED)
1227                 BT_DBG("SCO Audio is Connected");
1228         else
1229                 BT_DBG("SCO Audio is Disconnected");
1230
1231         g_variant_unref(reply);
1232         return BLUETOOTH_ERROR_NONE;
1233 }
1234
1235 BT_EXPORT_API int bluetooth_hf_is_connected(gboolean *hf_connected)
1236 {
1237         GVariant *reply = NULL;
1238         GError *err = NULL;
1239         gboolean hf_connected_from_bt_agent;
1240
1241         BT_CHECK_ENABLED(return);
1242
1243         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1244                         "IsHfConnected", &err, NULL);
1245         if (!reply) {
1246                 BT_ERR("Error returned in method call\n");
1247                 if (err) {
1248                         BT_ERR("Error = %s", err->message);
1249                         g_clear_error(&err);
1250                 }
1251                 return BLUETOOTH_ERROR_INTERNAL;
1252         }
1253
1254         g_variant_get(reply, "(b)", &hf_connected_from_bt_agent);
1255         *hf_connected = hf_connected_from_bt_agent;
1256
1257         BT_DBG("%s", *hf_connected ? "Connected" : "Disconnected");
1258
1259         g_variant_unref(reply);
1260         return BLUETOOTH_ERROR_NONE;
1261 }
1262
1263 BT_EXPORT_API int bluetooth_hf_is_ibr_supported(gboolean *ibr_supported)
1264 {
1265         GVariant *reply = NULL;
1266         GError *err = NULL;
1267         gboolean is_supported;
1268         int ret = BLUETOOTH_ERROR_NONE;
1269
1270         BT_CHECK_ENABLED(return);
1271
1272         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1273                         "IsInbandRingtoneSupported", &err, NULL);
1274         if (!reply) {
1275                 BT_ERR("Error returned in method call");
1276                 if (err) {
1277                         g_dbus_error_strip_remote_error(err);
1278                         ret = __bluetooth_hf_get_error(err->message);
1279                         g_error_free(err);
1280                         return ret;
1281                 }
1282                 return BLUETOOTH_ERROR_INTERNAL;
1283         }
1284
1285         g_variant_get(reply, "(b)", &is_supported);
1286         *ibr_supported = is_supported;
1287
1288         BT_DBG("%s", *ibr_supported ? "Supported" : "Not Supported");
1289
1290         g_variant_unref(reply);
1291         return ret;
1292 }
1293
1294 static int __bluetooth_hf_audio_mute_onoff(bool is_mute)
1295 {
1296         GVariant *reply = NULL;
1297         GError *err = NULL;
1298         int ret = BLUETOOTH_ERROR_INTERNAL;
1299
1300         BT_CHECK_ENABLED(return);
1301         BT_DBG("HF Audio Mute %s", is_mute ? "ON" : "OFF");
1302
1303         if (is_mute)
1304                 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1305                                         "AudioMuteOn", &err, NULL);
1306         else
1307                 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1308                                         "AudioMuteOff", &err, NULL);
1309
1310         if (!reply) {
1311                 BT_ERR("Error returned in method call\n");
1312                 if (err) {
1313                        BT_ERR("Error = %s", err->message);
1314                        g_dbus_error_strip_remote_error(err);
1315                        ret = _bt_get_error_value_from_message(err->message);
1316                        g_clear_error(&err);
1317                 }
1318                 return ret;
1319         }
1320
1321         g_variant_unref(reply);
1322         return BLUETOOTH_ERROR_NONE;
1323 }
1324
1325 BT_EXPORT_API int bluetooth_hf_audio_mute_on()
1326 {
1327         return __bluetooth_hf_audio_mute_onoff(true);
1328 }
1329
1330 BT_EXPORT_API int bluetooth_hf_audio_mute_off()
1331 {
1332         return __bluetooth_hf_audio_mute_onoff(false);
1333 }