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;
66 char *adapter_path = NULL;
70 if (system_conn == NULL) {
71 system_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
72 retv_if(system_conn == NULL, NULL);
75 manager_proxy = _bt_get_manager_proxy();
76 retv_if(manager_proxy == NULL, NULL);
78 adapter_path = _bt_get_adapter_path();
79 retv_if(adapter_path == NULL, NULL);
81 proxy = dbus_g_proxy_new_for_name(system_conn, BT_BLUEZ_NAME,
82 adapter_path, BT_ADAPTER_INTERFACE);
86 retv_if(proxy == NULL, NULL);
88 adapter_proxy = proxy;
93 static DBusGProxy *__bt_init_adapter_properties_proxy(void)
95 DBusGProxy *manager_proxy;
97 char *adapter_path = NULL;
101 if (system_conn == NULL) {
102 system_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
103 retv_if(system_conn == NULL, NULL);
106 manager_proxy = _bt_get_manager_proxy();
107 retv_if(manager_proxy == NULL, NULL);
109 adapter_path = _bt_get_adapter_path();
110 retv_if(adapter_path == NULL, NULL);
112 proxy = dbus_g_proxy_new_for_name(system_conn, BT_BLUEZ_NAME,
113 adapter_path, BT_PROPERTIES_INTERFACE);
115 g_free(adapter_path);
117 retv_if(proxy == NULL, NULL);
119 adapter_properties_proxy = proxy;
124 DBusGConnection *__bt_init_system_gconn(void)
128 if (system_conn == NULL)
129 system_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
134 DBusGConnection *__bt_init_session_conn(void)
136 if (session_conn == NULL)
137 session_conn = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
142 DBusGConnection *_bt_get_session_gconn(void)
144 return (session_conn) ? session_conn : __bt_init_session_conn();
147 DBusGConnection *_bt_get_system_gconn(void)
149 return (system_conn) ? system_conn : __bt_init_system_gconn();
152 DBusConnection *_bt_get_system_conn(void)
154 DBusGConnection *g_conn;
156 if (system_conn == NULL) {
157 g_conn = __bt_init_system_gconn();
159 g_conn = system_conn;
162 retv_if(g_conn == NULL, NULL);
164 return dbus_g_connection_get_connection(g_conn);
167 DBusGProxy *_bt_get_manager_proxy(void)
169 return (manager_proxy) ? manager_proxy : __bt_init_manager_proxy();
172 DBusGProxy *_bt_get_adapter_proxy(void)
174 return (adapter_proxy) ? adapter_proxy : __bt_init_adapter_proxy();
177 DBusGProxy *_bt_get_adapter_properties_proxy(void)
179 return (adapter_properties_proxy) ? adapter_properties_proxy :
180 __bt_init_adapter_properties_proxy();
183 static char *__bt_extract_adapter_path(DBusMessageIter *msg_iter)
185 char *object_path = NULL;
186 DBusMessageIter value_iter;
188 /* Parse the signature: oa{sa{sv}}} */
189 retv_if(dbus_message_iter_get_arg_type(msg_iter) !=
190 DBUS_TYPE_OBJECT_PATH, NULL);
192 dbus_message_iter_get_basic(msg_iter, &object_path);
193 retv_if(object_path == NULL, NULL);
195 /* object array (oa) */
196 retv_if(dbus_message_iter_next(msg_iter) == FALSE, NULL);
197 retv_if(dbus_message_iter_get_arg_type(msg_iter) !=
198 DBUS_TYPE_ARRAY, NULL);
200 dbus_message_iter_recurse(msg_iter, &value_iter);
202 /* string array (sa) */
203 while (dbus_message_iter_get_arg_type(&value_iter) ==
204 DBUS_TYPE_DICT_ENTRY) {
205 char *interface_name = NULL;
206 DBusMessageIter interface_iter;
208 dbus_message_iter_recurse(&value_iter, &interface_iter);
210 retv_if(dbus_message_iter_get_arg_type(&interface_iter) !=
211 DBUS_TYPE_STRING, NULL);
213 dbus_message_iter_get_basic(&interface_iter, &interface_name);
215 if (g_strcmp0(interface_name, "org.bluez.Adapter1") == 0) {
216 /* Tizen don't allow the multi-adapter */
217 BT_DBG("Found an adapter: %s", object_path);
218 return g_strdup(object_path);
221 dbus_message_iter_next(&value_iter);
224 BT_DBG("There is no adapter");
229 char *_bt_get_adapter_path(void)
233 DBusMessageIter reply_iter;
234 DBusMessageIter value_iter;
236 DBusConnection *conn;
237 char *adapter_path = NULL;
239 conn = _bt_get_system_conn();
240 retv_if(conn == NULL, NULL);
242 msg = dbus_message_new_method_call(BT_BLUEZ_NAME, BT_MANAGER_PATH,
243 BT_MANAGER_INTERFACE,
244 "GetManagedObjects");
246 retv_if(msg == NULL, NULL);
248 /* Synchronous call */
249 dbus_error_init(&err);
250 reply = dbus_connection_send_with_reply_and_block(
253 dbus_message_unref(msg);
256 BT_ERR("Can't get managed objects");
258 if (dbus_error_is_set(&err)) {
259 BT_ERR("%s", err.message);
260 dbus_error_free(&err);
265 if (dbus_message_iter_init(reply, &reply_iter) == FALSE) {
266 BT_ERR("Fail to iterate the reply");
270 dbus_message_iter_recurse(&reply_iter, &value_iter);
272 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
273 while (dbus_message_iter_get_arg_type(&value_iter) ==
274 DBUS_TYPE_DICT_ENTRY) {
275 DBusMessageIter msg_iter;
277 dbus_message_iter_recurse(&value_iter, &msg_iter);
279 adapter_path = __bt_extract_adapter_path(&msg_iter);
280 if (adapter_path != NULL) {
281 BT_DBG("Found the adapter path");
285 dbus_message_iter_next(&value_iter);
291 void _bt_deinit_bluez_proxy(void)
294 g_object_unref(manager_proxy);
295 manager_proxy = NULL;
299 g_object_unref(adapter_proxy);
300 adapter_proxy = NULL;
303 if (adapter_properties_proxy) {
304 g_object_unref(adapter_properties_proxy);
305 adapter_properties_proxy = NULL;
309 void _bt_deinit_proxys(void)
312 _bt_deinit_bluez_proxy();
315 dbus_g_connection_unref(system_conn);
320 dbus_g_connection_unref(session_conn);
326 void _bt_convert_device_path_to_address(const char *device_path,
327 char *device_address)
329 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
332 ret_if(device_path == NULL);
333 ret_if(device_address == NULL);
335 dev_addr = strstr(device_path, "dev_");
336 if (dev_addr != NULL) {
339 g_strlcpy(address, dev_addr, sizeof(address));
341 while ((pos = strchr(address, '_')) != NULL) {
345 g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
350 void _bt_convert_addr_string_to_type(unsigned char *addr,
356 ret_if(address == NULL);
357 ret_if(addr == NULL);
359 for (i = 0; i < BT_ADDRESS_LENGTH_MAX; i++) {
360 addr[i] = strtol(address, &ptr, 16);
370 void _bt_convert_addr_type_to_string(char *address,
373 ret_if(address == NULL);
374 ret_if(addr == NULL);
376 snprintf(address, BT_ADDRESS_STRING_SIZE,
377 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
378 addr[0], addr[1], addr[2],
379 addr[3], addr[4], addr[5]);
382 void _bt_print_device_address_t(const bluetooth_device_address_t *addr)
384 BT_DBG("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", addr->addr[0], addr->addr[1], addr->addr[2],
385 addr->addr[3], addr->addr[4], addr->addr[5]);
388 void _bt_divide_device_class(bluetooth_device_class_t *device_class,
391 ret_if(device_class == NULL);
393 device_class->major_class = (unsigned short)(cod & 0x00001F00) >> 8;
394 device_class->minor_class = (unsigned short)((cod & 0x000000FC));
395 device_class->service_class = (unsigned long)((cod & 0x00FF0000));
397 if (cod & 0x002000) {
398 device_class->service_class |=
399 BLUETOOTH_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE;
403 void _bt_free_device_info(bt_remote_dev_info_t *dev_info)
407 ret_if(dev_info == NULL);
409 g_free(dev_info->address);
410 g_free(dev_info->name);
412 if (dev_info->uuids) {
413 for (i = 0; dev_info->uuids[i] != NULL; i++)
414 g_free(dev_info->uuids[i]);
416 g_free(dev_info->uuids);
422 int _bt_register_osp_server_in_agent(int type, char *uuid)
424 if (!_bt_agent_register_osp_server( type, uuid))
425 return BLUETOOTH_ERROR_INTERNAL;
427 return BLUETOOTH_ERROR_NONE;
430 int _bt_unregister_osp_server_in_agent(int type, char *uuid)
432 if (!_bt_agent_unregister_osp_server( type, uuid))
433 return BLUETOOTH_ERROR_INTERNAL;
435 return BLUETOOTH_ERROR_NONE;
438 int _bt_set_socket_non_blocking(int socket_fd)
440 /* Set Nonblocking */
443 arg = fcntl(socket_fd, F_GETFL);
448 if (arg & O_NONBLOCK) {
449 BT_ERR("Already Non-blocking \n");
454 if (fcntl(socket_fd, F_SETFL, arg) < 0)
457 return BLUETOOTH_ERROR_NONE;
460 int _bt_set_non_blocking_tty(int sk)
462 struct termios ti = {0,};
465 err = _bt_set_socket_non_blocking(sk);
468 BT_ERR("Error in set non blocking!\n");
472 tcflush(sk, TCIOFLUSH);
474 /* Switch tty to RAW mode */
476 tcsetattr(sk, TCSANOW, &ti);
478 return BLUETOOTH_ERROR_NONE;
481 gboolean _bt_is_headset_class(int dev_class)
483 gboolean is_headset = FALSE;
485 switch ((dev_class & 0x1f00) >> 8) {
487 switch ((dev_class & 0xfc) >> 2) {
498 case 0x0c: /* Video Camera */
499 case 0x0d: /* Camcorder */
502 /* Other audio device */
512 static char *__bt_extract_device_path(DBusMessageIter *msg_iter, char *address)
514 char *object_path = NULL;
515 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
517 /* Parse the signature: oa{sa{sv}}} */
518 retv_if(dbus_message_iter_get_arg_type(msg_iter) !=
519 DBUS_TYPE_OBJECT_PATH, NULL);
521 dbus_message_iter_get_basic(msg_iter, &object_path);
522 retv_if(object_path == NULL, NULL);
524 _bt_convert_device_path_to_address(object_path, device_address);
526 if (g_strcmp0(address, device_address) == 0) {
527 return g_strdup(object_path);
533 char *_bt_get_device_object_path(char *address)
537 DBusMessageIter reply_iter;
538 DBusMessageIter value_iter;
540 DBusConnection *conn;
541 char *object_path = NULL;
543 conn = _bt_get_system_conn();
544 retv_if(conn == NULL, NULL);
546 msg = dbus_message_new_method_call(BT_BLUEZ_NAME, BT_MANAGER_PATH,
547 BT_MANAGER_INTERFACE,
548 "GetManagedObjects");
550 retv_if(msg == NULL, NULL);
552 /* Synchronous call */
553 dbus_error_init(&err);
554 reply = dbus_connection_send_with_reply_and_block(
557 dbus_message_unref(msg);
560 BT_ERR("Can't get managed objects");
562 if (dbus_error_is_set(&err)) {
563 BT_ERR("%s", err.message);
564 dbus_error_free(&err);
569 if (dbus_message_iter_init(reply, &reply_iter) == FALSE) {
570 BT_ERR("Fail to iterate the reply");
574 dbus_message_iter_recurse(&reply_iter, &value_iter);
576 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
577 while (dbus_message_iter_get_arg_type(&value_iter) ==
578 DBUS_TYPE_DICT_ENTRY) {
579 DBusMessageIter msg_iter;
581 dbus_message_iter_recurse(&value_iter, &msg_iter);
583 object_path = __bt_extract_device_path(&msg_iter, address);
584 if (object_path != NULL) {
585 BT_DBG("Found the device path");
589 dbus_message_iter_next(&value_iter);