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