2012-03-29 13:52:53

by Ganir, Chen

[permalink] [raw]
Subject: [PATCH v4 0/4] Add DeviceInformationService plugin

From: Chen Ganir <[email protected]>

Add Device Information Service GATT Client for reading peer
device PNP_ID and store it.

This is v4 of the patch set, fixing issues raised in the mailing list

Chen Ganir (4):
Add DeviceInformation GATT Client
DeviceInfo: Add connection logic
DeviceInfo: Discover Characteristics
DeviceInfo: Read PNP ID

Makefile.am | 9 ++-
deviceinfo/deviceinfo.c | 194 +++++++++++++++++++++++++++++++++++++++++++++++
deviceinfo/deviceinfo.h | 24 ++++++
deviceinfo/main.c | 52 +++++++++++++
deviceinfo/manager.c | 82 ++++++++++++++++++++
deviceinfo/manager.h | 24 ++++++
doc/device-api.txt | 4 +
src/device.c | 33 ++++++++
src/device.h | 3 +
9 files changed, 422 insertions(+), 3 deletions(-)
create mode 100644 deviceinfo/deviceinfo.c
create mode 100644 deviceinfo/deviceinfo.h
create mode 100644 deviceinfo/main.c
create mode 100644 deviceinfo/manager.c
create mode 100644 deviceinfo/manager.h

--
1.7.4.1



2012-03-29 13:52:57

by Ganir, Chen

[permalink] [raw]
Subject: [PATCH v4 4/4] DeviceInfo: Read PNP ID

From: Chen Ganir <[email protected]>

Read the PNP ID characteristic of the DeviceInfo Service, and
store it inside the btd_device, for use by other profiles.
---
deviceinfo/deviceinfo.c | 35 +++++++++++++++++++++++++++++++++++
doc/device-api.txt | 4 ++++
src/device.c | 33 +++++++++++++++++++++++++++++++++
src/device.h | 3 +++
4 files changed, 75 insertions(+), 0 deletions(-)

diff --git a/deviceinfo/deviceinfo.c b/deviceinfo/deviceinfo.c
index af99156..113ac7e 100644
--- a/deviceinfo/deviceinfo.c
+++ b/deviceinfo/deviceinfo.c
@@ -82,6 +82,39 @@ static gint cmp_device(gconstpointer a, gconstpointer b)
return -1;
}

+static void read_pnpid_cb(guint8 status, const guint8 *pdu, guint16 len,
+ gpointer user_data)
+{
+ struct characteristic *ch = user_data;
+ uint8_t value[ATT_MAX_MTU];
+ int vlen;
+
+ if (status != 0) {
+ error("Error reading PNP_ID value: %s", att_ecode2str(status));
+ return;
+ }
+
+ if (!dec_read_resp(pdu, len, value, &vlen)) {
+ error("Error reading PNP_ID: Protocol error");
+ return;
+ }
+
+ if (vlen < 7) {
+ error("Error reading PNP_ID: Invalid pdu length received");
+ return;
+ }
+
+ device_set_pnpid(ch->d->dev,value[0],att_get_u16(&value[1]),
+ att_get_u16(&value[3]), att_get_u16(&value[5]));
+}
+
+static void process_deviceinfo_char(struct characteristic *ch)
+{
+ if (g_strcmp0(ch->attr.uuid, PNPID_UUID) == 0)
+ gatt_read_char(ch->d->attrib, ch->attr.value_handle, 0,
+ read_pnpid_cb, ch);
+}
+
static void configure_deviceinfo_cb(GSList *characteristics, guint8 status,
gpointer user_data)
{
@@ -106,6 +139,8 @@ static void configure_deviceinfo_cb(GSList *characteristics, guint8 status,
ch->d = d;

d->chars = g_slist_append(d->chars, ch);
+
+ process_deviceinfo_char(ch);
}
}
static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
diff --git a/doc/device-api.txt b/doc/device-api.txt
index e8fc314..6c1a3c7 100644
--- a/doc/device-api.txt
+++ b/doc/device-api.txt
@@ -129,6 +129,10 @@ Properties string Address [readonly]

Vendor unique numeric identifier.

+ uint16 VendorSource [readonly]
+
+ Vendor source numeric identifier.
+
uint16 Product [readonly]

Product unique numeric identifier.
diff --git a/src/device.c b/src/device.c
index 3b772ee..dad8c26 100644
--- a/src/device.c
+++ b/src/device.c
@@ -131,6 +131,7 @@ struct btd_device {
gchar *path;
char name[MAX_NAME_LENGTH + 1];
char *alias;
+ uint16_t vendor_src;
uint16_t vendor;
uint16_t product;
uint16_t version;
@@ -377,6 +378,11 @@ static DBusMessage *get_properties(DBusConnection *conn,
dict_append_entry(&dict, "Vendor", DBUS_TYPE_UINT16,
&device->vendor);

+ /* Vendor Source*/
+ if (device->vendor_src)
+ dict_append_entry(&dict, "VendorSource", DBUS_TYPE_UINT16,
+ &device->vendor_src);
+
/* Product */
if (device->product)
dict_append_entry(&dict, "Product", DBUS_TYPE_UINT16,
@@ -983,6 +989,19 @@ static void device_set_vendor(struct btd_device *device, uint16_t value)
DBUS_TYPE_UINT16, &value);
}

+static void device_set_vendor_src(struct btd_device *device, uint16_t value)
+{
+ DBusConnection *conn = get_dbus_connection();
+
+ if (device->vendor_src == value)
+ return;
+
+ device->vendor_src = value;
+
+ emit_property_changed(conn, device->path, DEVICE_INTERFACE, "VendorSource",
+ DBUS_TYPE_UINT16, &value);
+}
+
static void device_set_product(struct btd_device *device, uint16_t value)
{
DBusConnection *conn = get_dbus_connection();
@@ -1102,6 +1121,11 @@ uint16_t btd_device_get_vendor(struct btd_device *device)
return device->vendor;
}

+uint16_t btd_device_get_vendor_src(struct btd_device *device)
+{
+ return device->vendor_src;
+}
+
uint16_t btd_device_get_product(struct btd_device *device)
{
return device->product;
@@ -2992,3 +3016,12 @@ gboolean btd_device_remove_attio_callback(struct btd_device *device, guint id)

return TRUE;
}
+
+void device_set_pnpid(struct btd_device *device, uint8_t vendor_id_src,
+ uint16_t vendor_id, uint16_t product_id, uint16_t product_ver)
+{
+ device_set_vendor(device, vendor_id);
+ device_set_vendor_src(device, vendor_id_src);
+ device_set_product(device, product_id);
+ device_set_version(device, product_ver);
+}
diff --git a/src/device.h b/src/device.h
index 7cb9bb2..c7973c5 100644
--- a/src/device.h
+++ b/src/device.h
@@ -39,6 +39,7 @@ struct btd_device *device_create(DBusConnection *conn,
void device_set_name(struct btd_device *device, const char *name);
void device_get_name(struct btd_device *device, char *name, size_t len);
uint16_t btd_device_get_vendor(struct btd_device *device);
+uint16_t btd_device_get_vendor_src(struct btd_device *device);
uint16_t btd_device_get_product(struct btd_device *device);
uint16_t btd_device_get_version(struct btd_device *device);
void device_remove(struct btd_device *device, gboolean remove_stored);
@@ -120,3 +121,5 @@ int device_block(DBusConnection *conn, struct btd_device *device,
gboolean update_only);
int device_unblock(DBusConnection *conn, struct btd_device *device,
gboolean silent, gboolean update_only);
+void device_set_pnpid(struct btd_device *device, uint8_t vendor_id_src,
+ uint16_t vendor_id, uint16_t product_id, uint16_t product_ver);
--
1.7.4.1


2012-03-29 13:52:56

by Ganir, Chen

[permalink] [raw]
Subject: [PATCH v4 3/4] DeviceInfo: Discover Characteristics

From: Chen Ganir <[email protected]>

Add logic to discover all characteristics and build a
characteristic list.
---
deviceinfo/deviceinfo.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
deviceinfo/deviceinfo.h | 2 +-
deviceinfo/manager.c | 5 ++++-
3 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/deviceinfo/deviceinfo.c b/deviceinfo/deviceinfo.c
index 51eaf1f..af99156 100644
--- a/deviceinfo/deviceinfo.c
+++ b/deviceinfo/deviceinfo.c
@@ -34,17 +34,26 @@
#include "att.h"
#include "gattrib.h"
#include "gatt.h"
+#include "log.h"
#include "deviceinfo.h"

+#define PNPID_UUID "00002a50-0000-1000-8000-00805f9b34fb"

struct deviceinfo {
struct btd_device *dev; /* Device reference */
GAttrib *attrib; /* GATT connection */
guint attioid; /* Att watcher id */
+ struct att_range *svc_range; /* DeviceInfo range */
+ GSList *chars; /* Characteristics */
};

static GSList *servers = NULL;

+struct characteristic {
+ struct gatt_char attr; /* Characteristic */
+ struct deviceinfo *d; /* deviceinfo where the char belongs */
+};
+
static void deviceinfo_free(gpointer user_data)
{
struct deviceinfo *d = user_data;
@@ -55,7 +64,10 @@ static void deviceinfo_free(gpointer user_data)
if (d->attrib != NULL)
g_attrib_unref(d->attrib);

+ g_slist_free_full(d->chars, g_free);
+
btd_device_unref(d->dev);
+ g_free(d->svc_range);
g_free(d);
}

@@ -70,11 +82,40 @@ static gint cmp_device(gconstpointer a, gconstpointer b)
return -1;
}

+static void configure_deviceinfo_cb(GSList *characteristics, guint8 status,
+ gpointer user_data)
+{
+ struct deviceinfo *d = user_data;
+ GSList *l;
+
+ if (status != 0) {
+ error("Discover deviceinfo characteristics: %s",
+ att_ecode2str(status));
+ return;
+ }
+
+ for (l = characteristics; l; l = l->next) {
+ struct gatt_char *c = l->data;
+ struct characteristic *ch;
+
+ ch = g_new0(struct characteristic, 1);
+ ch->attr.handle = c->handle;
+ ch->attr.properties = c->properties;
+ ch->attr.value_handle = c->value_handle;
+ memcpy(ch->attr.uuid, c->uuid, MAX_LEN_UUID_STR + 1);
+ ch->d = d;
+
+ d->chars = g_slist_append(d->chars, ch);
+ }
+}
static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
{
struct deviceinfo *d = user_data;

d->attrib = g_attrib_ref(attrib);
+
+ gatt_discover_char(d->attrib, d->svc_range->start, d->svc_range->end,
+ NULL, configure_deviceinfo_cb, d);
}

static void attio_disconnected_cb(gpointer user_data)
@@ -85,12 +126,15 @@ static void attio_disconnected_cb(gpointer user_data)
d->attrib = NULL;
}

-int deviceinfo_register(struct btd_device *device)
+int deviceinfo_register(struct btd_device *device, struct gatt_primary *prim)
{
struct deviceinfo *d;

d = g_new0(struct deviceinfo, 1);
d->dev = btd_device_ref(device);
+ d->svc_range = g_new0(struct att_range, 1);
+ d->svc_range->start = prim->range.start;
+ d->svc_range->end = prim->range.end;

servers = g_slist_prepend(servers, d);

diff --git a/deviceinfo/deviceinfo.h b/deviceinfo/deviceinfo.h
index 0ea6ff5..7a804a5 100644
--- a/deviceinfo/deviceinfo.h
+++ b/deviceinfo/deviceinfo.h
@@ -20,5 +20,5 @@
*
*/

-int deviceinfo_register(struct btd_device *device);
+int deviceinfo_register(struct btd_device *device, struct gatt_primary *prim);
void deviceinfo_unregister(struct btd_device *device);
diff --git a/deviceinfo/manager.c b/deviceinfo/manager.c
index 025a076..c2378c2 100644
--- a/deviceinfo/manager.c
+++ b/deviceinfo/manager.c
@@ -44,6 +44,7 @@ static gint primary_uuid_cmp(gconstpointer a, gconstpointer b)

static int deviceinfo_driver_probe(struct btd_device *device, GSList *uuids)
{
+ struct gatt_primary *prim;
GSList *primaries, *l;

primaries = btd_device_get_primaries(device);
@@ -53,7 +54,9 @@ static int deviceinfo_driver_probe(struct btd_device *device, GSList *uuids)
if (l == NULL)
return -EINVAL;

- return deviceinfo_register(device);
+ prim = l->data;
+
+ return deviceinfo_register(device, prim);
}

static void deviceinfo_driver_remove(struct btd_device *device)
--
1.7.4.1


2012-03-29 13:52:55

by Ganir, Chen

[permalink] [raw]
Subject: [PATCH v4 2/4] DeviceInfo: Add connection logic

From: Chen Ganir <[email protected]>

Add connection logic to the Device Information Plugin. When the
driver is loaded, it will request a connection to the remote device
and release the connection request when destroyed.
---
deviceinfo/deviceinfo.c | 28 ++++++++++++++++++++++++++++
1 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/deviceinfo/deviceinfo.c b/deviceinfo/deviceinfo.c
index f004232..51eaf1f 100644
--- a/deviceinfo/deviceinfo.c
+++ b/deviceinfo/deviceinfo.c
@@ -29,13 +29,18 @@
#include <bluetooth/uuid.h>
#include "adapter.h"
#include "device.h"
+#include "gattrib.h"
+#include "attio.h"
#include "att.h"
#include "gattrib.h"
#include "gatt.h"
#include "deviceinfo.h"

+
struct deviceinfo {
struct btd_device *dev; /* Device reference */
+ GAttrib *attrib; /* GATT connection */
+ guint attioid; /* Att watcher id */
};

static GSList *servers = NULL;
@@ -44,6 +49,12 @@ static void deviceinfo_free(gpointer user_data)
{
struct deviceinfo *d = user_data;

+ if (d->attioid > 0)
+ btd_device_remove_attio_callback(d->dev, d->attioid);
+
+ if (d->attrib != NULL)
+ g_attrib_unref(d->attrib);
+
btd_device_unref(d->dev);
g_free(d);
}
@@ -59,6 +70,21 @@ static gint cmp_device(gconstpointer a, gconstpointer b)
return -1;
}

+static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
+{
+ struct deviceinfo *d = user_data;
+
+ d->attrib = g_attrib_ref(attrib);
+}
+
+static void attio_disconnected_cb(gpointer user_data)
+{
+ struct deviceinfo *d = user_data;
+
+ g_attrib_unref(d->attrib);
+ d->attrib = NULL;
+}
+
int deviceinfo_register(struct btd_device *device)
{
struct deviceinfo *d;
@@ -68,6 +94,8 @@ int deviceinfo_register(struct btd_device *device)

servers = g_slist_prepend(servers, d);

+ d->attioid = btd_device_add_attio_callback(device, attio_connected_cb,
+ attio_disconnected_cb, d);
return 0;
}

--
1.7.4.1


2012-03-29 13:52:54

by Ganir, Chen

[permalink] [raw]
Subject: [PATCH v4 1/4] Add DeviceInformation GATT Client

From: Chen Ganir <[email protected]>

Add the DeviceInformation GATT Client plugin skeleton.
---
Makefile.am | 9 +++--
deviceinfo/deviceinfo.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++
deviceinfo/deviceinfo.h | 24 +++++++++++++
deviceinfo/main.c | 52 ++++++++++++++++++++++++++++
deviceinfo/manager.c | 79 ++++++++++++++++++++++++++++++++++++++++++
deviceinfo/manager.h | 24 +++++++++++++
6 files changed, 272 insertions(+), 3 deletions(-)
create mode 100644 deviceinfo/deviceinfo.c
create mode 100644 deviceinfo/deviceinfo.h
create mode 100644 deviceinfo/main.c
create mode 100644 deviceinfo/manager.c
create mode 100644 deviceinfo/manager.h

diff --git a/Makefile.am b/Makefile.am
index ddc28d2..0a2a38d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -213,7 +213,8 @@ builtin_sources += health/hdp_main.c health/hdp_types.h \
endif

if GATTMODULES
-builtin_modules += thermometer alert time gatt_example proximity
+builtin_modules += thermometer alert time gatt_example proximity \
+ deviceinfo
builtin_sources += thermometer/main.c \
thermometer/manager.h thermometer/manager.c \
thermometer/thermometer.h thermometer/thermometer.c \
@@ -222,10 +223,12 @@ builtin_sources += thermometer/main.c \
plugins/gatt-example.c \
proximity/main.c proximity/manager.h proximity/manager.c \
proximity/monitor.h proximity/monitor.c \
- proximity/reporter.h proximity/reporter.c
+ proximity/reporter.h proximity/reporter.c \
+ deviceinfo/main.c \
+ deviceinfo/manager.h deviceinfo/manager.c \
+ deviceinfo/deviceinfo.h deviceinfo/deviceinfo.c
endif

-
builtin_modules += hciops mgmtops
builtin_sources += plugins/hciops.c plugins/mgmtops.c

diff --git a/deviceinfo/deviceinfo.c b/deviceinfo/deviceinfo.c
new file mode 100644
index 0000000..f004232
--- /dev/null
+++ b/deviceinfo/deviceinfo.c
@@ -0,0 +1,87 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * 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 <glib.h>
+#include <bluetooth/uuid.h>
+#include "adapter.h"
+#include "device.h"
+#include "att.h"
+#include "gattrib.h"
+#include "gatt.h"
+#include "deviceinfo.h"
+
+struct deviceinfo {
+ struct btd_device *dev; /* Device reference */
+};
+
+static GSList *servers = NULL;
+
+static void deviceinfo_free(gpointer user_data)
+{
+ struct deviceinfo *d = user_data;
+
+ btd_device_unref(d->dev);
+ g_free(d);
+}
+
+static gint cmp_device(gconstpointer a, gconstpointer b)
+{
+ const struct deviceinfo *d = a;
+ const struct btd_device *dev = b;
+
+ if (dev == d->dev)
+ return 0;
+
+ return -1;
+}
+
+int deviceinfo_register(struct btd_device *device)
+{
+ struct deviceinfo *d;
+
+ d = g_new0(struct deviceinfo, 1);
+ d->dev = btd_device_ref(device);
+
+ servers = g_slist_prepend(servers, d);
+
+ return 0;
+}
+
+void deviceinfo_unregister(struct btd_device *device)
+{
+ struct deviceinfo *d;
+ GSList *l;
+
+ l = g_slist_find_custom(servers, device, cmp_device);
+ if (l == NULL)
+ return;
+
+ d = l->data;
+ servers = g_slist_remove(servers, d);
+
+ deviceinfo_free(d);
+}
diff --git a/deviceinfo/deviceinfo.h b/deviceinfo/deviceinfo.h
new file mode 100644
index 0000000..0ea6ff5
--- /dev/null
+++ b/deviceinfo/deviceinfo.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * 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
+ *
+ */
+
+int deviceinfo_register(struct btd_device *device);
+void deviceinfo_unregister(struct btd_device *device);
diff --git a/deviceinfo/main.c b/deviceinfo/main.c
new file mode 100644
index 0000000..82ecc82
--- /dev/null
+++ b/deviceinfo/main.c
@@ -0,0 +1,52 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * 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 <glib.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include "plugin.h"
+#include "manager.h"
+#include "hcid.h"
+#include "log.h"
+
+static int deviceinfo_init(void)
+{
+ if (!main_opts.gatt_enabled) {
+ error("DIS cannot start: GATT is disabled");
+ return -ENOTSUP;
+ }
+
+ return deviceinfo_manager_init();
+}
+
+static void deviceinfo_exit(void)
+{
+ deviceinfo_manager_exit();
+}
+
+BLUETOOTH_PLUGIN_DEFINE(deviceinfo, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
+ deviceinfo_init, deviceinfo_exit)
diff --git a/deviceinfo/manager.c b/deviceinfo/manager.c
new file mode 100644
index 0000000..025a076
--- /dev/null
+++ b/deviceinfo/manager.c
@@ -0,0 +1,79 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * 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
+ *
+ */
+
+#include <glib.h>
+#include <errno.h>
+#include <bluetooth/uuid.h>
+
+#include "adapter.h"
+#include "device.h"
+#include "att.h"
+#include "gattrib.h"
+#include "gatt.h"
+#include "deviceinfo.h"
+#include "manager.h"
+
+#define DEVICE_INFORMATION_UUID "0000180a-0000-1000-8000-00805f9b34fb"
+
+static gint primary_uuid_cmp(gconstpointer a, gconstpointer b)
+{
+ const struct gatt_primary *prim = a;
+ const char *uuid = b;
+
+ return g_strcmp0(prim->uuid, uuid);
+}
+
+static int deviceinfo_driver_probe(struct btd_device *device, GSList *uuids)
+{
+ GSList *primaries, *l;
+
+ primaries = btd_device_get_primaries(device);
+
+ l = g_slist_find_custom(primaries, DEVICE_INFORMATION_UUID,
+ primary_uuid_cmp);
+ if (l == NULL)
+ return -EINVAL;
+
+ return deviceinfo_register(device);
+}
+
+static void deviceinfo_driver_remove(struct btd_device *device)
+{
+ deviceinfo_unregister(device);
+}
+
+static struct btd_device_driver deviceinfo_device_driver = {
+ .name = "deviceinfo-driver",
+ .uuids = BTD_UUIDS(DEVICE_INFORMATION_UUID),
+ .probe = deviceinfo_driver_probe,
+ .remove = deviceinfo_driver_remove
+};
+
+int deviceinfo_manager_init(void)
+{
+ return btd_register_device_driver(&deviceinfo_device_driver);
+}
+
+void deviceinfo_manager_exit(void)
+{
+ btd_unregister_device_driver(&deviceinfo_device_driver);
+}
diff --git a/deviceinfo/manager.h b/deviceinfo/manager.h
new file mode 100644
index 0000000..0f742ca
--- /dev/null
+++ b/deviceinfo/manager.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * 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
+ *
+ */
+
+int deviceinfo_manager_init(void);
+void deviceinfo_manager_exit(void);
--
1.7.4.1