* [PATCH BlueZ v0 08/18] gatt: Add server unix socket
From: Claudio Takahasi @ 2014-01-09 16:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi, Claudio Takahasi
In-Reply-To: <1389285503-19348-1-git-send-email-claudio.takahasi@openbossa.org>
This patch adds a server unix socket to handle local ATT traffic. This
is a development purpose feature used to allow local testing without
breaking the current attribute server.
---
src/gatt.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
diff --git a/src/gatt.c b/src/gatt.c
index ee045b1..4806205 100644
--- a/src/gatt.c
+++ b/src/gatt.c
@@ -25,6 +25,11 @@
#include <config.h>
#endif
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
#include <glib.h>
#include "adapter.h"
@@ -50,6 +55,7 @@ struct btd_attribute {
static GList *local_attribute_db;
static uint16_t next_handle = 0x0001;
+static guint unix_watch;
static int local_database_add(uint16_t handle, struct btd_attribute *attr)
{
@@ -94,11 +100,71 @@ struct btd_attribute *btd_gatt_add_service(const bt_uuid_t *uuid)
return attr;
}
+static gboolean unix_accept_cb(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ struct sockaddr_un uaddr;
+ socklen_t len = sizeof(uaddr);
+ GIOChannel *nio;
+ int err, nsk, sk;
+
+ sk = g_io_channel_unix_get_fd(io);
+
+ nsk = accept(sk, (struct sockaddr *) &uaddr, &len);
+ if (nsk < 0) {
+ err = errno;
+ error("ATT UNIX socket accept: %s(%d)", strerror(err), err);
+ return TRUE;
+ }
+
+ nio = g_io_channel_unix_new(nsk);
+ g_io_channel_set_close_on_unref(nio, TRUE);
+ DBG("ATT UNIX socket: %p new client", nio);
+ g_io_channel_unref(nio);
+
+ return TRUE;
+}
+
void gatt_init(void)
{
+ struct sockaddr_un uaddr = {
+ .sun_family = AF_UNIX,
+ .sun_path = "\0/bluetooth/unix_att",
+ };
+ GIOChannel *io;
+ int sk, err;
+
DBG("Starting GATT server");
gatt_dbus_manager_register();
+
+ sk = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC , 0);
+ if (sk < 0) {
+ err = errno;
+ error("ATT UNIX socket: %s(%d)", strerror(err), err);
+ return;
+ }
+
+ if (bind(sk, (struct sockaddr *) &uaddr, sizeof(uaddr)) < 0) {
+ err = errno;
+ error("binding ATT UNIX socket: %s(%d)", strerror(err), err);
+ close(sk);
+ return;
+ }
+
+ if (listen(sk, 5) < 0) {
+ err = errno;
+ error("listen ATT UNIX socket: %s(%d)", strerror(err), err);
+ close(sk);
+ return;
+ }
+
+ io = g_io_channel_unix_new(sk);
+ g_io_channel_set_close_on_unref(io, TRUE);
+ unix_watch = g_io_add_watch(io,
+ G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ unix_accept_cb, NULL);
+ g_io_channel_unref(io);
}
void gatt_cleanup(void)
@@ -106,4 +172,5 @@ void gatt_cleanup(void)
DBG("Stopping GATT server");
gatt_dbus_manager_unregister();
+ g_source_remove(unix_watch);
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v0 07/18] gatt: Implement UnregisterService
From: Claudio Takahasi @ 2014-01-09 16:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi, Alvaro Silva
In-Reply-To: <1389285503-19348-1-git-send-email-claudio.takahasi@openbossa.org>
From: Alvaro Silva <alvaro.silva@openbossa.org>
This patch implements UnregisterService method of ServiceManager1.
External applications may call this method to unregister a given
service without leaving the system bus.
---
src/gatt-dbus.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/src/gatt-dbus.c b/src/gatt-dbus.c
index fc41d00..1f789b0 100644
--- a/src/gatt-dbus.c
+++ b/src/gatt-dbus.c
@@ -243,6 +243,31 @@ static DBusMessage *register_service(DBusConnection *conn,
static DBusMessage *unregister_service(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
+ struct external_app *eapp = user_data;
+ DBusMessageIter iter;
+ const char *path;
+ GSList *list;
+
+ DBG("Unregistering GATT Service");
+
+ if (!dbus_message_iter_init(msg, &iter))
+ return btd_error_invalid_args(msg);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_OBJECT_PATH)
+ return btd_error_invalid_args(msg);
+
+ dbus_message_iter_get_basic(&iter, &path);
+
+ list = g_slist_find_custom(external_apps, path, external_app_path_cmp);
+ if (list == NULL)
+ return btd_error_does_not_exist(msg);
+
+ eapp = list->data;
+ if (g_strcmp0(dbus_message_get_sender(msg), eapp->owner) != 0)
+ return btd_error_does_not_exist(msg);
+
+ g_dbus_remove_watch(conn, eapp->watch);
+
return dbus_message_new_method_return(msg);
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v0 06/18] gatt: Add external services tracking
From: Claudio Takahasi @ 2014-01-09 16:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi, Alvaro Silva
In-Reply-To: <1389285503-19348-1-git-send-email-claudio.takahasi@openbossa.org>
From: Alvaro Silva <alvaro.silva@openbossa.org>
All primary services declarations provided by an external application
will be automatically inserted in the attribute database.
---
src/gatt-dbus.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 109 insertions(+)
diff --git a/src/gatt-dbus.c b/src/gatt-dbus.c
index fc41b78..fc41d00 100644
--- a/src/gatt-dbus.c
+++ b/src/gatt-dbus.c
@@ -39,15 +39,21 @@
#include "log.h"
#include "error.h"
+#include "gatt.h"
#include "gatt-dbus.h"
+#define SERVICE_IFACE "org.bluez.Service1"
#define SERVICE_MGR_IFACE "org.bluez.ServiceManager1"
+#define REGISTER_TIMER 1
+
struct external_app {
char *owner;
char *path;
GDBusClient *client;
+ GSList *proxies;
unsigned int watch;
+ guint register_timer;
};
static GSList *external_apps;
@@ -60,6 +66,36 @@ static int external_app_path_cmp(gconstpointer a, gconstpointer b)
return g_strcmp0(eapp->path, path);
}
+static void proxy_added(GDBusProxy *proxy, void *user_data)
+{
+ struct external_app *eapp = user_data;
+ const char *interface, *path;
+
+ interface = g_dbus_proxy_get_interface(proxy);
+ path = g_dbus_proxy_get_path(proxy);
+
+ DBG("path %s iface %s", path, interface);
+
+ if (g_strcmp0(interface, SERVICE_IFACE) != 0)
+ return;
+
+ eapp->proxies = g_slist_append(eapp->proxies, proxy);
+}
+
+static void proxy_removed(GDBusProxy *proxy, void *user_data)
+{
+ struct external_app *eapp = user_data;
+ const char *interface, *path;
+
+ interface = g_dbus_proxy_get_interface(proxy);
+ path = g_dbus_proxy_get_path(proxy);
+
+ DBG("path %s iface %s", path, interface);
+
+ eapp->proxies = g_slist_remove(eapp->proxies, proxy);
+}
+
+
static void external_app_watch_destroy(gpointer user_data)
{
struct external_app *eapp = user_data;
@@ -70,6 +106,9 @@ static void external_app_watch_destroy(gpointer user_data)
g_dbus_client_unref(eapp->client);
+ if (eapp->register_timer)
+ g_source_remove(eapp->register_timer);
+
g_free(eapp->owner);
g_free(eapp->path);
g_free(eapp);
@@ -99,9 +138,75 @@ static struct external_app *new_external_app(DBusConnection *conn,
eapp->client = client;
eapp->path = g_strdup(path);
+ g_dbus_client_set_proxy_handlers(client, proxy_added, proxy_removed,
+ NULL, eapp);
+
return eapp;
}
+static int register_external_service(GDBusProxy *proxy)
+{
+ DBusMessageIter iter;
+ const char *uuid;
+ bt_uuid_t btuuid;
+
+ if (!g_dbus_proxy_get_property(proxy, "UUID", &iter))
+ return -EINVAL;
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&iter, &uuid);
+
+ if (bt_string_to_uuid(&btuuid, uuid) < 0)
+ return -EINVAL;
+
+ if (btd_gatt_add_service(&btuuid) == NULL)
+ return -EINVAL;
+
+ return 0;
+}
+
+static gboolean finish_register(gpointer user_data)
+{
+ struct external_app *eapp = user_data;
+ GSList *list;
+
+ /*
+ * It is not possible to detect when the last proxy object
+ * was reported. "Proxy added" handler reports objects
+ * added on demand or returned by GetManagedObjects().
+ * This timer helps to register all the GATT declarations
+ * (services, characteristics and descriptors) after fetching
+ * all the D-Bus objects.
+ */
+
+ eapp->register_timer = 0;
+
+ for (list = eapp->proxies; list; list = g_slist_next(list)) {
+ const char *interface, *path;
+ GDBusProxy *proxy = list->data;
+
+ interface = g_dbus_proxy_get_interface(proxy);
+ path = g_dbus_proxy_get_path(proxy);
+
+ if (g_strcmp0(SERVICE_IFACE, interface) != 0)
+ continue;
+
+ if (g_strcmp0(path, eapp->path) != 0)
+ continue;
+
+ if (register_external_service(proxy) < 0) {
+ DBG("Inconsistent external service: %s", path);
+ continue;
+ }
+
+ DBG("External service: %s", path);
+ }
+
+ return FALSE;
+}
+
static DBusMessage *register_service(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
@@ -109,6 +214,8 @@ static DBusMessage *register_service(DBusConnection *conn,
DBusMessageIter iter;
const char *path;
+ DBG("Registering GATT Service");
+
if (!dbus_message_iter_init(msg, &iter))
return btd_error_invalid_args(msg);
@@ -127,6 +234,8 @@ static DBusMessage *register_service(DBusConnection *conn,
external_apps = g_slist_prepend(external_apps, eapp);
DBG("New app %p: %s", eapp, path);
+ eapp->register_timer = g_timeout_add_seconds(REGISTER_TIMER,
+ finish_register, eapp);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v0 05/18] gatt: Add helper for creating GATT services
From: Claudio Takahasi @ 2014-01-09 16:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi, Andre Guedes
In-Reply-To: <1389285503-19348-1-git-send-email-claudio.takahasi@openbossa.org>
From: Andre Guedes <andre.guedes@openbossa.org>
This patch adds the btd_gatt_add_service() helper which adds a
GATT Service declaration to the local attribute database.
---
lib/uuid.h | 5 +++++
src/gatt.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/gatt.h | 10 ++++++++++
3 files changed, 77 insertions(+)
diff --git a/lib/uuid.h b/lib/uuid.h
index c24cee5..237145b 100644
--- a/lib/uuid.h
+++ b/lib/uuid.h
@@ -158,6 +158,11 @@ void bt_uuid_to_uuid128(const bt_uuid_t *src, bt_uuid_t *dst);
int bt_uuid_to_string(const bt_uuid_t *uuid, char *str, size_t n);
int bt_string_to_uuid(bt_uuid_t *uuid, const char *string);
+static inline int bt_uuid_len(const bt_uuid_t *uuid)
+{
+ return uuid->type / 8;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gatt.c b/src/gatt.c
index e8b691a..ee045b1 100644
--- a/src/gatt.c
+++ b/src/gatt.c
@@ -27,11 +27,73 @@
#include <glib.h>
+#include "adapter.h"
+#include "device.h"
+
#include "log.h"
+#include "lib/uuid.h"
+#include "attrib/att.h"
#include "gatt-dbus.h"
#include "gatt.h"
+/* Common GATT UUIDs */
+static const bt_uuid_t primary_uuid = { .type = BT_UUID16,
+ .value.u16 = GATT_PRIM_SVC_UUID };
+
+struct btd_attribute {
+ uint16_t handle;
+ bt_uuid_t type;
+ uint16_t value_len;
+ uint8_t value[0];
+};
+
+static GList *local_attribute_db;
+static uint16_t next_handle = 0x0001;
+
+static int local_database_add(uint16_t handle, struct btd_attribute *attr)
+{
+ attr->handle = handle;
+
+ local_attribute_db = g_list_append(local_attribute_db, attr);
+
+ return 0;
+}
+
+struct btd_attribute *btd_gatt_add_service(const bt_uuid_t *uuid)
+{
+ uint16_t len = bt_uuid_len(uuid);
+ struct btd_attribute *attr = g_malloc0(sizeof(struct btd_attribute) +
+ len);
+
+ /*
+ * Service DECLARATION
+ *
+ * TYPE ATTRIBUTE VALUE
+ * +-------+---------------------------------+
+ * |0x2800 | 0xYYYY... |
+ * | (1) | (2) |
+ * +------+----------------------------------+
+ * (1) - 2 octets: Primary/Secondary Service UUID
+ * (2) - 2 or 16 octets: Service UUID
+ */
+
+ attr->type = primary_uuid;
+
+ att_put_uuid(*uuid, attr->value);
+ attr->value_len = len;
+
+ if (local_database_add(next_handle, attr) < 0) {
+ g_free(attr);
+ return NULL;
+ }
+
+ /* TODO: missing overflow checking */
+ next_handle = next_handle + 1;
+
+ return attr;
+}
+
void gatt_init(void)
{
DBG("Starting GATT server");
diff --git a/src/gatt.h b/src/gatt.h
index 3a320b4..8dd1312 100644
--- a/src/gatt.h
+++ b/src/gatt.h
@@ -21,6 +21,16 @@
*
*/
+struct btd_attribute;
+
void gatt_init(void);
void gatt_cleanup(void);
+
+/* btd_gatt_add_service - Add a service declaration to local attribute database.
+ * @uuid: Service UUID.
+ *
+ * Returns a reference to service declaration attribute. In case of error,
+ * NULL is returned.
+ */
+struct btd_attribute *btd_gatt_add_service(const bt_uuid_t *uuid);
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v0 04/18] lib: Move GATT UUID to uuid.h
From: Claudio Takahasi @ 2014-01-09 16:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi, Claudio Takahasi
In-Reply-To: <1389285503-19348-1-git-send-email-claudio.takahasi@openbossa.org>
This patch moves GATT UUIDs definitions to a common header. uuid.h contains
helper functions to manipulate Bluetooth UUIDs and some common BR/EDR services
UUIDs.
---
attrib/gatt.h | 25 -------------------------
lib/uuid.h | 25 +++++++++++++++++++++++++
2 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/attrib/gatt.h b/attrib/gatt.h
index e5abd85..9e4ade2 100644
--- a/attrib/gatt.h
+++ b/attrib/gatt.h
@@ -24,31 +24,6 @@
#include <bluetooth/sdp.h>
-/* GATT Profile Attribute types */
-#define GATT_PRIM_SVC_UUID 0x2800
-#define GATT_SND_SVC_UUID 0x2801
-#define GATT_INCLUDE_UUID 0x2802
-#define GATT_CHARAC_UUID 0x2803
-
-/* GATT Characteristic Types */
-#define GATT_CHARAC_DEVICE_NAME 0x2A00
-#define GATT_CHARAC_APPEARANCE 0x2A01
-#define GATT_CHARAC_PERIPHERAL_PRIV_FLAG 0x2A02
-#define GATT_CHARAC_RECONNECTION_ADDRESS 0x2A03
-#define GATT_CHARAC_PERIPHERAL_PREF_CONN 0x2A04
-#define GATT_CHARAC_SERVICE_CHANGED 0x2A05
-
-/* GATT Characteristic Descriptors */
-#define GATT_CHARAC_EXT_PROPER_UUID 0x2900
-#define GATT_CHARAC_USER_DESC_UUID 0x2901
-#define GATT_CLIENT_CHARAC_CFG_UUID 0x2902
-#define GATT_SERVER_CHARAC_CFG_UUID 0x2903
-#define GATT_CHARAC_FMT_UUID 0x2904
-#define GATT_CHARAC_AGREG_FMT_UUID 0x2905
-#define GATT_CHARAC_VALID_RANGE_UUID 0x2906
-#define GATT_EXTERNAL_REPORT_REFERENCE 0x2907
-#define GATT_REPORT_REFERENCE 0x2908
-
/* Client Characteristic Configuration bit field */
#define GATT_CLIENT_CHARAC_CFG_NOTIF_BIT 0x0001
#define GATT_CLIENT_CHARAC_CFG_IND_BIT 0x0002
diff --git a/lib/uuid.h b/lib/uuid.h
index 95e5a9a..c24cee5 100644
--- a/lib/uuid.h
+++ b/lib/uuid.h
@@ -105,6 +105,31 @@ extern "C" {
#define OBEX_MNS_UUID "00001133-0000-1000-8000-00805f9b34fb"
#define OBEX_MAP_UUID "00001134-0000-1000-8000-00805f9b34fb"
+/* GATT UUIDs section */
+#define GATT_PRIM_SVC_UUID 0x2800
+#define GATT_SND_SVC_UUID 0x2801
+#define GATT_INCLUDE_UUID 0x2802
+#define GATT_CHARAC_UUID 0x2803
+
+/* GATT Characteristic Types */
+#define GATT_CHARAC_DEVICE_NAME 0x2A00
+#define GATT_CHARAC_APPEARANCE 0x2A01
+#define GATT_CHARAC_PERIPHERAL_PRIV_FLAG 0x2A02
+#define GATT_CHARAC_RECONNECTION_ADDRESS 0x2A03
+#define GATT_CHARAC_PERIPHERAL_PREF_CONN 0x2A04
+#define GATT_CHARAC_SERVICE_CHANGED 0x2A05
+
+/* GATT Characteristic Descriptors */
+#define GATT_CHARAC_EXT_PROPER_UUID 0x2900
+#define GATT_CHARAC_USER_DESC_UUID 0x2901
+#define GATT_CLIENT_CHARAC_CFG_UUID 0x2902
+#define GATT_SERVER_CHARAC_CFG_UUID 0x2903
+#define GATT_CHARAC_FMT_UUID 0x2904
+#define GATT_CHARAC_AGREG_FMT_UUID 0x2905
+#define GATT_CHARAC_VALID_RANGE_UUID 0x2906
+#define GATT_EXTERNAL_REPORT_REFERENCE 0x2907
+#define GATT_REPORT_REFERENCE 0x2908
+
typedef struct {
enum {
BT_UUID_UNSPEC = 0,
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v0 03/18] gatt: Add registering external service
From: Claudio Takahasi @ 2014-01-09 16:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi, Alvaro Silva
In-Reply-To: <1389285503-19348-1-git-send-email-claudio.takahasi@openbossa.org>
From: Alvaro Silva <alvaro.silva@openbossa.org>
This patch allows external applications register a given service on
Bluez. Applications must provide an object path and a dictionary of
options. Options dictionary will be used later to provide additional
service information.
---
src/gatt-dbus.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 88 insertions(+), 1 deletion(-)
diff --git a/src/gatt-dbus.c b/src/gatt-dbus.c
index 90a321b..fc41b78 100644
--- a/src/gatt-dbus.c
+++ b/src/gatt-dbus.c
@@ -26,22 +26,109 @@
#endif
#include <stdint.h>
+#include <errno.h>
#include <glib.h>
#include <dbus/dbus.h>
#include <gdbus/gdbus.h>
+#include "adapter.h"
+#include "device.h"
+#include "lib/uuid.h"
#include "dbus-common.h"
#include "log.h"
+#include "error.h"
#include "gatt-dbus.h"
#define SERVICE_MGR_IFACE "org.bluez.ServiceManager1"
+struct external_app {
+ char *owner;
+ char *path;
+ GDBusClient *client;
+ unsigned int watch;
+};
+
+static GSList *external_apps;
+
+static int external_app_path_cmp(gconstpointer a, gconstpointer b)
+{
+ const struct external_app *eapp = a;
+ const char *path = b;
+
+ return g_strcmp0(eapp->path, path);
+}
+
+static void external_app_watch_destroy(gpointer user_data)
+{
+ struct external_app *eapp = user_data;
+
+ /* TODO: Remove from the database */
+
+ external_apps = g_slist_remove(external_apps, eapp);
+
+ g_dbus_client_unref(eapp->client);
+
+ g_free(eapp->owner);
+ g_free(eapp->path);
+ g_free(eapp);
+}
+
+static struct external_app *new_external_app(DBusConnection *conn,
+ const char *sender, const char *path)
+{
+ struct external_app *eapp;
+ GDBusClient *client;
+
+ client = g_dbus_client_new(conn, sender, "/");
+ if (client == NULL)
+ return NULL;
+
+ eapp = g_new0(struct external_app, 1);
+
+ eapp->watch = g_dbus_add_disconnect_watch(btd_get_dbus_connection(),
+ sender, NULL, eapp, external_app_watch_destroy);
+ if (eapp->watch == 0) {
+ g_dbus_client_unref(client);
+ g_free(eapp);
+ return NULL;
+ }
+
+ eapp->owner = g_strdup(sender);
+ eapp->client = client;
+ eapp->path = g_strdup(path);
+
+ return eapp;
+}
+
static DBusMessage *register_service(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
- return dbus_message_new_method_return(msg);
+ struct external_app *eapp;
+ DBusMessageIter iter;
+ const char *path;
+
+ if (!dbus_message_iter_init(msg, &iter))
+ return btd_error_invalid_args(msg);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_OBJECT_PATH)
+ return btd_error_invalid_args(msg);
+
+ dbus_message_iter_get_basic(&iter, &path);
+
+ if (g_slist_find_custom(external_apps, path, external_app_path_cmp))
+ return btd_error_already_exists(msg);
+
+ eapp = new_external_app(conn, dbus_message_get_sender(msg), path);
+ if (eapp == NULL)
+ return btd_error_failed(msg, "Not enough resources");
+
+ external_apps = g_slist_prepend(external_apps, eapp);
+
+ DBG("New app %p: %s", eapp, path);
+
+ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
static DBusMessage *unregister_service(DBusConnection *conn,
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v0 02/18] gatt: Register Manager D-Bus Interface
From: Claudio Takahasi @ 2014-01-09 16:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi, Alvaro Silva
In-Reply-To: <1389285503-19348-1-git-send-email-claudio.takahasi@openbossa.org>
From: Alvaro Silva <alvaro.silva@openbossa.org>
This patch registers the Service Manager D-Bus Interface. This
interface implements the methods to allow external application register
and unregister GATT Services.
---
Makefile.am | 1 +
src/gatt-dbus.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/gatt-dbus.h | 25 +++++++++++++++++++
src/gatt.c | 9 +++++++
4 files changed, 110 insertions(+)
create mode 100644 src/gatt-dbus.c
create mode 100644 src/gatt-dbus.h
diff --git a/Makefile.am b/Makefile.am
index de7cdc2..6405f3a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -146,6 +146,7 @@ src_bluetoothd_SOURCES = $(builtin_sources) \
src/adapter.h src/adapter.c \
src/profile.h src/profile.c \
src/service.h src/service.c \
+ src/gatt-dbus.h src/gatt-dbus.c \
src/gatt.h src/gatt.c \
src/device.h src/device.c src/attio.h \
src/dbus-common.c src/dbus-common.h \
diff --git a/src/gatt-dbus.c b/src/gatt-dbus.c
new file mode 100644
index 0000000..90a321b
--- /dev/null
+++ b/src/gatt-dbus.c
@@ -0,0 +1,75 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2014 Instituto Nokia de Tecnologia - INdT
+ *
+ *
+ * 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 <stdint.h>
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <gdbus/gdbus.h>
+
+#include "dbus-common.h"
+#include "log.h"
+
+#include "gatt-dbus.h"
+
+#define SERVICE_MGR_IFACE "org.bluez.ServiceManager1"
+
+static DBusMessage *register_service(DBusConnection *conn,
+ DBusMessage *msg, void *user_data)
+{
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *unregister_service(DBusConnection *conn,
+ DBusMessage *msg, void *user_data)
+{
+ return dbus_message_new_method_return(msg);
+}
+
+static const GDBusMethodTable methods[] = {
+ { GDBUS_EXPERIMENTAL_METHOD("RegisterService",
+ GDBUS_ARGS({ "service", "o"},
+ { "options", "a{sv}"}),
+ NULL, register_service) },
+ { GDBUS_EXPERIMENTAL_METHOD("UnregisterService",
+ GDBUS_ARGS({"service", "o"}),
+ NULL, unregister_service) },
+ { }
+};
+
+gboolean gatt_dbus_manager_register(void)
+{
+ return g_dbus_register_interface(btd_get_dbus_connection(),
+ "/org/bluez", SERVICE_MGR_IFACE,
+ methods, NULL, NULL, NULL, NULL);
+}
+
+void gatt_dbus_manager_unregister(void)
+{
+ g_dbus_unregister_interface(btd_get_dbus_connection(), "/org/bluez",
+ SERVICE_MGR_IFACE);
+}
diff --git a/src/gatt-dbus.h b/src/gatt-dbus.h
new file mode 100644
index 0000000..310cfa9
--- /dev/null
+++ b/src/gatt-dbus.h
@@ -0,0 +1,25 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2014 Instituto Nokia de Tecnologia - INdT
+ *
+ *
+ * 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
+ *
+ */
+
+gboolean gatt_dbus_manager_register(void);
+void gatt_dbus_manager_unregister(void);
diff --git a/src/gatt.c b/src/gatt.c
index 06619f0..e8b691a 100644
--- a/src/gatt.c
+++ b/src/gatt.c
@@ -25,14 +25,23 @@
#include <config.h>
#endif
+#include <glib.h>
+
+#include "log.h"
+
+#include "gatt-dbus.h"
#include "gatt.h"
void gatt_init(void)
{
+ DBG("Starting GATT server");
+ gatt_dbus_manager_register();
}
void gatt_cleanup(void)
{
+ DBG("Stopping GATT server");
+ gatt_dbus_manager_unregister();
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v0 01/18] gatt: Add stub for gatt.{c, h} files
From: Claudio Takahasi @ 2014-01-09 16:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi, Alvaro Silva
In-Reply-To: <1389285503-19348-1-git-send-email-claudio.takahasi@openbossa.org>
From: Alvaro Silva <alvaro.silva@openbossa.org>
These files implement functions to manipulate ATT transactions, and expose
functions to allow other entities to manage GATT based services.
---
Makefile.am | 1 +
src/gatt.c | 38 ++++++++++++++++++++++++++++++++++++++
src/gatt.h | 26 ++++++++++++++++++++++++++
src/main.c | 4 ++++
4 files changed, 69 insertions(+)
create mode 100644 src/gatt.c
create mode 100644 src/gatt.h
diff --git a/Makefile.am b/Makefile.am
index 23516b9..de7cdc2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -146,6 +146,7 @@ src_bluetoothd_SOURCES = $(builtin_sources) \
src/adapter.h src/adapter.c \
src/profile.h src/profile.c \
src/service.h src/service.c \
+ src/gatt.h src/gatt.c \
src/device.h src/device.c src/attio.h \
src/dbus-common.c src/dbus-common.h \
src/eir.h src/eir.c \
diff --git a/src/gatt.c b/src/gatt.c
new file mode 100644
index 0000000..06619f0
--- /dev/null
+++ b/src/gatt.c
@@ -0,0 +1,38 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2014 Instituto Nokia de Tecnologia - INdT
+ *
+ *
+ * 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 "gatt.h"
+
+void gatt_init(void)
+{
+
+}
+
+void gatt_cleanup(void)
+{
+
+}
diff --git a/src/gatt.h b/src/gatt.h
new file mode 100644
index 0000000..3a320b4
--- /dev/null
+++ b/src/gatt.h
@@ -0,0 +1,26 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2014 Instituto Nokia de Tecnologia - INdT
+ *
+ *
+ * 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
+ *
+ */
+
+void gatt_init(void);
+
+void gatt_cleanup(void);
diff --git a/src/main.c b/src/main.c
index 91d90b4..fccc838 100644
--- a/src/main.c
+++ b/src/main.c
@@ -55,6 +55,7 @@
#include "dbus-common.h"
#include "agent.h"
#include "profile.h"
+#include "gatt.h"
#include "systemd.h"
#define BLUEZ_NAME "org.bluez"
@@ -545,6 +546,8 @@ int main(int argc, char *argv[])
g_dbus_set_flags(gdbus_flags);
+ gatt_init();
+
if (option_compat == TRUE)
sdp_flags |= SDP_SERVER_COMPAT;
@@ -595,6 +598,7 @@ int main(int argc, char *argv[])
btd_profile_cleanup();
btd_agent_cleanup();
btd_device_cleanup();
+ gatt_cleanup();
adapter_cleanup();
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v0 00/18] GATT API: External Services
From: Claudio Takahasi @ 2014-01-09 16:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi, Claudio Takahasi
In-Reply-To: <1385585457-26951-1-git-send-email-claudio.takahasi@openbossa.org>
This patchset implements the minimal support for managing local
services declarations. Based on "[RFC BlueZ v2] doc: Add GATT API"
Changes from RFC v0 to PATCH v0:
* Changed copyright year : s/2013/2014
* Fixed coding style
* Added gatt-service binary to gitignore
* Added extra comment in the source code
Features:
* API for internal and external services declaration
* Unix socket for testing purpose: services are exported
through unix sockets to avoid breaking the current attribute
server.
How to test:
Run bluetoothd with EXPERIMENTAL flag
Replace bluetooth.conf and reload DBus settings
$gatttool -L --primary (or interactive mode)
Upstreaming plan (steps):
* GATT Server: External Services
* GATT Server: External Characteristics (Server)
* GATT Server: External Descriptors (Server)
* Remove ATTIO and automatic connection mechanism from userspace
* Replace attribute server
* Fix all GATT internal plugins
* GATT Client: Remote Services
* ...
Alvaro Silva (7):
gatt: Add stub for gatt.{c, h} files
gatt: Register Manager D-Bus Interface
gatt: Add registering external service
gatt: Add external services tracking
gatt: Implement UnregisterService
gatt: Register ATT command/event handler
gatt: Add Discover All Primary Services
Andre Guedes (1):
gatt: Add helper for creating GATT services
Claudio Takahasi (10):
lib: Move GATT UUID to uuid.h
gatt: Add server unix socket
gattrib: Use default ATT LE MTU for non-standard sockets
test: Add external service GATT skeleton
gitignore: Add test/gatt-service
test: Add signal handling for gatt-service
test: Add registering external service
gatttool: Add unix socket connect
gatttool: Add unix socket support for interactive mode
bluetooth.conf: Add ObjectManager interface
.gitignore | 1 +
Makefile.am | 2 +
Makefile.tools | 5 +
attrib/gatt.h | 25 ----
attrib/gattrib.c | 16 +--
attrib/gatttool.c | 27 +++-
attrib/gatttool.h | 1 +
attrib/interactive.c | 19 +--
attrib/utils.c | 54 ++++++++
lib/uuid.h | 30 ++++
src/bluetooth.conf | 1 +
src/gatt-dbus.c | 296 +++++++++++++++++++++++++++++++++++++++
src/gatt-dbus.h | 25 ++++
src/gatt.c | 383 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/gatt.h | 36 +++++
src/main.c | 4 +
test/gatt-service.c | 254 ++++++++++++++++++++++++++++++++++
17 files changed, 1131 insertions(+), 48 deletions(-)
create mode 100644 src/gatt-dbus.c
create mode 100644 src/gatt-dbus.h
create mode 100644 src/gatt.c
create mode 100644 src/gatt.h
create mode 100644 test/gatt-service.c
--
1.8.3.1
^ permalink raw reply
* Re: [PATCH 1/3] hcidump: Fix missing break
From: Johan Hedberg @ 2014-01-09 16:23 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1389283864-15135-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Thu, Jan 09, 2014, Andrei Emeltchenko wrote:
> ---
> tools/parser/avrcp.c | 4 ++++
> 1 file changed, 4 insertions(+)
All three patches have been applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] shared: Fix not calling destroy callback while clearing up handlers
From: Johan Hedberg @ 2014-01-09 16:21 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1389281160-17452-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Thu, Jan 09, 2014, Szymon Janc wrote:
> @@ -191,8 +191,10 @@ bool io_set_read_handler(struct io *io, io_callback_func_t callback,
>
> done:
> io->read_callback = callback;
> - io->read_destroy = destroy;
> - io->read_data = user_data;
> + if (callback) {
> + io->read_destroy = destroy;
> + io->read_data = user_data;
> + }
>
> return true;
> }
You're already checking for the value of callback earlier in the
function, so to avoid another check how about just move these
assignments right before the done: label?
> @@ -252,8 +254,10 @@ bool io_set_write_handler(struct io *io, io_callback_func_t callback,
>
> done:
> io->write_callback = callback;
> - io->write_destroy = destroy;
> - io->write_data = user_data;
> + if (callback) {
> + io->write_destroy = destroy;
> + io->write_data = user_data;
> + }
>
> return true;
> }
Same here.
Johan
^ permalink raw reply
* [PATCH 3/3] sdp: Fix incorrect sizeof argument
From: Andrei Emeltchenko @ 2014-01-09 16:11 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389283864-15135-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
length is a pointer to int table not int* table.
---
lib/sdp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/sdp.c b/lib/sdp.c
index cbdf15e..886e7cf 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -4773,7 +4773,7 @@ int sdp_set_supp_feat(sdp_record_t *rec, const sdp_list_t *sf)
free(dtds);
goto fail;
}
- lengths = malloc(plen * sizeof(int *));
+ lengths = malloc(plen * sizeof(int));
if (!lengths) {
free(dtds);
free(vals);
--
1.8.3.2
^ permalink raw reply related
* [PATCH 2/3] l2test: Fix using incorrect size of option
From: Andrei Emeltchenko @ 2014-01-09 16:11 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389283864-15135-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Use size of option instead of size of pointer
---
tools/l2test.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/l2test.c b/tools/l2test.c
index 9a7c809..aaa1608 100644
--- a/tools/l2test.c
+++ b/tools/l2test.c
@@ -287,7 +287,7 @@ static int setopts(int sk, struct l2cap_options *opts)
{
if (bdaddr_type == BDADDR_BREDR || cid)
return setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, opts,
- sizeof(opts));
+ sizeof(*opts));
return setsockopt(sk, SOL_BLUETOOTH, BT_RCVMTU, &opts->imtu,
sizeof(opts->imtu));
--
1.8.3.2
^ permalink raw reply related
* [PATCH 1/3] hcidump: Fix missing break
From: Andrei Emeltchenko @ 2014-01-09 16:11 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
tools/parser/avrcp.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tools/parser/avrcp.c b/tools/parser/avrcp.c
index b523533..7c320ea 100644
--- a/tools/parser/avrcp.c
+++ b/tools/parser/avrcp.c
@@ -1180,12 +1180,16 @@ response:
switch (status) {
case 0x00:
printf("(POWER_ON)\n");
+ break;
case 0x01:
printf("(POWER_OFF)\n");
+ break;
case 0x02:
printf("(UNPLUGGED)\n");
+ break;
default:
printf("(UNKOWN)\n");
+ break;
}
break;
case AVRCP_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH 0/7] sixaxis: Don't mark USB plugged device as trusted
From: Johan Hedberg @ 2014-01-09 15:57 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth, Bastien Nocera
In-Reply-To: <1389139348-3552-1-git-send-email-szymon.janc@gmail.com>
Hi Szymon,
On Wed, Jan 08, 2014, Szymon Janc wrote:
> This serie removes marking USB plugged sixaxis DS3 devices as trusted.
> Now agent is asked for service authorization before device is connected
> over BT. This is to address conserns about possibly crafted USB devices.
>
> This is implemented in PATCH 1. Rest are fixes for bugs that were uncovered
> due this change and client functionality that I've found missing while
> testing this.
>
> Comments and testing are welcome.
>
> --
> BR
> Szymon Janc
>
>
> Szymon Janc (7):
> sixaxis: Don't mark USB plugged device as trusted
> input: Fix crash on authorization reply with first sixaxis connection
> input: Fix check if device is sixaxis in auth_callback
> input: Fix connecting new trusted sixaxis device
> client: Add untrust command
> client: Add block command
> client: Add unblock command
>
> client/main.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++
> plugins/sixaxis.c | 1 -
> profiles/input/server.c | 37 ++++----------------
> 3 files changed, 99 insertions(+), 32 deletions(-)
All patches have been applied. Thanks.
Johan
^ permalink raw reply
* [PATCH] shared: Fix not calling destroy callback while clearing up handlers
From: Szymon Janc @ 2014-01-09 15:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
read/write_watch_destroy is be called after io_set_read/write_handler
exits. This was resulting in io destroy callback being NULLem before
destroy was called resulting in io destroy not being called at all.
Fix this by assigning destroy callback only if setting non-NULL
callback. destroy_watch will clean it when called.
Fix following valgrind report:
168 (120 direct, 48 indirect) bytes in 1 blocks are definitely lost in
loss record 34 of 36
at 0x4C2C494: calloc (in /usr/lib/valgrind/
vgpreload_memcheck-amd64-linux.so)
by 0x409BAE: mgmt_new (mgmt.c:372)
by 0x409D05: mgmt_new_default (mgmt.c:469)
by 0x40E100: test_pre_setup (android-tester.c:371)
by 0x40AD84: start_tester (tester.c:586)
by 0x4E7C3B5: g_main_context_dispatch (in /lib/x86_64-linux-gnu/
libglib-2.0.so.0.3800.1)
by 0x4E7C707: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
by 0x4E7CB09: g_main_loop_run (in /lib/x86_64-linux-gnu/
libglib-2.0.so.0.3800.1)
by 0x40B76C: tester_run (tester.c:784)
by 0x4034F4: main (android-tester.c:2127)
---
src/shared/io-glib.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/shared/io-glib.c b/src/shared/io-glib.c
index 488b1a2..b7b3ff2 100644
--- a/src/shared/io-glib.c
+++ b/src/shared/io-glib.c
@@ -191,8 +191,10 @@ bool io_set_read_handler(struct io *io, io_callback_func_t callback,
done:
io->read_callback = callback;
- io->read_destroy = destroy;
- io->read_data = user_data;
+ if (callback) {
+ io->read_destroy = destroy;
+ io->read_data = user_data;
+ }
return true;
}
@@ -252,8 +254,10 @@ bool io_set_write_handler(struct io *io, io_callback_func_t callback,
done:
io->write_callback = callback;
- io->write_destroy = destroy;
- io->write_data = user_data;
+ if (callback) {
+ io->write_destroy = destroy;
+ io->write_data = user_data;
+ }
return true;
}
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH] shared: Fix memory leaks in mgmt_unref
From: Johan Hedberg @ 2014-01-09 14:32 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1389277030-2131-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Thu, Jan 09, 2014, Szymon Janc wrote:
> Destroy notify and pending lists on freeing mgmt. Those two lists
> cannot be destroyed in same place as reply and request queues due
> to being used in can_read_data().
>
> Fix following valgrind reports:
>
> 24 bytes in 1 blocks are definitely lost in loss record 70 of 212
> at 0x4C2C494: calloc (in /usr/lib/valgrind/
> vgpreload_memcheck-amd64-linux.so)
> by 0x46B5E2: queue_new (queue.c:46)
> by 0x46C3CA: mgmt_new (mgmt.c:407)
> by 0x46C4B5: mgmt_new_default (mgmt.c:466)
> by 0x45FB45: adapter_init (adapter.c:6237)
> by 0x40A4F1: main (main.c:534)
>
> 24 bytes in 1 blocks are definitely lost in loss record 71 of 212
> at 0x4C2C494: calloc (in /usr/lib/
> valgrind/vgpreload_memcheck-amd64-linux.so)
> by 0x46B5E2: queue_new (queue.c:46)
> by 0x46C3D8: mgmt_new (mgmt.c:417)
> by 0x46C4B5: mgmt_new_default (mgmt.c:466)
> by 0x45FB45: adapter_init (adapter.c:6237)
> by 0x40A4F1: main (main.c:534)
> ---
> src/shared/mgmt.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] shared: Fix use after free in queue_foreach
From: Johan Hedberg @ 2014-01-09 14:32 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1389274357-25902-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Thu, Jan 09, 2014, Szymon Janc wrote:
> Function passed to queue_foreach may free queue entry. Make loop safe
> with that. Fix number of following valgrin reports.
>
> Invalid read of size 8
> at 0x408EEC: queue_foreach (queue.c:181)
> by 0x409A0E: can_read_data (mgmt.c:286)
> by 0x40896C: read_callback (io-glib.c:164)
> by 0x4E7C3B5: g_main_context_dispatch (in
> /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
> by 0x4E7C707: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
> by 0x4E7CB09: g_main_loop_run (in /lib/x86_64-linux-gnu/
> libglib-2.0.so.0.3800.1)
> by 0x40B5FC: tester_run (tester.c:784)
> by 0x4034F4: main (android-tester.c:2127)
> Address 0x59603a8 is 8 bytes inside a block of size 16 free'd
> at 0x4C2B60C: free (in /usr/lib/valgrind/
> vgpreload_memcheck-amd64-linux.so)
> by 0x40910D: queue_remove_all (queue.c:289)
> by 0x40A0BD: mgmt_unregister_all (mgmt.c:792)
> by 0x40A0F4: mgmt_unref (mgmt.c:499)
> by 0x40D814: index_removed_callback (android-tester.c:329)
> by 0x408EEB: queue_foreach (queue.c:184)
> by 0x409A0E: can_read_data (mgmt.c:286)
> by 0x40896C: read_callback (io-glib.c:164)
> by 0x4E7C3B5: g_main_context_dispatch (in /lib/x86_64-linux-gnu/
> libglib-2.0.so.0.3800.1)
> by 0x4E7C707: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
> by 0x4E7CB09: g_main_loop_run (in /lib/x86_64-linux-gnu/
> libglib-2.0.so.0.3800.1)
> by 0x40B5FC: tester_run (tester.c:784)
> ---
> src/shared/queue.c | 11 +++++++++--
> 1 file changed, 9 insertions(+), 2 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* [PATCH] shared: Fix memory leaks in mgmt_unref
From: Szymon Janc @ 2014-01-09 14:17 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
Destroy notify and pending lists on freeing mgmt. Those two lists
cannot be destroyed in same place as reply and request queues due
to being used in can_read_data().
Fix following valgrind reports:
24 bytes in 1 blocks are definitely lost in loss record 70 of 212
at 0x4C2C494: calloc (in /usr/lib/valgrind/
vgpreload_memcheck-amd64-linux.so)
by 0x46B5E2: queue_new (queue.c:46)
by 0x46C3CA: mgmt_new (mgmt.c:407)
by 0x46C4B5: mgmt_new_default (mgmt.c:466)
by 0x45FB45: adapter_init (adapter.c:6237)
by 0x40A4F1: main (main.c:534)
24 bytes in 1 blocks are definitely lost in loss record 71 of 212
at 0x4C2C494: calloc (in /usr/lib/
valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x46B5E2: queue_new (queue.c:46)
by 0x46C3D8: mgmt_new (mgmt.c:417)
by 0x46C4B5: mgmt_new_default (mgmt.c:466)
by 0x45FB45: adapter_init (adapter.c:6237)
by 0x40A4F1: main (main.c:534)
---
src/shared/mgmt.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/shared/mgmt.c b/src/shared/mgmt.c
index 2a2c2a3..b663d3a 100644
--- a/src/shared/mgmt.c
+++ b/src/shared/mgmt.c
@@ -291,8 +291,11 @@ static void read_watch_destroy(void *user_data)
{
struct mgmt *mgmt = user_data;
- if (mgmt->destroyed)
+ if (mgmt->destroyed) {
+ queue_destroy(mgmt->notify_list, NULL);
+ queue_destroy(mgmt->pending_list, NULL);
free(mgmt);
+ }
}
static bool can_read_data(struct io *io, void *user_data)
@@ -514,6 +517,8 @@ void mgmt_unref(struct mgmt *mgmt)
mgmt->buf = NULL;
if (!mgmt->in_notify) {
+ queue_destroy(mgmt->notify_list, NULL);
+ queue_destroy(mgmt->pending_list, NULL);
free(mgmt);
return;
}
--
1.8.3.2
^ permalink raw reply related
* [PATCH] shared: Fix use after free in queue_foreach
From: Szymon Janc @ 2014-01-09 13:32 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
Function passed to queue_foreach may free queue entry. Make loop safe
with that. Fix number of following valgrin reports.
Invalid read of size 8
at 0x408EEC: queue_foreach (queue.c:181)
by 0x409A0E: can_read_data (mgmt.c:286)
by 0x40896C: read_callback (io-glib.c:164)
by 0x4E7C3B5: g_main_context_dispatch (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
by 0x4E7C707: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
by 0x4E7CB09: g_main_loop_run (in /lib/x86_64-linux-gnu/
libglib-2.0.so.0.3800.1)
by 0x40B5FC: tester_run (tester.c:784)
by 0x4034F4: main (android-tester.c:2127)
Address 0x59603a8 is 8 bytes inside a block of size 16 free'd
at 0x4C2B60C: free (in /usr/lib/valgrind/
vgpreload_memcheck-amd64-linux.so)
by 0x40910D: queue_remove_all (queue.c:289)
by 0x40A0BD: mgmt_unregister_all (mgmt.c:792)
by 0x40A0F4: mgmt_unref (mgmt.c:499)
by 0x40D814: index_removed_callback (android-tester.c:329)
by 0x408EEB: queue_foreach (queue.c:184)
by 0x409A0E: can_read_data (mgmt.c:286)
by 0x40896C: read_callback (io-glib.c:164)
by 0x4E7C3B5: g_main_context_dispatch (in /lib/x86_64-linux-gnu/
libglib-2.0.so.0.3800.1)
by 0x4E7C707: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
by 0x4E7CB09: g_main_loop_run (in /lib/x86_64-linux-gnu/
libglib-2.0.so.0.3800.1)
by 0x40B5FC: tester_run (tester.c:784)
---
src/shared/queue.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/shared/queue.c b/src/shared/queue.c
index 0019e53..a7cc8d5 100644
--- a/src/shared/queue.c
+++ b/src/shared/queue.c
@@ -176,8 +176,15 @@ void queue_foreach(struct queue *queue, queue_foreach_func_t function,
if (!queue || !function)
return;
- for (entry = queue->head; entry; entry = entry->next)
- function(entry->data, user_data);
+ entry = queue->head;
+
+ while (entry) {
+ struct queue_entry *tmp = entry;
+
+ entry = tmp->next;
+
+ function(tmp->data, user_data);
+ }
}
void *queue_find(struct queue *queue, queue_match_func_t function,
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH] shared: Add ref counting to struct io
From: Johan Hedberg @ 2014-01-09 13:22 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1389271491-20388-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Thu, Jan 09, 2014, Szymon Janc wrote:
> This fix use after free in watch_destroy callbacks after mgmt_unref.
> Fix number of following valgrind reports:
>
> Invalid read of size 8
> at 0x4088A1: read_watch_destroy (io-glib.c:116)
> by 0x4E794A7: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
> by 0x4E7C4C1: g_main_context_dispatch (in /lib/x86_64-linux-gnu/
> libglib-2.0.so.0.3800.1)
> by 0x4E7C707: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
> by 0x4E7CB09: g_main_loop_run (in /lib/x86_64-linux-gnu/
> libglib-2.0.so.0.3800.1)
> by 0x40B53C: tester_run (tester.c:784)
> by 0x4034F4: main (android-tester.c:2127)
> Address 0x595f828 is 24 bytes inside a block of size 72 free'd
> at 0x4C2B60C: free (in /usr/lib/valgrind/
> vgpreload_memcheck-amd64-linux.so)
> by 0x40A079: mgmt_unref (mgmt.c:504)
> by 0x40D754: index_removed_callback (android-tester.c:329)
> by 0x408E67: queue_foreach (queue.c:180)
> by 0x40994E: can_read_data (mgmt.c:282)
> by 0x40893C: read_callback (io-glib.c:135)
> by 0x4E7C3B5: g_main_context_dispatch (in /lib/x86_64-linux-gnu/
> libglib-2.0.so.0.3800.1)
> by 0x4E7C707: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
> by 0x4E7CB09: g_main_loop_run (in /lib/x86_64-linux-gnu/
> libglib-2.0.so.0.3800.1)
> by 0x40B53C: tester_run (tester.c:784)
> by 0x4034F4: main (android-tester.c:2127)
>
> Invalid write of size 4
> at 0x4088B3: read_watch_destroy (io-glib.c:119)
> by 0x4E794A7: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
> by 0x4E7C4C1: g_main_context_dispatch (in /lib/x86_64-linux-gnu/
> libglib-2.0.so.0.3800.1)
> by 0x4E7C707: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
> by 0x4E7CB09: g_main_loop_run (in /lib/x86_64-linux-gnu/
> libglib-2.0.so.0.3800.1)
> by 0x40B53C: tester_run (tester.c:784)
> by 0x4034F4: main (android-tester.c:2127)
> Address 0x595f818 is 8 bytes inside a block of size 72 free'd
> at 0x4C2B60C: free (in /usr/lib/valgrind/
> vgpreload_memcheck-amd64-linux.so)
> by 0x40A079: mgmt_unref (mgmt.c:504)
> by 0x40D754: index_removed_callback (android-tester.c:329)
> by 0x408E67: queue_foreach (queue.c:180)
> by 0x40994E: can_read_data (mgmt.c:282)
> by 0x40893C: read_callback (io-glib.c:135)
> by 0x4E7C3B5: g_main_context_dispatch (in /lib/x86_64-linux-gnu/
> libglib-2.0.so.0.3800.1)
> by 0x4E7C707: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
> by 0x4E7CB09: g_main_loop_run (in /lib/x86_64-linux-gnu/
> libglib-2.0.so.0.3800.1)
> by 0x40B53C: tester_run (tester.c:784)
> by 0x4034F4: main (android-tester.c:2127)
> ---
> src/shared/io-glib.c | 45 +++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 39 insertions(+), 6 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* [PATCH] shared: Add ref counting to struct io
From: Szymon Janc @ 2014-01-09 12:44 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
This fix use after free in watch_destroy callbacks after mgmt_unref.
Fix number of following valgrind reports:
Invalid read of size 8
at 0x4088A1: read_watch_destroy (io-glib.c:116)
by 0x4E794A7: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
by 0x4E7C4C1: g_main_context_dispatch (in /lib/x86_64-linux-gnu/
libglib-2.0.so.0.3800.1)
by 0x4E7C707: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
by 0x4E7CB09: g_main_loop_run (in /lib/x86_64-linux-gnu/
libglib-2.0.so.0.3800.1)
by 0x40B53C: tester_run (tester.c:784)
by 0x4034F4: main (android-tester.c:2127)
Address 0x595f828 is 24 bytes inside a block of size 72 free'd
at 0x4C2B60C: free (in /usr/lib/valgrind/
vgpreload_memcheck-amd64-linux.so)
by 0x40A079: mgmt_unref (mgmt.c:504)
by 0x40D754: index_removed_callback (android-tester.c:329)
by 0x408E67: queue_foreach (queue.c:180)
by 0x40994E: can_read_data (mgmt.c:282)
by 0x40893C: read_callback (io-glib.c:135)
by 0x4E7C3B5: g_main_context_dispatch (in /lib/x86_64-linux-gnu/
libglib-2.0.so.0.3800.1)
by 0x4E7C707: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
by 0x4E7CB09: g_main_loop_run (in /lib/x86_64-linux-gnu/
libglib-2.0.so.0.3800.1)
by 0x40B53C: tester_run (tester.c:784)
by 0x4034F4: main (android-tester.c:2127)
Invalid write of size 4
at 0x4088B3: read_watch_destroy (io-glib.c:119)
by 0x4E794A7: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
by 0x4E7C4C1: g_main_context_dispatch (in /lib/x86_64-linux-gnu/
libglib-2.0.so.0.3800.1)
by 0x4E7C707: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
by 0x4E7CB09: g_main_loop_run (in /lib/x86_64-linux-gnu/
libglib-2.0.so.0.3800.1)
by 0x40B53C: tester_run (tester.c:784)
by 0x4034F4: main (android-tester.c:2127)
Address 0x595f818 is 8 bytes inside a block of size 72 free'd
at 0x4C2B60C: free (in /usr/lib/valgrind/
vgpreload_memcheck-amd64-linux.so)
by 0x40A079: mgmt_unref (mgmt.c:504)
by 0x40D754: index_removed_callback (android-tester.c:329)
by 0x408E67: queue_foreach (queue.c:180)
by 0x40994E: can_read_data (mgmt.c:282)
by 0x40893C: read_callback (io-glib.c:135)
by 0x4E7C3B5: g_main_context_dispatch (in /lib/x86_64-linux-gnu/
libglib-2.0.so.0.3800.1)
by 0x4E7C707: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
by 0x4E7CB09: g_main_loop_run (in /lib/x86_64-linux-gnu/
libglib-2.0.so.0.3800.1)
by 0x40B53C: tester_run (tester.c:784)
by 0x4034F4: main (android-tester.c:2127)
---
src/shared/io-glib.c | 45 +++++++++++++++++++++++++++++++++++++++------
1 file changed, 39 insertions(+), 6 deletions(-)
diff --git a/src/shared/io-glib.c b/src/shared/io-glib.c
index ea84a69..488b1a2 100644
--- a/src/shared/io-glib.c
+++ b/src/shared/io-glib.c
@@ -30,6 +30,7 @@
#include "src/shared/io.h"
struct io {
+ int ref_count;
GIOChannel *channel;
guint read_watch;
io_callback_func_t read_callback;
@@ -41,6 +42,27 @@ struct io {
void *write_data;
};
+static struct io *io_ref(struct io *io)
+{
+ if (!io)
+ return NULL;
+
+ __sync_fetch_and_add(&io->ref_count, 1);
+
+ return io;
+}
+
+static void io_unref(struct io *io)
+{
+ if (!io)
+ return;
+
+ if (__sync_sub_and_fetch(&io->ref_count, 1))
+ return;
+
+ g_free(io);
+}
+
struct io *io_new(int fd)
{
struct io *io;
@@ -69,7 +91,7 @@ struct io *io_new(int fd)
io->write_destroy = NULL;
io->write_data = NULL;
- return io;
+ return io_ref(io);
}
void io_destroy(struct io *io)
@@ -77,15 +99,20 @@ void io_destroy(struct io *io)
if (!io)
return;
- if (io->read_watch > 0)
+ if (io->read_watch > 0) {
g_source_remove(io->read_watch);
+ io->read_watch = 0;
+ }
- if (io->write_watch > 0)
+ if (io->write_watch > 0) {
g_source_remove(io->write_watch);
+ io->write_watch = 0;
+ }
g_io_channel_unref(io->channel);
+ io->channel = NULL;
- g_free(io);
+ io_unref(io);
}
int io_get_fd(struct io *io)
@@ -120,6 +147,8 @@ static void read_watch_destroy(gpointer user_data)
io->read_callback = NULL;
io->read_destroy = NULL;
io->read_data = NULL;
+
+ io_unref(io);
}
static gboolean read_callback(GIOChannel *channel, GIOCondition cond,
@@ -155,7 +184,8 @@ bool io_set_read_handler(struct io *io, io_callback_func_t callback,
io->read_watch = g_io_add_watch_full(io->channel, G_PRIORITY_DEFAULT,
G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- read_callback, io, read_watch_destroy);
+ read_callback, io_ref(io),
+ read_watch_destroy);
if (io->read_watch == 0)
return false;
@@ -178,6 +208,8 @@ static void write_watch_destroy(gpointer user_data)
io->write_callback = NULL;
io->write_destroy = NULL;
io->write_data = NULL;
+
+ io_unref(io);
}
static gboolean write_callback(GIOChannel *channel, GIOCondition cond,
@@ -213,7 +245,8 @@ bool io_set_write_handler(struct io *io, io_callback_func_t callback,
io->write_watch = g_io_add_watch_full(io->channel, G_PRIORITY_DEFAULT,
G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- write_callback, io, write_watch_destroy);
+ write_callback, io_ref(io),
+ write_watch_destroy);
if (io->write_watch == 0)
return false;
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH] shared: Fix clearing of IO handlers
From: Johan Hedberg @ 2014-01-09 12:15 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1389263508-7073-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Thu, Jan 09, 2014, Szymon Janc wrote:
> If NULL callback is passed to io_set_read/write_handler don't add watch
> for it and just clear struct io memebers. This was resulting in
> write/read_callback being call in loop due to fd being never written
> or read.
> ---
> src/shared/io-glib.c | 16 ++++++++++++++--
> 1 file changed, 14 insertions(+), 2 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH 2/4] android/audio: Change mainloop handle in ipc_handler
From: Luiz Augusto von Dentz @ 2014-01-09 12:14 UTC (permalink / raw)
To: Lukasz Rymanowski
Cc: linux-bluetooth@vger.kernel.org, Szymon Janc, Johan Hedberg
In-Reply-To: <1389267956-2297-3-git-send-email-lukasz.rymanowski@tieto.com>
Hi Lukasz,
On Thu, Jan 9, 2014 at 1:45 PM, Lukasz Rymanowski
<lukasz.rymanowski@tieto.com> wrote:
> Make sure we wait 1 sec after each loop iteration.
> It is important in case of failure that we do not overload cpu.
>
> ---
> android/hal-audio.c | 5 ++---
> 1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/android/hal-audio.c b/android/hal-audio.c
> index 7a7c111..4a12bcb 100644
> --- a/android/hal-audio.c
> +++ b/android/hal-audio.c
> @@ -465,15 +465,14 @@ failed:
>
> static void *ipc_handler(void *data)
> {
> - bool done = false;
> struct pollfd pfd;
> + bool done;
>
> DBG("");
>
> - while (!done) {
> + for (done = false; !done; sleep(1)) {
This is getting bad really quickly, I did not realize there was a
sleep in it but usually the use of it means we are doing something
wrong which I suspect it has to do with either bind or listen failing
since you are executing them in a loop, in that case I would suggest
to start the listen socket on audio_open and only do the accept in the
thread.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH 1/4] android/audio: Prefix error log with "a2dp"
From: Luiz Augusto von Dentz @ 2014-01-09 12:06 UTC (permalink / raw)
To: Lukasz Rymanowski
Cc: linux-bluetooth@vger.kernel.org, Szymon Janc, Johan Hedberg
In-Reply-To: <1389267956-2297-2-git-send-email-lukasz.rymanowski@tieto.com>
Hi Lukasz,
On Thu, Jan 9, 2014 at 1:45 PM, Lukasz Rymanowski
<lukasz.rymanowski@tieto.com> wrote:
> ---
> android/hal-audio.c | 16 +++++++++-------
> 1 file changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/android/hal-audio.c b/android/hal-audio.c
> index 59a8269..7a7c111 100644
> --- a/android/hal-audio.c
> +++ b/android/hal-audio.c
> @@ -423,7 +423,8 @@ static bool create_audio_ipc(void)
> sk = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
> if (sk < 0) {
> err = errno;
> - error("Failed to create socket: %d (%s)", err, strerror(err));
> + error("a2dp: Failed to create socket: %d (%s)", err,
> + strerror(err));
> return false;
> }
>
> @@ -435,13 +436,14 @@ static bool create_audio_ipc(void)
>
> if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
> err = errno;
> - error("Failed to bind socket: %d (%s)", err, strerror(err));
> + error("a2dp: Failed to bind socket: %d (%s)", err,
> + strerror(err));
> goto failed;
> }
>
> if (listen(sk, 1) < 0) {
> err = errno;
> - error("Failed to listen on the socket: %d (%s)", err,
> + error("a2dp: Failed to listen on the socket: %d (%s)", err,
> strerror(err));
> goto failed;
> }
> @@ -449,7 +451,7 @@ static bool create_audio_ipc(void)
> audio_sk = accept(sk, NULL, NULL);
> if (audio_sk < 0) {
> err = errno;
> - error("Failed to accept socket: %d (%s)", err, strerror(err));
> + error("a2dp: Failed to accept socket: %d (%s)", err, strerror(err));
> goto failed;
> }
>
> @@ -470,7 +472,7 @@ static void *ipc_handler(void *data)
>
> while (!done) {
> if(!create_audio_ipc()) {
> - error("Failed to create listening socket");
> + error("a2dp: Failed to create listening socket");
> sleep(1);
> continue;
> }
> @@ -511,7 +513,7 @@ static int audio_open(const hw_module_t *module, const char *name,
> DBG("");
>
> if (strcmp(name, AUDIO_HARDWARE_INTERFACE)) {
> - error("interface %s not matching [%s]", name,
> + error("ad2p: interface %s not matching [%s]", name,
> AUDIO_HARDWARE_INTERFACE);
> return -EINVAL;
> }
> @@ -547,7 +549,7 @@ static int audio_open(const hw_module_t *module, const char *name,
> err = pthread_create(&ipc_th, NULL, ipc_handler, NULL);
> if (err < 0) {
> ipc_th = 0;
> - error("Failed to start Audio IPC thread: %d (%s)",
> + error("a2dp: Failed to start Audio IPC thread: %d (%s)",
> -err, strerror(-err));
> return (-err);
> }
> --
> 1.8.4
I prefer you use the term Audio as prefix e.g. Audo: Failed to start
IPC thread as this may be used for more than just A2DP.
--
Luiz Augusto von Dentz
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox