4 * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
23 #include <dbus/dbus.h>
24 #include <dbus/dbus-glib-bindings.h>
27 #include <vconf-keys.h>
29 #include "bt-common.h"
30 #include "bluetooth-telephony-api.h"
34 DBusGConnection *conn;
36 DBusGProxy *dbus_proxy;
37 DBusGProxy *manager_proxy;
38 } telephony_dbus_info_t;
41 bt_telephony_func_ptr cb;
42 unsigned int call_count;
44 char address[BT_ADDRESS_STR_LEN];
45 char call_path[BT_AUDIO_CALL_PATH_LEN];
46 bluetooth_headset_state_t headset_state;
48 } bt_telephony_info_t;
50 #define BLUETOOTH_TELEPHONY_ERROR (__bluetooth_telephony_error_quark())
52 #define BLUEZ_SERVICE_NAME "org.bluez"
53 #define BLUEZ_HEADSET_INTERFACE "org.bluez.Headset"
54 #define BLUEZ_MANAGER_INTERFACE "org.bluez.Manager"
55 #define BLUEZ_ADAPTER_INTERFACE "org.bluez.Adapter"
56 #define BLUEZ_DEVICE_INTERFACE "org.bluez.Device"
58 #define HFP_AGENT_SERVICE "org.bluez.hfp_agent"
59 #define HFP_AGENT_PATH "/org/bluez/hfp_agent"
60 #define HFP_AGENT_INTERFACE "Org.Hfp.App.Interface"
62 #define CSD_CALL_APP_PATH "/org/tizen/csd/%d"
63 #define HFP_NREC_STATUS_CHANGE "NrecStatusChanged"
65 #define BT_TELEPHONY_CHECK_ENABLED() \
67 if (bluetooth_check_adapter() == BLUETOOTH_ADAPTER_DISABLED) \
69 BT_ERR("BT is not enabled"); \
70 return BLUETOOTH_TELEPHONY_ERROR_NOT_ENABLED; \
74 static gboolean is_initialized = FALSE;
75 #define BT_TELEPHONY_CHECK_INITIALIZED() \
77 if (is_initialized == FALSE) \
79 BT_ERR("Bluetooth telephony not initilized"); \
80 return BLUETOOTH_TELEPHONY_ERROR_NOT_INITIALIZED; \
84 #define BLUETOOTH_TELEPHONY_METHOD (bluetooth_telephony_method_get_type())
85 #define BLUETOOTH_TELEPHONY_METHOD_GET_OBJECT(obj) \
86 (G_TYPE_CHECK_INSTANCE_CAST((obj), \
87 BLUETOOTH_TELEPHONY_METHOD, BluetoothTelephonyMethod))
89 #define BLUETOOTH_TELEPHONY_METHOD_IS_OBJECT(obj) \
90 (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
91 BLUETOOTH_TELEPHONY_METHOD))
93 #define BLUETOOTH_TELEPHONY_METHOD_CLASS(class) \
94 (G_TYPE_CHECK_CLASS_CAST((class), \
95 BLUETOOTH_TELEPHONY_METHOD, BluetoothTelephonyMethodClass))
97 #define BLUETOOTH_TELEPHONY_METHOD_GET_AGENT_CLASS(obj) \
98 (G_TYPE_INSTANCE_GET_CLASS((obj), \
99 BLUETOOTH_TELEPHONY_METHOD, BluetoothTelephonyMethodClass))
101 #define BLUETOOTH_TELEPHONY_METHOD_IS_AGENT_CLASS(class) \
102 (G_TYPE_CHECK_CLASS_TYPE((class), BLUETOOTH_TELEPHONY_METHOD))
104 #define BLUETOOTH_TELEPHONY_METHOD_AGENT_GET_PRIVATE(obj) \
105 (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
106 BLUETOOTH_TELEPHONY_METHOD, BluetoothTelephonyMethodPrivate))
108 typedef struct _BluetoothTelephonyMethod BluetoothTelephonyMethod;
109 typedef struct _BluetoothTelephonyMethodClass BluetoothTelephonyMethodClass;
111 struct _BluetoothTelephonyMethod {
115 struct _BluetoothTelephonyMethodClass {
116 GObjectClass parent_class;
119 BluetoothTelephonyMethod *bluetooth_telephony_method_new(void);
120 GType bluetooth_telephony_method_get_type(void);
122 G_DEFINE_TYPE(BluetoothTelephonyMethod, bluetooth_telephony_method, G_TYPE_OBJECT)
125 static gboolean bluetooth_telephony_method_answer(BluetoothTelephonyMethod *object,
127 DBusGMethodInvocation *context);
129 static gboolean bluetooth_telephony_method_release(
130 BluetoothTelephonyMethod *object, guint callid,
131 DBusGMethodInvocation *context);
133 static gboolean bluetooth_telephony_method_reject(BluetoothTelephonyMethod *object,
134 guint callid, DBusGMethodInvocation *context);
136 static gboolean bluetooth_telephony_method_threeway(
137 BluetoothTelephonyMethod *object, guint value,
138 DBusGMethodInvocation *context);
140 static gboolean bluetooth_telephony_method_send_dtmf(
141 BluetoothTelephonyMethod *object,
142 gchar *dtmf, DBusGMethodInvocation *context);
144 #include "bt-telephony-glue.h"
146 static GObject *object;
147 static bt_telephony_info_t telephony_info;
148 static telephony_dbus_info_t telephony_dbus_info;
149 static gboolean is_active = FALSE;
151 /*Function Declaration*/
152 static int __bt_telephony_get_error(const char *error_message);
153 static void __bt_telephony_event_cb(int event, int result, void *param_data);
154 static GQuark __bluetooth_telephony_error_quark(void);
155 static DBusMessage* __bluetooth_telephony_dbus_method_send(const char *path,
156 const char *interface, const char *method, DBusError *err, int type, ...);
157 static int __bluetooth_telephony_send_call_status(
158 bt_telephony_call_status_t call_status,
159 unsigned int call_id);
160 static GError *__bluetooth_telephony_error(bluetooth_telephony_error_t error,
161 const char *err_msg);
163 static DBusHandlerResult __bluetooth_telephony_event_filter(
164 DBusConnection *conn,
165 DBusMessage *msg, void *data);
167 static void __bluetooth_telephony_adapter_added_cb(DBusGProxy *manager_proxy,
168 const char *adapter_path, gpointer user_data);
169 static int __bluetooth_telephony_proxy_init(void);
170 static void __bluetooth_telephony_proxy_deinit(void);
171 static int __bluetooth_telephony_register(void);
172 static int __bluetooth_telephony_unregister(void);
173 static int __bluetooth_get_default_adapter_path(DBusGConnection *GConn,
175 static int __bluetooth_telephony_get_connected_device(void);
176 static DBusGProxy *__bluetooth_telephony_get_connected_device_proxy(void);
178 /*Function Definition*/
179 static int __bt_telephony_get_error(const char *error_message)
181 if (error_message == NULL) {
182 BT_DBG("Error message NULL\n");
183 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
186 BT_DBG("Error message = %s \n", error_message);
187 if (g_strcmp0(error_message, "NotAvailable") == 0)
188 return BLUETOOTH_TELEPHONY_ERROR_NOT_AVAILABLE;
189 else if (g_strcmp0(error_message, "NotConnected") == 0)
190 return BLUETOOTH_TELEPHONY_ERROR_NOT_CONNECTED;
191 else if (g_strcmp0(error_message, "InProgress") == 0)
192 return BLUETOOTH_TELEPHONY_ERROR_BUSY;
193 else if (g_strcmp0(error_message, "InvalidArguments") == 0)
194 return BLUETOOTH_TELEPHONY_ERROR_INVALID_PARAM;
195 else if (g_strcmp0(error_message, "AlreadyExists") == 0)
196 return BLUETOOTH_TELEPHONY_ERROR_ALREADY_EXSIST;
197 else if (g_strcmp0(error_message, "Already Connected") == 0)
198 return BLUETOOTH_TELEPHONY_ERROR_ALREADY_CONNECTED;
199 else if (g_strcmp0(error_message, "No memory") == 0)
200 return BLUETOOTH_TELEPHONY_ERROR_NO_MEMORY;
201 else if (g_strcmp0(error_message, "I/O error") == 0)
202 return BLUETOOTH_TELEPHONY_ERROR_I_O_ERROR;
203 else if (g_strcmp0(error_message, "Operation currently not available") == 0)
204 return BLUETOOTH_TELEPHONY_ERROR_OPERATION_NOT_AVAILABLE;
206 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
209 static void __bt_telephony_event_cb(int event, int result, void *param_data)
211 telephony_event_param_t bt_event = { 0, };
213 bt_event.event = event;
214 bt_event.result = result;
215 bt_event.param_data = param_data;
217 ret_if(telephony_info.cb == NULL);
218 telephony_info.cb(bt_event.event, &bt_event, telephony_info.user_data);
222 static GQuark __bluetooth_telephony_error_quark(void)
224 static GQuark quark = 0;
226 quark = g_quark_from_static_string("telephony");
231 static DBusMessage* __bluetooth_telephony_dbus_method_send(const char *path,
232 const char *interface, const char *method, DBusError *err, int type, ...)
240 msg = dbus_message_new_method_call(HFP_AGENT_SERVICE,
241 path, interface, method);
243 BT_ERR("Unable to allocate new D-Bus %s message \n", method);
247 va_start(args, type);
249 if (!dbus_message_append_args_valist(msg, type, args)) {
250 dbus_message_unref(msg);
257 dbus_error_init(err);
259 reply = dbus_connection_send_with_reply_and_block(
260 dbus_g_connection_get_connection(telephony_dbus_info.conn),
262 dbus_message_unref(msg);
268 static int __bluetooth_telephony_send_call_status(
269 bt_telephony_call_status_t call_status,
270 unsigned int call_id)
274 char *path = g_strdup(telephony_info.call_path);
279 reply = __bluetooth_telephony_dbus_method_send(
280 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
281 "ChangeCallStatus", &err, DBUS_TYPE_STRING, &path,
282 DBUS_TYPE_INT32, &call_status,
283 DBUS_TYPE_INT32, &call_id, DBUS_TYPE_INVALID);
287 BT_ERR("Error returned in method call\n");
288 if (dbus_error_is_set(&err)) {
289 ret = __bt_telephony_get_error(err.message);
290 dbus_error_free(&err);
293 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
296 dbus_message_unref(reply);
298 return BLUETOOTH_TELEPHONY_ERROR_NONE;
301 static GError *__bluetooth_telephony_error(bluetooth_telephony_error_t error,
304 return g_error_new(BLUETOOTH_TELEPHONY_ERROR, error, err_msg, NULL);
307 static void bluetooth_telephony_method_init(BluetoothTelephonyMethod *object)
310 BT_DBG("agent %p\n", object);
314 static void __bluetooth_telephony_method_finalize(
315 BluetoothTelephonyMethod *object)
318 G_OBJECT_CLASS(bluetooth_telephony_method_parent_class)->finalize((
323 static BluetoothTelephonyMethod *__bluetooth_telephony_method_new(void)
325 BluetoothTelephonyMethod *obj;
328 obj = g_object_new(BLUETOOTH_TELEPHONY_METHOD, NULL);
334 static void bluetooth_telephony_method_class_init(
335 BluetoothTelephonyMethodClass *klass)
337 GObjectClass *object_class = NULL;
340 object_class = G_OBJECT_CLASS(klass);
341 object_class->finalize = (void *)__bluetooth_telephony_method_finalize;
343 /*Registration of the Framework methods */
344 dbus_g_object_type_install_info(BLUETOOTH_TELEPHONY_METHOD,
345 &dbus_glib_bluetooth_telephony_method_object_info);
350 static gboolean bluetooth_telephony_method_answer(
351 BluetoothTelephonyMethod *object,
352 guint callid, DBusGMethodInvocation *context)
354 telephony_event_callid_t call_data = { 0, };
357 BT_DBG("call_id = [%d]", callid);
359 call_data.callid = callid;
361 __bt_telephony_event_cb(BLUETOOTH_EVENT_TELEPHONY_ANSWER_CALL,
362 BLUETOOTH_TELEPHONY_ERROR_NONE,
365 dbus_g_method_return(context);
370 static gboolean bluetooth_telephony_method_release(
371 BluetoothTelephonyMethod *object,
372 guint callid, DBusGMethodInvocation *context)
374 telephony_event_callid_t call_data = { 0, };
377 BT_DBG("call_id = [%d]\n", callid);
379 call_data.callid = callid;
381 __bt_telephony_event_cb(BLUETOOTH_EVENT_TELEPHONY_RELEASE_CALL,
382 BLUETOOTH_TELEPHONY_ERROR_NONE,
385 dbus_g_method_return(context);
391 static gboolean bluetooth_telephony_method_reject(
392 BluetoothTelephonyMethod *object,
393 guint callid, DBusGMethodInvocation *context)
395 telephony_event_callid_t call_data = { 0, };
398 BT_DBG("call_id = [%d]", callid);
400 call_data.callid = callid;
402 __bt_telephony_event_cb(BLUETOOTH_EVENT_TELEPHONY_REJECT_CALL,
403 BLUETOOTH_TELEPHONY_ERROR_NONE,
406 dbus_g_method_return(context);
411 static gboolean bluetooth_telephony_method_threeway(
412 BluetoothTelephonyMethod *object,
413 guint value, DBusGMethodInvocation *context)
419 BT_DBG("chld value = [%d]", value);
423 event = BLUETOOTH_EVENT_TELEPHONY_CHLD_0_RELEASE_ALL_HELD_CALL;
426 event = BLUETOOTH_EVENT_TELEPHONY_CHLD_1_RELEASE_ALL_ACTIVE_CALL;
429 event = BLUETOOTH_EVENT_TELEPHONY_CHLD_2_ACTIVE_HELD_CALL;
432 event = BLUETOOTH_EVENT_TELEPHONY_CHLD_3_MERGE_CALL;
435 BT_ERR("Invalid CHLD command");
436 err = __bluetooth_telephony_error(
437 BLUETOOTH_TELEPHONY_ERROR_INVALID_CHLD_INDEX,
438 "Invalid chld command");
439 dbus_g_method_return_error(context, err);
444 BT_DBG("event = [%d]", event);
446 __bt_telephony_event_cb(event,
447 BLUETOOTH_TELEPHONY_ERROR_NONE, NULL);
448 dbus_g_method_return(context);
453 static gboolean bluetooth_telephony_method_send_dtmf(
454 BluetoothTelephonyMethod *object,
455 gchar *dtmf, DBusGMethodInvocation *context)
457 telephony_event_dtmf_t call_data = { 0, };
463 BT_DBG("Number dial failed\n");
464 err = __bluetooth_telephony_error(
465 BLUETOOTH_TELEPHONY_ERROR_INVALID_DTMF,
467 dbus_g_method_return_error(context, err);
472 BT_DBG("Dtmf = %s \n", dtmf);
474 call_data.dtmf = g_strdup(dtmf);
476 __bt_telephony_event_cb(BLUETOOTH_EVENT_TELEPHONY_SEND_DTMF,
477 BLUETOOTH_TELEPHONY_ERROR_NONE, (void *)&call_data);
479 dbus_g_method_return(context);
480 g_free(call_data.dtmf);
485 static void __bluetooth_handle_nrec_status_change(DBusMessage *msg)
487 gboolean status = FALSE;
489 if (!dbus_message_get_args(msg, NULL,
490 DBUS_TYPE_BOOLEAN, &status,
491 DBUS_TYPE_INVALID)) {
492 BT_DBG("Error Getting parameters\n");
495 BT_DBG("NREC status = %d\n", status);
497 __bt_telephony_event_cb(BLUETOOTH_EVENT_TELEPHONY_NREC_CHANGED,
498 BLUETOOTH_TELEPHONY_ERROR_NONE, (void *)&status);
502 static DBusHandlerResult __bluetooth_telephony_event_filter(
503 DBusConnection *conn,
504 DBusMessage *msg, void *data)
506 const char *path = dbus_message_get_path(msg);
507 char *dev_addr = NULL;
508 DBusMessageIter item_iter;
509 DBusMessageIter value_iter;
510 const char *property;
512 /* Check NREC status change Signal*/
513 if (dbus_message_is_signal(msg, HFP_AGENT_SERVICE,
514 HFP_NREC_STATUS_CHANGE)) {
515 __bluetooth_handle_nrec_status_change(msg);
516 return DBUS_HANDLER_RESULT_HANDLED;
519 if (!dbus_message_has_interface(msg, BLUEZ_HEADSET_INTERFACE))
520 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
522 if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
523 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
525 dbus_message_iter_init(msg, &item_iter);
526 if (dbus_message_iter_get_arg_type(&item_iter) != DBUS_TYPE_STRING) {
527 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
530 dbus_message_iter_get_basic(&item_iter, &property);
532 if (property == NULL)
533 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
535 BT_DBG("Property (%s)\n", property);
537 if (g_strcmp0(property, "State") == 0) {
539 dbus_message_iter_next(&item_iter);
540 dbus_message_iter_recurse(&item_iter, &value_iter);
541 dbus_message_iter_get_basic(&value_iter, &state);
543 BT_ERR("State is null\n");
544 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
546 BT_DBG("State %s\n", state);
548 if (g_strcmp0(state, "connected") == 0) {
549 telephony_info.headset_state = BLUETOOTH_STATE_CONNECTED;
550 } else if (g_strcmp0(state, "playing") == 0) {
551 telephony_info.headset_state = BLUETOOTH_STATE_PLAYING;
552 } else if (g_strcmp0(state, "disconnected") == 0) {
553 /* Headset state: playing -> disconnected */
554 if (telephony_info.headset_state == BLUETOOTH_STATE_PLAYING) {
555 if (!vconf_set_bool(VCONFKEY_BT_HEADSET_SCO, FALSE)) {
556 BT_DBG("SVCONFKEY_BT_HEADSET_SCO - Set to FALSE\n");
558 BT_DBG("vconf_set_bool - Failed\n");
561 __bt_telephony_event_cb(
562 BLUETOOTH_EVENT_TELEPHONY_AUDIO_DISCONNECTED,
563 BLUETOOTH_TELEPHONY_ERROR_NONE, NULL);
566 telephony_info.headset_state = BLUETOOTH_STATE_DISCONNETED;
569 return DBUS_HANDLER_RESULT_HANDLED;
572 if (g_strcmp0(property, "Connected") == 0) {
573 gboolean connected = FALSE;
574 dbus_message_iter_next(&item_iter);
575 dbus_message_iter_recurse(&item_iter, &value_iter);
576 dbus_message_iter_get_basic(&value_iter, &connected);
577 BT_DBG("Connected %d\n", connected);
580 /*Get device address*/
582 dev_addr = strstr(path, "dev_");
584 if (dev_addr != NULL) {
586 g_strlcpy(telephony_info.address,
588 sizeof(telephony_info.address));
589 g_strdelimit(telephony_info.address, "_", ':');
590 BT_DBG("address is %s",
591 telephony_info.address);
593 telephony_info.headset_state =
594 BLUETOOTH_STATE_CONNECTED;
596 if (telephony_dbus_info.proxy != NULL) {
597 g_object_unref(telephony_dbus_info.proxy);
598 telephony_dbus_info.proxy = NULL;
601 telephony_dbus_info.proxy =
602 __bluetooth_telephony_get_connected_device_proxy();
604 BT_DBG("Headset Connected");
606 __bt_telephony_event_cb(
607 BLUETOOTH_EVENT_TELEPHONY_HFP_CONNECTED,
608 BLUETOOTH_TELEPHONY_ERROR_NONE, NULL);
610 } else { /*Device disconnected*/
611 memset(telephony_info.address, 0x00,
612 sizeof(telephony_info.address));
613 telephony_info.headset_state =
614 BLUETOOTH_STATE_DISCONNETED;
616 if (telephony_dbus_info.proxy != NULL) {
617 g_object_unref(telephony_dbus_info.proxy);
618 telephony_dbus_info.proxy = NULL;
621 BT_DBG("Headset Disconnected");
623 __bt_telephony_event_cb(
624 BLUETOOTH_EVENT_TELEPHONY_HFP_DISCONNECTED,
625 BLUETOOTH_TELEPHONY_ERROR_NONE, NULL);
627 return DBUS_HANDLER_RESULT_HANDLED;
630 if (g_strcmp0(property, "SpeakerGain") == 0) {
631 unsigned int spkr_gain;
633 dbus_message_iter_next(&item_iter);
634 dbus_message_iter_recurse(&item_iter, &value_iter);
635 dbus_message_iter_get_basic(&value_iter, &gain);
637 spkr_gain = (unsigned int)gain;
638 BT_DBG("spk_gain[%d]\n", spkr_gain);
640 __bt_telephony_event_cb(
641 BLUETOOTH_EVENT_TELEPHONY_SET_SPEAKER_GAIN,
642 BLUETOOTH_TELEPHONY_ERROR_NONE,
645 return DBUS_HANDLER_RESULT_HANDLED;
648 if (g_strcmp0(property, "MicrophoneGain") == 0) {
649 unsigned int mic_gain;
651 dbus_message_iter_next(&item_iter);
652 dbus_message_iter_recurse(&item_iter, &value_iter);
653 dbus_message_iter_get_basic(&value_iter, &gain);
655 mic_gain = (unsigned int)gain;
656 BT_DBG("mic_gain[%d]\n", mic_gain);
658 __bt_telephony_event_cb(
659 BLUETOOTH_EVENT_TELEPHONY_SET_MIC_GAIN,
660 BLUETOOTH_TELEPHONY_ERROR_NONE,
663 return DBUS_HANDLER_RESULT_HANDLED;
666 if (g_strcmp0(property, "Playing") == 0) {
667 gboolean audio_sink_playing = FALSE;
668 dbus_message_iter_next(&item_iter);
669 dbus_message_iter_recurse(&item_iter, &value_iter);
670 dbus_message_iter_get_basic(&value_iter, &audio_sink_playing);
672 if (audio_sink_playing) {
673 if (!vconf_set_bool(VCONFKEY_BT_HEADSET_SCO, TRUE)) {
674 BT_DBG("SVCONFKEY_BT_HEADSET_SCO -"
677 BT_DBG("vconf_set_bool - Failed\n");
679 telephony_info.headset_state = BLUETOOTH_STATE_PLAYING;
680 __bt_telephony_event_cb(
681 BLUETOOTH_EVENT_TELEPHONY_AUDIO_CONNECTED,
682 BLUETOOTH_TELEPHONY_ERROR_NONE, NULL);
684 if (!vconf_set_bool(VCONFKEY_BT_HEADSET_SCO, FALSE)) {
685 BT_DBG("SVCONFKEY_BT_HEADSET_SCO -"
688 BT_DBG("vconf_set_bool - Failed\n");
690 telephony_info.headset_state =
691 BLUETOOTH_STATE_CONNECTED;
692 __bt_telephony_event_cb(
693 BLUETOOTH_EVENT_TELEPHONY_AUDIO_DISCONNECTED,
694 BLUETOOTH_TELEPHONY_ERROR_NONE, NULL);
697 return DBUS_HANDLER_RESULT_HANDLED;
699 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
702 static void __bluetooth_telephony_adapter_added_cb(DBusGProxy *manager_proxy,
703 const char *adapter_path, gpointer user_data)
706 DBusError dbus_error;
707 DBusConnection *conn;
709 BT_DBG("Adapter added [%s] \n", adapter_path);
711 if (strstr(adapter_path, "hci0")) {
712 BT_DBG("BlueZ is Activated and flag need to be reset");
713 BT_DBG("Send enabled to application\n");
715 ret = __bluetooth_telephony_register();
716 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
717 BT_DBG("__bluetooth_telephony_register failed\n");
721 dbus_error_init(&dbus_error);
722 conn = dbus_g_connection_get_connection(telephony_dbus_info.conn);
723 dbus_connection_add_filter(conn, __bluetooth_telephony_event_filter,
726 dbus_bus_add_match(conn,
727 "type='signal',interface='" BLUEZ_HEADSET_INTERFACE
728 "',member='PropertyChanged'", &dbus_error);
729 dbus_bus_add_match(conn,
730 "type='signal',interface='"HFP_AGENT_SERVICE
731 "',member='"HFP_NREC_STATUS_CHANGE"'" , &dbus_error);
733 if (dbus_error_is_set(&dbus_error)) {
734 BT_DBG("Fail to add dbus filter signal\n");
735 dbus_error_free(&dbus_error);
736 __bluetooth_telephony_unregister();
737 dbus_connection_remove_filter(dbus_g_connection_get_connection(
738 telephony_dbus_info.conn),
739 __bluetooth_telephony_event_filter, NULL);
744 static int __bluetooth_telephony_proxy_init(void)
748 object = (GObject *)__bluetooth_telephony_method_new();
751 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
753 BT_DBG("telephony_object = %x", object);
755 dbus_g_connection_register_g_object(telephony_dbus_info.conn,
756 telephony_info.call_path, G_OBJECT(object));
759 return BLUETOOTH_TELEPHONY_ERROR_NONE;
762 static void __bluetooth_telephony_proxy_deinit(void)
766 dbus_g_connection_unregister_g_object(telephony_dbus_info.conn,
769 g_object_unref(object);
776 static int __bluetooth_telephony_register(void)
780 char *path = g_strdup(telephony_info.call_path);
785 reply = __bluetooth_telephony_dbus_method_send(
786 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
787 "RegisterApplication", &err, DBUS_TYPE_STRING, &path,
792 BT_ERR("Error returned in method call\n");
793 if (dbus_error_is_set(&err)) {
794 ret = __bt_telephony_get_error(err.message);
795 dbus_error_free(&err);
798 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
801 dbus_message_unref(reply);
803 return BLUETOOTH_TELEPHONY_ERROR_NONE;
806 static int __bluetooth_telephony_unregister(void)
810 char *path = g_strdup(telephony_info.call_path);
815 reply = __bluetooth_telephony_dbus_method_send(
816 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
817 "UnregisterApplication", &err, DBUS_TYPE_STRING, &path,
822 BT_ERR("Error returned in method call\n");
823 if (dbus_error_is_set(&err)) {
824 ret = __bt_telephony_get_error(err.message);
825 dbus_error_free(&err);
828 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
831 dbus_message_unref(reply);
833 return BLUETOOTH_TELEPHONY_ERROR_NONE;
836 static int __bluetooth_get_default_adapter_path(DBusGConnection *GConn,
840 char *adapter_path = NULL;
844 if (!dbus_g_proxy_call(telephony_dbus_info.manager_proxy,
845 "DefaultAdapter", &err, G_TYPE_INVALID,
846 DBUS_TYPE_G_OBJECT_PATH, &adapter_path,
849 BT_ERR("Getting DefaultAdapter failed: [%s]",
853 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
856 if (adapter_path == NULL) {
857 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
860 if (strlen(adapter_path) >= BT_ADAPTER_PATH_LEN) {
861 BT_ERR("Path too long.\n");
862 g_free(adapter_path);
863 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
866 BT_DBG("path = %s", adapter_path);
867 g_strlcpy(path, adapter_path, BT_ADAPTER_PATH_LEN);
868 g_free(adapter_path);
870 return BLUETOOTH_TELEPHONY_ERROR_NONE;
873 static int __bluetooth_telephony_get_connected_device(void)
875 DBusGProxy *list_proxy = NULL;
876 DBusGProxy *device_proxy = NULL;
877 GPtrArray *gp_array = NULL;
878 GError *error = NULL;
879 gchar *gp_path = NULL;
880 GHashTable *list_hash;
881 GHashTable *device_hash;
883 gboolean playing = FALSE;
884 gboolean connected = FALSE;
885 const gchar *address;
886 char object_path[BT_ADAPTER_PATH_LEN] = {0};
888 DBusGProxy *proxy = NULL;
892 /*Get default adapter path*/
893 if (__bluetooth_get_default_adapter_path(telephony_dbus_info.conn,
895 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
896 /*Get List of All devices*/
897 list_proxy = dbus_g_proxy_new_for_name(telephony_dbus_info.conn,
898 BLUEZ_SERVICE_NAME, object_path,
899 BLUEZ_ADAPTER_INTERFACE);
901 if (list_proxy == NULL)
902 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
904 dbus_g_proxy_call(list_proxy, "ListDevices", &error, G_TYPE_INVALID,
905 dbus_g_type_get_collection("GPtrArray",
906 DBUS_TYPE_G_OBJECT_PATH),
907 &gp_array, G_TYPE_INVALID);
914 if (gp_array == NULL)
917 /*Check for headset devices*/
918 for (i = 0; i < gp_array->len; i++) {
921 gp_path = g_ptr_array_index(gp_array, i);
926 proxy = dbus_g_proxy_new_for_name(telephony_dbus_info.conn,
927 BLUEZ_SERVICE_NAME, gp_path,
928 BLUEZ_DEVICE_INTERFACE);
933 dbus_g_proxy_call(proxy, "GetProperties", NULL,
934 G_TYPE_INVALID, dbus_g_type_get_map(
935 "GHashTable", G_TYPE_STRING,
936 G_TYPE_VALUE), &list_hash, G_TYPE_INVALID);
938 if (list_hash == NULL)
941 /*Check for Connection*/
942 device_proxy = dbus_g_proxy_new_for_name(
943 telephony_dbus_info.conn,
944 BLUEZ_SERVICE_NAME, gp_path,
945 BLUEZ_HEADSET_INTERFACE);
947 if (device_proxy == NULL) {
948 g_hash_table_destroy(list_hash);
952 dbus_g_proxy_call(device_proxy, "GetProperties",
953 &error, G_TYPE_INVALID,
954 dbus_g_type_get_map("GHashTable",
955 G_TYPE_STRING, G_TYPE_VALUE),
956 &device_hash, G_TYPE_INVALID);
959 value = g_hash_table_lookup(device_hash,
961 connected = value ? g_value_get_boolean(
964 value = g_hash_table_lookup(list_hash,
966 address = value ? g_value_get_string(
968 g_strlcpy(telephony_info.address, address,
969 sizeof(telephony_info.address));
970 value = g_hash_table_lookup(device_hash,
972 playing = value ? g_value_get_boolean(
975 telephony_info.headset_state =
976 BLUETOOTH_STATE_PLAYING;
978 telephony_info.headset_state =
979 BLUETOOTH_STATE_CONNECTED;
981 g_hash_table_destroy(device_hash);
982 g_hash_table_destroy(list_hash);
985 g_hash_table_destroy(device_hash);
990 g_hash_table_destroy(list_hash);
991 g_object_unref(proxy);
998 g_object_unref(list_proxy);
1000 g_object_unref(device_proxy);
1002 g_object_unref(proxy);
1004 g_ptr_array_free(gp_array, TRUE);
1006 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1009 static DBusGProxy *__bluetooth_telephony_get_connected_device_proxy(void)
1011 DBusGProxy *proxy = NULL;
1012 char object_path[BT_ADAPTER_PATH_LEN] = {0};
1013 GError *error = NULL;
1014 DBusGProxy *default_proxy;
1018 /*Get default adapter path*/
1019 if (__bluetooth_get_default_adapter_path(telephony_dbus_info.conn,
1023 /*Get List of All devices*/
1024 default_proxy = dbus_g_proxy_new_for_name(telephony_dbus_info.conn,
1025 BLUEZ_SERVICE_NAME, object_path,
1026 BLUEZ_ADAPTER_INTERFACE);
1028 if (default_proxy == NULL)
1031 if (strlen(telephony_info.address) == 0)
1032 __bluetooth_telephony_get_connected_device();
1034 if (strlen(telephony_info.address) == 0) {
1035 g_object_unref(default_proxy);
1039 if (telephony_info.obj_path) {
1040 g_free(telephony_info.obj_path);
1041 telephony_info.obj_path = NULL;
1044 dbus_g_proxy_call(default_proxy, "FindDevice", &error,
1045 G_TYPE_STRING, telephony_info.address,
1046 G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH,
1047 &telephony_info.obj_path,
1049 if (error != NULL) {
1050 BT_ERR("dbus_g_proxy_call Failed!\n");
1051 g_error_free(error);
1052 g_object_unref(default_proxy);
1056 if (telephony_info.obj_path == NULL) {
1057 g_object_unref(default_proxy);
1061 proxy = dbus_g_proxy_new_for_name(telephony_dbus_info.conn,
1062 BLUEZ_SERVICE_NAME, telephony_info.obj_path,
1063 BLUEZ_HEADSET_INTERFACE);
1065 g_object_unref(default_proxy);
1070 BT_EXPORT_API int bluetooth_telephony_init(bt_telephony_func_ptr cb,
1073 DBusError dbus_error;
1074 DBusConnection *conn;
1075 int ret = BLUETOOTH_TELEPHONY_ERROR_NONE;
1076 GError *error = NULL;
1077 char object_path[BT_ADAPTER_PATH_LEN] = {0};
1082 if (is_initialized == TRUE) {
1083 BT_ERR("Bluetooth telephony already initilized");
1084 return BLUETOOTH_TELEPHONY_ERROR_ALREADY_INITIALIZED;
1087 is_initialized = TRUE;
1089 telephony_dbus_info.conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
1090 if (!telephony_dbus_info.conn) {
1091 if (NULL != error) {
1092 BT_ERR("dbus_g_bus_get() failed:[%d:%s]\n",
1093 error->code, error->message);
1094 g_error_free(error);
1096 is_initialized = FALSE;
1097 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1101 snprintf(telephony_info.call_path, sizeof(telephony_info.call_path),
1102 CSD_CALL_APP_PATH, getpid());
1103 BT_DBG("Call Path = %s", telephony_info.call_path);
1104 memset(telephony_info.address, 0x00, sizeof(telephony_info.address));
1106 if (__bluetooth_telephony_proxy_init()) {
1107 BT_ERR("__bluetooth_telephony_proxy_init failed\n");
1108 dbus_g_connection_unref(telephony_dbus_info.conn);
1109 telephony_dbus_info.conn = NULL;
1110 is_initialized = FALSE;
1111 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1114 telephony_dbus_info.manager_proxy = dbus_g_proxy_new_for_name(
1115 telephony_dbus_info.conn,
1117 "/", BLUEZ_MANAGER_INTERFACE);
1119 if (telephony_dbus_info.manager_proxy == NULL) {
1120 BT_ERR("Could not create a manager proxy\n");
1121 __bluetooth_telephony_proxy_deinit();
1122 dbus_g_connection_unref(telephony_dbus_info.conn);
1123 telephony_dbus_info.conn = NULL;
1124 is_initialized = FALSE;
1125 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1128 telephony_dbus_info.dbus_proxy = dbus_g_proxy_new_for_name(
1129 telephony_dbus_info.conn, DBUS_SERVICE_DBUS,
1130 DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
1132 if (NULL == telephony_dbus_info.dbus_proxy) {
1133 __bluetooth_telephony_proxy_deinit();
1134 dbus_g_connection_unref(telephony_dbus_info.conn);
1135 telephony_dbus_info.conn = NULL;
1136 g_object_unref(telephony_dbus_info.manager_proxy);
1137 telephony_dbus_info.manager_proxy = NULL;
1138 is_initialized = FALSE;
1139 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1142 /*Add Signal callback for BT enabled*/
1143 dbus_g_proxy_add_signal(telephony_dbus_info.manager_proxy,
1145 DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
1146 dbus_g_proxy_connect_signal(telephony_dbus_info.manager_proxy,
1148 G_CALLBACK(__bluetooth_telephony_adapter_added_cb),
1151 /*Callback and user applicaton data*/
1152 telephony_info.cb = cb;
1153 telephony_info.user_data = user_data;
1155 dbus_error_init(&dbus_error);
1156 conn = dbus_g_connection_get_connection(telephony_dbus_info.conn);
1157 dbus_connection_add_filter(conn, __bluetooth_telephony_event_filter,
1160 dbus_bus_add_match(conn,
1161 "type='signal',interface='" BLUEZ_HEADSET_INTERFACE
1162 "',member='PropertyChanged'", &dbus_error);
1163 dbus_bus_add_match(conn,
1164 "type='signal',interface='"HFP_AGENT_SERVICE
1165 "',member='"HFP_NREC_STATUS_CHANGE"'" , &dbus_error);
1167 if (dbus_error_is_set(&dbus_error)) {
1168 BT_ERR("Fail to add dbus filter signal\n");
1169 dbus_error_free(&dbus_error);
1170 dbus_connection_remove_filter(dbus_g_connection_get_connection(
1171 telephony_dbus_info.conn),
1172 __bluetooth_telephony_event_filter, NULL);
1176 /*Check for BT status*/
1177 ret = __bluetooth_get_default_adapter_path(telephony_dbus_info.conn,
1179 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE)
1180 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1182 /*Bluetooth is active, therefore set the flag */
1185 ret = __bluetooth_telephony_register();
1186 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
1187 BT_ERR("__bluetooth_telephony_register failed\n");
1194 telephony_info.cb = NULL;
1195 telephony_info.user_data = NULL;
1196 telephony_info.call_count = 0;
1198 __bluetooth_telephony_proxy_deinit();
1200 /*Remove BT enabled signal*/
1201 dbus_g_proxy_disconnect_signal(
1202 telephony_dbus_info.manager_proxy,
1204 G_CALLBACK(__bluetooth_telephony_adapter_added_cb),
1207 dbus_g_connection_unref(telephony_dbus_info.conn);
1208 telephony_dbus_info.conn = NULL;
1209 g_object_unref(telephony_dbus_info.manager_proxy);
1210 telephony_dbus_info.manager_proxy = NULL;
1211 g_object_unref(telephony_dbus_info.dbus_proxy);
1212 telephony_dbus_info.dbus_proxy = NULL;
1213 is_initialized = FALSE;
1217 BT_EXPORT_API int bluetooth_telephony_deinit(void)
1221 BT_TELEPHONY_CHECK_INITIALIZED();
1223 is_initialized = FALSE;
1225 dbus_connection_remove_filter(dbus_g_connection_get_connection(
1226 telephony_dbus_info.conn),
1227 __bluetooth_telephony_event_filter, NULL);
1229 if (bluetooth_check_adapter() == BLUETOOTH_ADAPTER_ENABLED)
1230 __bluetooth_telephony_unregister();
1232 __bluetooth_telephony_proxy_deinit();
1234 telephony_info.cb = NULL;
1235 telephony_info.user_data = NULL;
1236 telephony_info.call_count = 0;
1238 /*Remove BT enabled signal*/
1239 dbus_g_proxy_disconnect_signal(
1240 telephony_dbus_info.manager_proxy,
1242 G_CALLBACK(__bluetooth_telephony_adapter_added_cb),
1245 g_object_unref(telephony_dbus_info.manager_proxy);
1246 telephony_dbus_info.manager_proxy = NULL;
1248 dbus_g_connection_unref(telephony_dbus_info.conn);
1249 telephony_dbus_info.conn = NULL;
1251 g_object_unref(telephony_dbus_info.dbus_proxy);
1252 telephony_dbus_info.dbus_proxy = NULL;
1255 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1258 BT_EXPORT_API gboolean bluetooth_telephony_is_sco_connected(void)
1262 if (telephony_dbus_info.conn == NULL) {
1263 BT_ERR("Bluetooth telephony not initilized");
1267 /* To get the headset state */
1268 if (telephony_dbus_info.proxy == NULL)
1269 telephony_dbus_info.proxy =
1270 __bluetooth_telephony_get_connected_device_proxy();
1272 if (telephony_dbus_info.proxy == NULL)
1275 if (telephony_info.headset_state == BLUETOOTH_STATE_PLAYING)
1282 BT_EXPORT_API int bluetooth_telephony_is_nrec_enabled(gboolean *status)
1286 DBusMessageIter reply_iter;
1287 DBusMessageIter reply_iter_entry;
1288 const char *property;
1292 BT_TELEPHONY_CHECK_INITIALIZED();
1293 BT_TELEPHONY_CHECK_ENABLED();
1296 return BLUETOOTH_TELEPHONY_ERROR_INVALID_PARAM;
1298 reply = __bluetooth_telephony_dbus_method_send(
1299 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
1300 "GetProperties", &err, DBUS_TYPE_INVALID);
1303 BT_ERR("Error returned in method call\n");
1304 if (dbus_error_is_set(&err)) {
1305 BT_DBG("Error message = %s \n", err.message);
1306 dbus_error_free(&err);
1308 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1311 dbus_message_iter_init(reply, &reply_iter);
1313 if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) {
1314 BT_ERR("Can't get reply arguments - DBUS_TYPE_ARRAY\n");
1315 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1318 dbus_message_iter_recurse(&reply_iter, &reply_iter_entry);
1321 while (dbus_message_iter_get_arg_type(&reply_iter_entry) ==
1322 DBUS_TYPE_DICT_ENTRY) {
1324 DBusMessageIter dict_entry, dict_entry_val;
1325 dbus_message_iter_recurse(&reply_iter_entry, &dict_entry);
1326 dbus_message_iter_get_basic(&dict_entry, &property);
1327 BT_DBG("String received = %s\n", property);
1329 if (g_strcmp0("nrec", property) == 0) {
1330 dbus_message_iter_next(&dict_entry);
1331 dbus_message_iter_recurse(&dict_entry, &dict_entry_val);
1332 if (dbus_message_iter_get_arg_type(&dict_entry_val) !=
1336 dbus_message_iter_get_basic(&dict_entry_val, status);
1337 BT_DBG("NREC status = [%d]", *status);
1339 dbus_message_iter_next(&reply_iter_entry);
1341 dbus_message_unref(reply);
1343 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1346 BT_EXPORT_API int bluetooth_telephony_start_voice_recognition(void)
1348 GError *error = NULL;
1353 BT_TELEPHONY_CHECK_INITIALIZED();
1354 BT_TELEPHONY_CHECK_ENABLED();
1356 if (telephony_dbus_info.proxy == NULL)
1357 telephony_dbus_info.proxy =
1358 __bluetooth_telephony_get_connected_device_proxy();
1360 if (telephony_dbus_info.proxy == NULL)
1361 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1363 if (!dbus_g_proxy_call(telephony_dbus_info.proxy, "SetVoiceDial",
1364 &error, G_TYPE_BOOLEAN, TRUE, G_TYPE_INVALID,
1366 if (error != NULL) {
1367 ret = __bt_telephony_get_error(error->message);
1368 g_error_free(error);
1374 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1377 BT_EXPORT_API int bluetooth_telephony_stop_voice_recognition(void)
1379 GError *error = NULL;
1384 BT_TELEPHONY_CHECK_INITIALIZED();
1385 BT_TELEPHONY_CHECK_ENABLED();
1387 if (telephony_dbus_info.proxy == NULL)
1388 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1390 if (!dbus_g_proxy_call(telephony_dbus_info.proxy, "SetVoiceDial",
1391 &error, G_TYPE_BOOLEAN,
1392 FALSE, G_TYPE_INVALID, G_TYPE_INVALID)) {
1393 BT_ERR("Dbus Call Failed!\n");
1394 if (error != NULL) {
1395 ret = __bt_telephony_get_error(error->message);
1396 g_error_free(error);
1402 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1405 BT_EXPORT_API int bluetooth_telephony_audio_open(void)
1407 GError *error = NULL;
1412 BT_TELEPHONY_CHECK_INITIALIZED();
1413 BT_TELEPHONY_CHECK_ENABLED();
1415 if (telephony_dbus_info.proxy == NULL)
1416 telephony_dbus_info.proxy =
1417 __bluetooth_telephony_get_connected_device_proxy();
1419 if (telephony_dbus_info.proxy == NULL)
1420 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1422 if (telephony_info.headset_state == BLUETOOTH_STATE_PLAYING)
1423 return BLUETOOTH_TELEPHONY_ERROR_ALREADY_CONNECTED;
1425 if (!dbus_g_proxy_call(telephony_dbus_info.proxy, "Play", &error,
1426 G_TYPE_INVALID, G_TYPE_INVALID)) {
1427 BT_ERR("Dbus Call Failed!");
1428 if (error != NULL) {
1429 ret = __bt_telephony_get_error(error->message);
1430 g_error_free(error);
1435 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1438 BT_EXPORT_API int bluetooth_telephony_audio_close(void)
1440 GError *error = NULL;
1445 BT_TELEPHONY_CHECK_INITIALIZED();
1446 BT_TELEPHONY_CHECK_ENABLED();
1448 if (telephony_dbus_info.proxy == NULL)
1449 telephony_dbus_info.proxy =
1450 __bluetooth_telephony_get_connected_device_proxy();
1452 if (telephony_dbus_info.proxy == NULL)
1453 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1455 if (telephony_info.headset_state != BLUETOOTH_STATE_PLAYING) {
1456 return BLUETOOTH_TELEPHONY_ERROR_NOT_CONNECTED;
1459 if (!dbus_g_proxy_call(telephony_dbus_info.proxy, "Stop", &error,
1460 G_TYPE_INVALID, G_TYPE_INVALID)) {
1461 BT_ERR("Dbus Call Failed");
1462 if (error != NULL) {
1463 ret = __bt_telephony_get_error(error->message);
1464 g_error_free(error);
1470 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1473 BT_EXPORT_API int bluetooth_telephony_call_remote_ringing(unsigned int call_id)
1477 BT_TELEPHONY_CHECK_INITIALIZED();
1478 BT_TELEPHONY_CHECK_ENABLED();
1482 /*Make sure SCO is already connected */
1483 ret = __bluetooth_telephony_send_call_status(
1484 CSD_CALL_STATUS_MO_ALERTING, call_id);
1485 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
1486 BT_ERR("send call status Failed = [%d]", ret);
1487 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1490 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1493 BT_EXPORT_API int bluetooth_telephony_call_answered(unsigned int call_id,
1494 unsigned int bt_audio)
1499 BT_TELEPHONY_CHECK_INITIALIZED();
1500 BT_TELEPHONY_CHECK_ENABLED();
1502 ret = __bluetooth_telephony_send_call_status(CSD_CALL_STATUS_ACTIVE,
1504 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
1505 BT_ERR("send call status Failed = [%d]", ret);
1510 if (!bluetooth_telephony_is_sco_connected()) {
1511 ret = bluetooth_telephony_audio_open();
1513 BT_ERR("Audio connection call Failed = %d", ret);
1514 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1523 BT_EXPORT_API int bluetooth_telephony_call_end(unsigned int call_id)
1528 BT_TELEPHONY_CHECK_INITIALIZED();
1529 BT_TELEPHONY_CHECK_ENABLED();
1531 ret = __bluetooth_telephony_send_call_status(CSD_CALL_STATUS_MT_RELEASE,
1533 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
1534 BT_ERR("send call status Failed = [%d]", ret);
1537 if (telephony_info.call_count > 0)
1538 telephony_info.call_count = telephony_info.call_count - 1;
1540 if (telephony_info.call_count == 0) {
1541 if (bluetooth_telephony_is_sco_connected()) {
1542 ret = bluetooth_telephony_audio_close();
1543 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
1544 BT_ERR(" Failed = [%d]", ret);
1553 BT_EXPORT_API int bluetooth_telephony_call_held(unsigned int call_id)
1558 BT_TELEPHONY_CHECK_INITIALIZED();
1559 BT_TELEPHONY_CHECK_ENABLED();
1561 ret = __bluetooth_telephony_send_call_status(CSD_CALL_STATUS_HOLD,
1563 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
1564 BT_ERR("send call status Failed = [%d]", ret);
1570 BT_EXPORT_API int bluetooth_telephony_call_retrieved(unsigned int call_id)
1575 BT_TELEPHONY_CHECK_INITIALIZED();
1576 BT_TELEPHONY_CHECK_ENABLED();
1578 ret = __bluetooth_telephony_send_call_status(CSD_CALL_STATUS_ACTIVE,
1580 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
1581 BT_ERR("send call status Failed = [%d]", ret);
1587 BT_EXPORT_API int bluetooth_telephony_call_swapped(void *call_list,
1588 unsigned int call_count)
1592 GList *list = call_list;
1593 bt_telephony_call_status_info_t *call_status;
1597 BT_TELEPHONY_CHECK_INITIALIZED();
1598 BT_TELEPHONY_CHECK_ENABLED();
1601 BT_ERR("call_list is invalid");
1602 return BLUETOOTH_TELEPHONY_ERROR_INVALID_PARAM;
1605 BT_DBG(" call_count = [%d]", call_count);
1607 for (i = 0; i < call_count; i++) {
1608 call_status = g_list_nth_data(list, i);
1610 if (NULL == call_status)
1613 BT_DBG(" %d : Call id [%d] status[%d]", i,
1614 call_status->call_id,
1615 call_status->call_status);
1617 switch (call_status->call_status) {
1618 case BLUETOOTH_CALL_STATE_HELD:
1619 ret = __bluetooth_telephony_send_call_status(
1620 CSD_CALL_STATUS_HOLD,
1621 call_status->call_id);
1622 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
1623 BT_ERR("Failed = %d", ret);
1628 case BLUETOOTH_CALL_STATE_CONNECTED:
1629 ret = __bluetooth_telephony_send_call_status(
1630 CSD_CALL_STATUS_ACTIVE,
1631 call_status->call_id);
1632 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
1633 BT_ERR("Failed = [%d]", ret);
1639 if ((call_status->call_status < BLUETOOTH_CALL_STATE_NONE) ||
1640 (call_status->call_status >= BLUETOOTH_CALL_STATE_ERROR)) {
1641 BT_ERR("Unknown Call state");
1642 return BLUETOOTH_TELEPHONY_ERROR_NOT_AVAILABLE;
1648 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1651 BT_EXPORT_API int bluetooth_telephony_set_call_status(void *call_list,
1652 unsigned int call_count)
1658 ret = bluetooth_telephony_call_swapped(call_list, call_count);
1660 if (ret != BLUETOOTH_TELEPHONY_ERROR_NONE) {
1661 BT_ERR("Failed = [%d]", ret);
1665 telephony_info.call_count = call_count;
1668 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1671 BT_EXPORT_API int bluetooth_telephony_indicate_outgoing_call(
1672 const char *ph_number, unsigned int call_id,
1673 unsigned int bt_audio)
1677 const char *path = telephony_info.call_path;
1682 BT_TELEPHONY_CHECK_INITIALIZED();
1683 BT_TELEPHONY_CHECK_ENABLED();
1685 if (NULL == ph_number)
1686 return BLUETOOTH_TELEPHONY_ERROR_INVALID_PARAM;
1688 reply = __bluetooth_telephony_dbus_method_send(
1689 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
1690 "OutgoingCall", &err, DBUS_TYPE_STRING, &path,
1691 DBUS_TYPE_STRING, &ph_number, DBUS_TYPE_INT32,
1692 &call_id, DBUS_TYPE_INVALID);
1695 BT_ERR("Error returned in method call\n");
1696 if (dbus_error_is_set(&err)) {
1697 ret = __bt_telephony_get_error(err.message);
1698 dbus_error_free(&err);
1701 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1704 dbus_message_unref(reply);
1706 telephony_info.call_count++;
1707 BT_DBG(" ag_info.ag_call_count = [%d]", telephony_info.call_count);
1710 if (!bluetooth_telephony_is_sco_connected()) {
1711 ret = bluetooth_telephony_audio_open();
1713 BT_ERR(" Audio connection call Failed = %d", ret);
1714 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1720 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1723 BT_EXPORT_API int bluetooth_telephony_indicate_incoming_call(
1724 const char *ph_number, unsigned int call_id)
1728 const char *path = telephony_info.call_path;
1733 BT_TELEPHONY_CHECK_INITIALIZED();
1734 BT_TELEPHONY_CHECK_ENABLED();
1736 if (NULL == ph_number)
1737 return BLUETOOTH_TELEPHONY_ERROR_INVALID_PARAM;
1739 reply = __bluetooth_telephony_dbus_method_send(
1740 HFP_AGENT_PATH, HFP_AGENT_INTERFACE,
1741 "IncomingCall", &err, DBUS_TYPE_STRING, &path,
1742 DBUS_TYPE_STRING, &ph_number, DBUS_TYPE_INT32,
1743 &call_id, DBUS_TYPE_INVALID);
1746 BT_ERR("Error returned in method call\n");
1747 if (dbus_error_is_set(&err)) {
1748 ret = __bt_telephony_get_error(err.message);
1749 dbus_error_free(&err);
1752 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1755 dbus_message_unref(reply);
1757 telephony_info.call_count++;
1758 BT_DBG("telephony_info.call_count = [%d]", telephony_info.call_count);
1760 return BLUETOOTH_TELEPHONY_ERROR_NONE;
1763 BT_EXPORT_API int bluetooth_telephony_set_speaker_gain(unsigned short speaker_gain)
1766 DBusMessageIter iter;
1767 DBusMessageIter value;
1768 DBusConnection *conn;
1769 char *spkr_gain_str = "SpeakerGain";
1770 int ret = BLUETOOTH_TELEPHONY_ERROR_NONE;
1773 BT_DBG("set speaker_gain= [%d]", speaker_gain);
1775 BT_TELEPHONY_CHECK_INITIALIZED();
1776 BT_TELEPHONY_CHECK_ENABLED();
1778 conn = dbus_g_connection_get_connection(telephony_dbus_info.conn);
1780 if (telephony_info.obj_path == NULL)
1781 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1783 msg = dbus_message_new_method_call(BLUEZ_SERVICE_NAME,
1784 telephony_info.obj_path, BLUEZ_HEADSET_INTERFACE,
1788 char sig[2] = {DBUS_TYPE_UINT16, '\0'};
1790 dbus_message_iter_init_append(msg, &iter);
1791 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
1793 dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
1795 dbus_message_iter_append_basic(&value, DBUS_TYPE_UINT16,
1797 dbus_message_iter_close_container(&iter, &value);
1799 if (dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_METHOD_CALL)
1800 dbus_message_set_no_reply(msg, TRUE);
1801 if (!dbus_connection_send(conn, msg, NULL)) {
1802 BT_ERR("bluetooth_telephony_set_speaker_gain : dbus sending failed");
1803 ret = BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1805 dbus_message_unref(msg);
1807 ret = BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1813 BT_EXPORT_API int bluetooth_telephony_get_headset_volume(unsigned int *speaker_gain)
1815 GHashTable *hash = NULL;
1816 GValue *value = NULL;
1817 GError *error = NULL;
1821 BT_TELEPHONY_CHECK_INITIALIZED();
1822 BT_TELEPHONY_CHECK_ENABLED();
1824 if (telephony_dbus_info.proxy == NULL)
1825 telephony_dbus_info.proxy =
1826 __bluetooth_telephony_get_connected_device_proxy();
1828 if (telephony_dbus_info.proxy == NULL)
1829 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1831 if (!dbus_g_proxy_call(telephony_dbus_info.proxy, "GetProperties", &error,
1833 dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
1834 &hash, G_TYPE_INVALID)) {
1835 BT_ERR("Dbus Call Failed!");
1836 if (error != NULL) {
1837 ret = __bt_telephony_get_error(error->message);
1838 g_error_free(error);
1844 return BLUETOOTH_TELEPHONY_ERROR_INTERNAL;
1846 value = g_hash_table_lookup(hash, "SpeakerGain");
1847 *speaker_gain = g_value_get_uint(value);
1848 g_hash_table_destroy(hash);
1850 return BLUETOOTH_TELEPHONY_ERROR_NONE;