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 static char *__bt_extract_adapter_path(DBusMessageIter *msg_iter)
171 char *object_path = NULL;
172 DBusMessageIter value_iter;
174 /* Parse the signature: oa{sa{sv}}} */
175 retv_if(dbus_message_iter_get_arg_type(msg_iter) !=
176 DBUS_TYPE_OBJECT_PATH, NULL);
178 dbus_message_iter_get_basic(msg_iter, &object_path);
179 retv_if(object_path == NULL, NULL);
181 /* object array (oa) */
182 retv_if(dbus_message_iter_next(msg_iter) == FALSE, NULL);
183 retv_if(dbus_message_iter_get_arg_type(msg_iter) !=
184 DBUS_TYPE_ARRAY, NULL);
186 dbus_message_iter_recurse(msg_iter, &value_iter);
188 /* string array (sa) */
189 while (dbus_message_iter_get_arg_type(&value_iter) ==
190 DBUS_TYPE_DICT_ENTRY) {
191 char *interface_name = NULL;
192 DBusMessageIter interface_iter;
194 dbus_message_iter_recurse(&value_iter, &interface_iter);
196 retv_if(dbus_message_iter_get_arg_type(&interface_iter) !=
197 DBUS_TYPE_STRING, NULL);
199 dbus_message_iter_get_basic(&interface_iter, &interface_name);
201 if (g_strcmp0(interface_name, "org.bluez.Adapter1") == 0) {
202 /* Tizen don't allow the multi-adapter */
203 BT_DBG("Found an adapter: %s", object_path);
204 return g_strdup(object_path);
207 dbus_message_iter_next(&value_iter);
210 BT_DBG("There is no adapter");
215 char *_bt_get_adapter_path(void)
219 DBusMessageIter reply_iter;
220 DBusMessageIter value_iter;
222 DBusConnection *conn;
223 char *adapter_path = NULL;
225 conn = _bt_get_system_conn();
226 retv_if(conn == NULL, NULL);
228 msg = dbus_message_new_method_call(BT_BLUEZ_NAME, BT_MANAGER_PATH,
229 BT_MANAGER_INTERFACE,
230 "GetManagedObjects");
232 retv_if(msg == NULL, NULL);
234 /* Synchronous call */
235 dbus_error_init(&err);
236 reply = dbus_connection_send_with_reply_and_block(
239 dbus_message_unref(msg);
242 BT_ERR("Can't get managed objects");
244 if (dbus_error_is_set(&err)) {
245 BT_ERR("%s", err.message);
246 dbus_error_free(&err);
251 if (dbus_message_iter_init(reply, &reply_iter) == FALSE) {
252 BT_ERR("Fail to iterate the reply");
256 dbus_message_iter_recurse(&reply_iter, &value_iter);
258 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
259 while (dbus_message_iter_get_arg_type(&value_iter) ==
260 DBUS_TYPE_DICT_ENTRY) {
261 DBusMessageIter msg_iter;
263 dbus_message_iter_recurse(&value_iter, &msg_iter);
265 adapter_path = __bt_extract_adapter_path(&msg_iter);
266 if (adapter_path != NULL) {
267 BT_DBG("Found the adapter path");
271 dbus_message_iter_next(&value_iter);
277 void _bt_deinit_bluez_proxy(void)
280 g_object_unref(manager_proxy);
281 manager_proxy = NULL;
285 g_object_unref(adapter_proxy);
286 adapter_proxy = NULL;
289 if (adapter_properties_proxy) {
290 g_object_unref(adapter_properties_proxy);
291 adapter_properties_proxy = NULL;
295 void _bt_deinit_proxys(void)
298 _bt_deinit_bluez_proxy();
301 dbus_g_connection_unref(system_conn);
306 dbus_g_connection_unref(session_conn);
312 void _bt_convert_device_path_to_address(const char *device_path,
313 char *device_address)
315 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
318 ret_if(device_path == NULL);
319 ret_if(device_address == NULL);
321 dev_addr = strstr(device_path, "dev_");
322 if (dev_addr != NULL) {
325 g_strlcpy(address, dev_addr, sizeof(address));
327 while ((pos = strchr(address, '_')) != NULL) {
331 g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
336 void _bt_convert_addr_string_to_type(unsigned char *addr,
342 ret_if(address == NULL);
343 ret_if(addr == NULL);
345 for (i = 0; i < BT_ADDRESS_LENGTH_MAX; i++) {
346 addr[i] = strtol(address, &ptr, 16);
356 void _bt_convert_addr_type_to_string(char *address,
359 ret_if(address == NULL);
360 ret_if(addr == NULL);
362 snprintf(address, BT_ADDRESS_STRING_SIZE,
363 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
364 addr[0], addr[1], addr[2],
365 addr[3], addr[4], addr[5]);
368 void _bt_print_device_address_t(const bluetooth_device_address_t *addr)
370 BT_DBG("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", addr->addr[0], addr->addr[1], addr->addr[2],
371 addr->addr[3], addr->addr[4], addr->addr[5]);
374 void _bt_divide_device_class(bluetooth_device_class_t *device_class,
377 ret_if(device_class == NULL);
379 device_class->major_class = (unsigned short)(cod & 0x00001F00) >> 8;
380 device_class->minor_class = (unsigned short)((cod & 0x000000FC));
381 device_class->service_class = (unsigned long)((cod & 0x00FF0000));
383 if (cod & 0x002000) {
384 device_class->service_class |=
385 BLUETOOTH_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE;
389 void _bt_free_device_info(bt_remote_dev_info_t *dev_info)
393 ret_if(dev_info == NULL);
395 g_free(dev_info->address);
396 g_free(dev_info->name);
398 if (dev_info->uuids) {
399 for (i = 0; dev_info->uuids[i] != NULL; i++)
400 g_free(dev_info->uuids[i]);
402 g_free(dev_info->uuids);
408 int _bt_register_osp_server_in_agent(int type, char *uuid)
410 if (!_bt_agent_register_osp_server( type, uuid))
411 return BLUETOOTH_ERROR_INTERNAL;
413 return BLUETOOTH_ERROR_NONE;
416 int _bt_unregister_osp_server_in_agent(int type, char *uuid)
418 if (!_bt_agent_unregister_osp_server( type, uuid))
419 return BLUETOOTH_ERROR_INTERNAL;
421 return BLUETOOTH_ERROR_NONE;
424 int _bt_set_socket_non_blocking(int socket_fd)
426 /* Set Nonblocking */
429 arg = fcntl(socket_fd, F_GETFL);
434 if (arg & O_NONBLOCK) {
435 BT_ERR("Already Non-blocking \n");
440 if (fcntl(socket_fd, F_SETFL, arg) < 0)
443 return BLUETOOTH_ERROR_NONE;
446 int _bt_set_non_blocking_tty(int sk)
448 struct termios ti = {0,};
451 err = _bt_set_socket_non_blocking(sk);
454 BT_ERR("Error in set non blocking!\n");
458 tcflush(sk, TCIOFLUSH);
460 /* Switch tty to RAW mode */
462 tcsetattr(sk, TCSANOW, &ti);
464 return BLUETOOTH_ERROR_NONE;
467 gboolean _bt_is_headset_class(int dev_class)
469 gboolean is_headset = FALSE;
471 switch ((dev_class & 0x1f00) >> 8) {
473 switch ((dev_class & 0xfc) >> 2) {
484 case 0x0c: /* Video Camera */
485 case 0x0d: /* Camcorder */
488 /* Other audio device */
498 static char *__bt_extract_device_path(DBusMessageIter *msg_iter, char *address)
500 char *object_path = NULL;
501 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
503 /* Parse the signature: oa{sa{sv}}} */
504 retv_if(dbus_message_iter_get_arg_type(msg_iter) !=
505 DBUS_TYPE_OBJECT_PATH, NULL);
507 dbus_message_iter_get_basic(msg_iter, &object_path);
508 retv_if(object_path == NULL, NULL);
510 _bt_convert_device_path_to_address(object_path, device_address);
512 if (g_strcmp0(address, device_address) == 0) {
513 return g_strdup(object_path);
519 char *_bt_get_device_object_path(char *address)
523 DBusMessageIter reply_iter;
524 DBusMessageIter value_iter;
526 DBusConnection *conn;
527 char *object_path = NULL;
529 conn = _bt_get_system_conn();
530 retv_if(conn == NULL, NULL);
532 msg = dbus_message_new_method_call(BT_BLUEZ_NAME, BT_MANAGER_PATH,
533 BT_MANAGER_INTERFACE,
534 "GetManagedObjects");
536 retv_if(msg == NULL, NULL);
538 /* Synchronous call */
539 dbus_error_init(&err);
540 reply = dbus_connection_send_with_reply_and_block(
543 dbus_message_unref(msg);
546 BT_ERR("Can't get managed objects");
548 if (dbus_error_is_set(&err)) {
549 BT_ERR("%s", err.message);
550 dbus_error_free(&err);
555 if (dbus_message_iter_init(reply, &reply_iter) == FALSE) {
556 BT_ERR("Fail to iterate the reply");
560 dbus_message_iter_recurse(&reply_iter, &value_iter);
562 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
563 while (dbus_message_iter_get_arg_type(&value_iter) ==
564 DBUS_TYPE_DICT_ENTRY) {
565 DBusMessageIter msg_iter;
567 dbus_message_iter_recurse(&value_iter, &msg_iter);
569 object_path = __bt_extract_device_path(&msg_iter, address);
570 if (object_path != NULL) {
571 BT_DBG("Found the device path");
575 dbus_message_iter_next(&value_iter);