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.
22 #include <dbus/dbus-glib-lowlevel.h>
23 #include <dbus/dbus-glib.h>
24 #include <dbus/dbus.h>
31 #include "bluetooth-api.h"
32 #include "bt-service-common.h"
33 #include "bt-service-agent.h"
35 static DBusGConnection *system_conn;
36 static DBusGConnection *session_conn;
37 static DBusGProxy *manager_proxy;
38 static DBusGProxy *adapter_proxy;
39 static DBusGProxy *adapter_properties_proxy;
41 static DBusGProxy *__bt_init_manager_proxy(void)
47 if (system_conn == NULL) {
48 system_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
49 retv_if(system_conn == NULL, NULL);
52 proxy = dbus_g_proxy_new_for_name(system_conn, BT_BLUEZ_NAME,
53 BT_MANAGER_PATH, BT_MANAGER_INTERFACE);
55 retv_if(proxy == NULL, NULL);
57 manager_proxy = proxy;
62 static DBusGProxy *__bt_init_adapter_proxy(void)
64 DBusGProxy *manager_proxy;
67 if (system_conn == NULL) {
68 system_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
69 retv_if(system_conn == NULL, NULL);
72 manager_proxy = _bt_get_manager_proxy();
73 retv_if(manager_proxy == NULL, NULL);
75 proxy = dbus_g_proxy_new_for_name(system_conn, BT_BLUEZ_NAME,
76 BT_BLUEZ_HCI_PATH, BT_ADAPTER_INTERFACE);
78 retv_if(proxy == NULL, NULL);
80 adapter_proxy = proxy;
85 static DBusGProxy *__bt_init_adapter_properties_proxy(void)
87 DBusGProxy *manager_proxy;
92 if (system_conn == NULL) {
93 system_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
94 retv_if(system_conn == NULL, NULL);
97 manager_proxy = _bt_get_manager_proxy();
98 retv_if(manager_proxy == NULL, NULL);
100 proxy = dbus_g_proxy_new_for_name(system_conn, BT_BLUEZ_NAME,
101 BT_BLUEZ_HCI_PATH, BT_PROPERTIES_INTERFACE);
103 retv_if(proxy == NULL, NULL);
105 adapter_properties_proxy = proxy;
110 DBusGConnection *__bt_init_system_gconn(void)
114 if (system_conn == NULL)
115 system_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
120 DBusGConnection *__bt_init_session_conn(void)
122 if (session_conn == NULL)
123 session_conn = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
128 DBusGConnection *_bt_get_session_gconn(void)
130 return (session_conn) ? session_conn : __bt_init_session_conn();
133 DBusGConnection *_bt_get_system_gconn(void)
135 return (system_conn) ? system_conn : __bt_init_system_gconn();
138 DBusConnection *_bt_get_system_conn(void)
140 DBusGConnection *g_conn;
142 if (system_conn == NULL) {
143 g_conn = __bt_init_system_gconn();
145 g_conn = system_conn;
148 retv_if(g_conn == NULL, NULL);
150 return dbus_g_connection_get_connection(g_conn);
153 DBusGProxy *_bt_get_manager_proxy(void)
155 return (manager_proxy) ? manager_proxy : __bt_init_manager_proxy();
158 DBusGProxy *_bt_get_adapter_proxy(void)
160 return (adapter_proxy) ? adapter_proxy : __bt_init_adapter_proxy();
163 DBusGProxy *_bt_get_adapter_properties_proxy(void)
165 return (adapter_properties_proxy) ? adapter_properties_proxy :
166 __bt_init_adapter_properties_proxy();
169 gboolean _bt_get_adapter_power(void)
171 DBusGProxy *proxy = NULL;
173 GValue powered_v = { 0 };
176 proxy = _bt_get_adapter_properties_proxy();
177 retv_if(proxy == NULL, FALSE);
179 if (!dbus_g_proxy_call(proxy, "Get", &err,
180 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
181 G_TYPE_STRING, "Powered",
183 G_TYPE_VALUE, &powered_v,
186 BT_ERR("Getting property failed: [%s]\n", err->message);
192 powered = (gboolean)g_value_get_boolean(&powered_v);
194 BT_DBG("powered = %d", powered);
199 static char *__bt_extract_adapter_path(DBusMessageIter *msg_iter)
201 char *object_path = NULL;
202 DBusMessageIter value_iter;
204 /* Parse the signature: oa{sa{sv}}} */
205 retv_if(dbus_message_iter_get_arg_type(msg_iter) !=
206 DBUS_TYPE_OBJECT_PATH, NULL);
208 dbus_message_iter_get_basic(msg_iter, &object_path);
209 retv_if(object_path == NULL, NULL);
211 /* object array (oa) */
212 retv_if(dbus_message_iter_next(msg_iter) == FALSE, NULL);
213 retv_if(dbus_message_iter_get_arg_type(msg_iter) !=
214 DBUS_TYPE_ARRAY, NULL);
216 dbus_message_iter_recurse(msg_iter, &value_iter);
218 /* string array (sa) */
219 while (dbus_message_iter_get_arg_type(&value_iter) ==
220 DBUS_TYPE_DICT_ENTRY) {
221 char *interface_name = NULL;
222 DBusMessageIter interface_iter;
224 dbus_message_iter_recurse(&value_iter, &interface_iter);
226 retv_if(dbus_message_iter_get_arg_type(&interface_iter) !=
227 DBUS_TYPE_STRING, NULL);
229 dbus_message_iter_get_basic(&interface_iter, &interface_name);
231 if (g_strcmp0(interface_name, "org.bluez.Adapter1") == 0) {
232 /* Tizen don't allow the multi-adapter */
233 BT_DBG("Found an adapter: %s", object_path);
234 return g_strdup(object_path);
237 dbus_message_iter_next(&value_iter);
240 BT_DBG("There is no adapter");
245 char *_bt_get_adapter_path(void)
249 DBusMessageIter reply_iter;
250 DBusMessageIter value_iter;
252 DBusConnection *conn;
253 char *adapter_path = NULL;
255 conn = _bt_get_system_conn();
256 retv_if(conn == NULL, NULL);
258 msg = dbus_message_new_method_call(BT_BLUEZ_NAME, BT_MANAGER_PATH,
259 BT_MANAGER_INTERFACE,
260 "GetManagedObjects");
262 retv_if(msg == NULL, NULL);
264 /* Synchronous call */
265 dbus_error_init(&err);
266 reply = dbus_connection_send_with_reply_and_block(
269 dbus_message_unref(msg);
272 BT_ERR("Can't get managed objects");
274 if (dbus_error_is_set(&err)) {
275 BT_ERR("%s", err.message);
276 dbus_error_free(&err);
281 if (dbus_message_iter_init(reply, &reply_iter) == FALSE) {
282 BT_ERR("Fail to iterate the reply");
286 dbus_message_iter_recurse(&reply_iter, &value_iter);
288 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
289 while (dbus_message_iter_get_arg_type(&value_iter) ==
290 DBUS_TYPE_DICT_ENTRY) {
291 DBusMessageIter msg_iter;
293 dbus_message_iter_recurse(&value_iter, &msg_iter);
295 adapter_path = __bt_extract_adapter_path(&msg_iter);
296 if (adapter_path != NULL) {
297 BT_DBG("Found the adapter path");
301 dbus_message_iter_next(&value_iter);
307 void _bt_deinit_bluez_proxy(void)
310 g_object_unref(manager_proxy);
311 manager_proxy = NULL;
315 g_object_unref(adapter_proxy);
316 adapter_proxy = NULL;
319 if (adapter_properties_proxy) {
320 g_object_unref(adapter_properties_proxy);
321 adapter_properties_proxy = NULL;
325 void _bt_deinit_proxys(void)
328 _bt_deinit_bluez_proxy();
331 dbus_g_connection_unref(system_conn);
336 dbus_g_connection_unref(session_conn);
342 void _bt_convert_device_path_to_address(const char *device_path,
343 char *device_address)
345 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
348 ret_if(device_path == NULL);
349 ret_if(device_address == NULL);
351 dev_addr = strstr(device_path, "dev_");
352 if (dev_addr != NULL) {
355 g_strlcpy(address, dev_addr, sizeof(address));
357 while ((pos = strchr(address, '_')) != NULL) {
361 g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
366 void _bt_convert_addr_string_to_type(unsigned char *addr,
372 ret_if(address == NULL);
373 ret_if(addr == NULL);
375 for (i = 0; i < BT_ADDRESS_LENGTH_MAX; i++) {
376 addr[i] = strtol(address, &ptr, 16);
386 void _bt_convert_addr_type_to_string(char *address,
389 ret_if(address == NULL);
390 ret_if(addr == NULL);
392 snprintf(address, BT_ADDRESS_STRING_SIZE,
393 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
394 addr[0], addr[1], addr[2],
395 addr[3], addr[4], addr[5]);
398 void _bt_print_device_address_t(const bluetooth_device_address_t *addr)
400 BT_DBG("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", addr->addr[0], addr->addr[1], addr->addr[2],
401 addr->addr[3], addr->addr[4], addr->addr[5]);
404 void _bt_divide_device_class(bluetooth_device_class_t *device_class,
407 ret_if(device_class == NULL);
409 device_class->major_class = (unsigned short)(cod & 0x00001F00) >> 8;
410 device_class->minor_class = (unsigned short)((cod & 0x000000FC));
411 device_class->service_class = (unsigned long)((cod & 0x00FF0000));
413 if (cod & 0x002000) {
414 device_class->service_class |=
415 BLUETOOTH_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE;
419 void _bt_free_device_info(bt_remote_dev_info_t *dev_info)
423 ret_if(dev_info == NULL);
425 g_free(dev_info->address);
426 g_free(dev_info->name);
428 if (dev_info->uuids) {
429 for (i = 0; dev_info->uuids[i] != NULL; i++)
430 g_free(dev_info->uuids[i]);
432 g_free(dev_info->uuids);
438 int _bt_register_osp_server_in_agent(int type, char *uuid)
440 if (!_bt_agent_register_osp_server( type, uuid))
441 return BLUETOOTH_ERROR_INTERNAL;
443 return BLUETOOTH_ERROR_NONE;
446 int _bt_unregister_osp_server_in_agent(int type, char *uuid)
448 if (!_bt_agent_unregister_osp_server( type, uuid))
449 return BLUETOOTH_ERROR_INTERNAL;
451 return BLUETOOTH_ERROR_NONE;
454 int _bt_set_socket_non_blocking(int socket_fd)
456 /* Set Nonblocking */
459 arg = fcntl(socket_fd, F_GETFL);
464 if (arg & O_NONBLOCK) {
465 BT_ERR("Already Non-blocking \n");
470 if (fcntl(socket_fd, F_SETFL, arg) < 0)
473 return BLUETOOTH_ERROR_NONE;
476 int _bt_set_non_blocking_tty(int sk)
478 struct termios ti = {0,};
481 err = _bt_set_socket_non_blocking(sk);
484 BT_ERR("Error in set non blocking!\n");
488 tcflush(sk, TCIOFLUSH);
490 /* Switch tty to RAW mode */
492 tcsetattr(sk, TCSANOW, &ti);
494 return BLUETOOTH_ERROR_NONE;
497 gboolean _bt_is_headset_class(int dev_class)
499 gboolean is_headset = FALSE;
501 switch ((dev_class & 0x1f00) >> 8) {
503 switch ((dev_class & 0xfc) >> 2) {
514 case 0x0c: /* Video Camera */
515 case 0x0d: /* Camcorder */
518 /* Other audio device */
528 static char *__bt_extract_device_path(DBusMessageIter *msg_iter, char *address)
530 char *object_path = NULL;
531 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
533 /* Parse the signature: oa{sa{sv}}} */
534 retv_if(dbus_message_iter_get_arg_type(msg_iter) !=
535 DBUS_TYPE_OBJECT_PATH, NULL);
537 dbus_message_iter_get_basic(msg_iter, &object_path);
538 retv_if(object_path == NULL, NULL);
540 _bt_convert_device_path_to_address(object_path, device_address);
542 if (g_strcmp0(address, device_address) == 0) {
543 return g_strdup(object_path);
549 char *_bt_get_device_object_path(char *address)
553 DBusMessageIter reply_iter;
554 DBusMessageIter value_iter;
556 DBusConnection *conn;
557 char *object_path = NULL;
559 conn = _bt_get_system_conn();
560 retv_if(conn == NULL, NULL);
562 msg = dbus_message_new_method_call(BT_BLUEZ_NAME, BT_MANAGER_PATH,
563 BT_MANAGER_INTERFACE,
564 "GetManagedObjects");
566 retv_if(msg == NULL, NULL);
568 /* Synchronous call */
569 dbus_error_init(&err);
570 reply = dbus_connection_send_with_reply_and_block(
573 dbus_message_unref(msg);
576 BT_ERR("Can't get managed objects");
578 if (dbus_error_is_set(&err)) {
579 BT_ERR("%s", err.message);
580 dbus_error_free(&err);
585 if (dbus_message_iter_init(reply, &reply_iter) == FALSE) {
586 BT_ERR("Fail to iterate the reply");
590 dbus_message_iter_recurse(&reply_iter, &value_iter);
592 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
593 while (dbus_message_iter_get_arg_type(&value_iter) ==
594 DBUS_TYPE_DICT_ENTRY) {
595 DBusMessageIter msg_iter;
597 dbus_message_iter_recurse(&value_iter, &msg_iter);
599 object_path = __bt_extract_device_path(&msg_iter, address);
600 if (object_path != NULL) {
601 BT_DBG("Found the device path");
605 dbus_message_iter_next(&value_iter);