2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include "bluetooth-api.h"
21 #include "bluetooth-audio-api.h"
22 #include "bt-internal-types.h"
24 #include "bt-common.h"
25 #include "bt-request-sender.h"
26 #include "bt-event-handler.h"
29 BT_EXPORT_API int bluetooth_audio_init(bt_audio_func_ptr cb, void *user_data)
34 BT_ERR("callback is NULL");
35 return BLUETOOTH_ERROR_INVALID_PARAM;
37 ret = _bt_init_event_handler();
39 if (ret != BLUETOOTH_ERROR_NONE &&
40 ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
41 BT_ERR("Fail to init the event handler");
45 _bt_set_user_data(BT_AUDIO, (void *)cb, user_data);
47 /* Register All events */
48 ret = _bt_register_event(BT_HEADSET_EVENT, (void *)cb, user_data);
49 if (ret != BLUETOOTH_ERROR_NONE &&
50 ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
51 _bt_deinit_event_handler();
55 ret = _bt_register_event(BT_A2DP_SOURCE_EVENT, (void *)cb, user_data);
56 if (ret != BLUETOOTH_ERROR_NONE &&
57 ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
58 _bt_deinit_event_handler();
62 return BLUETOOTH_ERROR_NONE;
65 BT_EXPORT_API int bluetooth_audio_deinit(void)
67 _bt_unregister_event(BT_HEADSET_EVENT);
68 _bt_unregister_event(BT_A2DP_SOURCE_EVENT);
69 _bt_set_user_data(BT_AUDIO, NULL, NULL);
71 return BLUETOOTH_ERROR_NONE;
74 BT_EXPORT_API int bluetooth_audio_connect(bluetooth_device_address_t *remote_address)
76 int service_function = BT_AUDIO_CONNECT;
78 bt_user_info_t *user_info;
80 BT_CHECK_PARAMETER(remote_address, return);
81 BT_CHECK_ENABLED(return);
83 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AUDIO_CONNECT)
84 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
85 BT_ERR("Don't have a privilege to use this API");
86 return BLUETOOTH_ERROR_PERMISSION_DEINED;
89 if (_bt_check_dpm(BT_DPM_ADDRESS, (void *)remote_address) == BT_DPM_RESTRICTED) {
90 BT_ERR("Blacklist device");
91 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
94 if (_bt_check_dpm(BT_DPM_HSP, NULL) == BT_DPM_RESTRICTED &&
95 _bt_check_dpm(BT_DPM_A2DP, NULL) == BT_DPM_RESTRICTED) {
96 BT_ERR("Not allow to use HSP / A2DP profile");
97 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
98 } else if (_bt_check_dpm(BT_DPM_HSP, NULL) == BT_DPM_RESTRICTED) {
99 BT_ERR("Not allow to use HSP profile");
100 service_function = BT_AV_CONNECT;
101 } else if (_bt_check_dpm(BT_DPM_A2DP, NULL) == BT_DPM_RESTRICTED) {
102 BT_ERR("Not allow to use A2DP profile");
103 service_function = BT_AG_CONNECT;
106 if (_bt_check_dpm(BT_DPM_DESKTOP, NULL) == BT_DPM_RESTRICTED) {
107 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
108 bluetooth_device_class_t dev_class;
110 _bt_convert_addr_type_to_string(address, remote_address->addr);
111 _bt_get_cod_by_address(address, &dev_class);
113 if (dev_class.major_class == BLUETOOTH_DEVICE_MAJOR_CLASS_COMPUTER) {
114 BT_ERR("Reject a authorization due to MDM Policy");
115 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
119 user_info = _bt_get_user_data(BT_AUDIO);
120 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
123 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
125 g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
127 if (service_function == BT_AV_CONNECT)
128 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AV_CONNECT,
129 in_param1, in_param2, in_param3, in_param4,
130 user_info->cb, user_info->user_data);
131 else if (service_function == BT_AG_CONNECT)
132 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AG_CONNECT,
133 in_param1, in_param2, in_param3, in_param4,
134 user_info->cb, user_info->user_data);
135 else /* default case - with or without DPM enabled */
137 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AUDIO_CONNECT,
138 in_param1, in_param2, in_param3, in_param4,
139 user_info->cb, user_info->user_data);
141 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
146 BT_EXPORT_API int bluetooth_audio_disconnect(bluetooth_device_address_t *remote_address)
149 bt_user_info_t *user_info;
151 BT_CHECK_PARAMETER(remote_address, return);
152 BT_CHECK_ENABLED(return);
154 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AUDIO_DISCONNECT)
155 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
156 BT_ERR("Don't have a privilege to use this API");
157 return BLUETOOTH_ERROR_PERMISSION_DEINED;
160 user_info = _bt_get_user_data(BT_AUDIO);
161 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
164 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
166 g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
168 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AUDIO_DISCONNECT,
169 in_param1, in_param2, in_param3, in_param4,
170 user_info->cb, user_info->user_data);
172 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
177 BT_EXPORT_API int bluetooth_ag_connect(bluetooth_device_address_t *remote_address)
180 bt_user_info_t *user_info;
182 BT_CHECK_PARAMETER(remote_address, return);
183 BT_CHECK_ENABLED(return);
185 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AG_CONNECT)
186 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
187 BT_ERR("Don't have a privilege to use this API");
188 return BLUETOOTH_ERROR_PERMISSION_DEINED;
191 if (_bt_check_dpm(BT_DPM_ADDRESS, (void *)remote_address) == BT_DPM_RESTRICTED) {
192 BT_ERR("Blacklist device");
193 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
196 if (_bt_check_dpm(BT_DPM_HSP, NULL) == BT_DPM_RESTRICTED) {
197 BT_ERR("Not allow to use HSP profile");
198 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
201 if (_bt_check_dpm(BT_DPM_DESKTOP, NULL) == BT_DPM_RESTRICTED) {
202 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
203 bluetooth_device_class_t dev_class;
205 _bt_convert_addr_type_to_string(address, remote_address->addr);
206 _bt_get_cod_by_address(address, &dev_class);
208 if (dev_class.major_class == BLUETOOTH_DEVICE_MAJOR_CLASS_COMPUTER) {
209 BT_ERR("Reject a authorization due to MDM Policy");
210 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
214 user_info = _bt_get_user_data(BT_AUDIO);
215 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
218 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
220 g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
222 BT_INFO_C("### Connect AG");
223 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AG_CONNECT,
224 in_param1, in_param2, in_param3, in_param4,
225 user_info->cb, user_info->user_data);
227 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
232 BT_EXPORT_API int bluetooth_ag_disconnect(bluetooth_device_address_t *remote_address)
235 bt_user_info_t *user_info;
237 BT_CHECK_PARAMETER(remote_address, return);
238 BT_CHECK_ENABLED(return);
240 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AG_DISCONNECT)
241 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
242 BT_ERR("Don't have a privilege to use this API");
243 return BLUETOOTH_ERROR_PERMISSION_DEINED;
246 user_info = _bt_get_user_data(BT_AUDIO);
247 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
250 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
252 g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
254 BT_INFO_C("### Disconnect AG");
255 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AG_DISCONNECT,
256 in_param1, in_param2, in_param3, in_param4,
257 user_info->cb, user_info->user_data);
259 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
264 BT_EXPORT_API int bluetooth_av_connect(bluetooth_device_address_t *remote_address)
267 bt_user_info_t *user_info;
269 BT_CHECK_PARAMETER(remote_address, return);
270 BT_CHECK_ENABLED(return);
272 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AV_CONNECT)
273 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
274 BT_ERR("Don't have a privilege to use this API");
275 return BLUETOOTH_ERROR_PERMISSION_DEINED;
278 if (_bt_check_dpm(BT_DPM_ADDRESS, (void *)remote_address) == BT_DPM_RESTRICTED) {
279 BT_ERR("Blacklist device");
280 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
283 if (_bt_check_dpm(BT_DPM_A2DP, NULL) == BT_DPM_RESTRICTED) {
284 BT_ERR("Not allow to use A2DP profile");
285 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
288 if (_bt_check_dpm(BT_DPM_DESKTOP, NULL) == BT_DPM_RESTRICTED) {
289 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
290 bluetooth_device_class_t dev_class;
292 _bt_convert_addr_type_to_string(address, remote_address->addr);
293 _bt_get_cod_by_address(address, &dev_class);
295 if (dev_class.major_class == BLUETOOTH_DEVICE_MAJOR_CLASS_COMPUTER) {
296 BT_ERR("Reject a authorization due to MDM Policy");
297 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
301 user_info = _bt_get_user_data(BT_AUDIO);
302 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
305 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
307 g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
309 BT_INFO_C("### Connect AV");
310 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AV_CONNECT,
311 in_param1, in_param2, in_param3, in_param4,
312 user_info->cb, user_info->user_data);
314 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
319 BT_EXPORT_API int bluetooth_av_source_connect(bluetooth_device_address_t *remote_address)
322 bt_user_info_t *user_info;
324 BT_CHECK_PARAMETER(remote_address, return);
325 BT_CHECK_ENABLED(return);
327 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AV_SOURCE_CONNECT)
328 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
329 BT_ERR("Don't have a privilege to use this API");
330 return BLUETOOTH_ERROR_PERMISSION_DEINED;
333 if (_bt_check_dpm(BT_DPM_ADDRESS, (void *)remote_address) == BT_DPM_RESTRICTED) {
334 BT_ERR("Blacklist device");
335 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
338 if (_bt_check_dpm(BT_DPM_A2DP, NULL) == BT_DPM_RESTRICTED) {
339 BT_ERR("Not allow to use A2DP profile");
340 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
343 user_info = _bt_get_user_data(BT_AUDIO);
344 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
347 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
349 g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
351 BT_INFO_C("### Connect AV Source");
352 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AV_SOURCE_CONNECT,
353 in_param1, in_param2, in_param3, in_param4,
354 user_info->cb, user_info->user_data);
356 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
361 BT_EXPORT_API int bluetooth_av_disconnect(bluetooth_device_address_t *remote_address)
364 bt_user_info_t *user_info;
366 BT_CHECK_PARAMETER(remote_address, return);
367 BT_CHECK_ENABLED(return);
369 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AV_DISCONNECT)
370 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
371 BT_ERR("Don't have a privilege to use this API");
372 return BLUETOOTH_ERROR_PERMISSION_DEINED;
375 user_info = _bt_get_user_data(BT_AUDIO);
376 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
379 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
381 g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
383 BT_INFO_C("### Disconnect AV");
384 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AV_DISCONNECT,
385 in_param1, in_param2, in_param3, in_param4,
386 user_info->cb, user_info->user_data);
388 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
393 BT_EXPORT_API int bluetooth_av_source_disconnect(bluetooth_device_address_t *remote_address)
396 bt_user_info_t *user_info;
398 BT_CHECK_PARAMETER(remote_address, return);
399 BT_CHECK_ENABLED(return);
401 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_AV_SOURCE_DISCONNECT)
402 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
403 BT_ERR("Don't have a privilege to use this API");
404 return BLUETOOTH_ERROR_PERMISSION_DEINED;
407 user_info = _bt_get_user_data(BT_AUDIO);
408 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
411 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
413 g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
415 BT_INFO_C("### Disconnect AV Source");
416 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_AV_SOURCE_DISCONNECT,
417 in_param1, in_param2, in_param3, in_param4,
418 user_info->cb, user_info->user_data);
420 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
425 BT_EXPORT_API int bluetooth_audio_select_role(bluetooth_audio_role_t role)
429 BT_CHECK_ENABLED(return);
432 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
434 g_array_append_vals(in_param1, &role, sizeof(bluetooth_audio_role_t));
436 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_AUDIO_SELECT_ROLE,
437 in_param1, in_param2, in_param3, in_param4, &out_param);
439 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
443 BT_EXPORT_API int bluetooth_audio_set_absolute_volume(unsigned int volume)
447 BT_CHECK_ENABLED(return);
450 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
452 g_array_append_vals(in_param1, &volume, sizeof(unsigned int));
454 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_AUDIO_SET_ABSOLUTE_VOLUME,
455 in_param1, in_param2, in_param3, in_param4, &out_param);
457 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
461 BT_EXPORT_API int bluetooth_audio_get_absolute_volume(unsigned int *volume)
465 BT_CHECK_PARAMETER(volume, return);
466 BT_CHECK_ENABLED(return);
469 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
471 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_AUDIO_GET_ABSOLUTE_VOLUME,
472 in_param1, in_param2, in_param3, in_param4, &out_param);
474 if (result == BLUETOOTH_ERROR_NONE) {
475 *volume = g_array_index(out_param,
479 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
484 BT_EXPORT_API int bluetooth_audio_is_avc_activated(bool *activated)
488 BT_CHECK_PARAMETER(activated, return);
490 if (bluetooth_check_adapter() == BLUETOOTH_ADAPTER_DISABLED) {
491 BT_DBG("BT is not enabled. So activated value is false");
493 return BLUETOOTH_ERROR_NONE;
497 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
499 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_AUDIO_IS_AVC_ACTIVATED,
500 in_param1, in_param2, in_param3, in_param4, &out_param);
502 if (result == BLUETOOTH_ERROR_NONE) {
503 *activated = g_array_index(out_param,
507 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
512 BT_EXPORT_API int bluetooth_ag_get_headset_volume(unsigned int *speaker_gain)
516 BT_CHECK_PARAMETER(speaker_gain, return);
517 BT_CHECK_ENABLED(return);
520 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
522 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GET_SPEAKER_GAIN,
523 in_param1, in_param2, in_param3, in_param4, &out_param);
525 if (result == BLUETOOTH_ERROR_NONE) {
526 *speaker_gain = g_array_index(out_param,
530 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
535 BT_EXPORT_API int bluetooth_ag_set_speaker_gain(unsigned int speaker_gain)
539 BT_CHECK_ENABLED(return);
541 if (_bt_check_dpm(BT_DPM_HSP, NULL) == BT_DPM_RESTRICTED) {
542 BT_ERR("Not allow to use HSP profile");
543 return BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION;
547 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
549 g_array_append_vals(in_param1, &speaker_gain, sizeof(unsigned int));
551 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_SET_SPEAKER_GAIN,
552 in_param1, in_param2, in_param3, in_param4, &out_param);
554 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
559 #define BT_HF_SERVICE_NAME "org.bluez.hf_agent"
560 #define BT_HF_OBJECT_PATH "/org/bluez/handsfree_agent"
561 #define BT_HF_INTERFACE "org.tizen.HfApp"
564 static GVariant* __bt_hf_agent_dbus_send(const char *path, const char *interface,
565 const char *method, GError **err, GVariant *parameters)
567 GVariant *reply = NULL;
568 GDBusProxy *proxy = NULL;
569 GDBusConnection *conn = NULL;
571 conn = _bt_get_system_private_conn();
572 retv_if(conn == NULL, NULL);
574 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
575 NULL, BT_HF_SERVICE_NAME, path, interface, NULL, err);
577 BT_ERR("Unable to allocate new proxy");
581 reply = g_dbus_proxy_call_sync(proxy, method, parameters,
582 G_DBUS_CALL_FLAGS_NONE, -1, NULL, err);
584 g_object_unref(proxy);
588 static int __bt_hf_agent_read_call_list(GVariant *reply,
589 bt_hf_call_list_s **call_list) {
592 GVariant *var_temp = NULL;
595 int dir, status, mpart, idx;
599 g_variant_get(reply, "(i@a(siiii))", &call_count, &var_temp);
601 if (call_count <= 0) {
603 return BLUETOOTH_ERROR_NOT_FOUND;
605 BT_DBG("Call count = %d", call_count);
607 *call_list = g_malloc0(sizeof(bt_hf_call_list_s));
608 (*call_list)->count = call_count;
610 g_variant_iter_init(&iter, var_temp);
611 while (g_variant_iter_loop(&iter, "(siiii)", &num, &dir, &status, &mpart, &idx)) {
612 bt_hf_call_status_info_t *call_info;
614 call_info = g_malloc0(sizeof(bt_hf_call_status_info_t));
615 call_info->number = g_strdup(num);
616 call_info->direction = dir;
617 call_info->status = status;
618 call_info->mpart = mpart;
619 call_info->idx = idx;
621 (*call_list)->list = g_list_append((*call_list)->list,
622 (gpointer)call_info);
625 g_variant_unref(var_temp);
627 return BLUETOOTH_ERROR_NONE;
630 static int __bluetooth_hf_get_error(const char *error_message)
632 if (error_message == NULL) {
633 BT_ERR("Error message NULL");
634 return BLUETOOTH_ERROR_INTERNAL;
637 BT_ERR("Error message = %s", error_message);
639 if (g_strcmp0(error_message, "NotConnected") == 0)
640 return BLUETOOTH_ERROR_NOT_CONNECTED;
642 return BLUETOOTH_ERROR_INTERNAL;
645 BT_EXPORT_API int bluetooth_hf_init(bt_hf_func_ptr cb, void *user_data)
650 BT_ERR("callback is NULL");
651 return BLUETOOTH_ERROR_INVALID_PARAM;
654 ret = _bt_init_event_handler();
656 if (ret != BLUETOOTH_ERROR_NONE &&
657 ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
658 BT_ERR("Fail to init the event handler");
662 _bt_set_user_data(BT_HF, (void *)cb, user_data);
664 /* Register All events */
665 ret = _bt_register_event(BT_HF_AGENT_EVENT, (void *)cb, user_data);
666 if (ret != BLUETOOTH_ERROR_NONE &&
667 ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
668 _bt_deinit_event_handler();
672 return BLUETOOTH_ERROR_NONE;
675 BT_EXPORT_API int bluetooth_hf_deinit(void)
679 ret = _bt_unregister_event(BT_HF_AGENT_EVENT);
680 if (ret != BLUETOOTH_ERROR_NONE)
681 BT_ERR("_bt_unregister_event failed");
683 _bt_set_user_data(BT_HF, NULL, NULL);
685 return BLUETOOTH_ERROR_NONE;
688 BT_EXPORT_API int bluetooth_hf_connect(bluetooth_device_address_t *remote_address)
691 bt_user_info_t *user_info;
693 BT_CHECK_ENABLED(return);
694 BT_CHECK_PARAMETER(remote_address, return);
696 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HF_CONNECT)
697 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
698 BT_ERR("Don't have a privilege to use this API");
699 return BLUETOOTH_ERROR_PERMISSION_DEINED;
702 user_info = _bt_get_user_data(BT_HF);
703 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
706 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
708 g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
710 BT_INFO_C("### Connect HF");
711 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_HF_CONNECT,
712 in_param1, in_param2, in_param3, in_param4,
713 user_info->cb, user_info->user_data);
715 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
720 BT_EXPORT_API int bluetooth_hf_disconnect(bluetooth_device_address_t *remote_address)
723 bt_user_info_t *user_info;
725 BT_CHECK_PARAMETER(remote_address, return);
726 BT_CHECK_ENABLED(return);
728 if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_HF_DISCONNECT)
729 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
730 BT_ERR("Don't have a privilege to use this API");
731 return BLUETOOTH_ERROR_PERMISSION_DEINED;
734 user_info = _bt_get_user_data(BT_HF);
735 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
738 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
740 g_array_append_vals(in_param1, remote_address, sizeof(bluetooth_device_address_t));
742 BT_INFO_C("### Disconnect HF");
743 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_HF_DISCONNECT,
744 in_param1, in_param2, in_param3, in_param4,
745 user_info->cb, user_info->user_data);
747 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
752 BT_EXPORT_API int bluetooth_hf_answer_call()
754 GVariant *reply = NULL;
756 int ret = BLUETOOTH_ERROR_INTERNAL;
758 BT_CHECK_ENABLED(return);
760 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
761 "AnswerCall", &err, NULL);
763 BT_ERR("Error returned in method call\n");
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);
773 g_variant_unref(reply);
774 return BLUETOOTH_ERROR_NONE;
778 BT_EXPORT_API int bluetooth_hf_terminate_call()
780 GVariant *reply = NULL;
782 int ret = BLUETOOTH_ERROR_INTERNAL;
784 BT_CHECK_ENABLED(return);
786 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
787 "TerminateCall", &err, NULL);
789 BT_ERR("Error returned in method call\n");
791 BT_ERR("Error = %s", err->message);
792 g_dbus_error_strip_remote_error(err);
793 ret = _bt_get_error_value_from_message(err->message);
799 g_variant_unref(reply);
800 return BLUETOOTH_ERROR_NONE;
803 BT_EXPORT_API int bluetooth_hf_initiate_call(char *number)
805 GVariant *reply = NULL;
807 GVariant *param = NULL;
808 int ret = BLUETOOTH_ERROR_INTERNAL;
810 BT_CHECK_ENABLED(return);
815 param = g_variant_new("(s)", number);
816 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
817 "InitiateCall", &err, param);
819 BT_ERR("Error returned in method call");
821 BT_ERR("Error = %s", err->message);
822 g_dbus_error_strip_remote_error(err);
823 ret = _bt_get_error_value_from_message(err->message);
829 g_variant_unref(reply);
830 return BLUETOOTH_ERROR_NONE;
833 BT_EXPORT_API int bluetooth_hf_voice_recognition(unsigned int status)
835 GVariant *reply = NULL;
837 GVariant *param = NULL;
838 int ret = BLUETOOTH_ERROR_INTERNAL;
840 BT_CHECK_ENABLED(return);
842 param = g_variant_new("(i)", status);
843 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
844 "VoiceRecognition", &err, param);
846 BT_ERR("Error returned in method call\n");
848 BT_ERR("Error = %s", err->message);
849 g_dbus_error_strip_remote_error(err);
850 ret = _bt_get_error_value_from_message(err->message);
856 g_variant_unref(reply);
857 return BLUETOOTH_ERROR_NONE;
860 BT_EXPORT_API int bluetooth_hf_audio_disconnect(void)
862 GVariant *reply = NULL;
864 int ret = BLUETOOTH_ERROR_INTERNAL;
866 BT_CHECK_ENABLED(return);
868 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
869 "ScoDisconnect", &err, NULL);
871 BT_ERR("Error returned in method call\n");
873 BT_ERR("Error = %s", err->message);
874 g_dbus_error_strip_remote_error(err);
875 ret = _bt_get_error_value_from_message(err->message);
881 g_variant_unref(reply);
882 return BLUETOOTH_ERROR_NONE;
885 BT_EXPORT_API int bluetooth_hf_set_speaker_gain(unsigned int speaker_gain)
887 GVariant *reply = NULL;
889 GVariant *param = NULL;
890 int ret = BLUETOOTH_ERROR_INTERNAL;
892 BT_CHECK_ENABLED(return);
894 param = g_variant_new("(u)", speaker_gain);
895 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
896 "SpeakerGain", &err, param);
898 BT_ERR("Error returned in method call\n");
900 BT_ERR("Error = %s", err->message);
901 g_dbus_error_strip_remote_error(err);
902 ret = _bt_get_error_value_from_message(err->message);
908 g_variant_unref(reply);
909 return BLUETOOTH_ERROR_NONE;
912 BT_EXPORT_API int bluetooth_hf_send_dtmf(char *dtmf)
914 GVariant *reply = NULL;
916 GVariant *param = NULL;
917 int ret = BLUETOOTH_ERROR_INTERNAL;
919 BT_CHECK_ENABLED(return);
921 param = g_variant_new("(s)", dtmf);
922 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
923 "SendDtmf", &err, param);
925 BT_ERR("Error returned in method call\n");
927 BT_ERR("Error = %s", err->message);
928 g_dbus_error_strip_remote_error(err);
929 ret = _bt_get_error_value_from_message(err->message);
935 g_variant_unref(reply);
936 return BLUETOOTH_ERROR_NONE;
939 BT_EXPORT_API int bluetooth_hf_send_xsat_cmd(int app_id, char *xsat_cmd)
941 GVariant *reply = NULL;
943 GVariant *param = NULL;
944 char buffer[200] = {0,};
946 int ret = BLUETOOTH_ERROR_INTERNAL;
948 BT_CHECK_ENABLED(return);
950 strncpy(buffer, "AT+XSAT=\0", 200);
951 snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer),
953 strncat(buffer, xsat_cmd, (sizeof(buffer) - 1) - strlen(buffer));
954 BT_DBG("Xsat cmd received = %s", buffer);
956 param = g_variant_new("(s)", ptr);
958 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
959 "SendAtCmd", &err, param);
961 BT_ERR("Error returned in method call\n");
963 BT_ERR("Error = %s", err->message);
964 g_dbus_error_strip_remote_error(err);
965 ret = _bt_get_error_value_from_message(err->message);
971 g_variant_unref(reply);
972 return BLUETOOTH_ERROR_NONE;
975 BT_EXPORT_API int bluetooth_hf_release_and_accept(void)
977 GVariant *reply = NULL;
979 int ret = BLUETOOTH_ERROR_INTERNAL;
981 BT_CHECK_ENABLED(return);
983 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
984 "ReleaseAndAccept", &err, NULL);
986 BT_ERR("Error returned in method call\n");
988 BT_ERR("Error = %s", err->message);
989 g_dbus_error_strip_remote_error(err);
990 ret = _bt_get_error_value_from_message(err->message);
996 g_variant_unref(reply);
997 return BLUETOOTH_ERROR_NONE;
1000 BT_EXPORT_API int bluetooth_hf_swap_call(void)
1002 GVariant *reply = NULL;
1004 int ret = BLUETOOTH_ERROR_INTERNAL;
1006 BT_CHECK_ENABLED(return);
1008 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1009 "CallSwap", &err, NULL);
1011 BT_ERR("Error returned in method call\n");
1013 BT_ERR("Error = %s", err->message);
1014 g_dbus_error_strip_remote_error(err);
1015 ret = _bt_get_error_value_from_message(err->message);
1016 g_clear_error(&err);
1021 g_variant_unref(reply);
1022 return BLUETOOTH_ERROR_NONE;
1025 BT_EXPORT_API int bluetooth_hf_release_all_call(void)
1027 GVariant *reply = NULL;
1029 int ret = BLUETOOTH_ERROR_INTERNAL;
1031 BT_CHECK_ENABLED(return);
1033 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1034 "ReleaseAllCall", &err, NULL);
1036 BT_ERR("Error returned in method call\n");
1038 BT_ERR("Error = %s", err->message);
1039 g_dbus_error_strip_remote_error(err);
1040 ret = _bt_get_error_value_from_message(err->message);
1041 g_clear_error(&err);
1046 g_variant_unref(reply);
1047 return BLUETOOTH_ERROR_NONE;
1050 BT_EXPORT_API int bluetooth_hf_join_call(void)
1052 GVariant *reply = NULL;
1054 int ret = BLUETOOTH_ERROR_INTERNAL;
1056 BT_CHECK_ENABLED(return);
1058 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1059 "JoinCall", &err, NULL);
1061 BT_ERR("Error returned in method call\n");
1063 BT_ERR("Error = %s", err->message);
1064 g_dbus_error_strip_remote_error(err);
1065 ret = _bt_get_error_value_from_message(err->message);
1066 g_clear_error(&err);
1071 g_variant_unref(reply);
1072 return BLUETOOTH_ERROR_NONE;
1075 BT_EXPORT_API int bluetooth_hf_get_call_list(void *call_list,
1076 bt_hf_call_status_info_t **call_status)
1079 GList *list = call_list;
1081 bt_hf_call_status_info_t * call_info;
1083 BT_CHECK_ENABLED(return);
1084 retv_if(list == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1085 retv_if(call_status == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1087 call_count = g_list_length(list);
1089 BT_DBG(" call_count = [%d]", call_count);
1091 for (i = 0; i < call_count; i++) {
1092 call_info = g_list_nth_data(list, i);
1093 BT_DBG(" direction = [%d]", call_info->direction);
1094 BT_DBG(" status = [%d]", call_info->status);
1095 BT_DBG(" mpart = [%d]", call_info->mpart);
1096 BT_DBG(" number = [%s]", call_info->number);
1097 BT_DBG(" idx = [%d]", call_info->idx);
1098 call_status[i] = call_info;
1101 return BLUETOOTH_ERROR_NONE;
1104 BT_EXPORT_API int bluetooth_hf_free_call_list(bt_hf_call_list_s *call_list)
1106 bt_hf_call_list_s *handle;
1107 bt_hf_call_status_info_t *call_status;
1109 retv_if(call_list == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1111 handle = (bt_hf_call_list_s *)call_list;
1113 call_status = (bt_hf_call_status_info_t *)g_list_nth_data(
1115 if (call_status == NULL)
1117 handle->list = g_list_remove(handle->list, call_status);
1118 g_free(call_status->number);
1119 g_free(call_status);
1122 return BLUETOOTH_ERROR_NONE;
1125 BT_EXPORT_API int bluetooth_hf_request_call_list(
1126 bt_hf_call_list_s **call_list)
1128 GVariant *reply = NULL;
1131 BT_CHECK_ENABLED(return);
1133 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1134 "RequestCallList", &err, NULL);
1136 BT_ERR("dbus Error or call list is null\n");
1138 BT_ERR("Error = %s", err->message);
1139 g_clear_error(&err);
1142 return BLUETOOTH_ERROR_INTERNAL;
1144 __bt_hf_agent_read_call_list(reply, call_list);
1146 g_variant_unref(reply);
1147 return BLUETOOTH_ERROR_NONE;
1150 BT_EXPORT_API int bluetooth_hf_request_call_list_async(void)
1152 GVariant *reply = NULL;
1154 int ret = BLUETOOTH_ERROR_INTERNAL;
1156 BT_CHECK_ENABLED(return);
1158 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1159 "RequestCallListAsync", &err, NULL);
1161 BT_ERR("Error returned in method call\n");
1163 BT_ERR("Error = %s", err->message);
1164 if (strstr(err->message, "No data"))
1165 ret = BLUETOOTH_ERROR_NO_DATA;
1166 else if (strstr(err->message, "NotConnected"))
1167 ret = BLUETOOTH_ERROR_NOT_CONNECTED;
1168 g_clear_error(&err);
1173 g_variant_unref(reply);
1174 return BLUETOOTH_ERROR_NONE;
1177 BT_EXPORT_API int bluetooth_hf_get_codec(unsigned int *codec_id)
1179 GVariant *reply = NULL;
1181 int32_t current_codec;
1183 BT_CHECK_ENABLED(return);
1185 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1186 "GetCurrentCodec", &err, NULL);
1188 BT_ERR("Error returned in method call\n");
1190 BT_ERR("Error = %s", err->message);
1191 g_clear_error(&err);
1193 return BLUETOOTH_ERROR_INTERNAL;
1196 g_variant_get(reply, "(i)", ¤t_codec);
1197 *codec_id = current_codec;
1198 BT_DBG(" Codec ID is : %d", *codec_id);
1200 g_variant_unref(reply);
1201 return BLUETOOTH_ERROR_NONE;
1204 BT_EXPORT_API int bluetooth_hf_get_audio_connected(unsigned int *audio_connected)
1206 GVariant *reply = NULL;
1208 int32_t sco_audio_connected_from_bt_agent;
1210 BT_CHECK_ENABLED(return);
1212 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1213 "GetAudioConnected", &err, NULL);
1215 BT_ERR("Error returned in method call\n");
1217 BT_ERR("Error = %s", err->message);
1218 g_clear_error(&err);
1220 return BLUETOOTH_ERROR_INTERNAL;
1223 g_variant_get(reply, "(i)", &sco_audio_connected_from_bt_agent);
1224 *audio_connected = sco_audio_connected_from_bt_agent;
1226 if (*audio_connected == BLUETOOTH_HF_AUDIO_CONNECTED)
1227 BT_DBG("SCO Audio is Connected");
1229 BT_DBG("SCO Audio is Disconnected");
1231 g_variant_unref(reply);
1232 return BLUETOOTH_ERROR_NONE;
1235 BT_EXPORT_API int bluetooth_hf_is_connected(gboolean *hf_connected)
1237 GVariant *reply = NULL;
1239 gboolean hf_connected_from_bt_agent;
1241 BT_CHECK_ENABLED(return);
1243 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1244 "IsHfConnected", &err, NULL);
1246 BT_ERR("Error returned in method call\n");
1248 BT_ERR("Error = %s", err->message);
1249 g_clear_error(&err);
1251 return BLUETOOTH_ERROR_INTERNAL;
1254 g_variant_get(reply, "(b)", &hf_connected_from_bt_agent);
1255 *hf_connected = hf_connected_from_bt_agent;
1257 BT_DBG("%s", *hf_connected ? "Connected" : "Disconnected");
1259 g_variant_unref(reply);
1260 return BLUETOOTH_ERROR_NONE;
1263 BT_EXPORT_API int bluetooth_hf_is_ibr_supported(gboolean *ibr_supported)
1265 GVariant *reply = NULL;
1267 gboolean is_supported;
1268 int ret = BLUETOOTH_ERROR_NONE;
1270 BT_CHECK_ENABLED(return);
1272 reply = __bt_hf_agent_dbus_send(BT_HF_OBJECT_PATH, BT_HF_INTERFACE,
1273 "IsInbandRingtoneSupported", &err, NULL);
1275 BT_ERR("Error returned in method call");
1277 g_dbus_error_strip_remote_error(err);
1278 ret = __bluetooth_hf_get_error(err->message);
1282 return BLUETOOTH_ERROR_INTERNAL;
1285 g_variant_get(reply, "(b)", &is_supported);
1286 *ibr_supported = is_supported;
1288 BT_DBG("%s", *ibr_supported ? "Supported" : "Not Supported");
1290 g_variant_unref(reply);