Applied bluez patches present in Tizen branch. The following patches have been applied : 01/35601/1
authorAbhinav Kumar <abhinav.ku91@samsung.com>
Thu, 19 Feb 2015 04:15:59 +0000 (09:45 +0530)
committerAbhinav Kumar <abhinav.ku91@samsung.com>
Thu, 19 Feb 2015 04:15:59 +0000 (09:45 +0530)
1> bluetooth player: add searchable value to show cmd
2> add property connected for input device
3> core/service: Add btd_service_get_version
4> core/profile: Add version information to btd_profile
5> core/service: Add btd_service_set_auto_connect
6> core/service: Add btd_service_get_auto_connect
7> core/device: Use service auto_connect flag
8> profiles: Add missing local_uuid
9> core/service: Add btd_service_set_blocked
10> core/service: Add btd_service_is_blocked
11> core/profile: Add authorization UUID information to btd_profile
12> core/device: Add device_is_service_blocked
13> core/adapter: Check if service is blocked before authorizing
14> plugins: Add initial code for service plugin
15> plugins/service: Add initial code
16> Fix bluetoothd core dumped if disable bt tethering
17> Fix Security Static Code Analysis
18> Add param fd into authorize service
19> Modify the param of authorize service
20> Fix the remaining Security Static Code Analysis
21> Fix the length of string
22> Fix the remaining Security Static Code Analysis

Change-Id: I3191182d850b1252248de76d4bd8f70768230b93

31 files changed:
Makefile.plugins
client/agent.c
configure.ac
obexd/plugins/pbap.c
plugins/service.c [new file with mode: 0644]
profiles/audio/a2dp.c
profiles/audio/avctp.c
profiles/audio/avdtp.c
profiles/audio/avrcp.c
profiles/health/hdp_manager.c
profiles/input/device.c
profiles/input/manager.c
profiles/input/server.c
profiles/network/manager.c
profiles/network/server.c
profiles/sap/server.c
src/adapter.c
src/adapter.h
src/agent.c
src/agent.h
src/bluetooth.conf
src/device.c
src/device.h
src/org.bluez.service
src/profile.c
src/profile.h
src/service.c
src/service.h
tools/bluetooth-player.c
tools/hciattach.c
tools/hcitool.c

index ddcbd3a..ce2d2e1 100644 (file)
@@ -142,3 +142,11 @@ plugins_sixaxis_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version \
                                                -no-undefined @UDEV_LIBS@
 plugins_sixaxis_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden @UDEV_CFLAGS@
 endif
+
+if SERVICE
+plugin_LTLIBRARIES += plugins/service.la
+plugins_service_la_SOURCES = plugins/service.c
+plugins_service_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version \
+                                                               -no-undefined
+plugins_service_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden
+endif
index eeabd5b..54c83fc 100644 (file)
@@ -295,11 +295,13 @@ static DBusMessage *authorize_service(DBusConnection *conn,
 {
        const char *device, *uuid;
        char *str;
+       int fd;
 
        rl_printf("Authorize service\n");
 
        dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device,
-                               DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID);
+                               DBUS_TYPE_STRING, &uuid,
+                               DBUS_TYPE_UNIX_FD, &fd, DBUS_TYPE_INVALID);
 
        str = g_strdup_printf("Authorize service %s (yes/no): ", uuid);
        agent_prompt(str);
@@ -344,7 +346,8 @@ static const GDBusMethodTable methods[] = {
                        GDBUS_ARGS({ "device", "o" }),
                        NULL, request_authorization) },
        { GDBUS_ASYNC_METHOD("AuthorizeService",
-                       GDBUS_ARGS({ "device", "o" }, { "uuid", "s" }),
+                       GDBUS_ARGS({ "device", "o" }, { "uuid", "s" },
+                       {"fd", "h"}),
                        NULL,  authorize_service) },
        { GDBUS_METHOD("Cancel", NULL, NULL, cancel_request) },
        { }
index 8a4bae6..18e4ddb 100644 (file)
@@ -245,6 +245,10 @@ AC_ARG_ENABLE(sixaxis, AC_HELP_STRING([--enable-sixaxis],
 AM_CONDITIONAL(SIXAXIS, test "${enable_sixaxis}" = "yes" &&
                                         test "${enable_udev}" != "no")
 
+AC_ARG_ENABLE(service, AC_HELP_STRING([--enable-service],
+               [enable service plugin]), [enable_service=${enableval}])
+AM_CONDITIONAL(SERVICE, test "${enable_service}" = "yes")
+
 if (test "${prefix}" = "NONE"); then
        dnl no prefix and no localstatedir, so default to /var
        if (test "$localstatedir" = '${prefix}/var'); then
index 2008f36..d9e9643 100644 (file)
@@ -460,7 +460,7 @@ static void cache_entry_done(void *user_data)
 {
        struct pbap_session *pbap = user_data;
        const char *id;
-       int ret;
+       int ret = 0;
 
        DBG("");
 
diff --git a/plugins/service.c b/plugins/service.c
new file mode 100644 (file)
index 0000000..25111f6
--- /dev/null
@@ -0,0 +1,439 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2014  Intel Corporation.
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <gdbus/gdbus.h>
+
+#include "lib/uuid.h"
+#include "src/plugin.h"
+#include "src/log.h"
+#include "src/dbus-common.h"
+#include "src/error.h"
+#include "src/adapter.h"
+#include "src/device.h"
+#include "src/service.h"
+#include "src/profile.h"
+
+#define SERVICE_INTERFACE "org.bluez.Service1"
+
+static unsigned int service_id = 0;
+static GSList *services = NULL;
+
+struct service_data {
+       struct btd_service *service;
+       char *path;
+       DBusMessage *connect;
+       DBusMessage *disconnect;
+};
+
+static struct service_data *find_data(struct btd_service *service)
+{
+       GSList *l;
+
+       for (l = services; l; l = l->next) {
+               struct service_data *data = l->data;
+
+               if (data->service == service)
+                       return data;
+       }
+
+       return NULL;
+}
+
+static void data_free(void *user_data)
+{
+       struct service_data *data = user_data;
+
+       if (data->connect)
+               dbus_message_unref(data->connect);
+
+       if (data->disconnect)
+               dbus_message_unref(data->disconnect);
+
+       g_free(data->path);
+       g_free(data);
+}
+
+static void data_remove(struct service_data *data)
+{
+       services = g_slist_remove(services, data);
+       g_dbus_unregister_interface(btd_get_dbus_connection(), data->path,
+                                                       SERVICE_INTERFACE);
+}
+
+static DBusMessage *service_disconnect(DBusConnection *conn, DBusMessage *msg,
+                                                               void *user_data)
+{
+       struct service_data *data = user_data;
+       int err;
+
+       if (data->disconnect)
+               return btd_error_in_progress(msg);
+
+       data->disconnect = dbus_message_ref(msg);
+
+       err = btd_service_disconnect(data->service);
+       if (err == 0)
+               return NULL;
+
+       dbus_message_unref(data->disconnect);
+       data->disconnect = NULL;
+
+       return btd_error_failed(msg, strerror(-err));
+}
+
+static DBusMessage *service_connect(DBusConnection *conn, DBusMessage *msg,
+                                                               void *user_data)
+{
+       struct service_data *data = user_data;
+       int err;
+
+       if (data->connect)
+               return btd_error_in_progress(msg);
+
+       err = btd_service_connect(data->service);
+       if (err < 0)
+               return btd_error_failed(msg, strerror(-err));
+
+       data->connect = dbus_message_ref(msg);
+
+       return NULL;
+}
+
+static const char *data_get_state(struct service_data *data)
+{
+       btd_service_state_t state = btd_service_get_state(data->service);
+       int err;
+
+       switch (state) {
+       case BTD_SERVICE_STATE_UNAVAILABLE:
+               return "unavailable";
+       case BTD_SERVICE_STATE_DISCONNECTED:
+               err = btd_service_get_error(data->service);
+               return err < 0 ? "error" : "disconnected";
+       case BTD_SERVICE_STATE_CONNECTING:
+               return "connecting";
+       case BTD_SERVICE_STATE_CONNECTED:
+               return "connected";
+       case BTD_SERVICE_STATE_DISCONNECTING:
+               return "disconnecting";
+       }
+
+       return "unknown";
+}
+
+static gboolean get_device(const GDBusPropertyTable *property,
+                                       DBusMessageIter *iter, void *user_data)
+{
+       struct service_data *data = user_data;
+       struct btd_device *dev = btd_service_get_device(data->service);
+       const char *path = btd_device_get_path(dev);
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path);
+
+       return TRUE;
+}
+
+static gboolean get_state(const GDBusPropertyTable *property,
+                                       DBusMessageIter *iter, void *user_data)
+{
+       struct service_data *data = user_data;
+       const char *state;
+
+       state = data_get_state(data);
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &state);
+
+       return TRUE;
+}
+
+static gboolean remote_uuid_exists(const GDBusPropertyTable *property,
+                                                               void *user_data)
+{
+       struct service_data *data = user_data;
+       struct btd_profile *p = btd_service_get_profile(data->service);
+
+       return p->remote_uuid != NULL;
+}
+
+static gboolean get_remote_uuid(const GDBusPropertyTable *property,
+                                       DBusMessageIter *iter, void *user_data)
+{
+       struct service_data *data = user_data;
+       struct btd_profile *p = btd_service_get_profile(data->service);
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &p->remote_uuid);
+
+       return TRUE;
+}
+
+
+static gboolean local_uuid_exists(const GDBusPropertyTable *property,
+                                                               void *user_data)
+{
+       struct service_data *data = user_data;
+       struct btd_profile *p = btd_service_get_profile(data->service);
+
+       return p->local_uuid != NULL;
+}
+
+static gboolean get_local_uuid(const GDBusPropertyTable *property,
+                                       DBusMessageIter *iter, void *user_data)
+{
+       struct service_data *data = user_data;
+       struct btd_profile *p = btd_service_get_profile(data->service);
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &p->local_uuid);
+
+       return TRUE;
+}
+
+static gboolean version_exists(const GDBusPropertyTable *property,
+                                                               void *user_data)
+{
+       struct service_data *data = user_data;
+       uint16_t version = btd_service_get_version(data->service);
+
+       return version != 0x0000;
+}
+
+static gboolean get_version(const GDBusPropertyTable *property,
+                                       DBusMessageIter *iter, void *user_data)
+{
+       struct service_data *data = user_data;
+       uint16_t version = btd_service_get_version(data->service);
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &version);
+
+       return TRUE;
+}
+
+static gboolean get_auto_connect(const GDBusPropertyTable *property,
+                                       DBusMessageIter *iter, void *user_data)
+{
+       struct service_data *data = user_data;
+       dbus_bool_t value = btd_service_get_auto_connect(data->service);
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);
+
+       return TRUE;
+}
+
+static void set_auto_connect(const GDBusPropertyTable *property,
+                                               DBusMessageIter *value,
+                                               GDBusPendingPropertySet id,
+                                               void *user_data)
+{
+       struct service_data *data = user_data;
+       dbus_bool_t b;
+
+       if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
+               g_dbus_pending_property_error(id,
+                                       ERROR_INTERFACE ".InvalidArguments",
+                                       "Invalid arguments in method call");
+               return;
+       }
+
+       dbus_message_iter_get_basic(value, &b);
+
+       btd_service_set_auto_connect(data->service, b);
+
+       g_dbus_pending_property_success(id);
+}
+
+static gboolean get_blocked(const GDBusPropertyTable *property,
+                                       DBusMessageIter *iter, void *user_data)
+{
+       struct service_data *data = user_data;
+       dbus_bool_t value = btd_service_is_blocked(data->service);
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);
+
+       return TRUE;
+}
+
+static void set_blocked(const GDBusPropertyTable *property,
+                                               DBusMessageIter *value,
+                                               GDBusPendingPropertySet id,
+                                               void *user_data)
+{
+       struct service_data *data = user_data;
+       dbus_bool_t b;
+
+       if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
+               g_dbus_pending_property_error(id,
+                                       ERROR_INTERFACE ".InvalidArguments",
+                                       "Invalid arguments in method call");
+               return;
+       }
+
+       dbus_message_iter_get_basic(value, &b);
+
+       btd_service_set_blocked(data->service, b);
+
+       g_dbus_pending_property_success(id);
+}
+
+static const GDBusPropertyTable service_properties[] = {
+       { "Device", "o", get_device, NULL, NULL },
+       { "State", "s", get_state, NULL, NULL },
+       { "RemoteUUID", "s", get_remote_uuid, NULL, remote_uuid_exists },
+       { "LocalUUID", "s", get_local_uuid, NULL, local_uuid_exists },
+       { "Version", "q", get_version, NULL, version_exists },
+       { "AutoConnect", "b", get_auto_connect, set_auto_connect, NULL },
+       { "Blocked", "b", get_blocked, set_blocked, NULL },
+       { }
+};
+
+static const GDBusMethodTable service_methods[] = {
+       { GDBUS_ASYNC_METHOD("Disconnect", NULL, NULL, service_disconnect) },
+       { GDBUS_ASYNC_METHOD("Connect", NULL, NULL, service_connect) },
+       {}
+};
+
+static struct service_data *service_get_data(struct btd_service *service)
+{
+       struct btd_device *dev = btd_service_get_device(service);
+       struct btd_profile *p = btd_service_get_profile(service);
+       struct service_data *data;
+
+       data = find_data(service);
+       if (data != NULL)
+               return data;
+
+       data = g_new0(struct service_data, 1);
+       data->path = g_strdup_printf("%s/%s", btd_device_get_path(dev),
+                                                               p->remote_uuid);
+       data->path = g_strdelimit(data->path, "-", '_');
+       data->service = service;
+       if (g_dbus_register_interface(btd_get_dbus_connection(),
+                                       data->path, SERVICE_INTERFACE,
+                                       service_methods, NULL,
+                                       service_properties, data,
+                                       data_free) == FALSE) {
+               error("Unable to register service interface for %s",
+                                                               data->path);
+               data_free(data);
+               return NULL;
+       }
+
+       services = g_slist_prepend(services, data);
+
+       DBG("%s", data->path);
+
+       return data;
+}
+
+static void service_connected(struct service_data *data)
+{
+       DBusMessage *reply;
+
+       if (!data->connect)
+               return;
+
+       reply = dbus_message_new_method_return(data->connect);
+       g_dbus_send_message(btd_get_dbus_connection(), reply);
+       dbus_message_unref(data->connect);
+       data->connect = NULL;
+}
+
+static void service_disconnected(struct service_data *data)
+{
+       DBusMessage *reply;
+       int err;
+
+       if (data->disconnect) {
+               reply = dbus_message_new_method_return(data->disconnect);
+               g_dbus_send_message(btd_get_dbus_connection(), reply);
+               dbus_message_unref(data->disconnect);
+               data->connect = NULL;
+       }
+
+       if (!data->connect)
+               return;
+
+       err = btd_service_get_error(data->service);
+
+       reply = btd_error_failed(data->connect, strerror(-err));
+       g_dbus_send_message(btd_get_dbus_connection(), reply);
+       dbus_message_unref(data->connect);
+       data->connect = NULL;
+}
+
+static void service_cb(struct btd_service *service,
+                                               btd_service_state_t old_state,
+                                               btd_service_state_t new_state,
+                                               void *user_data)
+{
+       struct service_data *data;
+
+       data = service_get_data(service);
+       if (!data)
+               return;
+
+       switch (new_state) {
+       case BTD_SERVICE_STATE_UNAVAILABLE:
+               data_remove(data);
+               return;
+       case BTD_SERVICE_STATE_CONNECTED:
+               service_connected(data);
+               break;
+       case BTD_SERVICE_STATE_DISCONNECTED:
+               service_disconnected(data);
+               break;
+       default:
+               break;
+       }
+
+       g_dbus_emit_property_changed(btd_get_dbus_connection(), data->path,
+                                               SERVICE_INTERFACE, "State");
+}
+
+static int service_init(void)
+{
+       DBG("");
+
+       service_id = btd_service_add_state_cb(service_cb, NULL);
+
+       return 0;
+}
+
+static void service_exit(void)
+{
+       DBG("");
+
+       btd_service_remove_state_cb(service_id);
+
+       g_slist_free_full(services, data_free);
+}
+
+BLUETOOTH_PLUGIN_DEFINE(service, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
+                                       service_init, service_exit)
index 96416b5..ffb482b 100644 (file)
@@ -2071,8 +2071,12 @@ static void media_server_remove(struct btd_adapter *adapter)
 static struct btd_profile a2dp_source_profile = {
        .name           = "a2dp-source",
        .priority       = BTD_PROFILE_PRIORITY_MEDIUM,
+       .version        = 0x0103,
 
        .remote_uuid    = A2DP_SOURCE_UUID,
+       .local_uuid     = A2DP_SINK_UUID,
+       .auth_uuid      = ADVANCED_AUDIO_UUID,
+
        .device_probe   = a2dp_source_probe,
        .device_remove  = a2dp_source_remove,
 
@@ -2087,8 +2091,12 @@ static struct btd_profile a2dp_source_profile = {
 static struct btd_profile a2dp_sink_profile = {
        .name           = "a2dp-sink",
        .priority       = BTD_PROFILE_PRIORITY_MEDIUM,
+       .version        = 0x0103,
 
        .remote_uuid    = A2DP_SINK_UUID,
+       .local_uuid     = A2DP_SOURCE_UUID,
+       .auth_uuid      = ADVANCED_AUDIO_UUID,
+
        .device_probe   = a2dp_sink_probe,
        .device_remove  = a2dp_sink_remove,
 
index 3680400..4514d69 100644 (file)
@@ -1351,11 +1351,11 @@ static void avctp_control_confirm(struct avctp *session, GIOChannel *chan,
 #ifdef __TIZEN_PATCH__
        session->auth_id = btd_request_authorization(src, dst,
                                                        AVRCP_TARGET_UUID,
-                                                       auth_cb, session);
+                                                       auth_cb, session, 0);
 #else
        session->auth_id = btd_request_authorization(src, dst,
                                                        AVRCP_REMOTE_UUID,
-                                                       auth_cb, session);
+                                                       auth_cb, session, 0);
 #endif
        if (session->auth_id == 0)
                goto drop;
index f6d810e..ef6979e 100644 (file)
@@ -2722,7 +2722,7 @@ static void avdtp_confirm_cb(GIOChannel *chan, gpointer data)
 
        session->auth_id = btd_request_authorization(&src, &dst,
                                                        ADVANCED_AUDIO_UUID,
-                                                       auth_cb, session);
+                                                       auth_cb, session, 0);
        if (session->auth_id == 0) {
                avdtp_set_state(session, AVDTP_SESSION_STATE_DISCONNECTED);
                goto drop;
index f2817b7..90fd5d5 100644 (file)
@@ -4031,8 +4031,12 @@ done:
 
 static struct btd_profile avrcp_target_profile = {
        .name           = "audio-avrcp-target",
+       .version        = 0x0105,
 
        .remote_uuid    = AVRCP_TARGET_UUID,
+       .local_uuid     = AVRCP_REMOTE_UUID,
+       .auth_uuid      = AVRCP_REMOTE_UUID,
+
        .device_probe   = avrcp_target_probe,
        .device_remove  = avrcp_target_remove,
 
@@ -4114,8 +4118,12 @@ done:
 
 static struct btd_profile avrcp_controller_profile = {
        .name           = "avrcp-controller",
+       .version        = 0x0104,
 
        .remote_uuid    = AVRCP_REMOTE_UUID,
+       .local_uuid     = AVRCP_TARGET_UUID,
+       .auth_uuid      = AVRCP_REMOTE_UUID,
+
        .device_probe   = avrcp_controller_probe,
        .device_remove  = avrcp_controller_remove,
 
index 1882043..95ee7ac 100644 (file)
@@ -70,7 +70,10 @@ static void hdp_driver_remove(struct btd_service *service)
 
 static struct btd_profile hdp_source_profile = {
        .name           = "hdp-source",
+       .version        = 0x0100,
+
        .remote_uuid    = HDP_SOURCE_UUID,
+       .local_uuid     = HDP_SINK_UUID,
 
        .device_probe   = hdp_driver_probe,
        .device_remove  = hdp_driver_remove,
@@ -81,7 +84,10 @@ static struct btd_profile hdp_source_profile = {
 
 static struct btd_profile hdp_sink_profile = {
        .name           = "hdp-sink",
+       .version        = 0x0100,
+
        .remote_uuid    = HDP_SINK_UUID,
+       .local_uuid     = HDP_SOURCE_UUID,
 
        .device_probe   = hdp_driver_probe,
        .device_remove  = hdp_driver_remove,
index cfa5e23..277f8a5 100644 (file)
@@ -1341,8 +1341,29 @@ static gboolean property_get_reconnect_mode(
        return TRUE;
 }
 
+static gboolean property_get_connected(const GDBusPropertyTable *property,
+                                       DBusMessageIter *iter, void *data)
+{
+       struct input_device *idev = data;
+       dbus_bool_t connected;
+
+       if (idev->service == NULL)
+               return FALSE;
+
+       if (btd_service_get_state(idev->service)
+                               == BTD_SERVICE_STATE_CONNECTED) {
+               connected = true;
+       } else
+               connected = false;
+
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &connected);
+
+       return TRUE;
+}
+
 static const GDBusPropertyTable input_properties[] = {
        { "ReconnectMode", "s", property_get_reconnect_mode },
+       { "Connected", "b", property_get_connected },
        { }
 };
 
index 9712d2c..cfc9f6a 100644 (file)
@@ -57,6 +57,8 @@ static void hid_server_remove(struct btd_profile *p,
 
 static struct btd_profile input_profile = {
        .name           = "input-hid",
+       .version        = 0x0101,
+
        .local_uuid     = HID_UUID,
        .remote_uuid    = HID_UUID,
 
index 50a9074..95f7eeb 100644 (file)
@@ -270,7 +270,7 @@ static void confirm_event_cb(GIOChannel *chan, gpointer user_data)
        bacpy(&server->confirm->dst, &dst);
 
        ret = btd_request_authorization(&src, &dst, HID_UUID,
-                                       auth_callback, server);
+                                       auth_callback, server, 0);
        if (ret != 0)
                return;
 
index 0fe98a0..81b0ce0 100644 (file)
@@ -135,8 +135,10 @@ static void nap_server_remove(struct btd_profile *p,
 
 static struct btd_profile panu_profile = {
        .name           = "network-panu",
+       .version        = 0x0100,
        .local_uuid     = NAP_UUID,
        .remote_uuid    = PANU_UUID,
+       .auth_uuid      = BNEP_SVC_UUID,
        .device_probe   = connection_register,
        .device_remove  = connection_unregister,
        .connect        = connection_connect,
@@ -147,8 +149,10 @@ static struct btd_profile panu_profile = {
 
 static struct btd_profile gn_profile = {
        .name           = "network-gn",
+       .version        = 0x0100,
        .local_uuid     = PANU_UUID,
        .remote_uuid    = GN_UUID,
+       .auth_uuid      = BNEP_SVC_UUID,
        .device_probe   = connection_register,
        .device_remove  = connection_unregister,
        .connect        = connection_connect,
@@ -159,8 +163,10 @@ static struct btd_profile gn_profile = {
 
 static struct btd_profile nap_profile = {
        .name           = "network-nap",
+       .version        = 0x0100,
        .local_uuid     = PANU_UUID,
        .remote_uuid    = NAP_UUID,
+       .auth_uuid      = BNEP_SVC_UUID,
        .device_probe   = connection_register,
        .device_remove  = connection_unregister,
        .connect        = connection_connect,
index b010371..a1b4126 100644 (file)
@@ -325,7 +325,7 @@ static gboolean server_disconnected_cb(GIOChannel *chan,
 {
        struct network_server *ns = NULL;
        struct network_session *session = NULL;
-       char address[20] = {0};
+       char address[24] = {0};
        const char* paddr = address;
        char *name_str = NULL;
 
@@ -373,7 +373,7 @@ static gboolean bnep_setup(GIOChannel *chan,
                        GIOCondition cond, gpointer user_data)
 {
        struct network_adapter *na = user_data;
-       struct network_server *ns;
+       struct network_server *ns = NULL;
        uint8_t packet[BNEP_MTU];
        struct bnep_setup_conn_req *req = (void *) packet;
        uint16_t src_role, dst_role, rsp = BNEP_CONN_NOT_ALLOWED;
@@ -564,7 +564,7 @@ static void confirm_event(GIOChannel *chan, gpointer user_data)
        na->setup->io = g_io_channel_ref(chan);
 
        ret = btd_request_authorization(&src, &dst, BNEP_SVC_UUID,
-                                       auth_cb, na);
+                                       auth_cb, na, 0);
        if (ret == 0) {
                error("Refusing connect from %s", address);
                setup_destroy(na);
@@ -611,11 +611,26 @@ static void server_remove_sessions(struct network_server *ns)
 
        for (list = ns->sessions; list; list = list->next) {
                struct network_session *session = list->data;
+               char address[24] = {0};
+               char *paddr = address;
+               const char *name_str = NULL;
 
                if (*session->dev == '\0')
                        continue;
 
                bnep_server_delete(ns->bridge, session->dev, &session->dst);
+
+               name_str = session->dev;
+               ba2str(&session->dst, paddr);
+
+               DBG("send peerdisconnected signal");
+
+               g_dbus_emit_signal(btd_get_dbus_connection(),
+                       adapter_get_path(ns->na->adapter),
+                       NETWORK_SERVER_INTERFACE, "PeerDisconnected",
+                       DBUS_TYPE_STRING, &name_str,
+                       DBUS_TYPE_STRING, &paddr,
+                       DBUS_TYPE_INVALID);
        }
 
 #ifndef __TIZEN_PATCH__
index 20c6cab..683d6f2 100644 (file)
@@ -1253,7 +1253,7 @@ static void connect_confirm_cb(GIOChannel *io, gpointer data)
        ba2str(&dst, dstaddr);
 
        ret = btd_request_authorization(&src, &dst, SAP_UUID, connect_auth_cb,
-                                                               server);
+                                                               server, 0);
        if (ret == 0) {
                error("Authorization failure");
                sap_server_remove_conn(server);
index d7815e8..0066c76 100644 (file)
@@ -173,6 +173,7 @@ struct service_auth {
        struct btd_device *device;
        struct btd_adapter *adapter;
        struct agent *agent;            /* NULL for queued auths */
+       int fd;
 };
 
 struct btd_adapter_pin_cb_iter {
@@ -7266,6 +7267,11 @@ static gboolean process_auth_queue(gpointer user_data)
                if (auth->svc_id > 0)
                        return FALSE;
 
+               if (device_is_service_blocked(device, auth->uuid)) {
+                       auth->cb(&err, auth->user_data);
+                       goto next;
+               }
+
 /* The below patch should be removed after we provide the API
  * to control autorization for the specific UUID.
  */
@@ -7288,7 +7294,7 @@ static gboolean process_auth_queue(gpointer user_data)
                dev_path = device_get_path(device);
 
                if (agent_authorize_service(auth->agent, dev_path, auth->uuid,
-                                       agent_auth_cb, adapter, NULL) < 0) {
+                                       agent_auth_cb, adapter, NULL, auth->fd) < 0) {
                        auth->cb(&err, auth->user_data);
                        goto next;
                }
@@ -7324,7 +7330,7 @@ static void svc_complete(struct btd_device *dev, int err, void *user_data)
 
 static int adapter_authorize(struct btd_adapter *adapter, const bdaddr_t *dst,
                                        const char *uuid, service_auth_cb cb,
-                                       void *user_data)
+                                       void *user_data, int fd)
 {
        struct service_auth *auth;
        struct btd_device *device;
@@ -7348,6 +7354,7 @@ static int adapter_authorize(struct btd_adapter *adapter, const bdaddr_t *dst,
        auth->device = device;
        auth->adapter = adapter;
        auth->id = ++id;
+       auth->fd = fd;
        auth->svc_id = device_wait_for_svc_complete(device, svc_complete, auth);
 
        g_queue_push_tail(adapter->auths, auth);
@@ -7357,7 +7364,7 @@ static int adapter_authorize(struct btd_adapter *adapter, const bdaddr_t *dst,
 
 guint btd_request_authorization(const bdaddr_t *src, const bdaddr_t *dst,
                                        const char *uuid, service_auth_cb cb,
-                                       void *user_data)
+                                       void *user_data, int fd)
 {
        struct btd_adapter *adapter;
        GSList *l;
@@ -7367,7 +7374,7 @@ guint btd_request_authorization(const bdaddr_t *src, const bdaddr_t *dst,
                if (!adapter)
                        return 0;
 
-               return adapter_authorize(adapter, dst, uuid, cb, user_data);
+               return adapter_authorize(adapter, dst, uuid, cb, user_data, fd);
        }
 
        for (l = adapters; l != NULL; l = g_slist_next(l)) {
@@ -7375,7 +7382,7 @@ guint btd_request_authorization(const bdaddr_t *src, const bdaddr_t *dst,
 
                adapter = l->data;
 
-               id = adapter_authorize(adapter, dst, uuid, cb, user_data);
+               id = adapter_authorize(adapter, dst, uuid, cb, user_data, fd);
                if (id != 0)
                        return id;
        }
index 8cb3009..0069c4b 100644 (file)
@@ -127,7 +127,7 @@ void adapter_remove_profile(struct btd_adapter *adapter, gpointer p);
 int btd_register_adapter_driver(struct btd_adapter_driver *driver);
 void btd_unregister_adapter_driver(struct btd_adapter_driver *driver);
 guint btd_request_authorization(const bdaddr_t *src, const bdaddr_t *dst,
-               const char *uuid, service_auth_cb cb, void *user_data);
+               const char *uuid, service_auth_cb cb, void *user_data, int fd);
 int btd_cancel_authorization(guint id);
 
 int btd_adapter_restore_powered(struct btd_adapter *adapter);
index 73b2fdd..bd88eb9 100644 (file)
@@ -383,8 +383,9 @@ done:
 
 static int agent_call_authorize_service(struct agent_request *req,
                                                const char *device_path,
-                                               const char *uuid)
+                                               const char *uuid, const int fd)
 {
+       DBusMessageIter iter, dict;
        struct agent *agent = req->agent;
 
        req->msg = dbus_message_new_method_call(agent->owner, agent->path,
@@ -394,10 +395,14 @@ static int agent_call_authorize_service(struct agent_request *req,
                return -ENOMEM;
        }
 
-       dbus_message_append_args(req->msg,
-                               DBUS_TYPE_OBJECT_PATH, &device_path,
-                               DBUS_TYPE_STRING, &uuid,
-                               DBUS_TYPE_INVALID);
+       dbus_message_iter_init_append(req->msg, &iter);
+
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+                                               &device_path);
+
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &uuid);
+
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_UNIX_FD, &fd);
 
        if (g_dbus_send_message_with_reply(btd_get_dbus_connection(),
                                                req->msg, &req->call,
@@ -412,7 +417,7 @@ static int agent_call_authorize_service(struct agent_request *req,
 
 int agent_authorize_service(struct agent *agent, const char *path,
                                const char *uuid, agent_cb cb,
-                               void *user_data, GDestroyNotify destroy)
+                               void *user_data, GDestroyNotify destroy, int fd)
 {
        struct agent_request *req;
        int err;
@@ -423,7 +428,7 @@ int agent_authorize_service(struct agent *agent, const char *path,
        req = agent_request_new(agent, AGENT_REQUEST_AUTHORIZE_SERVICE, cb,
                                                        user_data, destroy);
 
-       err = agent_call_authorize_service(req, path, uuid);
+       err = agent_call_authorize_service(req, path, uuid, fd);
        if (err < 0) {
                agent_request_free(req, FALSE);
                return -ENOMEM;
index 1e46920..dafee9c 100644 (file)
@@ -40,7 +40,7 @@ struct agent *agent_get(const char *owner);
 
 int agent_authorize_service(struct agent *agent, const char *path,
                                const char *uuid, agent_cb cb,
-                               void *user_data, GDestroyNotify destroy);
+                               void *user_data, GDestroyNotify destroy, int fd);
 
 int agent_request_pincode(struct agent *agent, struct btd_device *device,
                                agent_pincode_cb cb, gboolean secure,
index 70d9aa6..b575f78 100644 (file)
@@ -8,6 +8,8 @@
   <!-- ../system.conf have denied everything, so we just punch some holes -->
 
   <policy user="root">
+    <allow own="org.bluez"/>
+    <allow send_destination="org.bluez"/>
     <allow own="org.projectx.bluetooth"/>
     <allow send_interface="org.projectx.bluetooth"/>
     <allow send_destination="org.projectx.bluetooth"/>
@@ -38,6 +40,7 @@
     <allow own="org.bluez.Profile1"/>
     <allow send_interface="org.bluez.Profile1"/>
     <allow send_destination="org.bluez.Profile1"/>
+    <allow send_interface="org.freedesktop.DBus.ObjectManager"/>
   </policy>
 
   <policy at_console="true">
index f98e4a6..9a4f5f2 100644 (file)
@@ -383,7 +383,7 @@ static GSList *find_service_with_gatt_handles(GSList *list,
 
 static void update_technologies(GKeyFile *file, struct btd_device *dev)
 {
-       const char *list[2];
+       const char *list[2] = {NULL, NULL};
        size_t len = 0;
 
        if (dev->bredr)
@@ -810,6 +810,34 @@ gboolean device_is_trusted(struct btd_device *device)
        return device->trusted;
 }
 
+bool device_is_service_blocked(struct btd_device *device, const char *uuid)
+{
+       GSList *l;
+       bool block = false;
+
+       for (l = device->services; l; l = g_slist_next(l)) {
+               struct btd_service *service = l->data;
+               struct btd_profile *p = btd_service_get_profile(service);
+               const char *p_uuid;
+
+               p_uuid = p->auth_uuid ? p->auth_uuid : p->local_uuid;
+               if (!p_uuid)
+                       continue;
+
+               if (strcasecmp(uuid, p_uuid))
+                       continue;
+
+               if (!btd_service_is_blocked(service))
+                       return false;
+
+               block = true;
+       }
+
+       /* Every service matching is blocked
+        */
+       return block;
+}
+
 static gboolean dev_property_get_address(const GDBusPropertyTable *property,
                                        DBusMessageIter *iter, void *data)
 {
@@ -1811,6 +1839,10 @@ static GSList *create_pending_list(struct btd_device *dev, const char *uuid)
 
        for (l = dev->services; l != NULL; l = g_slist_next(l)) {
                service = l->data;
+               
+               if (!btd_service_get_auto_connect(service))
+                       continue;
+               
                p = btd_service_get_profile(service);
 
 #ifdef __TIZEN_PATCH__
index cc4ab4e..383f268 100644 (file)
@@ -106,6 +106,7 @@ bool device_is_bonded(struct btd_device *device, uint8_t bdaddr_type);
 gboolean device_is_trusted(struct btd_device *device);
 void device_set_paired(struct btd_device *dev, uint8_t bdaddr_type);
 void device_set_unpaired(struct btd_device *dev, uint8_t bdaddr_type);
+bool device_is_service_blocked(struct btd_device *device, const char *uuid);
 void btd_device_set_temporary(struct btd_device *device, gboolean temporary);
 void btd_device_set_trusted(struct btd_device *device, gboolean trusted);
 void device_set_bonded(struct btd_device *device, uint8_t bdaddr_type);
index dd7ae8f..2a3b057 100644 (file)
@@ -2,4 +2,4 @@
 Name=org.bluez
 Exec=/bin/false
 User=root
-SystemdService=dbus-org.bluez.service
+SystemdService=bluetooth.service
index 4634920..0874ecb 100644 (file)
@@ -1253,6 +1253,7 @@ static void ext_confirm(GIOChannel *io, gpointer user_data)
        GError *gerr = NULL;
        bdaddr_t src, dst;
        char addr[18];
+       int fd;
 
        bt_io_get(io, &gerr,
                        BT_IO_OPT_SOURCE_BDADDR, &src,
@@ -1272,8 +1273,9 @@ static void ext_confirm(GIOChannel *io, gpointer user_data)
        if (conn == NULL)
                return;
 
+       fd = g_io_channel_unix_get_fd(conn->io);
        conn->auth_id = btd_request_authorization(&src, &dst, uuid, ext_auth,
-                                                                       conn);
+                                                                       conn, fd);
        if (conn->auth_id == 0) {
                error("%s authorization failure", ext->name);
                ext_io_destroy(conn);
index f5a3ded..254d85e 100644 (file)
@@ -30,9 +30,11 @@ struct btd_service;
 struct btd_profile {
        const char *name;
        int priority;
+       uint16_t version;
 
        const char *local_uuid;
        const char *remote_uuid;
+       const char *auth_uuid;
 
        bool auto_connect;
 
index 28e7169..8ecb7d4 100644 (file)
@@ -36,6 +36,8 @@
 #include <errno.h>
 
 #include <bluetooth/bluetooth.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
 
 #include <glib.h>
 
@@ -55,6 +57,8 @@ struct btd_service {
        int                     err;
        uint16_t                start_handle;
        uint16_t                end_handle;
+       bool                    auto_connect;
+       bool                    blocked;
 };
 
 struct service_state_callback {
@@ -146,6 +150,7 @@ struct btd_service *service_create(struct btd_device *device,
        service->ref = 1;
        service->device = device; /* Weak ref */
        service->profile = profile;
+       service->auto_connect = profile->auto_connect;
        service->state = BTD_SERVICE_STATE_UNAVAILABLE;
 
        return service;
@@ -325,6 +330,51 @@ int btd_service_get_error(const struct btd_service *service)
        return service->err;
 }
 
+uint16_t btd_service_get_version(const struct btd_service *service)
+{
+       const sdp_record_t *rec;
+       sdp_list_t *list;
+       sdp_profile_desc_t *desc;
+       uint16_t version;
+
+       if (!service->profile->version)
+               return 0;
+
+       rec = btd_device_get_record(service->device,
+                                       service->profile->remote_uuid);
+       if (rec == NULL)
+               return 0;
+
+       if (sdp_get_profile_descs(rec, &list) < 0)
+               return 0;
+
+       desc = list->data;
+       version = desc->version;
+       sdp_list_free(list, free);
+
+       return MIN(version, service->profile->version);
+}
+
+void btd_service_set_auto_connect(struct btd_service *service, bool value)
+{
+       service->auto_connect = value;
+}
+
+bool btd_service_get_auto_connect(const struct btd_service *service)
+{
+       return service->auto_connect;
+}
+
+void btd_service_set_blocked(struct btd_service *service, bool value)
+{
+       service->blocked = value;
+}
+
+bool btd_service_is_blocked(const struct btd_service *service)
+{
+       return service->blocked;
+}
+
 bool btd_service_get_gatt_handles(const struct btd_service *service,
                                                        uint16_t *start_handle,
                                                        uint16_t *end_handle)
index 3a0db6e..d092cc4 100644 (file)
@@ -63,6 +63,11 @@ struct btd_device *btd_service_get_device(const struct btd_service *service);
 struct btd_profile *btd_service_get_profile(const struct btd_service *service);
 btd_service_state_t btd_service_get_state(const struct btd_service *service);
 int btd_service_get_error(const struct btd_service *service);
+uint16_t btd_service_get_version(const struct btd_service *service);
+void btd_service_set_auto_connect(struct btd_service *service, bool value);
+bool btd_service_get_auto_connect(const struct btd_service *service);
+void btd_service_set_blocked(struct btd_service *service, bool value);
+bool btd_service_is_blocked(const struct btd_service *service);
 bool btd_service_get_gatt_handles(const struct btd_service *service,
                                                        uint16_t *start_handle,
                                                        uint16_t *end_handle);
index f10d9be..f090e1b 100644 (file)
@@ -654,6 +654,7 @@ static void cmd_show(int argc, char *argv[])
        rl_printf("Player %s\n", g_dbus_proxy_get_path(proxy));
 
        print_property(proxy, "Name");
+       print_property(proxy, "Searchable");
        print_property(proxy, "Repeat");
        print_property(proxy, "Equalizer");
        print_property(proxy, "Shuffle");
index db11f9a..3535faa 100644 (file)
@@ -1530,7 +1530,7 @@ int main(int argc, char *argv[])
                        dev[0] = 0;
                        if (!strchr(opt, '/'))
                                strcpy(dev, "/dev/");
-                       strcat(dev, opt);
+                       strncat(dev, opt, PATH_MAX);
                        break;
 
                case 1:
index 648a0f7..2c84dc7 100644 (file)
@@ -2404,7 +2404,9 @@ failed:
 
 static int print_advertising_devices(int dd, uint8_t filter_type)
 {
-       unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr;
+       unsigned char buf_array[HCI_MAX_EVENT_SIZE+1] = {0};
+       unsigned char *buf = buf_array;
+       unsigned char *ptr = NULL;
        struct hci_filter nf, of;
        struct sigaction sa;
        socklen_t olen;
@@ -2431,11 +2433,14 @@ static int print_advertising_devices(int dd, uint8_t filter_type)
        sigaction(SIGINT, &sa, NULL);
 
        while (1) {
-               evt_le_meta_event *meta;
-               le_advertising_info *info;
-               char addr[18];
+               evt_le_meta_event *meta = NULL;
+               le_advertising_info *info = NULL;
+               char addr_array[18];
+               char *addr = addr_array;
+
+               buf[HCI_MAX_EVENT_SIZE] = 0;
 
-               while ((len = read(dd, buf, sizeof(buf))) < 0) {
+               while ((len = read(dd, buf, HCI_MAX_EVENT_SIZE)) < 0) {
                        if (errno == EINTR && signal_received == SIGINT) {
                                len = 0;
                                goto done;
@@ -2457,14 +2462,16 @@ static int print_advertising_devices(int dd, uint8_t filter_type)
                /* Ignoring multiple reports */
                info = (le_advertising_info *) (meta->data + 1);
                if (check_report_filter(filter_type, info)) {
-                       char name[30];
+                       char name_array[30];
+                       char *name = name_array;
 
-                       memset(name, 0, sizeof(name));
+                       memset(name, 0, 30);
 
                        ba2str(&info->bdaddr, addr);
                        eir_parse_name(info->data, info->length,
-                                                       name, sizeof(name) - 1);
+                                                       name, 29);
 
+                       name[29] = '\0';
                        printf("%s %s\n", addr, name);
                }
        }