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.
20 #include <dbus/dbus-glib.h>
21 #include <dbus/dbus.h>
25 #include <syspopup_caller.h>
27 #include "bluetooth-api.h"
28 #include "bt-internal-types.h"
30 #include "bt-service-audio.h"
31 #include "bt-service-adapter.h"
32 #include "bt-service-common.h"
33 #include "bt-service-event.h"
34 #include "bt-service-util.h"
36 static void __bt_audio_request_cb(DBusGProxy *proxy, DBusGProxyCall *call,
39 GError *g_error = NULL;
40 GArray *out_param1 = NULL;
41 GArray *out_param2 = NULL;
42 int result = BLUETOOTH_ERROR_NONE;
43 bt_function_data_t *func_data;
44 request_info_t *req_info;
46 dbus_g_proxy_end_call(proxy, call, &g_error, G_TYPE_INVALID);
48 g_object_unref(proxy);
50 func_data = user_data;
52 if (func_data == NULL) {
54 BT_ERR("func_data == NULL");
58 req_info = _bt_get_request_info(func_data->req_id);
59 if (req_info == NULL) {
60 BT_ERR("req_info == NULL");
64 if (g_error != NULL) {
65 BT_ERR("Audio Connect Dbus Call Error: %s\n", g_error->message);
66 result = BLUETOOTH_ERROR_INTERNAL;
70 /* Event will be sent by the event reciever */
72 if (req_info->context == NULL)
75 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
76 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
78 g_array_append_vals(out_param1, func_data->address,
80 g_array_append_vals(out_param2, &result, sizeof(int));
82 dbus_g_method_return(req_info->context, out_param1, out_param2);
84 g_array_free(out_param1, TRUE);
85 g_array_free(out_param2, TRUE);
87 _bt_delete_request_list(req_info->req_id);
90 g_error_free(g_error);
93 g_free(func_data->address);
98 static char *__bt_get_audio_path(bluetooth_device_address_t *address)
101 char *object_path = NULL;
102 char addr_str[BT_ADDRESS_STRING_SIZE + 1] = { 0 };
103 DBusGProxy *audio_proxy;
104 DBusGProxy *adapter_proxy;
105 DBusGConnection *g_conn;
106 GError *error = NULL;
108 retv_if(address == NULL, NULL);
110 g_conn = _bt_get_system_gconn();
111 retv_if(g_conn == NULL, NULL);
113 adapter_proxy = _bt_get_adapter_proxy();
114 retv_if(adapter_proxy == NULL, NULL);
116 _bt_convert_addr_type_to_string(addr_str, address->addr);
118 dbus_g_proxy_call(adapter_proxy, "FindDevice",
119 &error, G_TYPE_STRING, addr_str,
120 G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH,
121 &object_path, G_TYPE_INVALID);
124 BT_ERR("Failed to Find device: %s\n", error->message);
129 retv_if(object_path == NULL, NULL);
131 audio_proxy = dbus_g_proxy_new_for_name(g_conn,
134 BT_HEADSET_INTERFACE);
135 retv_if(audio_proxy == NULL, NULL);
137 g_object_unref(audio_proxy);
142 static char *__bt_get_connected_audio_path(void)
146 char *audio_path = NULL;
148 bluetooth_device_info_t info;
150 /* allocate the g_pointer_array */
151 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
153 if (_bt_get_bonded_devices(&device_list)
154 != BLUETOOTH_ERROR_NONE) {
155 g_array_free(device_list, TRUE);
159 size = device_list->len;
160 size = (device_list->len) / sizeof(bluetooth_device_info_t);
162 for (i = 0; i < size; i++) {
164 info = g_array_index(device_list,
165 bluetooth_device_info_t, i);
167 if (info.connected == TRUE) {
168 audio_path = __bt_get_audio_path(&info.device_address);
174 g_array_free(device_list, TRUE);
179 int _bt_audio_connect(int request_id, int type,
180 bluetooth_device_address_t *device_address,
183 int result = BLUETOOTH_ERROR_NONE;
184 gchar *device_path = NULL;
186 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
187 bt_function_data_t *func_data;
188 DBusGProxy *adapter_proxy;
189 DBusGProxy *profile_proxy;
190 DBusGConnection *g_conn;
192 BT_CHECK_PARAMETER(device_address);
194 _bt_convert_addr_type_to_string(address, device_address->addr);
198 interface = BT_HEADSET_INTERFACE;
201 interface = BT_SINK_INTERFACE;
204 interface = BT_AUDIO_INTERFACE;
207 BT_ERR("Unknown role");
208 result = BLUETOOTH_ERROR_INTERNAL;
212 adapter_proxy = _bt_get_adapter_proxy();
213 if (adapter_proxy == NULL) {
214 result = BLUETOOTH_ERROR_INTERNAL;
218 g_conn = _bt_get_system_gconn();
219 if (g_conn == NULL) {
220 result = BLUETOOTH_ERROR_INTERNAL;
224 dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
225 G_TYPE_STRING, address, G_TYPE_INVALID,
226 DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
228 if (device_path == NULL) {
229 BT_ERR("No paired device");
230 result = BLUETOOTH_ERROR_NOT_PAIRED;
234 profile_proxy = dbus_g_proxy_new_for_name(g_conn, BT_BLUEZ_NAME,
235 device_path, interface);
239 if (profile_proxy == NULL) {
240 result = BLUETOOTH_ERROR_INTERNAL;
244 func_data = g_malloc0(sizeof(bt_function_data_t));
245 func_data->address = g_strdup(address);
246 func_data->req_id = request_id;
248 if (!dbus_g_proxy_begin_call(profile_proxy, "Connect",
249 (DBusGProxyCallNotify)__bt_audio_request_cb,
252 BT_ERR("Audio connect Dbus Call Error");
253 g_object_unref(profile_proxy);
255 g_free(func_data->address);
258 result = BLUETOOTH_ERROR_INTERNAL;
262 return BLUETOOTH_ERROR_NONE;
264 g_array_append_vals(*out_param1, address,
270 int _bt_audio_disconnect(int request_id, int type,
271 bluetooth_device_address_t *device_address,
274 int result = BLUETOOTH_ERROR_NONE;
275 gchar *device_path = NULL;
277 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
278 bt_function_data_t *func_data;
279 DBusGProxy *adapter_proxy;
280 DBusGProxy *profile_proxy;
281 DBusGConnection *g_conn;
283 BT_CHECK_PARAMETER(device_address);
285 _bt_convert_addr_type_to_string(address, device_address->addr);
289 interface = BT_HEADSET_INTERFACE;
292 interface = BT_SINK_INTERFACE;
295 interface = BT_AUDIO_INTERFACE;
298 BT_ERR("Unknown role");
299 return BLUETOOTH_ERROR_INTERNAL;
302 adapter_proxy = _bt_get_adapter_proxy();
303 if (adapter_proxy == NULL) {
304 result = BLUETOOTH_ERROR_INTERNAL;
308 g_conn = _bt_get_system_gconn();
309 if (g_conn == NULL) {
310 result = BLUETOOTH_ERROR_INTERNAL;
314 dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
315 G_TYPE_STRING, address, G_TYPE_INVALID,
316 DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
318 if (device_path == NULL) {
319 BT_ERR("No paired device");
320 result = BLUETOOTH_ERROR_NOT_PAIRED;
324 profile_proxy = dbus_g_proxy_new_for_name(g_conn, BT_BLUEZ_NAME,
325 device_path, interface);
329 if (profile_proxy == NULL) {
330 result = BLUETOOTH_ERROR_INTERNAL;
334 func_data = g_malloc0(sizeof(bt_function_data_t));
335 func_data->address = g_strdup(address);
336 func_data->req_id = request_id;
338 if (!dbus_g_proxy_begin_call(profile_proxy, "Disconnect",
339 (DBusGProxyCallNotify)__bt_audio_request_cb,
342 BT_ERR("Audio disconnect Dbus Call Error");
343 g_object_unref(profile_proxy);
345 g_free(func_data->address);
348 result = BLUETOOTH_ERROR_INTERNAL;
352 return BLUETOOTH_ERROR_NONE;
354 g_array_append_vals(*out_param1, address,
360 int _bt_audio_get_speaker_gain(unsigned int *gain)
362 char *device_path = NULL;
363 DBusGProxy *adapter_proxy;
364 DBusGProxy *profile_proxy;
365 DBusGConnection *g_conn;
366 GHashTable *hash = NULL;
369 adapter_proxy = _bt_get_adapter_proxy();
370 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
372 g_conn = _bt_get_system_gconn();
373 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
375 device_path = __bt_get_connected_audio_path();
376 retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
378 profile_proxy = dbus_g_proxy_new_for_name(g_conn, BT_BLUEZ_NAME,
379 device_path, BT_HEADSET_INTERFACE);
383 retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
385 dbus_g_proxy_call(profile_proxy, "GetProperties", NULL,
387 dbus_g_type_get_map("GHashTable",
388 G_TYPE_STRING, G_TYPE_VALUE),
389 &hash, G_TYPE_INVALID);
391 g_object_unref(profile_proxy);
393 retv_if(hash == NULL, BLUETOOTH_ERROR_INTERNAL);
395 value = g_hash_table_lookup(hash, "SpeakerGain");
396 *gain = value ? g_value_get_uint(value) : 0;
397 g_hash_table_destroy(hash);
398 return BLUETOOTH_ERROR_NONE;
401 int _bt_audio_set_speaker_gain(unsigned int gain)
403 char *device_path = NULL;
404 char *gain_str = "SpeakerGain";
405 char sig[2] = {DBUS_TYPE_UINT16, '\0'};
406 int ret = BLUETOOTH_ERROR_NONE;
408 DBusMessageIter iter;
409 DBusMessageIter value;
410 DBusConnection *conn;
412 conn = _bt_get_system_conn();
413 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
415 device_path = __bt_get_connected_audio_path();
416 retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
418 msg = dbus_message_new_method_call(BT_BLUEZ_NAME,
419 device_path, BT_HEADSET_INTERFACE,
424 retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
426 dbus_message_iter_init_append(msg, &iter);
427 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
429 dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
431 dbus_message_iter_append_basic(&value, DBUS_TYPE_UINT16,
433 dbus_message_iter_close_container(&iter, &value);
435 if (dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_METHOD_CALL)
436 dbus_message_set_no_reply(msg, TRUE);
438 if (!dbus_connection_send(conn, msg, NULL)) {
439 BT_ERR("Dbus sending failed\n");
440 ret = BLUETOOTH_ERROR_INTERNAL;
442 dbus_message_unref(msg);