Enhance debug message
[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         BT_DBG("-");
569         return BLUETOOTH_ERROR_NONE;
570 }
571
572 static int __bluetooth_hf_get_error(const char *error_message)
573 {
574         if (error_message == NULL) {
575                 BT_ERR("Error message NULL");
576                 return BLUETOOTH_ERROR_INTERNAL;
577         }
578
579         BT_ERR("Error message = %s", error_message);
580
581         if (g_strcmp0(error_message, "NotConnected") == 0)
582                 return BLUETOOTH_ERROR_NOT_CONNECTED;
583         else
584                 return BLUETOOTH_ERROR_INTERNAL;
585 }
586
587 BT_EXPORT_API int bluetooth_hf_init(bt_hf_func_ptr cb, void *user_data)
588 {
589         int ret;
590
591         if (cb == NULL) {
592                 BT_ERR("callback is NULL");
593                 return BLUETOOTH_ERROR_INVALID_PARAM;
594         }
595
596         ret = _bt_init_event_handler();
597
598         if (ret != BLUETOOTH_ERROR_NONE &&
599              ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
600                 BT_ERR("Fail to init the event handler");
601                 return ret;
602         }
603
604         _bt_set_user_data(BT_HF, (void *)cb, user_data);
605
606         /* Register All events */
607         ret = _bt_register_event(BT_HF_AGENT_EVENT, (void *)cb, user_data);
608         if (ret != BLUETOOTH_ERROR_NONE &&
609              ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
610                 _bt_deinit_event_handler();
611                 return ret;
612         }
613
614         return BLUETOOTH_ERROR_NONE;
615 }
616
617 BT_EXPORT_API int bluetooth_hf_deinit(void)
618 {
619         int ret;
620
621         ret = _bt_unregister_event(BT_HF_AGENT_EVENT);
622         if (ret != BLUETOOTH_ERROR_NONE)
623                 BT_ERR("_bt_unregister_event failed");
624
625         _bt_set_user_data(BT_HF, NULL, NULL);
626
627         return BLUETOOTH_ERROR_NONE;
628 }
629
630 BT_EXPORT_API int bluetooth_hf_connect(bluetooth_device_address_t *remote_address)
631 {
632         int result;
633         bt_user_info_t *user_info;
634
635         BT_CHECK_ENABLED(return);
636         BT_CHECK_PARAMETER(remote_address, return);
637
638         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HF_CONNECT)
639              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
640                 BT_ERR("Don't have a privilege to use this API");
641                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
642         }
643
644         user_info = _bt_get_user_data(BT_HF);
645         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
646
647         BT_INIT_PARAMS();
648         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
649
650         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
651
652         BT_INFO_C("### Connect HF");
653         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_HF_CONNECT,
654                 in_param1, in_param2, in_param3, in_param4,
655                 user_info->cb, user_info->user_data);
656
657         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
658
659         return result;
660 }
661
662 BT_EXPORT_API int bluetooth_hf_disconnect(bluetooth_device_address_t *remote_address)
663 {
664         int result;
665         bt_user_info_t *user_info;
666
667         BT_CHECK_PARAMETER(remote_address, return);
668         BT_CHECK_ENABLED(return);
669
670         if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HF_DISCONNECT)
671              == BLUETOOTH_ERROR_PERMISSION_DEINED) {
672                 BT_ERR("Don't have a privilege to use this API");
673                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
674         }
675
676         user_info = _bt_get_user_data(BT_HF);
677         retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
678
679         BT_INIT_PARAMS();
680         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
681
682         g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
683
684         BT_INFO_C("### Disconnect HF");
685         result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_HF_DISCONNECT,
686                 in_param1, in_param2, in_param3, in_param4,
687                 user_info->cb, user_info->user_data);
688
689         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
690
691         return result;
692 }
693
694 BT_EXPORT_API int bluetooth_hf_answer_call()
695 {
696         GVariant *reply = NULL;
697         GError *err = NULL;
698         int ret = BLUETOOTH_ERROR_INTERNAL;
699
700         BT_CHECK_ENABLED(return);
701
702         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
703                         "AnswerCall", &err, NULL);
704         if (!reply) {
705                 BT_ERR("Error returned in method call\n");
706                 if (err) {
707                         BT_ERR("Error = %s", err->message);
708                         g_dbus_error_strip_remote_error(err);
709                         ret = _bt_get_error_value_from_message(err->message);
710                         g_clear_error(&err);
711                 }
712                 return ret;
713         }
714
715         g_variant_unref(reply);
716         return BLUETOOTH_ERROR_NONE;
717
718 }
719
720 BT_EXPORT_API int bluetooth_hf_terminate_call()
721 {
722         GVariant *reply = NULL;
723         GError *err = NULL;
724         int ret = BLUETOOTH_ERROR_INTERNAL;
725
726         BT_CHECK_ENABLED(return);
727
728         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
729                         "TerminateCall", &err, NULL);
730         if (!reply) {
731                 BT_ERR("Error returned in method call\n");
732                 if (err) {
733                         BT_ERR("Error = %s", err->message);
734                         g_dbus_error_strip_remote_error(err);
735                         ret = _bt_get_error_value_from_message(err->message);
736                         g_clear_error(&err);
737                 }
738                 return ret;
739         }
740
741         g_variant_unref(reply);
742         return BLUETOOTH_ERROR_NONE;
743 }
744
745 BT_EXPORT_API int bluetooth_hf_initiate_call(char *number)
746 {
747         GVariant *reply = NULL;
748         GError *err = NULL;
749         GVariant *param = NULL;
750         int ret = BLUETOOTH_ERROR_INTERNAL;
751
752         BT_CHECK_ENABLED(return);
753
754         if (!number)
755                 number = "";
756
757         param = g_variant_new("(s)", number);
758         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
759                         "InitiateCall", &err, param);
760         if (!reply) {
761                 BT_ERR("Error returned in method call");
762                 if (err) {
763                         BT_ERR("Error = %s", err->message);
764                         g_dbus_error_strip_remote_error(err);
765                         ret = _bt_get_error_value_from_message(err->message);
766                         g_clear_error(&err);
767                 }
768                 return ret;
769         }
770
771         g_variant_unref(reply);
772         return BLUETOOTH_ERROR_NONE;
773 }
774
775 BT_EXPORT_API int bluetooth_hf_voice_recognition(unsigned int status)
776 {
777         GVariant *reply = NULL;
778         GError *err = NULL;
779         GVariant *param = NULL;
780         int ret = BLUETOOTH_ERROR_INTERNAL;
781
782         BT_CHECK_ENABLED(return);
783
784         param = g_variant_new("(i)", status);
785         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
786                         "VoiceRecognition", &err, param);
787         if (!reply) {
788                 BT_ERR("Error returned in method call\n");
789                 if (err) {
790                         BT_ERR("Error = %s", err->message);
791                         g_dbus_error_strip_remote_error(err);
792                         ret = _bt_get_error_value_from_message(err->message);
793                         g_clear_error(&err);
794                 }
795                 return ret;
796         }
797
798         g_variant_unref(reply);
799         return BLUETOOTH_ERROR_NONE;
800 }
801
802 BT_EXPORT_API int bluetooth_hf_audio_disconnect(void)
803 {
804         GVariant *reply = NULL;
805         GError *err = NULL;
806         int ret = BLUETOOTH_ERROR_INTERNAL;
807
808         BT_CHECK_ENABLED(return);
809
810         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
811                         "ScoDisconnect", &err, NULL);
812         if (!reply) {
813                 BT_ERR("Error returned in method call\n");
814                 if (err) {
815                         BT_ERR("Error = %s", err->message);
816                         g_dbus_error_strip_remote_error(err);
817                         ret = _bt_get_error_value_from_message(err->message);
818                         g_clear_error(&err);
819                 }
820                 return ret;
821         }
822
823         g_variant_unref(reply);
824         return BLUETOOTH_ERROR_NONE;
825 }
826
827 BT_EXPORT_API int bluetooth_hf_set_speaker_gain(unsigned int speaker_gain)
828 {
829         GVariant *reply = NULL;
830         GError *err = NULL;
831         GVariant *param = NULL;
832         int ret = BLUETOOTH_ERROR_INTERNAL;
833
834         BT_CHECK_ENABLED(return);
835
836         param = g_variant_new("(u)", speaker_gain);
837         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
838                         "SpeakerGain", &err, param);
839         if (!reply) {
840                 BT_ERR("Error returned in method call\n");
841                 if (err) {
842                         BT_ERR("Error = %s", err->message);
843                         g_dbus_error_strip_remote_error(err);
844                         ret = _bt_get_error_value_from_message(err->message);
845                         g_clear_error(&err);
846                 }
847                 return ret;
848         }
849
850         g_variant_unref(reply);
851         return BLUETOOTH_ERROR_NONE;
852 }
853
854 BT_EXPORT_API int bluetooth_hf_send_dtmf(char *dtmf)
855 {
856         GVariant *reply = NULL;
857         GError *err = NULL;
858         GVariant *param = NULL;
859         int ret = BLUETOOTH_ERROR_INTERNAL;
860
861         BT_CHECK_ENABLED(return);
862
863         param = g_variant_new("(s)", dtmf);
864         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
865                         "SendDtmf", &err, param);
866         if (!reply) {
867                 BT_ERR("Error returned in method call\n");
868                 if (err) {
869                         BT_ERR("Error = %s", err->message);
870                         g_dbus_error_strip_remote_error(err);
871                         ret = _bt_get_error_value_from_message(err->message);
872                         g_clear_error(&err);
873                 }
874                 return ret;
875         }
876
877         g_variant_unref(reply);
878         return BLUETOOTH_ERROR_NONE;
879 }
880
881 BT_EXPORT_API int bluetooth_hf_send_xsat_cmd(int app_id, char *xsat_cmd)
882 {
883         GVariant *reply = NULL;
884         GError *err = NULL;
885         GVariant *param = NULL;
886         char buffer[200] = {0,};
887         char *ptr = buffer;
888         int ret = BLUETOOTH_ERROR_INTERNAL;
889
890         BT_CHECK_ENABLED(return);
891
892         strncpy(buffer, "AT+XSAT=\0", 200);
893         snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer),
894                 "%d,", app_id);
895         strncat(buffer, xsat_cmd, (sizeof(buffer) - 1) - strlen(buffer));
896         BT_DBG("Xsat cmd received = %s", buffer);
897
898         param = g_variant_new("(s)", ptr);
899
900         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
901                                         "SendAtCmd", &err, param);
902         if (!reply) {
903                 BT_ERR("Error returned in method call\n");
904                 if (err) {
905                         BT_ERR("Error = %s", err->message);
906                         g_dbus_error_strip_remote_error(err);
907                         ret = _bt_get_error_value_from_message(err->message);
908                         g_clear_error(&err);
909                 }
910                 return ret;
911         }
912
913         g_variant_unref(reply);
914         return BLUETOOTH_ERROR_NONE;
915 }
916
917 BT_EXPORT_API int bluetooth_hf_release_and_accept(void)
918 {
919         GVariant *reply = NULL;
920         GError *err = NULL;
921         int ret = BLUETOOTH_ERROR_INTERNAL;
922
923         BT_CHECK_ENABLED(return);
924
925         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
926                         "ReleaseAndAccept", &err, NULL);
927         if (!reply) {
928                 BT_ERR("Error returned in method call\n");
929                 if (err) {
930                         BT_ERR("Error = %s", err->message);
931                         g_dbus_error_strip_remote_error(err);
932                         ret = _bt_get_error_value_from_message(err->message);
933                         g_clear_error(&err);
934                 }
935                 return ret;
936         }
937
938         g_variant_unref(reply);
939         return BLUETOOTH_ERROR_NONE;
940 }
941
942 BT_EXPORT_API int bluetooth_hf_swap_call(void)
943 {
944         GVariant *reply = NULL;
945         GError *err = NULL;
946         int ret = BLUETOOTH_ERROR_INTERNAL;
947
948         BT_CHECK_ENABLED(return);
949
950         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
951                         "CallSwap", &err, NULL);
952         if (!reply) {
953                 BT_ERR("Error returned in method call\n");
954                 if (err) {
955                         BT_ERR("Error = %s", err->message);
956                         g_dbus_error_strip_remote_error(err);
957                         ret = _bt_get_error_value_from_message(err->message);
958                         g_clear_error(&err);
959                 }
960                 return ret;
961         }
962
963         g_variant_unref(reply);
964         return BLUETOOTH_ERROR_NONE;
965 }
966
967 BT_EXPORT_API int bluetooth_hf_release_all_call(void)
968 {
969         GVariant *reply = NULL;
970         GError *err = NULL;
971         int ret = BLUETOOTH_ERROR_INTERNAL;
972
973         BT_CHECK_ENABLED(return);
974
975         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
976                         "ReleaseAllCall", &err, NULL);
977         if (!reply) {
978                 BT_ERR("Error returned in method call\n");
979                 if (err) {
980                         BT_ERR("Error = %s", err->message);
981                         g_dbus_error_strip_remote_error(err);
982                         ret = _bt_get_error_value_from_message(err->message);
983                         g_clear_error(&err);
984                 }
985                 return ret;
986         }
987
988         g_variant_unref(reply);
989         return BLUETOOTH_ERROR_NONE;
990 }
991
992 BT_EXPORT_API int bluetooth_hf_join_call(void)
993 {
994         GVariant *reply = NULL;
995         GError *err = NULL;
996         int ret = BLUETOOTH_ERROR_INTERNAL;
997
998         BT_CHECK_ENABLED(return);
999
1000         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1001                         "JoinCall", &err, NULL);
1002         if (!reply) {
1003                 BT_ERR("Error returned in method call\n");
1004                 if (err) {
1005                         BT_ERR("Error = %s", err->message);
1006                         g_dbus_error_strip_remote_error(err);
1007                         ret = _bt_get_error_value_from_message(err->message);
1008                         g_clear_error(&err);
1009                 }
1010                 return ret;
1011         }
1012
1013         g_variant_unref(reply);
1014         return BLUETOOTH_ERROR_NONE;
1015 }
1016
1017 BT_EXPORT_API int bluetooth_hf_get_call_list(void *call_list,
1018                                                                 bt_hf_call_status_info_t **call_status)
1019 {
1020         int i;
1021         GList *list = call_list;
1022         int call_count;
1023         bt_hf_call_status_info_t * call_info;
1024
1025         BT_CHECK_ENABLED(return);
1026         retv_if(list == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1027         retv_if(call_status == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1028
1029         call_count = g_list_length(list);
1030
1031         BT_DBG(" call_count = [%d]", call_count);
1032
1033         for (i = 0; i < call_count; i++) {
1034                 call_info = g_list_nth_data(list, i);
1035                 BT_DBG(" direction = [%d]", call_info->direction);
1036                 BT_DBG(" status = [%d]", call_info->status);
1037                 BT_DBG(" mpart = [%d]", call_info->mpart);
1038                 BT_DBG(" number = [%s]", call_info->number);
1039                 BT_DBG(" idx = [%d]", call_info->idx);
1040                 call_status[i] = call_info;
1041         }
1042
1043         return BLUETOOTH_ERROR_NONE;
1044 }
1045
1046 BT_EXPORT_API int bluetooth_hf_free_call_list(bt_hf_call_list_s *call_list)
1047 {
1048         bt_hf_call_list_s *handle;
1049         bt_hf_call_status_info_t *call_status;
1050
1051         retv_if(call_list == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1052
1053         handle = (bt_hf_call_list_s *)call_list;
1054         do  {
1055                 call_status = (bt_hf_call_status_info_t *)g_list_nth_data(
1056                                                         handle->list, 0);
1057                 if (call_status == NULL)
1058                         break;
1059                 handle->list = g_list_remove(handle->list, call_status);
1060                 g_free(call_status->number);
1061                 g_free(call_status);
1062         } while (1);
1063         g_free(handle);
1064         return BLUETOOTH_ERROR_NONE;
1065 }
1066
1067 BT_EXPORT_API int bluetooth_hf_request_call_list(
1068                                         bt_hf_call_list_s **call_list)
1069 {
1070         GVariant *reply = NULL;
1071         GError *err = NULL;
1072
1073         BT_CHECK_ENABLED(return);
1074
1075         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1076                         "RequestCallList", &err, NULL);
1077         if (!reply) {
1078                 BT_ERR("dbus Error or call list is null\n");
1079                 if (err) {
1080                         BT_ERR("Error = %s", err->message);
1081                         g_clear_error(&err);
1082                 }
1083                 *call_list = NULL;
1084                 return BLUETOOTH_ERROR_INTERNAL;
1085         }
1086         __bt_hf_agent_read_call_list(reply, call_list);
1087
1088         g_variant_unref(reply);
1089         return BLUETOOTH_ERROR_NONE;
1090 }
1091
1092 BT_EXPORT_API int bluetooth_hf_request_call_list_async(void)
1093 {
1094         GVariant *reply = NULL;
1095         GError *err = NULL;
1096         int ret = BLUETOOTH_ERROR_INTERNAL;
1097
1098         BT_CHECK_ENABLED(return);
1099
1100         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1101                         "RequestCallListAsync", &err, NULL);
1102         if (!reply) {
1103                 BT_ERR("Error returned in method call\n");
1104                 if (err) {
1105                         BT_ERR("Error = %s", err->message);
1106                         if (strstr(err->message, "No data"))
1107                                 ret = BLUETOOTH_ERROR_NO_DATA;
1108                         else if (strstr(err->message, "NotConnected"))
1109                                 ret = BLUETOOTH_ERROR_NOT_CONNECTED;
1110                         g_clear_error(&err);
1111                 }
1112                 return ret;
1113         }
1114
1115         g_variant_unref(reply);
1116         return BLUETOOTH_ERROR_NONE;
1117 }
1118
1119 BT_EXPORT_API int bluetooth_hf_get_codec(unsigned int *codec_id)
1120 {
1121         GVariant *reply = NULL;
1122         GError *err = NULL;
1123         int32_t current_codec;
1124
1125         BT_CHECK_ENABLED(return);
1126
1127         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1128                         "GetCurrentCodec", &err, NULL);
1129         if (!reply) {
1130                 BT_ERR("Error returned in method call\n");
1131                 if (err) {
1132                         BT_ERR("Error = %s", err->message);
1133                         g_clear_error(&err);
1134                 }
1135                 return BLUETOOTH_ERROR_INTERNAL;
1136         }
1137
1138         g_variant_get(reply, "(i)", &current_codec);
1139         *codec_id = current_codec;
1140         BT_DBG(" Codec ID is : %d", *codec_id);
1141
1142         g_variant_unref(reply);
1143         return BLUETOOTH_ERROR_NONE;
1144 }
1145
1146 BT_EXPORT_API int bluetooth_hf_get_audio_connected(unsigned int *audio_connected)
1147 {
1148         GVariant *reply = NULL;
1149         GError *err = NULL;
1150         int32_t sco_audio_connected_from_bt_agent;
1151
1152         BT_CHECK_ENABLED(return);
1153
1154         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1155                         "GetAudioConnected", &err, NULL);
1156         if (!reply) {
1157                 BT_ERR("Error returned in method call\n");
1158                 if (err) {
1159                         BT_ERR("Error = %s", err->message);
1160                         g_clear_error(&err);
1161                 }
1162                 return BLUETOOTH_ERROR_INTERNAL;
1163         }
1164
1165         g_variant_get(reply, "(i)", &sco_audio_connected_from_bt_agent);
1166         *audio_connected = sco_audio_connected_from_bt_agent;
1167
1168         if (*audio_connected == BLUETOOTH_HF_AUDIO_CONNECTED)
1169                 BT_DBG("SCO Audio is Connected");
1170         else
1171                 BT_DBG("SCO Audio is Disconnected");
1172
1173         g_variant_unref(reply);
1174         return BLUETOOTH_ERROR_NONE;
1175 }
1176
1177 BT_EXPORT_API int bluetooth_hf_is_connected(gboolean *hf_connected)
1178 {
1179         GVariant *reply = NULL;
1180         GError *err = NULL;
1181         gboolean hf_connected_from_bt_agent;
1182
1183         BT_CHECK_ENABLED(return);
1184
1185         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1186                         "IsHfConnected", &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, "(b)", &hf_connected_from_bt_agent);
1197         *hf_connected = hf_connected_from_bt_agent;
1198
1199         BT_DBG("%s", *hf_connected ? "Connected" : "Disconnected");
1200
1201         g_variant_unref(reply);
1202         return BLUETOOTH_ERROR_NONE;
1203 }
1204
1205 BT_EXPORT_API int bluetooth_hf_is_ibr_supported(gboolean *ibr_supported)
1206 {
1207         GVariant *reply = NULL;
1208         GError *err = NULL;
1209         gboolean is_supported;
1210         int ret = BLUETOOTH_ERROR_NONE;
1211
1212         BT_CHECK_ENABLED(return);
1213
1214         reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1215                         "IsInbandRingtoneSupported", &err, NULL);
1216         if (!reply) {
1217                 BT_ERR("Error returned in method call");
1218                 if (err) {
1219                         g_dbus_error_strip_remote_error(err);
1220                         ret = __bluetooth_hf_get_error(err->message);
1221                         g_error_free(err);
1222                         return ret;
1223                 }
1224                 return BLUETOOTH_ERROR_INTERNAL;
1225         }
1226
1227         g_variant_get(reply, "(b)", &is_supported);
1228         *ibr_supported = is_supported;
1229
1230         BT_DBG("%s", *ibr_supported ? "Supported" : "Not Supported");
1231
1232         g_variant_unref(reply);
1233         return ret;
1234 }