4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * GirishAshok Joshi <girish.joshi@samsung.com>
8 * Chanyeol Park <chanyeol.park@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
27 #include <dbus/dbus.h>
28 #include <dbus/dbus-glib-bindings.h>
31 #include <vconf-keys.h>
33 #include "bt-common.h"
34 #include "bluetooth-telephony-api.h"
37 #define BT_SCO_TIMEOUT 3000
39 #define BT_CVSD_CODEC_ID 1
40 #define BT_MSBC_CODEC_ID 2
43 DBusGConnection *conn;
45 DBusGProxy *dbus_proxy;
46 DBusGProxy *manager_proxy;
47 } telephony_dbus_info_t;
50 bt_telephony_func_ptr cb;
51 unsigned int call_count;
53 char address[BT_ADDRESS_STR_LEN];
54 char call_path[BT_AUDIO_CALL_PATH_LEN];
55 bluetooth_headset_state_t headset_state;
57 } bt_telephony_info_t;
60 char *src_addr = NULL;
64 #define BLUETOOTH_TELEPHONY_ERROR (__bluetooth_telephony_error_quark())
66 #define BLUEZ_SERVICE_NAME "org.bluez"
67 #define BLUEZ_HEADSET_INTERFACE "org.bluez.Headset"
69 #define BLUEZ_MANAGER_INTERFACE "org.freedesktop.DBus.ObjectManager"
70 #define BLUEZ_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
71 #define BLUEZ_ADAPTER_INTERFACE "org.bluez.Adapter1"
72 #define BLUEZ_DEVICE_INTERFACE "org.bluez.Device1"
73 #define HFP_AGENT_SERVICE "org.bluez.ag_agent"
76 #define HFP_AGENT_PATH "/org/bluez/hfp_agent"
77 #define HFP_AGENT_INTERFACE "Org.Hfp.App.Interface"
79 #define CSD_CALL_APP_PATH "/org/tizen/csd/%d"
80 #define HFP_NREC_STATUS_CHANGE "NrecStatusChanged"
81 #define HFP_ANSWER_CALL "Answer"
82 #define HFP_REJECT_CALL "Reject"
83 #define HFP_RELEASE_CALL "Release"
84 #define HFP_THREEWAY_CALL "Threeway"
86 #define DEFAULT_ADAPTER_OBJECT_PATH "/org/bluez/hci0"
89 #define BT_TELEPHONY_CHECK_ENABLED() \
91 if (bluetooth_check_adapter() == BLUETOOTH_ADAPTER_DISABLED) \
93 BT_ERR("BT is not enabled"); \
94 return BLUETOOTH_TELEPHONY_ERROR_NOT_ENABLED; \
98 static gboolean is_initialized = FALSE;
99 #define BT_TELEPHONY_CHECK_INITIALIZED() \
101 if (is_initialized == FALSE) \
103 BT_ERR("Bluetooth telephony not initilized"); \
104 return BLUETOOTH_TELEPHONY_ERROR_NOT_INITIALIZED; \
108 #define BLUETOOTH_TELEPHONY_METHOD (bluetooth_telephony_method_get_type())
109 #define BLUETOOTH_TELEPHONY_METHOD_GET_OBJECT(obj) \
110 (G_TYPE_CHECK_INSTANCE_CAST((obj), \
111 BLUETOOTH_TELEPHONY_METHOD, BluetoothTelephonyMethod))
113 #define BLUETOOTH_TELEPHONY_METHOD_IS_OBJECT(obj) \
114 (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
115 BLUETOOTH_TELEPHONY_METHOD))
117 #define BLUETOOTH_TELEPHONY_METHOD_CLASS(class) \
118 (G_TYPE_CHECK_CLASS_CAST((class), \
119 BLUETOOTH_TELEPHONY_METHOD, BluetoothTelephonyMethodClass))
121 #define BLUETOOTH_TELEPHONY_METHOD_GET_AGENT_CLASS(obj) \
122 (G_TYPE_INSTANCE_GET_CLASS((obj), \
123 BLUETOOTH_TELEPHONY_METHOD, BluetoothTelephonyMethodClass))
125 #define BLUETOOTH_TELEPHONY_METHOD_IS_AGENT_CLASS(class) \
126 (G_TYPE_CHECK_CLASS_TYPE((class), BLUETOOTH_TELEPHONY_METHOD))
128 #define BLUETOOTH_TELEPHONY_METHOD_AGENT_GET_PRIVATE(obj) \
129 (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
130 BLUETOOTH_TELEPHONY_METHOD, BluetoothTelephonyMethodPrivate))
132 typedef struct _BluetoothTelephonyMethod BluetoothTelephonyMethod;
133 typedef struct _BluetoothTelephonyMethodClass BluetoothTelephonyMethodClass;
135 struct _BluetoothTelephonyMethod {
139 struct _BluetoothTelephonyMethodClass {
140 GObjectClass parent_class;
143 BluetoothTelephonyMethod *bluetooth_telephony_method_new(void);
144 GType bluetooth_telephony_method_get_type(void);
146 G_DEFINE_TYPE(BluetoothTelephonyMethod, bluetooth_telephony_method, G_TYPE_OBJECT)
149 static DBusHandlerResult __bt_telephony_adapter_filter(DBusConnection *conn,
150 DBusMessage *msg, void *data);
152 static int __bt_telephony_get_object_path(DBusMessage *msg, char **path);
154 static int __bt_telephony_get_src_addr(DBusMessage *msg);
156 static gboolean bluetooth_telephony_method_send_dtmf(
157 BluetoothTelephonyMethod *object,
158 gchar *dtmf, DBusGMethodInvocation *context);
160 static gboolean bluetooth_telephony_method_vendor_cmd(
161 BluetoothTelephonyMethod *object,
162 gchar *at_cmd, DBusGMethodInvocation *context);
163 #include "bt-telephony-glue.h"
165 static GObject *object;
166 static bt_telephony_info_t telephony_info;
167 static telephony_dbus_info_t telephony_dbus_info;
168 static gboolean is_active = FALSE;
170 /*Function Declaration*/
171 static int __bt_telephony_get_error(const char *error_message);
172 static void __bt_telephony_event_cb(int event, int result, void *param_data);
173 static GQuark __bluetooth_telephony_error_quark(void);
174 static DBusMessage* __bluetooth_telephony_dbus_method_send(const char *path,
175 const char *interface, const char *method, DBusError *err, int type, ...);
176 static int __bluetooth_telephony_send_call_status(
177 bt_telephony_call_status_t call_status,
178 unsigned int call_id, const char *ph_number);
179 static GError *__bluetooth_telephony_error(bluetooth_telephony_error_t error,
180 const char *err_msg);
182 static DBusHandlerResult __bluetooth_telephony_event_filter(
183 DBusConnection *conn,
184 DBusMessage *msg, void *data);
186 static int __bluetooth_telephony_proxy_init(void);
187 static void __bluetooth_telephony_proxy_deinit(void);
188 static int __bluetooth_telephony_register(void);
189 static int __bluetooth_telephony_unregister(void);
191 static gboolean __bluetooth_telephony_is_headset(uint32_t device_class);
192 static int __bluetooth_telephony_get_connected_device(void);
193 static DBusGProxy *__bluetooth_telephony_get_connected_device_proxy(void);
195 /*Function Definition*/
196 static int __bt_telephony_get_error(const char *error_message)
198 if (error_message == NULL) {
199 BT_ERR("Error message NULL");
200 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
203 BT_ERR("Error message = %s", error_message);
204 if (g_strcmp0(error_message, "NotAvailable") == 0)
205 return BLUETOOTH_TELEPHONY_ERROR_NOT_AVAILABLE;
206 else if (g_strcmp0(error_message, "NotConnected") == 0)
207 return BLUETOOTH_TELEPHONY_ERROR_NOT_CONNECTED;
208 else if (g_strcmp0(error_message, "InProgress") == 0)
209 return BLUETOOTH_TELEPHONY_ERROR_BUSY;
210 else if (g_strcmp0(error_message, "InvalidArguments") == 0)
211 return BLUETOOTH_TELEPHONY_ERROR_INVALID_PARAM;
212 else if (g_strcmp0(error_message, "AlreadyExists") == 0)
213 return BLUETOOTH_TELEPHONY_ERROR_ALREADY_EXSIST;
214 else if (g_strcmp0(error_message, "Already Connected") == 0)
215 return BLUETOOTH_TELEPHONY_ERROR_ALREADY_CONNECTED;
216 else if (g_strcmp0(error_message, "No memory") == 0)
217 return BLUETOOTH_TELEPHONY_ERROR_NO_MEMORY;
218 else if (g_strcmp0(error_message, "I/O error") == 0)
219 return BLUETOOTH_TELEPHONY_ERROR_I_O_ERROR;
220 else if (g_strcmp0(error_message, "Operation currently not available") == 0)
221 return BLUETOOTH_TELEPHONY_ERROR_OPERATION_NOT_AVAILABLE;
222 else if (g_strrstr(error_message, BT_ACCESS_DENIED_MSG))
223 return BLUETOOTH_TELEPHONY_ERROR_PERMISSION_DENIED;
225 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
228 static int __bt_telephony_check_privilege(void)
233 DBusConnection *conn;
236 conn = _bt_get_system_conn();
237 retv_if(conn == NULL, BLUETOOTH_TELEPHONY_ERROR_INTERNAL);
239 msg = dbus_message_new_method_call(HFP_AGENT_SERVICE,
240 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
243 BT_ERR("Unable to allocate new D-Bus message \n");
244 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
247 dbus_error_init(&err);
249 reply = dbus_connection_send_with_reply_and_block(conn,
252 dbus_message_unref(msg);
255 BT_ERR("Error returned in method call");
256 if (dbus_error_is_set(&err)) {
257 ret = __bt_telephony_get_error(err.message);
258 BT_ERR("Error here %d\n", ret);
259 dbus_error_free(&err);
262 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
265 dbus_message_unref(reply);
267 return BLUETOOTH_TELEPHONY_ERROR_NONE;
270 static void __bt_telephony_event_cb(int event, int result, void *param_data)
272 telephony_event_param_t bt_event = { 0, };
274 bt_event.event = event;
275 bt_event.result = result;
276 bt_event.param_data = param_data;
278 ret_if(telephony_info.cb == NULL);
279 telephony_info.cb(bt_event.event, &bt_event, telephony_info.user_data);
283 static GQuark __bluetooth_telephony_error_quark(void)
285 static GQuark quark = 0;
287 quark = g_quark_from_static_string("telephony");
292 static DBusMessage* __bluetooth_telephony_dbus_method_send(const char *path,
293 const char *interface, const char *method, DBusError *err, int type, ...)
298 #ifdef TIZEN_WEARABLE
306 msg = dbus_message_new_method_call(HFP_AGENT_SERVICE,
307 path, interface, method);
309 BT_ERR("Unable to allocate new D-Bus %s message \n", method);
313 va_start(args, type);
315 if (!dbus_message_append_args_valist(msg, type, args)) {
316 dbus_message_unref(msg);
323 dbus_error_init(err);
325 reply = dbus_connection_send_with_reply_and_block(
326 dbus_g_connection_get_connection(telephony_dbus_info.conn),
328 dbus_message_unref(msg);
334 static int __bluetooth_telephony_send_call_status(
335 bt_telephony_call_status_t call_status,
336 unsigned int call_id, const char *ph_number)
340 char *path = g_strdup(telephony_info.call_path);
346 if (NULL == ph_number)
347 phone_number = g_strdup("");
349 phone_number = g_strdup(ph_number);
351 reply = __bluetooth_telephony_dbus_method_send(
352 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
353 "ChangeCallStatus", &err, DBUS_TYPE_STRING, &path,
354 DBUS_TYPE_STRING, &phone_number,
355 DBUS_TYPE_INT32, &call_status,
356 DBUS_TYPE_INT32, &call_id, DBUS_TYPE_INVALID);
359 g_free(phone_number);
362 BT_ERR("Error returned in method call\n");
363 if (dbus_error_is_set(&err)) {
364 ret = __bt_telephony_get_error(err.message);
365 dbus_error_free(&err);
368 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
371 dbus_message_unref(reply);
373 return BLUETOOTH_TELEPHONY_ERROR_NONE;
376 static GError *__bluetooth_telephony_error(bluetooth_telephony_error_t error,
379 return g_error_new(BLUETOOTH_TELEPHONY_ERROR, error, err_msg, NULL);
382 static void bluetooth_telephony_method_init(BluetoothTelephonyMethod *object)
385 BT_DBG("agent %p\n", object);
389 static void __bluetooth_telephony_method_finalize(
390 BluetoothTelephonyMethod *object)
393 G_OBJECT_CLASS(bluetooth_telephony_method_parent_class)->finalize((
398 static BluetoothTelephonyMethod *__bluetooth_telephony_method_new(void)
400 BluetoothTelephonyMethod *obj;
403 obj = g_object_new(BLUETOOTH_TELEPHONY_METHOD, NULL);
409 static void bluetooth_telephony_method_class_init(
410 BluetoothTelephonyMethodClass *klass)
412 GObjectClass *object_class = NULL;
415 object_class = G_OBJECT_CLASS(klass);
416 object_class->finalize = (void *)__bluetooth_telephony_method_finalize;
418 /*Registration of the Framework methods */
419 dbus_g_object_type_install_info(BLUETOOTH_TELEPHONY_METHOD,
420 &dbus_glib_bluetooth_telephony_method_object_info);
425 static void __bluetooth_telephony_answer_call(DBusMessage *msg)
427 telephony_event_callid_t call_data = { 0, };
431 if (!dbus_message_get_args(msg, NULL,
432 DBUS_TYPE_UINT32, &callid,
433 DBUS_TYPE_INVALID)) {
434 BT_ERR("Error Getting parameters");
438 BT_DBG("call_id = [%d]", callid);
439 call_data.callid = callid;
441 __bt_telephony_event_cb(BLUETOOTH_EVENT_TELEPHONY_ANSWER_CALL,
442 BLUETOOTH_TELEPHONY_ERROR_NONE,
447 static void __bluetooth_telephony_release_call(DBusMessage *msg)
449 telephony_event_callid_t call_data = { 0, };
453 if (!dbus_message_get_args(msg, NULL,
454 DBUS_TYPE_UINT32, &callid,
455 DBUS_TYPE_INVALID)) {
456 BT_ERR("Error Getting parameters");
460 BT_DBG("call_id = [%d]", callid);
461 call_data.callid = callid;
463 __bt_telephony_event_cb(BLUETOOTH_EVENT_TELEPHONY_RELEASE_CALL,
464 BLUETOOTH_TELEPHONY_ERROR_NONE,
469 static void __bluetooth_telephony_reject_call(DBusMessage *msg)
471 telephony_event_callid_t call_data = { 0, };
475 if (!dbus_message_get_args(msg, NULL,
476 DBUS_TYPE_UINT32, &callid,
477 DBUS_TYPE_INVALID)) {
478 BT_ERR("Error Getting parameters");
482 BT_DBG("call_id = [%d]", callid);
483 call_data.callid = callid;
485 __bt_telephony_event_cb(BLUETOOTH_EVENT_TELEPHONY_REJECT_CALL,
486 BLUETOOTH_TELEPHONY_ERROR_NONE,
491 static void __bluetooth_telephony_threeway_call(DBusMessage *msg)
494 unsigned int chld_value;
497 if (!dbus_message_get_args(msg, NULL,
498 DBUS_TYPE_UINT32, &chld_value,
499 DBUS_TYPE_INVALID)) {
500 BT_ERR("Error Getting parameters");
504 BT_DBG("chld value = [%d]", chld_value);
506 switch (chld_value) {
508 event = BLUETOOTH_EVENT_TELEPHONY_CHLD_0_RELEASE_ALL_HELD_CALL;
511 event = BLUETOOTH_EVENT_TELEPHONY_CHLD_1_RELEASE_ALL_ACTIVE_CALL;
514 event = BLUETOOTH_EVENT_TELEPHONY_CHLD_2_ACTIVE_HELD_CALL;
517 event = BLUETOOTH_EVENT_TELEPHONY_CHLD_3_MERGE_CALL;
520 BT_ERR("Invalid CHLD command");
524 __bt_telephony_event_cb(event,
525 BLUETOOTH_TELEPHONY_ERROR_NONE, NULL);
529 static gboolean bluetooth_telephony_method_send_dtmf(
530 BluetoothTelephonyMethod *object,
531 gchar *dtmf, DBusGMethodInvocation *context)
533 telephony_event_dtmf_t call_data = { 0, };
539 BT_ERR("Number dial failed");
540 err = __bluetooth_telephony_error(
541 BLUETOOTH_TELEPHONY_ERROR_INVALID_DTMF,
543 dbus_g_method_return_error(context, err);
548 DBG_SECURE("Dtmf = %s", dtmf);
550 call_data.dtmf = g_strdup(dtmf);
552 __bt_telephony_event_cb(BLUETOOTH_EVENT_TELEPHONY_SEND_DTMF,
553 BLUETOOTH_TELEPHONY_ERROR_NONE, (void *)&call_data);
555 dbus_g_method_return(context);
556 g_free(call_data.dtmf);
561 static gboolean bluetooth_telephony_method_vendor_cmd(
562 BluetoothTelephonyMethod *object,
563 gchar *at_cmd, DBusGMethodInvocation *context)
569 if (at_cmd == NULL) {
570 BT_ERR("Vendor command is NULL\n");
571 err = __bluetooth_telephony_error(
572 BLUETOOTH_TELEPHONY_ERROR_APPLICATION,
573 "Invalid at vendor cmd");
574 dbus_g_method_return_error(context, err);
579 DBG_SECURE("Vendor AT cmd = %s", at_cmd);
581 __bt_telephony_event_cb(BLUETOOTH_EVENT_TELEPHONY_VENDOR_AT_CMD,
582 BLUETOOTH_TELEPHONY_ERROR_NONE, at_cmd);
584 dbus_g_method_return(context);
589 static void __bluetooth_handle_nrec_status_change(DBusMessage *msg)
591 gboolean status = FALSE;
593 if (!dbus_message_get_args(msg, NULL,
594 DBUS_TYPE_BOOLEAN, &status,
595 DBUS_TYPE_INVALID)) {
596 BT_ERR("Error Getting parameters");
599 BT_INFO("NREC status = %d", status);
601 __bt_telephony_event_cb(BLUETOOTH_EVENT_TELEPHONY_NREC_CHANGED,
602 BLUETOOTH_TELEPHONY_ERROR_NONE, (void *)&status);
606 static DBusHandlerResult __bluetooth_telephony_event_filter(
607 DBusConnection *conn,
608 DBusMessage *msg, void *data)
610 const char *path = dbus_message_get_path(msg);
611 char *dev_addr = NULL;
612 DBusMessageIter item_iter;
613 DBusMessageIter value_iter;
614 const char *property;
616 /* Check NREC status change Signal*/
617 if (dbus_message_is_signal(msg, HFP_AGENT_SERVICE,
618 HFP_NREC_STATUS_CHANGE)) {
619 __bluetooth_handle_nrec_status_change(msg);
620 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
623 if (dbus_message_is_signal(msg, HFP_AGENT_SERVICE,
625 __bluetooth_telephony_answer_call(msg);
626 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
629 if (dbus_message_is_signal(msg, HFP_AGENT_SERVICE,
631 __bluetooth_telephony_reject_call(msg);
632 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
635 if (dbus_message_is_signal(msg, HFP_AGENT_SERVICE,
637 __bluetooth_telephony_release_call(msg);
638 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
641 if (dbus_message_is_signal(msg, HFP_AGENT_SERVICE,
642 HFP_THREEWAY_CALL)) {
643 __bluetooth_telephony_threeway_call(msg);
644 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
647 if (!dbus_message_has_interface(msg, BLUEZ_HEADSET_INTERFACE))
648 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
650 if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
651 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
653 dbus_message_iter_init(msg, &item_iter);
654 if (dbus_message_iter_get_arg_type(&item_iter) != DBUS_TYPE_STRING) {
655 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
658 dbus_message_iter_get_basic(&item_iter, &property);
660 if (property == NULL)
661 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
663 BT_DBG("Property (%s)", property);
665 if (g_strcmp0(property, "State") == 0) {
667 dbus_message_iter_next(&item_iter);
668 dbus_message_iter_recurse(&item_iter, &value_iter);
669 dbus_message_iter_get_basic(&value_iter, &state);
671 BT_ERR("State is null");
672 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
674 BT_DBG("State : %s", state);
676 if (g_strcmp0(state, "connected") == 0) {
677 telephony_info.headset_state = BLUETOOTH_STATE_CONNECTED;
678 } else if (g_strcmp0(state, "playing") == 0) {
679 telephony_info.headset_state = BLUETOOTH_STATE_PLAYING;
680 } else if (g_strcmp0(state, "disconnected") == 0) {
681 /* Headset state: playing -> disconnected */
682 if (telephony_info.headset_state == BLUETOOTH_STATE_PLAYING) {
683 __bt_telephony_event_cb(
684 BLUETOOTH_EVENT_TELEPHONY_AUDIO_DISCONNECTED,
685 BLUETOOTH_TELEPHONY_ERROR_NONE, NULL);
688 telephony_info.headset_state = BLUETOOTH_STATE_DISCONNETED;
691 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
694 if (g_strcmp0(property, "Connected") == 0) {
695 gboolean connected = FALSE;
696 dbus_message_iter_next(&item_iter);
697 dbus_message_iter_recurse(&item_iter, &value_iter);
698 dbus_message_iter_get_basic(&value_iter, &connected);
699 BT_DBG("Connected : %d", connected);
702 /*Get device address*/
704 dev_addr = strstr(path, "dev_");
706 if (dev_addr != NULL) {
708 g_strlcpy(telephony_info.address,
710 sizeof(telephony_info.address));
711 g_strdelimit(telephony_info.address, "_", ':');
712 BT_DBG("address is %s",
713 telephony_info.address);
715 telephony_info.headset_state =
716 BLUETOOTH_STATE_CONNECTED;
718 if (telephony_dbus_info.proxy != NULL) {
719 g_object_unref(telephony_dbus_info.proxy);
720 telephony_dbus_info.proxy = NULL;
723 telephony_dbus_info.proxy =
724 __bluetooth_telephony_get_connected_device_proxy();
726 BT_INFO("Headset Connected");
728 __bt_telephony_event_cb(
729 BLUETOOTH_EVENT_TELEPHONY_HFP_CONNECTED,
730 BLUETOOTH_TELEPHONY_ERROR_NONE, NULL);
732 } else { /*Device disconnected*/
733 memset(telephony_info.address, 0x00,
734 sizeof(telephony_info.address));
735 telephony_info.headset_state =
736 BLUETOOTH_STATE_DISCONNETED;
738 if (telephony_dbus_info.proxy != NULL) {
739 g_object_unref(telephony_dbus_info.proxy);
740 telephony_dbus_info.proxy = NULL;
743 BT_INFO("Headset Disconnected");
745 __bt_telephony_event_cb(
746 BLUETOOTH_EVENT_TELEPHONY_HFP_DISCONNECTED,
747 BLUETOOTH_TELEPHONY_ERROR_NONE, NULL);
749 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
752 if (g_strcmp0(property, "SpeakerGain") == 0) {
753 unsigned int spkr_gain;
755 dbus_message_iter_next(&item_iter);
756 dbus_message_iter_recurse(&item_iter, &value_iter);
757 dbus_message_iter_get_basic(&value_iter, &gain);
759 spkr_gain = (unsigned int)gain;
760 BT_DBG("spk_gain[%d]", spkr_gain);
762 __bt_telephony_event_cb(
763 BLUETOOTH_EVENT_TELEPHONY_SET_SPEAKER_GAIN,
764 BLUETOOTH_TELEPHONY_ERROR_NONE,
767 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
770 if (g_strcmp0(property, "MicrophoneGain") == 0) {
771 unsigned int mic_gain;
773 dbus_message_iter_next(&item_iter);
774 dbus_message_iter_recurse(&item_iter, &value_iter);
775 dbus_message_iter_get_basic(&value_iter, &gain);
777 mic_gain = (unsigned int)gain;
778 BT_DBG("mic_gain[%d]", mic_gain);
780 __bt_telephony_event_cb(
781 BLUETOOTH_EVENT_TELEPHONY_SET_MIC_GAIN,
782 BLUETOOTH_TELEPHONY_ERROR_NONE,
785 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
788 if (g_strcmp0(property, "Playing") == 0) {
789 gboolean audio_sink_playing = FALSE;
790 dbus_message_iter_next(&item_iter);
791 dbus_message_iter_recurse(&item_iter, &value_iter);
792 dbus_message_iter_get_basic(&value_iter, &audio_sink_playing);
794 if (audio_sink_playing) {
795 telephony_info.headset_state = BLUETOOTH_STATE_PLAYING;
796 __bt_telephony_event_cb(
797 BLUETOOTH_EVENT_TELEPHONY_AUDIO_CONNECTED,
798 BLUETOOTH_TELEPHONY_ERROR_NONE, NULL);
800 telephony_info.headset_state =
801 BLUETOOTH_STATE_CONNECTED;
802 __bt_telephony_event_cb(
803 BLUETOOTH_EVENT_TELEPHONY_AUDIO_DISCONNECTED,
804 BLUETOOTH_TELEPHONY_ERROR_NONE, NULL);
807 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
809 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
813 static int __bluetooth_telephony_proxy_init(void)
817 object = (GObject *)__bluetooth_telephony_method_new();
820 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
822 BT_DBG("telephony_object = %x", object);
824 dbus_g_connection_register_g_object(telephony_dbus_info.conn,
825 telephony_info.call_path, G_OBJECT(object));
828 return BLUETOOTH_TELEPHONY_ERROR_NONE;
831 static void __bluetooth_telephony_proxy_deinit(void)
835 dbus_g_connection_unregister_g_object(telephony_dbus_info.conn,
838 g_object_unref(object);
845 static int __bluetooth_telephony_register(void)
849 char *path = g_strdup(telephony_info.call_path);
854 reply = __bluetooth_telephony_dbus_method_send(
855 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
856 "RegisterApplication", &err, DBUS_TYPE_STRING, &path,
857 DBUS_TYPE_STRING, &src_addr,
862 BT_ERR("Error returned in method call");
863 if (dbus_error_is_set(&err)) {
864 ret = __bt_telephony_get_error(err.message);
865 BT_ERR("Error here %d\n", ret);
866 dbus_error_free(&err);
869 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
872 dbus_message_unref(reply);
873 BT_DBG("__bluetooth_telephony_register completed");
875 return BLUETOOTH_TELEPHONY_ERROR_NONE;
878 static int __bluetooth_telephony_unregister(void)
882 char *path = g_strdup(telephony_info.call_path);
887 reply = __bluetooth_telephony_dbus_method_send(
888 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
889 "UnregisterApplication", &err, DBUS_TYPE_STRING, &path,
894 BT_ERR("Error returned in method call");
895 if (dbus_error_is_set(&err)) {
896 ret = __bt_telephony_get_error(err.message);
897 dbus_error_free(&err);
900 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
903 dbus_message_unref(reply);
904 BT_DBG("__bluetooth_telephony_unregister completed");
906 return BLUETOOTH_TELEPHONY_ERROR_NONE;
909 #ifndef TIZEN_WEARABLE
910 static void __bluetooth_telephony_init_headset_state(void)
915 gboolean status = FALSE;
919 if (telephony_dbus_info.conn == NULL) {
920 BT_ERR("Bluetooth telephony not initilized");
923 reply = __bluetooth_telephony_dbus_method_send(
924 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
925 "IsConnected", &err, DBUS_TYPE_INVALID);
928 BT_ERR("Error returned in method call\n");
929 if (dbus_error_is_set(&err)) {
930 __bt_telephony_get_error(err.message);
931 dbus_error_free(&err);
936 if (!dbus_message_get_args(reply, &err,
937 DBUS_TYPE_BOOLEAN, &status,
938 DBUS_TYPE_INVALID)) {
939 BT_ERR("Error to get features");
940 if (dbus_error_is_set(&err)) {
941 BT_ERR("error message: %s", err.message);
942 dbus_error_free(&err);
944 dbus_message_unref(reply);
948 BT_INFO("Headset Connected Status = [%d]", status);
950 telephony_info.headset_state = BLUETOOTH_STATE_CONNECTED;
954 if (bluetooth_telephony_is_sco_connected())
955 telephony_info.headset_state = BLUETOOTH_STATE_PLAYING;
961 static gboolean __bluetooth_telephony_is_headset(uint32_t device_class)
963 gboolean flag = FALSE;
966 switch ((device_class & 0x1f00) >> 8) {
968 switch ((device_class & 0xfc) >> 2) {
986 /* Tizen Wearable device */
988 switch ((device_class & 0xfc) >> 2) {
989 case 0x01: /* Wrist Watch */
997 BT_DBG("[%d]", flag);
1002 static gboolean __bluetooth_telephony_is_headset_by_uuid(GValue *value)
1007 unsigned int service = 0;
1011 retv_if(value == NULL, FALSE);
1013 uuids = g_value_get_boxed(value);
1014 retv_if(uuids == NULL, FALSE);
1016 for (i = 0; uuids[i] != NULL; i++) {
1017 parts = g_strsplit(uuids[i], "-", -1);
1019 if (parts == NULL || parts[0] == NULL) {
1024 service = g_ascii_strtoull(parts[0], NULL, 16);
1027 if (service == BLUETOOTH_HS_PROFILE_UUID ||
1028 service == BLUETOOTH_HF_PROFILE_UUID)
1037 static int __bluetooth_telephony_get_connected_device(void)
1041 DBusMessageIter reply_iter;
1042 DBusMessageIter value_iter;
1044 DBusConnection *conn;
1045 DBusGProxy *headset_agent_proxy = NULL;
1047 GError *error = NULL;
1048 uint32_t device_class;
1049 gboolean playing = FALSE;
1050 gboolean connected = FALSE;
1051 GHashTable *list_hash = NULL;
1052 GValue *value = {0};
1053 char *object_path = NULL;
1054 DBusGProxy *proxy = NULL;
1055 const gchar *address;
1058 conn = _bt_get_system_conn();
1059 retv_if(conn == NULL, BLUETOOTH_TELEPHONY_ERROR_INTERNAL);
1061 msg = dbus_message_new_method_call(BLUEZ_SERVICE_NAME, "/",
1062 BLUEZ_MANAGER_INTERFACE,
1063 "GetManagedObjects");
1065 retv_if(msg == NULL, BLUETOOTH_TELEPHONY_ERROR_INTERNAL);
1067 /* Synchronous call */
1068 dbus_error_init(&err);
1069 reply = dbus_connection_send_with_reply_and_block(
1072 dbus_message_unref(msg);
1075 BT_ERR("Can't get managed objects");
1077 if (dbus_error_is_set(&err)) {
1078 BT_ERR("%s", err.message);
1079 dbus_error_free(&err);
1081 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1084 if (dbus_message_iter_init(reply, &reply_iter) == FALSE) {
1085 BT_ERR("Fail to iterate the reply");
1086 dbus_message_unref(reply);
1087 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1090 dbus_message_iter_recurse(&reply_iter, &value_iter);
1092 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
1093 while (dbus_message_iter_get_arg_type(&value_iter) ==
1094 DBUS_TYPE_DICT_ENTRY) {
1095 DBusMessageIter msg_iter;
1097 dbus_message_iter_recurse(&value_iter, &msg_iter);
1099 /* Parse the signature: oa{sa{sv}}} */
1100 retv_if(dbus_message_iter_get_arg_type(&msg_iter) !=
1101 DBUS_TYPE_OBJECT_PATH,
1102 BLUETOOTH_TELEPHONY_ERROR_INTERNAL);
1104 dbus_message_iter_get_basic(&msg_iter, &object_path);
1107 proxy = dbus_g_proxy_new_for_name(
1108 telephony_dbus_info.conn,
1111 BLUEZ_PROPERTIES_INTERFACE);
1115 dbus_g_proxy_call(proxy, "GetAll", &error,
1117 BLUEZ_DEVICE_INTERFACE,
1119 dbus_g_type_get_map("GHashTable",
1124 if (list_hash == NULL)
1128 BT_ERR("error in GetBasicProperties [%s]\n", error->message);
1129 g_error_free(error);
1133 value = g_hash_table_lookup(list_hash, "Class");
1134 device_class = value ? g_value_get_uint(value) : 0;
1136 if (device_class == 0) {
1137 BT_DBG("COD is NULL (maybe paired by nfc)... Checking UUIDs");
1138 value = g_hash_table_lookup(list_hash, "UUIDs");
1139 if (!__bluetooth_telephony_is_headset_by_uuid(value)) {
1140 BT_DBG("UUID checking completed. None HF device");
1141 g_object_unref(proxy);
1143 g_hash_table_destroy(list_hash);
1144 dbus_message_iter_next(&value_iter);
1147 BT_DBG("UUID checking completed. HF device");
1149 if (!__bluetooth_telephony_is_headset(device_class)) {
1150 g_object_unref(proxy);
1152 g_hash_table_destroy(list_hash);
1153 dbus_message_iter_next(&value_iter);
1158 /* this is headset; Check for Connection */
1159 headset_agent_proxy = dbus_g_proxy_new_for_name(
1160 telephony_dbus_info.conn,
1161 HFP_AGENT_SERVICE, object_path,
1162 HFP_AGENT_INTERFACE);
1164 if (headset_agent_proxy == NULL) {
1165 g_hash_table_destroy(list_hash);
1169 dbus_g_proxy_call(headset_agent_proxy, "IsConnected",
1170 &error, G_TYPE_INVALID,
1171 G_TYPE_BOOLEAN, &connected,
1174 if (error == NULL) {
1176 value = g_hash_table_lookup(list_hash,
1178 address = value ? g_value_get_string(
1181 g_strlcpy(telephony_info.address,
1183 sizeof(telephony_info.address));
1184 dbus_g_proxy_call(headset_agent_proxy,
1192 telephony_info.headset_state =
1193 BLUETOOTH_STATE_PLAYING;
1195 telephony_info.headset_state =
1196 BLUETOOTH_STATE_CONNECTED;
1198 g_hash_table_destroy(list_hash);
1202 g_error_free(error);
1205 g_hash_table_destroy(list_hash);
1206 g_object_unref(proxy);
1208 } /* end of if(object_path) */
1210 dbus_message_iter_next(&value_iter);
1211 } /* end of while */
1215 g_object_unref(proxy);
1217 dbus_message_unref(reply);
1220 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1223 static DBusGProxy *__bluetooth_telephony_get_connected_device_proxy(void)
1225 DBusGProxy *proxy = NULL;
1229 if (strlen(telephony_info.address) == 0)
1230 __bluetooth_telephony_get_connected_device();
1232 if (strlen(telephony_info.address) == 0)
1235 proxy = dbus_g_proxy_new_for_name(telephony_dbus_info.conn,
1236 HFP_AGENT_SERVICE, HFP_AGENT_PATH,
1237 HFP_AGENT_INTERFACE);
1244 BT_EXPORT_API int bluetooth_telephony_init(bt_telephony_func_ptr cb,
1247 DBusError dbus_error;
1248 DBusConnection *conn;
1249 int ret = BLUETOOTH_TELEPHONY_ERROR_NONE;
1250 GError *error = NULL;
1252 DBusConnection *dbus_conn;
1253 bluetooth_device_address_t loc_address = { {0} };
1254 char src_address[BT_ADDRESS_STRING_SIZE] = { 0 };
1260 if (is_initialized == TRUE) {
1261 BT_ERR("Bluetooth telephony already initilized");
1262 return BLUETOOTH_TELEPHONY_ERROR_ALREADY_INITIALIZED;
1265 is_initialized = TRUE;
1267 telephony_dbus_info.conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
1268 if (!telephony_dbus_info.conn) {
1269 if (NULL != error) {
1270 BT_ERR("dbus_g_bus_get() failed:[%d:%s]\n",
1271 error->code, error->message);
1272 g_error_free(error);
1274 is_initialized = FALSE;
1275 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1279 snprintf(telephony_info.call_path, sizeof(telephony_info.call_path),
1280 CSD_CALL_APP_PATH, getpid());
1281 BT_DBG("Call Path = %s", telephony_info.call_path);
1282 memset(telephony_info.address, 0x00, sizeof(telephony_info.address));
1284 if (__bluetooth_telephony_proxy_init()) {
1285 BT_ERR("__bluetooth_telephony_proxy_init failed\n");
1286 dbus_g_connection_unref(telephony_dbus_info.conn);
1287 telephony_dbus_info.conn = NULL;
1288 is_initialized = FALSE;
1289 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1292 telephony_dbus_info.manager_proxy = dbus_g_proxy_new_for_name(
1293 telephony_dbus_info.conn,
1295 "/", BLUEZ_MANAGER_INTERFACE);
1297 if (telephony_dbus_info.manager_proxy == NULL) {
1298 BT_ERR("Could not create a manager proxy\n");
1299 __bluetooth_telephony_proxy_deinit();
1300 dbus_g_connection_unref(telephony_dbus_info.conn);
1301 telephony_dbus_info.conn = NULL;
1302 is_initialized = FALSE;
1303 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1306 telephony_dbus_info.dbus_proxy = dbus_g_proxy_new_for_name(
1307 telephony_dbus_info.conn, DBUS_SERVICE_DBUS,
1308 DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
1310 if (NULL == telephony_dbus_info.dbus_proxy) {
1311 __bluetooth_telephony_proxy_deinit();
1312 dbus_g_connection_unref(telephony_dbus_info.conn);
1313 telephony_dbus_info.conn = NULL;
1314 g_object_unref(telephony_dbus_info.manager_proxy);
1315 telephony_dbus_info.manager_proxy = NULL;
1316 is_initialized = FALSE;
1317 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1320 dbus_conn = dbus_g_connection_get_connection(telephony_dbus_info.conn);
1322 /*Add Signal callback for BT enabled*/
1323 if (!dbus_connection_add_filter(dbus_conn,
1324 __bt_telephony_adapter_filter,
1326 BT_ERR("Fail to add filter");
1327 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1330 dbus_error_init(&dbus_error);
1331 dbus_bus_add_match(dbus_conn,
1332 "type='signal',interface='org.freedesktop.DBus.ObjectManager'"
1333 ",member='InterfacesAdded'",
1335 if (dbus_error_is_set(&dbus_error)) {
1336 BT_ERR("Fail to add match: %s\n", dbus_error.message);
1337 dbus_error_free(&dbus_error);
1341 /*Callback and user applicaton data*/
1342 telephony_info.cb = cb;
1343 telephony_info.user_data = user_data;
1344 telephony_info.headset_state = BLUETOOTH_STATE_DISCONNETED;
1346 dbus_error_init(&dbus_error);
1347 conn = dbus_g_connection_get_connection(telephony_dbus_info.conn);
1348 dbus_connection_add_filter(conn, __bluetooth_telephony_event_filter,
1350 dbus_bus_add_match(conn,
1351 "type='signal',interface='"BLUEZ_HEADSET_INTERFACE
1352 "',member='PropertyChanged'", &dbus_error);
1353 if (dbus_error_is_set(&dbus_error)) {
1354 BT_ERR("Fail to add dbus filter signal\n");
1355 dbus_error_free(&dbus_error);
1359 dbus_error_init(&dbus_error);
1360 dbus_bus_add_match(conn,
1361 "type='signal',interface='"HFP_AGENT_SERVICE
1362 "',member='"HFP_NREC_STATUS_CHANGE"'" , &dbus_error);
1363 if (dbus_error_is_set(&dbus_error)) {
1364 BT_ERR("Fail to add dbus filter signal\n");
1365 dbus_error_free(&dbus_error);
1369 dbus_error_init(&dbus_error);
1370 dbus_bus_add_match(conn,
1371 "type='signal',interface='"HFP_AGENT_SERVICE
1372 "',member='"HFP_ANSWER_CALL"'" , &dbus_error);
1373 if (dbus_error_is_set(&dbus_error)) {
1374 BT_ERR("Fail to add dbus filter signal\n");
1375 dbus_error_free(&dbus_error);
1379 dbus_error_init(&dbus_error);
1380 dbus_bus_add_match(conn,
1381 "type='signal',interface='"HFP_AGENT_SERVICE
1382 "',member='"HFP_REJECT_CALL"'" , &dbus_error);
1383 if (dbus_error_is_set(&dbus_error)) {
1384 BT_ERR("Fail to add dbus filter signal\n");
1385 dbus_error_free(&dbus_error);
1389 dbus_error_init(&dbus_error);
1390 dbus_bus_add_match(conn,
1391 "type='signal',interface='"HFP_AGENT_SERVICE
1392 "',member='"HFP_RELEASE_CALL"'" , &dbus_error);
1393 if (dbus_error_is_set(&dbus_error)) {
1394 BT_ERR("Fail to add dbus filter signal\n");
1395 dbus_error_free(&dbus_error);
1399 dbus_error_init(&dbus_error);
1400 dbus_bus_add_match(conn,
1401 "type='signal',interface='"HFP_AGENT_SERVICE
1402 "',member='"HFP_THREEWAY_CALL"'" , &dbus_error);
1403 if (dbus_error_is_set(&dbus_error)) {
1404 BT_ERR("Fail to add dbus filter signal\n");
1405 dbus_error_free(&dbus_error);
1409 if (bluetooth_check_adapter() == BLUETOOTH_ADAPTER_DISABLED)
1410 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1412 /*Bluetooth is active, therefore set the flag */
1415 ret = bluetooth_get_local_address(&loc_address);
1416 if (ret != BLUETOOTH_ERROR_NONE) {
1417 BT_ERR("Fail to get local address\n");
1418 ret = BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1421 _bt_convert_addr_type_to_string(src_address, loc_address.addr);
1422 src_addr = g_strdup(src_address);
1424 ret = __bluetooth_telephony_register();
1425 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
1426 BT_ERR("__bluetooth_telephony_register failed\n");
1430 #ifndef TIZEN_WEARABLE
1431 __bluetooth_telephony_init_headset_state();
1437 bluetooth_telephony_deinit();
1441 BT_EXPORT_API int bluetooth_telephony_deinit(void)
1443 DBusConnection *conn;
1447 BT_TELEPHONY_CHECK_INITIALIZED();
1449 is_initialized = FALSE;
1451 conn = dbus_g_connection_get_connection(telephony_dbus_info.conn);
1453 dbus_error_init(&error);
1454 dbus_bus_remove_match(conn,
1455 "type='signal',interface='"BLUEZ_HEADSET_INTERFACE
1456 "',member='PropertyChanged'", &error);
1457 if (dbus_error_is_set(&error)) {
1458 BT_ERR("Fail to remove dbus filter signal\n");
1459 dbus_error_free(&error);
1460 /* Need to re initilize before use */
1461 dbus_error_init(&error);
1464 dbus_error_init(&error);
1465 dbus_bus_remove_match(conn,
1466 "type='signal',interface='"HFP_AGENT_SERVICE
1467 "',member='"HFP_NREC_STATUS_CHANGE"'", &error);
1468 if (dbus_error_is_set(&error)) {
1469 BT_ERR("Fail to remove dbus filter signal\n");
1470 dbus_error_free(&error);
1473 dbus_error_init(&error);
1474 dbus_bus_remove_match(conn,
1475 "type='signal',interface='"HFP_AGENT_SERVICE
1476 "',member='"HFP_ANSWER_CALL"'", &error);
1477 if (dbus_error_is_set(&error)) {
1478 BT_ERR("Fail to remove dbus filter signal\n");
1479 dbus_error_free(&error);
1482 dbus_error_init(&error);
1483 dbus_bus_remove_match(conn,
1484 "type='signal',interface='"HFP_AGENT_SERVICE
1485 "',member='"HFP_REJECT_CALL"'", &error);
1486 if (dbus_error_is_set(&error)) {
1487 BT_ERR("Fail to remove dbus filter signal\n");
1488 dbus_error_free(&error);
1491 dbus_error_init(&error);
1492 dbus_bus_remove_match(conn,
1493 "type='signal',interface='"HFP_AGENT_SERVICE
1494 "',member='"HFP_RELEASE_CALL"'", &error);
1495 if (dbus_error_is_set(&error)) {
1496 BT_ERR("Fail to remove dbus filter signal\n");
1497 dbus_error_free(&error);
1500 dbus_error_init(&error);
1501 dbus_bus_remove_match(conn,
1502 "type='signal',interface='"HFP_AGENT_SERVICE
1503 "',member='"HFP_THREEWAY_CALL"'", &error);
1504 if (dbus_error_is_set(&error)) {
1505 BT_ERR("Fail to remove dbus filter signal\n");
1506 dbus_error_free(&error);
1509 dbus_connection_remove_filter(conn,
1510 __bluetooth_telephony_event_filter,
1513 if (bluetooth_check_adapter() != BLUETOOTH_ADAPTER_DISABLED ||
1514 bluetooth_check_adapter_le() != BLUETOOTH_ADAPTER_LE_DISABLED)
1515 __bluetooth_telephony_unregister();
1517 __bluetooth_telephony_proxy_deinit();
1519 telephony_info.cb = NULL;
1520 telephony_info.user_data = NULL;
1521 telephony_info.call_count = 0;
1522 telephony_info.headset_state = BLUETOOTH_STATE_DISCONNETED;
1524 /* Remove BT enabled signal */
1525 dbus_error_init(&error);
1526 dbus_bus_remove_match(conn,
1527 "type='signal',interface='org.freedesktop.DBus.ObjectManager'"
1528 ",member='InterfacesAdded'",
1530 if (dbus_error_is_set(&error)) {
1531 BT_ERR("Fail to remove dbus filter signal\n");
1532 dbus_error_free(&error);
1535 dbus_connection_remove_filter(dbus_g_connection_get_connection(
1536 telephony_dbus_info.conn),
1537 __bt_telephony_adapter_filter,
1542 if (telephony_dbus_info.manager_proxy != NULL) {
1543 g_object_unref(telephony_dbus_info.manager_proxy);
1544 telephony_dbus_info.manager_proxy = NULL;
1547 if (telephony_dbus_info.conn != NULL) {
1548 dbus_g_connection_unref(telephony_dbus_info.conn);
1549 telephony_dbus_info.conn = NULL;
1552 if (telephony_dbus_info.dbus_proxy != NULL) {
1553 g_object_unref(telephony_dbus_info.dbus_proxy);
1554 telephony_dbus_info.dbus_proxy = NULL;
1558 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1561 BT_EXPORT_API gboolean bluetooth_telephony_is_sco_connected(void)
1566 gboolean status = FALSE;
1570 retv_if(is_initialized == FALSE, FALSE);
1571 retv_if(bluetooth_check_adapter() == BLUETOOTH_ADAPTER_DISABLED, FALSE);
1573 reply = __bluetooth_telephony_dbus_method_send(
1574 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
1575 "IsPlaying", &err, DBUS_TYPE_INVALID);
1578 BT_ERR("Error returned in method call\n");
1579 if (dbus_error_is_set(&err)) {
1580 __bt_telephony_get_error(err.message);
1581 dbus_error_free(&err);
1586 if (!dbus_message_get_args(reply, &err,
1587 DBUS_TYPE_BOOLEAN, &status,
1588 DBUS_TYPE_INVALID)) {
1589 BT_ERR("Error to get features");
1590 if (dbus_error_is_set(&err)) {
1591 BT_ERR("error message: %s", err.message);
1592 dbus_error_free(&err);
1594 dbus_message_unref(reply);
1598 #ifdef TIZEN_WEARABLE
1599 if (status == TRUE && telephony_info.headset_state != BLUETOOTH_STATE_PLAYING)
1600 telephony_info.headset_state = BLUETOOTH_STATE_PLAYING;
1603 BT_INFO("SCO Connected Status = [%d]", status);
1607 BT_EXPORT_API int bluetooth_telephony_is_nrec_enabled(gboolean *status)
1611 DBusMessageIter reply_iter;
1612 DBusMessageIter reply_iter_entry;
1613 const char *property;
1617 BT_TELEPHONY_CHECK_INITIALIZED();
1618 BT_TELEPHONY_CHECK_ENABLED();
1621 return BLUETOOTH_TELEPHONY_ERROR_INVALID_PARAM;
1623 if (telephony_info.headset_state == BLUETOOTH_STATE_DISCONNETED)
1624 return BLUETOOTH_TELEPHONY_ERROR_AUDIO_NOT_CONNECTED;
1626 reply = __bluetooth_telephony_dbus_method_send(
1627 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
1628 "GetProperties", &err, DBUS_TYPE_INVALID);
1631 BT_ERR("Error returned in method call\n");
1632 if (dbus_error_is_set(&err)) {
1633 BT_DBG("Error message = %s", err.message);
1634 dbus_error_free(&err);
1636 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1639 dbus_message_iter_init(reply, &reply_iter);
1641 if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) {
1642 BT_ERR("Can't get reply arguments - DBUS_TYPE_ARRAY");
1643 dbus_message_unref(reply);
1644 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1647 dbus_message_iter_recurse(&reply_iter, &reply_iter_entry);
1650 while (dbus_message_iter_get_arg_type(&reply_iter_entry) ==
1651 DBUS_TYPE_DICT_ENTRY) {
1653 DBusMessageIter dict_entry, dict_entry_val;
1654 dbus_message_iter_recurse(&reply_iter_entry, &dict_entry);
1655 dbus_message_iter_get_basic(&dict_entry, &property);
1656 BT_DBG("String received = %s", property);
1658 if (g_strcmp0("nrec", property) == 0) {
1659 dbus_message_iter_next(&dict_entry);
1660 dbus_message_iter_recurse(&dict_entry, &dict_entry_val);
1661 if (dbus_message_iter_get_arg_type(&dict_entry_val) !=
1665 dbus_message_iter_get_basic(&dict_entry_val, status);
1666 BT_DBG("NREC status = [%d]", *status);
1668 dbus_message_iter_next(&reply_iter_entry);
1670 dbus_message_unref(reply);
1672 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1675 BT_EXPORT_API int bluetooth_telephony_is_wbs_mode(gboolean *status)
1679 DBusMessageIter reply_iter;
1680 DBusMessageIter reply_iter_entry;
1682 const char *property;
1686 BT_TELEPHONY_CHECK_INITIALIZED();
1687 BT_TELEPHONY_CHECK_ENABLED();
1690 return BLUETOOTH_TELEPHONY_ERROR_INVALID_PARAM;
1694 reply = __bluetooth_telephony_dbus_method_send(
1695 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
1696 "GetProperties", &err, DBUS_TYPE_INVALID);
1699 BT_ERR("Error returned in method call");
1700 if (dbus_error_is_set(&err)) {
1701 BT_ERR("Error message = %s", err.message);
1702 dbus_error_free(&err);
1704 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1707 dbus_message_iter_init(reply, &reply_iter);
1709 if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) {
1710 BT_ERR("Can't get reply arguments - DBUS_TYPE_ARRAY");
1711 dbus_message_unref(reply);
1712 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1715 dbus_message_iter_recurse(&reply_iter, &reply_iter_entry);
1718 while (dbus_message_iter_get_arg_type(&reply_iter_entry) ==
1719 DBUS_TYPE_DICT_ENTRY) {
1721 DBusMessageIter dict_entry, dict_entry_val;
1722 dbus_message_iter_recurse(&reply_iter_entry, &dict_entry);
1723 dbus_message_iter_get_basic(&dict_entry, &property);
1724 BT_DBG("String received = %s", property);
1726 if (g_strcmp0("codec", property) == 0) {
1727 dbus_message_iter_next(&dict_entry);
1728 dbus_message_iter_recurse(&dict_entry, &dict_entry_val);
1729 if (dbus_message_iter_get_arg_type(&dict_entry_val) !=
1733 dbus_message_iter_get_basic(&dict_entry_val, &codec);
1734 BT_DBG("Codec = [%d]", codec);
1735 *status = codec == BT_MSBC_CODEC_ID ? TRUE : FALSE;
1737 dbus_message_iter_next(&reply_iter_entry);
1739 dbus_message_unref(reply);
1741 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1744 BT_EXPORT_API int bluetooth_telephony_send_vendor_cmd(const char *cmd)
1746 GError *error = NULL;
1751 BT_TELEPHONY_CHECK_INITIALIZED();
1752 BT_TELEPHONY_CHECK_ENABLED();
1754 BT_DBG("Send Vendor %s", cmd);
1756 if (telephony_dbus_info.proxy == NULL)
1757 telephony_dbus_info.proxy =
1758 __bluetooth_telephony_get_connected_device_proxy();
1760 if (telephony_dbus_info.proxy == NULL)
1761 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1763 if (!dbus_g_proxy_call(telephony_dbus_info.proxy, "SendVendorAtCmd",
1766 G_TYPE_INVALID, G_TYPE_INVALID)) {
1767 if (error != NULL) {
1768 ret = __bt_telephony_get_error(error->message);
1769 g_error_free(error);
1775 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1778 BT_EXPORT_API int bluetooth_telephony_start_voice_recognition(void)
1783 gboolean state = TRUE;
1787 BT_TELEPHONY_CHECK_INITIALIZED();
1788 BT_TELEPHONY_CHECK_ENABLED();
1790 reply = __bluetooth_telephony_dbus_method_send(
1791 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
1792 "SetVoiceDial", &err, DBUS_TYPE_BOOLEAN, &state,
1796 BT_ERR("Error returned in method call\n");
1797 if (dbus_error_is_set(&err)) {
1798 ret = __bt_telephony_get_error(err.message);
1799 dbus_error_free(&err);
1802 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1805 dbus_message_unref(reply);
1808 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1811 BT_EXPORT_API int bluetooth_telephony_stop_voice_recognition(void)
1816 gboolean state = FALSE;
1820 BT_TELEPHONY_CHECK_INITIALIZED();
1821 BT_TELEPHONY_CHECK_ENABLED();
1823 reply = __bluetooth_telephony_dbus_method_send(
1824 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
1825 "SetVoiceDial", &err, DBUS_TYPE_BOOLEAN, &state,
1829 BT_ERR("Error returned in method call\n");
1830 if (dbus_error_is_set(&err)) {
1831 ret = __bt_telephony_get_error(err.message);
1832 dbus_error_free(&err);
1835 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1838 dbus_message_unref(reply);
1841 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1844 static void __bluetooth_telephony_sco_start_cb(
1845 DBusPendingCall *call, gpointer user_data)
1849 DBusMessage *msg = user_data;
1851 reply = dbus_pending_call_steal_reply(call);
1852 dbus_error_init(&derr);
1854 if (dbus_set_error_from_message(&derr, reply)) {
1855 BT_ERR("hs_sco_cb error: %s, %s",
1856 derr.name, derr.message);
1857 dbus_error_free(&derr);
1860 dbus_pending_call_unref(call);
1862 BT_DBG("sco_start_cb : -");
1863 dbus_message_unref(msg);
1864 dbus_message_unref(reply);
1867 BT_EXPORT_API int bluetooth_telephony_audio_open(void)
1869 DBusConnection *conn;
1875 BT_TELEPHONY_CHECK_INITIALIZED();
1876 BT_TELEPHONY_CHECK_ENABLED();
1878 /* Because this API is async call, so can't use dbus SMACK */
1879 if (__bt_telephony_check_privilege() ==
1880 BLUETOOTH_TELEPHONY_ERROR_PERMISSION_DENIED) {
1881 BT_ERR("Don't have a privilege to use this API");
1882 return BLUETOOTH_TELEPHONY_ERROR_PERMISSION_DENIED;
1885 conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
1887 BT_DBG("No System Bus found\n");
1888 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1891 if (telephony_info.headset_state == BLUETOOTH_STATE_PLAYING)
1892 return BLUETOOTH_TELEPHONY_ERROR_ALREADY_CONNECTED;
1894 msg = dbus_message_new_method_call(HFP_AGENT_SERVICE,
1895 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
1898 BT_ERR("dbus method call failed");
1899 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1902 if (dbus_connection_send_with_reply(conn, msg, &c, -1) == FALSE) {
1903 BT_DBG("HFP_AGENT: send with reply failed");
1904 dbus_message_unref(msg);
1905 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1907 dbus_pending_call_set_notify(c, __bluetooth_telephony_sco_start_cb,
1911 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1914 static void __bluetooth_telephony_sco_close_cb(DBusPendingCall *call, gpointer user_data)
1918 DBusMessage *msg = user_data;
1920 reply = dbus_pending_call_steal_reply(call);
1921 dbus_error_init(&derr);
1923 if (dbus_set_error_from_message(&derr, reply)) {
1924 BT_ERR("sco_close_cb error: %s, %s",
1925 derr.name, derr.message);
1926 dbus_error_free(&derr);
1930 dbus_pending_call_unref(call);
1932 BT_DBG("sco_close_cb : -");
1933 dbus_message_unref(msg);
1934 dbus_message_unref(reply);
1936 BT_EXPORT_API int bluetooth_telephony_audio_close(void)
1938 DBusConnection *conn;
1944 BT_TELEPHONY_CHECK_INITIALIZED();
1945 BT_TELEPHONY_CHECK_ENABLED();
1947 /* Because this API is async call, so can't use dbus SMACK */
1948 if (__bt_telephony_check_privilege() ==
1949 BLUETOOTH_TELEPHONY_ERROR_PERMISSION_DENIED) {
1950 BT_ERR("Don't have a privilege to use this API");
1951 return BLUETOOTH_TELEPHONY_ERROR_PERMISSION_DENIED;
1954 conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
1956 BT_DBG("No System Bus found\n");
1957 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1960 if (telephony_info.headset_state != BLUETOOTH_STATE_PLAYING)
1961 return BLUETOOTH_TELEPHONY_ERROR_NOT_CONNECTED;
1963 msg = dbus_message_new_method_call(HFP_AGENT_SERVICE,
1964 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
1967 BT_ERR("dbus method call failed");
1968 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1971 if (dbus_connection_send_with_reply(conn, msg, &c, -1) == FALSE) {
1972 BT_DBG("HFP_AGENT: send with reply failed");
1973 dbus_message_unref(msg);
1974 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1976 telephony_info.headset_state = BLUETOOTH_STATE_CONNECTED;
1978 dbus_pending_call_set_notify(c, __bluetooth_telephony_sco_close_cb,
1982 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1985 BT_EXPORT_API int bluetooth_telephony_call_remote_ringing(unsigned int call_id)
1989 BT_TELEPHONY_CHECK_INITIALIZED();
1990 BT_TELEPHONY_CHECK_ENABLED();
1993 BT_DBG("call_id = [%d]", call_id);
1995 /*Make sure SCO is already connected */
1996 ret = __bluetooth_telephony_send_call_status(
1997 CSD_CALL_STATUS_MO_ALERTING, call_id, NULL);
1998 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
1999 BT_ERR("send call status Failed = [%d]", ret);
2000 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
2003 return BLUETOOTH_TELEPHONY_ERROR_NONE;
2006 BT_EXPORT_API int bluetooth_telephony_call_answered(unsigned int call_id,
2007 unsigned int bt_audio)
2012 BT_DBG("call_id = [%d]", call_id);
2014 BT_TELEPHONY_CHECK_INITIALIZED();
2015 BT_TELEPHONY_CHECK_ENABLED();
2017 ret = __bluetooth_telephony_send_call_status(CSD_CALL_STATUS_ACTIVE,
2019 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
2020 BT_ERR("send call status Failed = [%d]", ret);
2025 if (!bluetooth_telephony_is_sco_connected()) {
2026 ret = bluetooth_telephony_audio_open();
2028 BT_ERR("Audio connection call Failed = %d", ret);
2029 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
2038 BT_EXPORT_API int bluetooth_telephony_call_end(unsigned int call_id)
2043 BT_DBG("call_id = [%d]", call_id);
2045 BT_TELEPHONY_CHECK_INITIALIZED();
2046 BT_TELEPHONY_CHECK_ENABLED();
2048 if (telephony_info.call_count > 0)
2049 telephony_info.call_count = telephony_info.call_count - 1;
2051 if (telephony_info.call_count == 0) {
2052 if (bluetooth_telephony_is_sco_connected()) {
2053 ret = bluetooth_telephony_audio_close();
2054 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE)
2055 BT_ERR(" Failed = [%d]", ret);
2059 ret = __bluetooth_telephony_send_call_status(CSD_CALL_STATUS_MT_RELEASE,
2061 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
2062 BT_ERR("send call status Failed = [%d]", ret);
2070 BT_EXPORT_API int bluetooth_telephony_call_held(unsigned int call_id)
2075 BT_DBG("call_id = [%d]", call_id);
2077 BT_TELEPHONY_CHECK_INITIALIZED();
2078 BT_TELEPHONY_CHECK_ENABLED();
2080 ret = __bluetooth_telephony_send_call_status(CSD_CALL_STATUS_HOLD,
2082 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE)
2083 BT_ERR("send call status Failed = [%d]", ret);
2089 BT_EXPORT_API int bluetooth_telephony_call_retrieved(unsigned int call_id)
2094 BT_DBG("call_id = [%d]", call_id);
2096 BT_TELEPHONY_CHECK_INITIALIZED();
2097 BT_TELEPHONY_CHECK_ENABLED();
2099 ret = __bluetooth_telephony_send_call_status(CSD_CALL_STATUS_ACTIVE,
2101 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE)
2102 BT_ERR("send call status Failed = [%d]", ret);
2108 BT_EXPORT_API int bluetooth_telephony_call_swapped(void *call_list,
2109 unsigned int call_count)
2113 GList *list = call_list;
2114 bt_telephony_call_status_info_t *call_status;
2118 BT_TELEPHONY_CHECK_INITIALIZED();
2119 BT_TELEPHONY_CHECK_ENABLED();
2122 BT_ERR("call_list is invalid");
2123 return BLUETOOTH_TELEPHONY_ERROR_INVALID_PARAM;
2126 /* Because this API is async call, so can't use dbus SMACK */
2127 if (__bt_telephony_check_privilege() ==
2128 BLUETOOTH_TELEPHONY_ERROR_PERMISSION_DENIED) {
2129 BT_ERR("Don't have a privilege to use this API");
2130 return BLUETOOTH_TELEPHONY_ERROR_PERMISSION_DENIED;
2133 BT_DBG(" call_count = [%d]", call_count);
2135 for (i = 0; i < call_count; i++) {
2136 call_status = g_list_nth_data(list, i);
2138 if (NULL == call_status)
2141 BT_DBG(" %d : Call id [%d] status[%d]", i,
2142 call_status->call_id,
2143 call_status->call_status);
2145 if (NULL != call_status->phone_number)
2146 DBG_SECURE(" call number [%s]", call_status->phone_number);
2148 switch (call_status->call_status) {
2149 case BLUETOOTH_CALL_STATE_HELD:
2150 ret = __bluetooth_telephony_send_call_status(
2151 CSD_CALL_STATUS_HOLD,
2152 call_status->call_id,
2153 call_status->phone_number);
2154 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
2155 BT_ERR("Failed = %d", ret);
2160 case BLUETOOTH_CALL_STATE_CONNECTED:
2161 ret = __bluetooth_telephony_send_call_status(
2162 CSD_CALL_STATUS_ACTIVE,
2163 call_status->call_id,
2164 call_status->phone_number);
2165 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
2166 BT_ERR("Failed = [%d]", ret);
2172 if ((call_status->call_status < BLUETOOTH_CALL_STATE_NONE) ||
2173 (call_status->call_status >= BLUETOOTH_CALL_STATE_ERROR)) {
2174 BT_ERR("Unknown Call state");
2175 return BLUETOOTH_TELEPHONY_ERROR_NOT_AVAILABLE;
2181 return BLUETOOTH_TELEPHONY_ERROR_NONE;
2184 BT_EXPORT_API int bluetooth_telephony_set_call_status(void *call_list,
2185 unsigned int call_count)
2191 ret = bluetooth_telephony_call_swapped(call_list, call_count);
2193 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
2194 BT_ERR("Failed = [%d]", ret);
2198 telephony_info.call_count = call_count;
2201 return BLUETOOTH_TELEPHONY_ERROR_NONE;
2204 BT_EXPORT_API int bluetooth_telephony_indicate_outgoing_call(
2205 const char *ph_number, unsigned int call_id,
2206 unsigned int bt_audio)
2210 const char *path = telephony_info.call_path;
2215 BT_TELEPHONY_CHECK_INITIALIZED();
2216 BT_TELEPHONY_CHECK_ENABLED();
2218 if (NULL == ph_number)
2219 return BLUETOOTH_TELEPHONY_ERROR_INVALID_PARAM;
2221 reply = __bluetooth_telephony_dbus_method_send(
2222 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
2223 "OutgoingCall", &err, DBUS_TYPE_STRING, &path,
2224 DBUS_TYPE_STRING, &ph_number, DBUS_TYPE_INT32,
2225 &call_id, DBUS_TYPE_INVALID);
2228 BT_ERR("Error returned in method call\n");
2229 if (dbus_error_is_set(&err)) {
2230 ret = __bt_telephony_get_error(err.message);
2231 dbus_error_free(&err);
2234 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
2237 dbus_message_unref(reply);
2239 telephony_info.call_count++;
2240 BT_DBG(" ag_info.ag_call_count = [%d]", telephony_info.call_count);
2243 if (!bluetooth_telephony_is_sco_connected()) {
2244 ret = bluetooth_telephony_audio_open();
2246 BT_ERR(" Audio connection Failed = %d", ret);
2247 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
2253 return BLUETOOTH_TELEPHONY_ERROR_NONE;
2256 BT_EXPORT_API int bluetooth_telephony_indicate_incoming_call(
2257 const char *ph_number, unsigned int call_id)
2261 const char *path = telephony_info.call_path;
2266 BT_TELEPHONY_CHECK_INITIALIZED();
2267 BT_TELEPHONY_CHECK_ENABLED();
2269 if (NULL == ph_number)
2270 return BLUETOOTH_TELEPHONY_ERROR_INVALID_PARAM;
2272 reply = __bluetooth_telephony_dbus_method_send(
2273 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
2274 "IncomingCall", &err, DBUS_TYPE_STRING, &path,
2275 DBUS_TYPE_STRING, &ph_number, DBUS_TYPE_INT32,
2276 &call_id, DBUS_TYPE_INVALID);
2279 BT_ERR("Error returned in method call\n");
2280 if (dbus_error_is_set(&err)) {
2281 ret = __bt_telephony_get_error(err.message);
2282 dbus_error_free(&err);
2285 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
2288 dbus_message_unref(reply);
2290 telephony_info.call_count++;
2291 BT_DBG("telephony_info.call_count = [%d]", telephony_info.call_count);
2293 return BLUETOOTH_TELEPHONY_ERROR_NONE;
2296 BT_EXPORT_API int bluetooth_telephony_set_speaker_gain(
2297 unsigned short speaker_gain)
2305 BT_TELEPHONY_CHECK_INITIALIZED();
2306 BT_TELEPHONY_CHECK_ENABLED();
2308 BT_DBG("set speaker_gain= [%d]", speaker_gain);
2310 reply = __bluetooth_telephony_dbus_method_send(
2311 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
2312 "SetSpeakerGain", &err, DBUS_TYPE_UINT16,
2313 &speaker_gain, DBUS_TYPE_INVALID);
2316 BT_ERR("Error returned in method call\n");
2317 if (dbus_error_is_set(&err)) {
2318 ret = __bt_telephony_get_error(err.message);
2319 dbus_error_free(&err);
2322 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
2325 dbus_message_unref(reply);
2328 return BLUETOOTH_TELEPHONY_ERROR_NONE;
2331 BT_EXPORT_API int bluetooth_telephony_get_headset_volume(
2332 unsigned int *speaker_gain)
2341 BT_TELEPHONY_CHECK_INITIALIZED();
2342 BT_TELEPHONY_CHECK_ENABLED();
2344 reply = __bluetooth_telephony_dbus_method_send(
2345 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
2346 "GetSpeakerGain", &err, DBUS_TYPE_INVALID);
2349 BT_ERR("Error returned in method call\n");
2350 if (dbus_error_is_set(&err)) {
2351 ret = __bt_telephony_get_error(err.message);
2352 dbus_error_free(&err);
2355 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
2358 if (!dbus_message_get_args(reply, &err,
2359 DBUS_TYPE_UINT16, &gain,
2360 DBUS_TYPE_INVALID)) {
2361 BT_ERR("Error to get features");
2362 if (dbus_error_is_set(&err)) {
2363 BT_ERR("error message: %s", err.message);
2364 dbus_error_free(&err);
2366 dbus_message_unref(reply);
2367 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
2369 *speaker_gain = gain;
2370 BT_DBG("Get speaker_gain= [%d]", *speaker_gain);
2372 dbus_message_unref(reply);
2374 return BLUETOOTH_TELEPHONY_ERROR_NONE;
2377 static DBusHandlerResult __bt_telephony_adapter_filter(DBusConnection *conn,
2378 DBusMessage *msg, void *data)
2381 char *object_path = NULL;
2382 const char *member = dbus_message_get_member(msg);
2385 if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
2386 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
2389 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
2391 if (strcasecmp(member, "InterfacesAdded") == 0) {
2392 if (__bt_telephony_get_object_path(msg, &object_path)) {
2393 BT_ERR("Fail to get the path");
2394 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
2397 if (strcasecmp(object_path, DEFAULT_ADAPTER_OBJECT_PATH) == 0) {
2399 BT_DBG("Adapter added [%s]", object_path);
2400 BT_DBG("BlueZ is Activated and flag need to be reset");
2401 BT_DBG("Send enabled to application");
2403 if (__bt_telephony_get_src_addr(msg)) {
2404 BT_ERR("Fail to get the local adapter address");
2405 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
2408 ret = __bluetooth_telephony_register();
2409 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE)
2410 BT_ERR("__bluetooth_telephony_register failed");
2415 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
2418 static int __bt_telephony_get_object_path(DBusMessage *msg, char **path)
2420 DBusMessageIter item_iter;
2421 dbus_message_iter_init(msg, &item_iter);
2424 if (dbus_message_iter_get_arg_type(&item_iter)
2425 != DBUS_TYPE_OBJECT_PATH) {
2426 BT_ERR("This is bad format dbus");
2427 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
2430 dbus_message_iter_get_basic(&item_iter, path);
2433 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
2436 return BLUETOOTH_TELEPHONY_ERROR_NONE;
2440 static int __bt_telephony_get_src_addr(DBusMessage *msg)
2443 const char *property = NULL;
2444 char *interface_name;
2445 DBusMessageIter item_iter;
2446 DBusMessageIter value_iter;
2447 DBusMessageIter msg_iter, dict_iter;
2448 DBusMessageIter in_iter, in2_iter;
2452 dbus_message_iter_init(msg, &item_iter);
2454 /* signature of InterfacesAdded signal is oa{sa{sv}} */
2455 if (dbus_message_iter_get_arg_type(&item_iter)
2456 != DBUS_TYPE_OBJECT_PATH) {
2457 BT_ERR("This is bad format dbus");
2458 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
2461 dbus_message_iter_get_basic(&item_iter, &object_path);
2462 retv_if(object_path == NULL,
2463 BLUETOOTH_TELEPHONY_ERROR_INTERNAL);
2465 if (strcasecmp(object_path, DEFAULT_ADAPTER_OBJECT_PATH) == 0) {
2466 /* get address from here */
2467 retv_if(dbus_message_iter_next(&item_iter) == FALSE,
2468 BLUETOOTH_TELEPHONY_ERROR_INTERNAL);
2470 /* signature a{sa{sv}} */
2471 retv_if(dbus_message_iter_get_arg_type(&item_iter) !=
2473 BLUETOOTH_TELEPHONY_ERROR_INTERNAL);
2474 dbus_message_iter_recurse(&item_iter, &value_iter);
2475 while (dbus_message_iter_get_arg_type(&value_iter) ==
2476 DBUS_TYPE_DICT_ENTRY) {
2477 dbus_message_iter_recurse(&value_iter, &msg_iter);
2478 if (dbus_message_iter_get_arg_type(&msg_iter)
2479 != DBUS_TYPE_STRING) {
2480 BT_ERR("This is bad format dbus");
2481 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
2484 dbus_message_iter_get_basic(&msg_iter, &interface_name);
2485 retv_if(interface_name == NULL,
2486 BLUETOOTH_TELEPHONY_ERROR_INTERNAL);
2488 BT_DBG("interface name is %s", interface_name);
2490 if (strcasecmp(interface_name, BLUEZ_ADAPTER_INTERFACE) == 0) {
2491 retv_if(!dbus_message_iter_next(&msg_iter),
2492 BLUETOOTH_TELEPHONY_ERROR_INTERNAL);
2493 dbus_message_iter_recurse(&msg_iter, &in_iter);
2495 if (dbus_message_iter_get_arg_type(&in_iter)
2496 != DBUS_TYPE_DICT_ENTRY) {
2497 BT_ERR("This is bad format dbus");
2498 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
2501 dbus_message_iter_recurse(&in_iter, &dict_iter);
2502 dbus_message_iter_get_basic(
2503 &dict_iter, &property);
2505 retv_if(property == NULL,
2506 BLUETOOTH_TELEPHONY_ERROR_INTERNAL);
2507 retv_if(!dbus_message_iter_next(&dict_iter),
2508 BLUETOOTH_TELEPHONY_ERROR_INTERNAL);
2510 if (strcasecmp(property, "Address") == 0) {
2511 dbus_message_iter_recurse
2512 (&dict_iter, &in2_iter);
2513 dbus_message_iter_get_basic
2514 (&in2_iter, &bd_addr);
2515 src_addr = g_strdup(bd_addr);
2519 dbus_message_iter_next(&value_iter);
2522 BT_DBG("default adapter address is src_addr = %s", src_addr);
2524 return BLUETOOTH_TELEPHONY_ERROR_NONE;