Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH 1/5 v2] Add new UUID utility functions
From: Brian Gix @ 2011-03-11 18:37 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: Johan Hedberg, linux-bluetooth, Elvis Pfützenreuter
In-Reply-To: <AANLkTims=7dS56VhVQXgSgwkLQsjcu=rYL3cvrsZCfFq@mail.gmail.com>

On 3/11/2011 10:02 AM, Claudio Takahasi wrote:
> Hi Johan/Brian,
>
> On Fri, Mar 11, 2011 at 2:30 PM, Elvis Pfützenreuter<epx@signove.com>  wrote:
>> From: Claudio Takahasi<claudio.takahasi@openbossa.org>
>>
>> New UUID functions will store the UUIDs values on host order. Added
>> functions to create, compare and convert UUIDs.

[...]

>> +
>> +       memcpy(&uuid128->value.u128.data[BASE_UUID16_OFFSET],
>> +&uuid16->value.u16, sizeof(uuid16->value.u16));
>
> Are you fine with memcpy or it is better to use assignments(as
> proposed by Brian)?

Well, the memcpy does have the added advantage of being more immune to 
memory alignment issues.  These structures are all multiple of 4 bytes, 
so it probably doesn't matter, but the memcpy will place the data in the 
correct place for all supported architectures, without any danger of 
misalignment exceptions.  I'd now keep it as a memcpy.


Regards,

-- 
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply

* Re: [PATCH 1/5 v2] Add new UUID utility functions
From: Claudio Takahasi @ 2011-03-11 18:02 UTC (permalink / raw)
  To: Brian Gix, Johan Hedberg; +Cc: linux-bluetooth, Elvis Pfützenreuter
In-Reply-To: <1299853813-15753-1-git-send-email-epx@signove.com>

Hi Johan/Brian,

On Fri, Mar 11, 2011 at 2:30 PM, Elvis Pfützenreuter <epx@signove.com> wrote:
> From: Claudio Takahasi <claudio.takahasi@openbossa.org>
>
> New UUID functions will store the UUIDs values on host order. Added
> functions to create, compare and convert UUIDs.
> ---
>  Makefile.am |    6 +-
>  lib/uuid.c  |  126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/uuid.h  |   61 ++++++++++++++++++++++++++++
>  3 files changed, 190 insertions(+), 3 deletions(-)
>  create mode 100644 lib/uuid.c
>  create mode 100644 lib/uuid.h
>
> diff --git a/Makefile.am b/Makefile.am
> index 49c45c1..804ba9d 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -43,8 +43,8 @@ plugin_LTLIBRARIES =
>
>
>  lib_headers = lib/bluetooth.h lib/hci.h lib/hci_lib.h lib/mgmt.h \
> -                       lib/sco.h lib/l2cap.h lib/sdp.h lib/sdp_lib.h \
> -                               lib/rfcomm.h lib/bnep.h lib/cmtp.h lib/hidp.h
> +               lib/sco.h lib/l2cap.h lib/sdp.h lib/sdp_lib.h lib/uuid.h \
> +                       lib/rfcomm.h lib/bnep.h lib/cmtp.h lib/hidp.h
>  local_headers = $(foreach file,$(lib_headers), lib/bluetooth/$(notdir $(file)))
>
>  include_HEADERS += $(lib_headers)
> @@ -52,7 +52,7 @@ include_HEADERS += $(lib_headers)
>  lib_LTLIBRARIES += lib/libbluetooth.la
>
>  lib_libbluetooth_la_SOURCES = $(lib_headers) \
> -                                       lib/bluetooth.c lib/hci.c lib/sdp.c
> +                             lib/bluetooth.c lib/hci.c lib/sdp.c lib/uuid.c
>  lib_libbluetooth_la_LDFLAGS = -version-info 13:5:10
>  lib_libbluetooth_la_DEPENDENCIES = $(local_headers)
>
> diff --git a/lib/uuid.c b/lib/uuid.c
> new file mode 100644
> index 0000000..66ab544
> --- /dev/null
> +++ b/lib/uuid.c
> @@ -0,0 +1,126 @@
> +/*
> + *
> + *  BlueZ - Bluetooth protocol stack for Linux
> + *
> + *  Copyright (C) 2011  Nokia Corporation
> + *  Copyright (C) 2011  Marcel Holtmann <marcel@holtmann.org>
> + *
> + *
> + *  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 <string.h>
> +
> +#include "uuid.h"
> +
> +#if __BYTE_ORDER == __BIG_ENDIAN
> +static uint128_t bluetooth_base_uuid = {
> +       .data = {       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
> +                       0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }
> +};
> +
> +#define BASE_UUID16_OFFSET     2
> +#define BASE_UUID32_OFFSET     0
> +
> +#else
> +static uint128_t bluetooth_base_uuid = {
> +       .data = {       0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
> +                       0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
> +};
> +
> +#define BASE_UUID16_OFFSET     12
> +#define BASE_UUID32_OFFSET     BASE_UUID16_OFFSET
> +
> +#endif
> +
> +static void bt_uuid16_to_uuid128(const bt_uuid_t *uuid16, bt_uuid_t *uuid128)
> +{
> +       uuid128->value.u128 = bluetooth_base_uuid;
> +       uuid128->type = BT_UUID128;
> +
> +       memcpy(&uuid128->value.u128.data[BASE_UUID16_OFFSET],
> +                       &uuid16->value.u16, sizeof(uuid16->value.u16));

Are you fine with memcpy or it is better to use assignments(as
proposed by Brian)?

> +}
> +
> +static void bt_uuid32_to_uuid128(const bt_uuid_t *uuid32, bt_uuid_t *uuid128)
> +{
> +       uuid128->value.u128 = bluetooth_base_uuid;
> +       uuid128->type = BT_UUID128;
> +
> +       memcpy(&uuid128->value.u128.data[BASE_UUID32_OFFSET],
> +                               &uuid32->value.u32, sizeof(uuid32->value.u32));

Same comment here.

> +}
> +
> +static void bt_uuid2uuid128(const bt_uuid_t *uuid, bt_uuid_t *uuid128)

I will rename it to bt_uuid_to_uuid128 to follow the same name
standard of the other functions.

BR,
Claudio

> +{
> +       switch (uuid->type) {
> +       case BT_UUID128:
> +               memcpy(uuid128, uuid, sizeof(bt_uuid_t));
> +               break;
> +       case BT_UUID32:
> +               bt_uuid32_to_uuid128(uuid, uuid128);
> +               break;
> +       case BT_UUID16:
> +               bt_uuid16_to_uuid128(uuid, uuid128);
> +               break;
> +       }
> +}
> +
> +static int bt_uuid128_cmp(const bt_uuid_t *u1, const bt_uuid_t *u2)
> +{
> +       return memcmp(&u1->value.u128, &u2->value.u128, sizeof(uint128_t));
> +}
> +
> +int bt_uuid16_create(bt_uuid_t *btuuid, uint16_t value)
> +{
> +       memset(btuuid, 0, sizeof(bt_uuid_t));
> +       btuuid->type = BT_UUID16;
> +       btuuid->value.u16 = value;
> +
> +       return 0;
> +}
> +
> +int bt_uuid32_create(bt_uuid_t *btuuid, uint32_t value)
> +{
> +       memset(btuuid, 0, sizeof(bt_uuid_t));
> +       btuuid->type = BT_UUID32;
> +       btuuid->value.u32 = value;
> +
> +       return 0;
> +}
> +
> +int bt_uuid128_create(bt_uuid_t *btuuid, uint128_t value)
> +{
> +       memset(btuuid, 0, sizeof(bt_uuid_t));
> +       btuuid->type = BT_UUID128;
> +       btuuid->value.u128 = value;
> +
> +       return 0;
> +}
> +
> +int bt_uuid_cmp(const bt_uuid_t *uuid1, const bt_uuid_t *uuid2)
> +{
> +       bt_uuid_t u1, u2;
> +
> +       bt_uuid2uuid128(uuid1, &u1);
> +       bt_uuid2uuid128(uuid2, &u2);
> +
> +       return bt_uuid128_cmp(&u1, &u2);
> +}
> diff --git a/lib/uuid.h b/lib/uuid.h
> new file mode 100644
> index 0000000..bc9ca31
> --- /dev/null
> +++ b/lib/uuid.h
> @@ -0,0 +1,61 @@
> +/*
> + *
> + *  BlueZ - Bluetooth protocol stack for Linux
> + *
> + *  Copyright (C) 2011  Nokia Corporation
> + *  Copyright (C) 2011  Marcel Holtmann <marcel@holtmann.org>
> + *
> + *
> + *  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
> + *
> + */
> +
> +#ifndef __BLUETOOTH_UUID_H
> +#define __BLUETOOTH_UUID_H
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <stdint.h>
> +
> +typedef struct {
> +       uint8_t data[16];
> +} uint128_t;
> +
> +typedef struct {
> +       enum {
> +               BT_UUID16 = 16,
> +               BT_UUID32 = 32,
> +               BT_UUID128 = 128,
> +       } type;
> +       union {
> +               uint16_t  u16;
> +               uint32_t  u32;
> +               uint128_t u128;
> +       } value;
> +} bt_uuid_t;
> +
> +int bt_uuid16_create(bt_uuid_t *btuuid, uint16_t value);
> +int bt_uuid32_create(bt_uuid_t *btuuid, uint32_t value);
> +int bt_uuid128_create(bt_uuid_t *btuuid, uint128_t value);
> +
> +int bt_uuid_cmp(const bt_uuid_t *uuid1, const bt_uuid_t *uuid2);
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* __BLUETOOTH_UUID_H */
> --
> 1.7.1
>
>

^ permalink raw reply

* Re: [PATCH] Bluetooth: Increment unacked_frames count only the first transmit
From: Gustavo F. Padovan @ 2011-03-11 17:59 UTC (permalink / raw)
  To: Suraj Sumangala; +Cc: linux-bluetooth, Jothikumar.Mothilal
In-Reply-To: <1299662045-5214-1-git-send-email-suraj@atheros.com>

Hi Suraj,

* Suraj Sumangala <suraj@atheros.com> [2011-03-09 14:44:05 +0530]:

> This patch lets 'l2cap_pinfo.unacked_frames' be incremented only
> the first time a frame is transmitted.
> 
> Previously it was being incremented for retransmitted packets
> too resulting the value to cross the transmit window size.
> 
> Signed-off-by: Suraj Sumangala <suraj@atheros.com>
> ---
>  net/bluetooth/l2cap_core.c |    4 +++-
>  1 files changed, 3 insertions(+), 1 deletions(-)

Applied, thanks.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* [PATCH 4/4] Update the test-attrib test script
From: Vinicius Costa Gomes @ 2011-03-11 17:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1299865982-13601-1-git-send-email-vinicius.gomes@openbossa.org>

Now it is more similar to the other test-* scripts. And allows to
exercise more of the API.
---
 test/test-attrib |  211 +++++++++++++++++++++++++-----------------------------
 1 files changed, 97 insertions(+), 114 deletions(-)

diff --git a/test/test-attrib b/test/test-attrib
index dc3f804..1a4684e 100755
--- a/test/test-attrib
+++ b/test/test-attrib
@@ -6,119 +6,102 @@ from optparse import OptionParser, OptionValueError
 from binascii import hexlify, unhexlify
 
 import gobject
+
+import sys
 import dbus
-import dbus.service
 import dbus.mainloop.glib
-
-def handle_set_property(option, opt_str, value, parser):
-    """Handle --set-property parameter."""
-
-    char_path = parser.values.char_path
-    if not char_path:
-        raise OptionValueError, "%s requires --char-path" % opt_str
-    if len(value.split("=")) != 2:
-        raise OptionValueError, "%s must have format \"property=value\"" % opt_str
-    if not getattr(parser.values, option.dest, None):
-        setattr(parser.values, option.dest, {})
-    props = getattr(parser.values, option.dest)
-    if not props.get(char_path):
-        props[char_path] = []
-    props[char_path].append(value.split("="))
-
-def command_parse():
-    """Parse command line options."""
-
-    usage = """
-    Usage: %s [options]""" % sys.argv[0]
-    parser = OptionParser(usage=usage)
-    parser.add_option("-i", "--adapter", action="store", type="string",
-            help="Specify local adapter interface")
-    parser.add_option("--listen", action="store_true",
-            help="Listen for notifications and indications (requires policy changes)")
-    parser.add_option("--char-path", action="store", type="string",
-            help="D-Bus path for specific characteristic")
-    parser.add_option("--set-property", action="callback", type="string",
-            metavar="NAME=VALUE", callback=handle_set_property,
-            help="Set property for characteristic")
-    return parser.parse_args()
-
-def dbus_type_to_str(d):
-    """Convert a D-Bus array to a hexdump."""
-
-    if isinstance(d, dbus.Array):
-        return hexlify("".join([str(x) for x in d]))
-    else:
-        return str(d)
-
-def hexdump_to_dbus(data):
-    """Convert an hexadecimal dump to D-Bus array."""
-
-    d = [dbus.Byte(ord(i)) for i in unhexlify(data)]
-    return dbus.Array(d, signature=dbus.Signature('y'), variant_level=1)
-
-class Watcher(dbus.service.Object):
-    @dbus.service.method("org.bluez.Watcher", in_signature="oay", out_signature="")
-    def ValueChanged(self, char, newvalue):
-        print "Watcher: new value for %s: %s" % (char, dbus_type_to_str(newvalue))
-
-def handle_characteristics(char):
-    char.Discover()
-    for c in char.GetProperties()["Characteristics"]:
-        char = dbus.Interface(bus.get_object("org.bluez", c),
-                "org.bluez.Characteristic")
-
-        if options.char_path and c != options.char_path:
-            continue
-
-        if not options.set_property:
-            ret = "Characteristic: %s\nProperties:\n" % c
-            for (k, v) in char.GetProperties().iteritems():
-                ret += "\t%s: %s\n" % (k, dbus_type_to_str(v))
-            print ret
-        elif options.set_property.get(path, None):
-            for (k, v) in options.set_property[path]:
-                char2 = dbus.Interface(bus.get_object("org.bluez",
-                    path), "org.bluez.Characteristic")
-                if k == "Value":
-                    char2.SetProperty(k, hexdump_to_dbus(v))
-                else:
-                    char2.SetProperty(k, v)
-
-def handle_services(device):
-    for s in device.GetProperties()["Services"]:
-        char = dbus.Interface(bus.get_object("org.bluez", s),
-                "org.bluez.Characteristic")
-        if options.listen:
-            char.RegisterCharacteristicsWatcher(watcher_path)
-        else:
-            handle_characteristics(char)
-
-if __name__ == "__main__":
-    (options, args) = command_parse()
-
-    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-    bus = dbus.SystemBus()
-    manager = dbus.Interface(bus.get_object("org.bluez", "/"),
-            "org.bluez.Manager")
-
-    if options.adapter:
-        path = manager.FindAdapter(options.adapter)
-    else:
-        path = manager.DefaultAdapter()
-
-    adapter = dbus.Interface(bus.get_object("org.bluez", path),
-            "org.bluez.Adapter")
-
-    if options.listen:
-        watcher_path = "/test/watcher"
-        watcher = Watcher(bus, watcher_path)
-
-    for d in adapter.GetProperties()["Devices"]:
-        device = dbus.Interface(bus.get_object("org.bluez", d),
-                "org.bluez.Device")
-        handle_services(device)
-
-    if options.listen:
-        print "Waiting for incoming notifications/indications..."
-        mainloop = gobject.MainLoop()
-        mainloop.run()
+from optparse import OptionParser, make_option
+
+dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+bus = dbus.SystemBus()
+mainloop = gobject.MainLoop()
+
+manager = dbus.Interface(bus.get_object("org.bluez", "/"), "org.bluez.Manager")
+
+option_list = [
+		make_option("-i", "--device", action="store",
+				type="string", dest="dev_id"),
+		]
+parser = OptionParser(option_list=option_list)
+
+(options, args) = parser.parse_args()
+
+if options.dev_id:
+	adapter_path = manager.FindAdapter(options.dev_id)
+else:
+	adapter_path = manager.DefaultAdapter()
+
+adapter = dbus.Interface(bus.get_object("org.bluez", adapter_path),
+							"org.bluez.Adapter")
+
+if (len(args) < 1):
+	print "Usage: %s <command>" % (sys.argv[0])
+	print ""
+	print "	 list"
+	print "	 services <address>"
+	print "	 discover <service path>"
+	print "	 chars <service path>"
+	sys.exit(1)
+
+if (args[0] == "list"):
+	for path in adapter.ListDevices():
+		device = dbus.Interface(bus.get_object("org.bluez", path),
+							"org.bluez.Device")
+		devprop = device.GetProperties()
+		print "[ %s ]" % devprop["Address"]
+		for path in devprop["Services"]:
+
+			service = dbus.Interface(bus.get_object("org.bluez", path),
+									 "org.bluez.Characteristic")
+			srvprop = service.GetProperties()
+			print " * %s" % (path)
+			print "	UUID: %s" % srvprop["UUID"]
+			print "	Chars: ",
+			for char in srvprop["Characteristics"]:
+				print "%s " % char,
+			print
+			print
+		print
+	sys.exit(0)
+
+if (args[0] == "services"):
+	if (len(args) < 2):
+		print "Need address parameter"
+	else:
+		path = adapter.FindDevice(args[1])
+		device = dbus.Interface(bus.get_object("org.bluez", path),
+							"org.bluez.Device")
+		properties = device.GetProperties()
+		for path in properties["Services"]:
+			print path
+	sys.exit(0)
+
+if (args[0] == "discover"):
+	if (len(args) < 2):
+		print "Need service path parameter"
+	else:
+		service = dbus.Interface(bus.get_object("org.bluez", args[1]),
+							"org.bluez.Characteristic")
+		service.Discover()
+	sys.exit(0)
+
+if (args[0] == "chars"):
+	if (len(args) < 2):
+		print "Need service path parameter"
+	else:
+		service = dbus.Interface(bus.get_object("org.bluez", args[1]),
+								 "org.bluez.Characteristic")
+		srvprop = service.GetProperties()
+		for path in srvprop["Characteristics"]:
+			print "[ %s ]" % (path)
+			char = dbus.Interface(bus.get_object("org.bluez", path),
+								 "org.bluez.Characteristic")
+			charprop = char.GetProperties()
+			print "	Name: %s" % charprop["Name"]
+			print "	UUID: %s" % charprop["UUID"]
+			print
+		print
+	sys.exit(0)
+
+print "Unknown command"
+sys.exit(1)
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 3/4] Add Discover method to the Attribute API
From: Vinicius Costa Gomes @ 2011-03-11 17:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1299865982-13601-1-git-send-email-vinicius.gomes@openbossa.org>

---
 doc/attribute-api.txt |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/doc/attribute-api.txt b/doc/attribute-api.txt
index 23808e6..10a9a66 100644
--- a/doc/attribute-api.txt
+++ b/doc/attribute-api.txt
@@ -50,6 +50,14 @@ Methods 	dict GetProperties()
 			Returns all properties for the interface. See the
 			Properties section for the available properties.
 
+		Discover()
+
+			Discover all characteristics that belongs in this service.
+			When it returns all the characteristics paths will be
+			already registered. It will return as soon as all the
+			characteristics are discovered. After that it will try to
+			read all values.
+
 		RegisterCharacteristicsWatcher(object agent)
 
 			Register a watcher to monitor characteristic changes.
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 2/4] Fix not returning an error when Discover() fails
From: Vinicius Costa Gomes @ 2011-03-11 17:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1299865982-13601-1-git-send-email-vinicius.gomes@openbossa.org>

When the connection fails an error should be returned to inform
the user.

This adds a field to store the DBusMessage that caused the error,
so we can send the correct reply.
---
 attrib/client.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/attrib/client.c b/attrib/client.c
index 47c5d4d..e67edc2 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -59,6 +59,7 @@ struct gatt_service {
 	char *path;
 	GSList *primary;
 	GAttrib *attrib;
+	DBusMessage *msg;
 	int psm;
 	gboolean listen;
 };
@@ -335,6 +336,12 @@ static void connect_cb(GIOChannel *chan, GError *gerr, gpointer user_data)
 	struct gatt_service *gatt = user_data;
 
 	if (gerr) {
+		if (gatt->msg) {
+			DBusMessage *reply = btd_error_failed(gatt->msg,
+							gerr->message);
+			g_dbus_send_message(connection, reply);
+		}
+
 		error("%s", gerr->message);
 		goto fail;
 	}
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 1/4] Fix the behaviour of the Attribute API Discover method
From: Vinicius Costa Gomes @ 2011-03-11 17:52 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

This method returns as soons as all the characteristics
are discovered or a error happens. The old behaviour was
to return as soon as the connection was made.

Now it is safe to call GetCharacteristics() as soon as this
method returns sucessfully.

After this method returns it will try to read all the characteristics
values.
---
 attrib/client.c |   17 +++++++++++++----
 1 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/attrib/client.c b/attrib/client.c
index 17157cd..47c5d4d 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -96,6 +96,7 @@ struct characteristic {
 struct query_data {
 	struct primary *prim;
 	struct characteristic *chr;
+	DBusMessage *msg;
 	uint16_t handle;
 };
 
@@ -863,6 +864,7 @@ static void update_all_chars(gpointer data, gpointer user_data)
 static void char_discovered_cb(GSList *characteristics, guint8 status,
 							gpointer user_data)
 {
+	DBusMessage *reply;
 	struct query_data *current = user_data;
 	struct primary *prim = current->prim;
 	struct att_primary *att = prim->att;
@@ -871,8 +873,10 @@ static void char_discovered_cb(GSList *characteristics, guint8 status,
 	GSList *l;
 
 	if (status != 0) {
-		DBG("Discover all characteristics failed: %s",
-						att_ecode2str(status));
+		const char *str = att_ecode2str(status);
+
+		DBG("Discover all characteristics failed: %s", str);
+		reply = btd_error_failed(current->msg, str);
 		goto fail;
 	}
 
@@ -909,9 +913,12 @@ static void char_discovered_cb(GSList *characteristics, guint8 status,
 	store_characteristics(gatt, prim);
 	register_characteristics(prim);
 
+	reply = dbus_message_new_method_return(current->msg);
+
 	g_slist_foreach(prim->chars, update_all_chars, prim);
 
 fail:
+	g_dbus_send_message(connection, reply);
 	g_attrib_unref(gatt->attrib);
 	g_free(current);
 }
@@ -933,11 +940,12 @@ static DBusMessage *discover_char(DBusConnection *conn, DBusMessage *msg,
 
 	qchr = g_new0(struct query_data, 1);
 	qchr->prim = prim;
+	qchr->msg = dbus_message_ref(msg);
 
 	gatt_discover_char(gatt->attrib, att->start, att->end,
 						char_discovered_cb, qchr);
 
-	return dbus_message_new_method_return(msg);
+	return NULL;
 }
 
 static DBusMessage *prim_get_properties(DBusConnection *conn, DBusMessage *msg,
@@ -983,7 +991,8 @@ static DBusMessage *prim_get_properties(DBusConnection *conn, DBusMessage *msg,
 }
 
 static GDBusMethodTable prim_methods[] = {
-	{ "Discover",		"",	"",		discover_char	},
+	{ "Discover",		"",	"",		discover_char,
+						G_DBUS_METHOD_FLAG_ASYNC},
 	{ "RegisterCharacteristicsWatcher",	"o", "",
 						register_watcher	},
 	{ "UnregisterCharacteristicsWatcher",	"o", "",
-- 
1.7.4.1


^ permalink raw reply related

* Re: [PATCH] Change order of freeing contacts data in send_pull_part
From: Radoslaw Jablonski @ 2011-03-11 15:46 UTC (permalink / raw)
  To: Radoslaw Jablonski; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1299839095-12008-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

  Hi,

On 03/11/2011 12:24 PM, Radoslaw Jablonski wrote:
> Moved freeing data->contacts before asynchronous data sending
> is triggered via data->cb callback.
> This data is no longer needed anyway after vcards are generated
> and freeing it later may cause race condition (because freeing
> this data need to be handled also in phonebook_req_finalize to
> avoid memory leaks when client disconnects in the middle of
> retrieving contacts from db).
> ---
>   plugins/phonebook-tracker.c |    9 ++++++---
>   1 files changed, 6 insertions(+), 3 deletions(-)
>
Please ignore this patch - these changes are not needed in
current architecture (based on offline discussion with Johan).

BR,
Radek

^ permalink raw reply

* Re: [PATCH v2 4/4] Add detection of MAP function in OBEX requests
From: Johan Hedberg @ 2011-03-11 14:48 UTC (permalink / raw)
  To: Slawomir Bochenski; +Cc: linux-bluetooth
In-Reply-To: <AANLkTikJaxmK3pjyptv0xSfb10ivFSu49GdGRTJrXdhP@mail.gmail.com>

Hi Slawek,

On Fri, Mar 11, 2011, Slawomir Bochenski wrote:
> >> +enum messages_function_id {
> >> +     MFID_INVALID = 0,
> >> +     MFID_SET_NOTIFICATION_REGISTRATION,
> >> +     MFID_GET_FOLDER_LISTING,
> >> +     MFID_GET_MESSAGES_LISTING,
> >> +     MFID_GET_MESSAGE,
> >> +     MFID_SET_MESSAGE_STATUS,
> >> +     MFID_PUSH_MESSAGE,
> >> +     MFID_UPDATE_INBOX,
> >> +};
> >
> > Since "function" here doesn't seem to be referring to a C function but
> > to the type of request, could you call it e.g. request_type instead? Is
> > there a reason you you want to have this enum instead of e.g. storing
> > the original value of the type header?
>
> Function here refers to function as used in MAP specification (see
> chapter 5: Message Access Profile Functions). Functions in MAP are an
> abstraction above OBEX requests and types. There is one case where one
> type is used for two functions (the difference is whether it is GET or
> PUT request).
> 
> In 3 (of 9 total) cases type is used solely for selecting function, as
> there is no real object transmitted (well, to be exact the body in
> this cases consist of single filler byte).
> 
> And those MAP functions also accept input parameters and return output
> ones, so the name "function" is quite appropriate.
> 
> As checking for this MAP function called is needed in more places it
> is convenient to store it as a number instead of doing expensive
> string comparison each time.

Ok, this makes sense (this was a good chance for me to catch up on the
MAP spec ;). However only as far as the MAP core is concerned. On the
MAP back-end side the only relevant purpose of the id seems to be to
pick the right internal function to call. Therefore, I think it'd make
more sense to have these request specific functions exported by the
back-end and have the MAP core call them directly.

This would be similar to how we handle the telephony driver in BlueZ and
how the PBAP phonebook back-end is handled in obexd. I'm not saying this
as justification for the approach but just as a place to look for
examples. The main justification is to remove one unnecessary
abstraction layer (the numeric function id) and to remove the need to
fit each MAP request into the same C function signature (messages_open).

Trying to fit everything into the same mold forces you to create very
generic structs like mas_request which then end up needing a
private_data pointer (for request specific data) and all this layering
just increases the overall complexity of the code.

Johan

^ permalink raw reply

* [PATCH 5/5 v2] Add "unit test" for new UUID functions
From: Elvis Pfützenreuter @ 2011-03-11 14:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: epx
In-Reply-To: <1299853813-15753-1-git-send-email-epx@signove.com>

---
 Makefile.tools  |    6 +-
 test/uuidtest.c |  289 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 294 insertions(+), 1 deletions(-)
 create mode 100644 test/uuidtest.c

diff --git a/Makefile.tools b/Makefile.tools
index 9c43202..1a1f5a1 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -142,7 +142,8 @@ bin_PROGRAMS += test/l2test test/rctest
 noinst_PROGRAMS += test/gaptest test/sdptest test/scotest \
 			test/attest test/hstest test/avtest test/ipctest \
 					test/lmptest test/bdaddr test/agent \
-					test/btiotest test/test-textfile
+					test/btiotest test/test-textfile \
+					test/uuidtest
 
 test_hciemu_LDADD = @GLIB_LIBS@ lib/libbluetooth.la
 
@@ -175,6 +176,9 @@ test_agent_LDADD = @DBUS_LIBS@
 test_btiotest_SOURCES = test/btiotest.c btio/btio.h btio/btio.c
 test_btiotest_LDADD = @GLIB_LIBS@ lib/libbluetooth.la
 
+test_uuidtest_SOURCES = test/uuidtest.c
+test_uuidtest_LDADD = lib/libbluetooth.la
+
 test_test_textfile_SOURCES = test/test-textfile.c src/textfile.h src/textfile.c
 
 dist_man_MANS += test/rctest.1 test/hciemu.1
diff --git a/test/uuidtest.c b/test/uuidtest.c
new file mode 100644
index 0000000..9df0998
--- /dev/null
+++ b/test/uuidtest.c
@@ -0,0 +1,289 @@
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/uuid.h>
+
+const char *base = "00000000-0000-1000-8000-00805F9B34FB";
+
+uint8_t xbase[] = {0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00,
+		  0x10, 0x00,
+		  0x80, 0x00,
+		  0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
+
+uint16_t sixteen = 0x1234;
+const char *uuidsixteen128 = "00001234-0000-1000-8000-00805F9B34FB";
+const char *uuidsixteen16 = "0x1234";
+const char *uuidsixteen16a = "1234";
+
+uint8_t xuuidsixteen[] = {0x00, 0x00, 0x12, 0x34, 0x00, 0x00, 0x10, 0x00,
+			0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
+
+uint32_t thirtytwo = 0x12345678;
+const char *uuidthirtytwo32 = "0x12345678";
+const char *uuidthirtytwo32a = "12345678";
+const char *uuidthirtytwo128 = "12345678-0000-1000-8000-00805F9B34FB";
+
+uint8_t xuuidthirtytwo[] = {0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x10, 0x00,
+			0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
+
+const char *malformed[] = {
+	"0",
+	"01",
+	"012",
+	"xxxx",
+	"xxxxx",
+	"0xxxxx",
+	"0123456",
+	"012g4567",
+	"012345678",
+	"0x234567u9",
+	"01234567890",
+	"00001234-0000-1000-8000-00805F9B34F",
+	"00001234-0000-1000-8000 00805F9B34FB",
+	"00001234-0000-1000-8000-00805F9B34FBC",
+	"00001234-0000-1000-800G-00805F9B34FB",
+	NULL };
+
+int main()
+{
+	bt_uuid_t u, u2, u3, u4, u5, ub;
+	uint128_t n, i;
+	char buf[512];
+	int s;
+
+	memcpy(&n, xbase, 16);
+	ntoh128(&n, &i);
+
+	if (bt_string_to_uuid(&u, base)) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_string_to_uuid(&ub, base)) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (u.type != 128) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (ub.type != 128) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (memcmp(&u.value.u128, &i, 16) != 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (memcmp(&ub.value.u128, &i, 16) != 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (memcmp(&ub.value.u128, &u.value.u128, 16) != 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_uuid_cmp(&u, &ub) != 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	bt_uuid_to_string(&u, buf, sizeof(buf));
+	/* printf("%s\n", buf); */
+
+	if (strcasecmp(buf, base) != 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	memcpy(&n, xuuidsixteen, 16);
+	ntoh128(&n, &i);
+
+	bt_uuid16_create(&u, sixteen);
+
+	if (bt_string_to_uuid(&u2, uuidsixteen16)) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_string_to_uuid(&u3, uuidsixteen16a)) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_string_to_uuid(&u4, uuidsixteen128)) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	bt_uuid128_create(&u5, i);
+
+	if (u.type != 16) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (u.value.u16 != sixteen) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (u2.type != 16) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (u3.type != 16) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (u4.type != 128) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (u5.type != 128) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_uuid_cmp(&u, &u2) != 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_uuid_cmp(&u2, &u3) != 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_uuid_cmp(&u, &u3) != 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_uuid_cmp(&u3, &u4) != 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_uuid_cmp(&u4, &u5) != 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_uuid_cmp(&u5, &u) != 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_uuid_cmp(&u, &ub) == 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_uuid_cmp(&u5, &ub) == 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	memcpy(&n, xuuidthirtytwo, 16);
+	ntoh128(&n, &i);
+
+	bt_uuid32_create(&u, thirtytwo);
+	bt_string_to_uuid(&u2, uuidthirtytwo32);
+	bt_string_to_uuid(&u3, uuidthirtytwo32a);
+	bt_string_to_uuid(&u4, uuidthirtytwo128);
+	bt_uuid128_create(&u5, i);
+
+	/*
+	bt_uuid_to_string(&u2, buf, sizeof(buf));
+	printf("%s\n", buf);
+
+	bt_uuid_to_string(&u3, buf, sizeof(buf));
+	printf("%s\n", buf);
+
+	bt_uuid_to_string(&u4, buf, sizeof(buf));
+	printf("%s\n", buf);
+	*/
+
+	if (u.type != 32) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (u.value.u32 != thirtytwo) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (u2.type != 32) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (u3.type != 32) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (u4.type != 128) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (u5.type != 128) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_uuid_cmp(&u, &u2) != 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_uuid_cmp(&u2, &u3) != 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_uuid_cmp(&u3, &u4) != 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_uuid_cmp(&u4, &u5) != 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_uuid_cmp(&u5, &u) != 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_uuid_cmp(&u, &ub) == 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	if (bt_uuid_cmp(&u5, &ub) == 0) {
+		printf("Fail %d\n", __LINE__);
+		return 1;
+	}
+
+	for (s = 0; malformed[s]; ++s) {
+		if (bt_string_to_uuid(&u3, malformed[s]) == 0) {
+			printf("Fail %s %d\n", malformed[s], __LINE__);
+			return 1;
+		}
+	}
+
+	return 0;
+}
-- 
1.7.1


^ permalink raw reply related

* [PATCH 4/5 v2] Use new UUID functions in example GATT server
From: Elvis Pfützenreuter @ 2011-03-11 14:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: epx
In-Reply-To: <1299853813-15753-1-git-send-email-epx@signove.com>

---
 attrib/example.c |   92 ++++++++++++++++++++++++++++--------------------------
 1 files changed, 48 insertions(+), 44 deletions(-)

diff --git a/attrib/example.c b/attrib/example.c
index 395650a..fae288c 100644
--- a/attrib/example.c
+++ b/attrib/example.c
@@ -29,8 +29,7 @@
 
 #include <arpa/inet.h>
 
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
+#include <bluetooth/uuid.h>
 
 #include <glib.h>
 
@@ -70,36 +69,41 @@ static int register_attributes(void)
 	const char *manufacturer_name2 = "ACME Weighing Scales";
 	const char *serial1 = "237495-3282-A";
 	const char *serial2 = "11267-2327A00239";
-	const unsigned char char_weight_uuid[] = { 0x80, 0x88, 0xF2, 0x18, 0x90,
-		0x2C, 0x45, 0x0B, 0xB6, 0xC4, 0x62, 0x89, 0x1E, 0x8C, 0x25,
-		0xE9 };
-	const unsigned char prim_weight_uuid[] = { 0x4F, 0x0A, 0xC0, 0x96, 0x35,
-		0xD4, 0x49, 0x11, 0x96, 0x31, 0xDE, 0xA8, 0xDC, 0x74, 0xEE,
-		0xFE };
+
+	const uint128_t char_weight_uuid_btorder = {
+		.data = { 0x80, 0x88, 0xF2, 0x18, 0x90, 0x2C, 0x45, 0x0B,
+			  0xB6, 0xC4, 0x62, 0x89, 0x1E, 0x8C, 0x25, 0xE9 } };
+	const uint128_t prim_weight_uuid_btorder = {
+		.data = { 0x4F, 0x0A, 0xC0, 0x96, 0x35, 0xD4, 0x49, 0x11,
+			  0x96, 0x31, 0xDE, 0xA8, 0xDC, 0x74, 0xEE, 0xFE } };
+
+	uint128_t char_weight_uuid;
 	uint8_t atval[256];
 	uint32_t handle;
-	uuid_t uuid;
+	bt_uuid_t uuid;
 	int len;
 
+	btoh128(&char_weight_uuid_btorder, &char_weight_uuid);
+
 	/* Battery state service: primary service definition */
-	sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
+	bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
 	att_put_u16(BATTERY_STATE_SVC_UUID, &atval[0]);
 	attrib_db_add(0x0100, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
 
 	/* Battery: battery state characteristic */
-	sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
 	atval[0] = ATT_CHAR_PROPER_READ;
 	att_put_u16(0x0110, &atval[1]);
 	att_put_u16(BATTERY_STATE_UUID, &atval[3]);
 	attrib_db_add(0x0106, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
 
 	/* Battery: battery state attribute */
-	sdp_uuid16_create(&uuid, BATTERY_STATE_UUID);
+	bt_uuid16_create(&uuid, BATTERY_STATE_UUID);
 	atval[0] = 0x04;
 	attrib_db_add(0x0110, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 1);
 
 	/* Battery: Client Characteristic Configuration */
-	sdp_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
+	bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
 	atval[0] = 0x00;
 	atval[1] = 0x00;
 	attrib_db_add(0x0111, &uuid, ATT_NONE, ATT_AUTHENTICATION, atval, 2);
@@ -110,12 +114,12 @@ static int register_attributes(void)
 		sdp_handles = g_slist_prepend(sdp_handles, GUINT_TO_POINTER(handle));
 
 	/* Thermometer: primary service definition */
-	sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
+	bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
 	att_put_u16(THERM_HUMIDITY_SVC_UUID, &atval[0]);
 	attrib_db_add(0x0200, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
 
 	/* Thermometer: Include */
-	sdp_uuid16_create(&uuid, GATT_INCLUDE_UUID);
+	bt_uuid16_create(&uuid, GATT_INCLUDE_UUID);
 	att_put_u16(0x0500, &atval[0]);
 	att_put_u16(0x0504, &atval[2]);
 	att_put_u16(MANUFACTURER_SVC_UUID, &atval[4]);
@@ -128,20 +132,20 @@ static int register_attributes(void)
 	attrib_db_add(0x0202, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 6);
 
 	/* Thermometer: temperature characteristic */
-	sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
 	atval[0] = ATT_CHAR_PROPER_READ;
 	att_put_u16(0x0204, &atval[1]);
 	att_put_u16(TEMPERATURE_UUID, &atval[3]);
 	attrib_db_add(0x0203, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
 
 	/* Thermometer: temperature characteristic value */
-	sdp_uuid16_create(&uuid, TEMPERATURE_UUID);
+	bt_uuid16_create(&uuid, TEMPERATURE_UUID);
 	atval[0] = 0x8A;
 	atval[1] = 0x02;
 	attrib_db_add(0x0204, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
 
 	/* Thermometer: temperature characteristic format */
-	sdp_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID);
 	atval[0] = 0x0E;
 	atval[1] = 0xFE;
 	att_put_u16(FMT_CELSIUS_UUID, &atval[2]);
@@ -150,25 +154,25 @@ static int register_attributes(void)
 	attrib_db_add(0x0205, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 7);
 
 	/* Thermometer: characteristic user description */
-	sdp_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID);
 	len = strlen(desc_out_temp);
 	strncpy((char *) atval, desc_out_temp, len);
 	attrib_db_add(0x0206, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);
 
 	/* Thermometer: relative humidity characteristic */
-	sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
 	atval[0] = ATT_CHAR_PROPER_READ;
 	att_put_u16(0x0212, &atval[1]);
 	att_put_u16(RELATIVE_HUMIDITY_UUID, &atval[3]);
 	attrib_db_add(0x0210, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
 
 	/* Thermometer: relative humidity value */
-	sdp_uuid16_create(&uuid, RELATIVE_HUMIDITY_UUID);
+	bt_uuid16_create(&uuid, RELATIVE_HUMIDITY_UUID);
 	atval[0] = 0x27;
 	attrib_db_add(0x0212, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 1);
 
 	/* Thermometer: relative humidity characteristic format */
-	sdp_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID);
 	atval[0] = 0x04;
 	atval[1] = 0x00;
 	att_put_u16(FMT_PERCENT_UUID, &atval[2]);
@@ -177,7 +181,7 @@ static int register_attributes(void)
 	attrib_db_add(0x0213, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 8);
 
 	/* Thermometer: characteristic user description */
-	sdp_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID);
 	len = strlen(desc_out_hum);
 	strncpy((char *) atval, desc_out_hum, len);
 	attrib_db_add(0x0214, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);
@@ -188,62 +192,62 @@ static int register_attributes(void)
 		sdp_handles = g_slist_prepend(sdp_handles, GUINT_TO_POINTER(handle));
 
 	/* Secondary Service: Manufacturer Service */
-	sdp_uuid16_create(&uuid, GATT_SND_SVC_UUID);
+	bt_uuid16_create(&uuid, GATT_SND_SVC_UUID);
 	att_put_u16(MANUFACTURER_SVC_UUID, &atval[0]);
 	attrib_db_add(0x0500, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
 
 	/* Manufacturer name characteristic definition */
-	sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
 	atval[0] = ATT_CHAR_PROPER_READ;
 	att_put_u16(0x0502, &atval[1]);
 	att_put_u16(MANUFACTURER_NAME_UUID, &atval[3]);
 	attrib_db_add(0x0501, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
 
 	/* Manufacturer name characteristic value */
-	sdp_uuid16_create(&uuid, MANUFACTURER_NAME_UUID);
+	bt_uuid16_create(&uuid, MANUFACTURER_NAME_UUID);
 	len = strlen(manufacturer_name1);
 	strncpy((char *) atval, manufacturer_name1, len);
 	attrib_db_add(0x0502, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);
 
 	/* Manufacturer serial number characteristic */
-	sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
 	atval[0] = ATT_CHAR_PROPER_READ;
 	att_put_u16(0x0504, &atval[1]);
 	att_put_u16(MANUFACTURER_SERIAL_UUID, &atval[3]);
 	attrib_db_add(0x0503, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
 
 	/* Manufacturer serial number characteristic value */
-	sdp_uuid16_create(&uuid, MANUFACTURER_SERIAL_UUID);
+	bt_uuid16_create(&uuid, MANUFACTURER_SERIAL_UUID);
 	len = strlen(serial1);
 	strncpy((char *) atval, serial1, len);
 	attrib_db_add(0x0504, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);
 
 	/* Secondary Service: Manufacturer Service */
-	sdp_uuid16_create(&uuid, GATT_SND_SVC_UUID);
+	bt_uuid16_create(&uuid, GATT_SND_SVC_UUID);
 	att_put_u16(MANUFACTURER_SVC_UUID, &atval[0]);
 	attrib_db_add(0x0505, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
 
 	/* Manufacturer name characteristic definition */
-	sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
 	atval[0] = ATT_CHAR_PROPER_READ;
 	att_put_u16(0x0507, &atval[1]);
 	att_put_u16(MANUFACTURER_NAME_UUID, &atval[3]);
 	attrib_db_add(0x0506, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
 
 	/* Secondary Service: Vendor Specific Service */
-	sdp_uuid16_create(&uuid, GATT_SND_SVC_UUID);
+	bt_uuid16_create(&uuid, GATT_SND_SVC_UUID);
 	att_put_u16(VENDOR_SPECIFIC_SVC_UUID, &atval[0]);
 	attrib_db_add(0x0550, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
 
 	/* Vendor Specific Type characteristic definition */
-	sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
 	atval[0] = ATT_CHAR_PROPER_READ;
 	att_put_u16(0x0568, &atval[1]);
 	att_put_u16(VENDOR_SPECIFIC_TYPE_UUID, &atval[3]);
 	attrib_db_add(0x0560, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
 
 	/* Vendor Specific Type characteristic value */
-	sdp_uuid16_create(&uuid, VENDOR_SPECIFIC_TYPE_UUID);
+	bt_uuid16_create(&uuid, VENDOR_SPECIFIC_TYPE_UUID);
 	atval[0] = 0x56;
 	atval[1] = 0x65;
 	atval[2] = 0x6E;
@@ -253,45 +257,45 @@ static int register_attributes(void)
 	attrib_db_add(0x0568, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 6);
 
 	/* Manufacturer name attribute */
-	sdp_uuid16_create(&uuid, MANUFACTURER_NAME_UUID);
+	bt_uuid16_create(&uuid, MANUFACTURER_NAME_UUID);
 	len = strlen(manufacturer_name2);
 	strncpy((char *) atval, manufacturer_name2, len);
 	attrib_db_add(0x0507, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);
 
 	/* Characteristic: serial number */
-	sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
 	atval[0] = ATT_CHAR_PROPER_READ;
 	att_put_u16(0x0509, &atval[1]);
 	att_put_u16(MANUFACTURER_SERIAL_UUID, &atval[3]);
 	attrib_db_add(0x0508, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
 
 	/* Serial number characteristic value */
-	sdp_uuid16_create(&uuid, MANUFACTURER_SERIAL_UUID);
+	bt_uuid16_create(&uuid, MANUFACTURER_SERIAL_UUID);
 	len = strlen(serial2);
 	strncpy((char *) atval, serial2, len);
 	attrib_db_add(0x0509, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);
 
 	/* Weight service: primary service definition */
-	sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
-	memcpy(atval, prim_weight_uuid, 16);
+	bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
+	memcpy(atval, &prim_weight_uuid_btorder, 16);
 	attrib_db_add(0x0680, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 16);
 
 	/* Weight: include */
-	sdp_uuid16_create(&uuid, GATT_INCLUDE_UUID);
+	bt_uuid16_create(&uuid, GATT_INCLUDE_UUID);
 	att_put_u16(0x0505, &atval[0]);
 	att_put_u16(0x0509, &atval[2]);
 	att_put_u16(MANUFACTURER_SVC_UUID, &atval[4]);
 	attrib_db_add(0x0681, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 6);
 
 	/* Weight: characteristic */
-	sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
 	atval[0] = ATT_CHAR_PROPER_READ;
 	att_put_u16(0x0683, &atval[1]);
-	memcpy(&atval[3], char_weight_uuid, 16);
+	memcpy(&atval[3], &char_weight_uuid_btorder, 16);
 	attrib_db_add(0x0682, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 19);
 
 	/* Weight: characteristic value */
-	sdp_uuid128_create(&uuid, char_weight_uuid);
+	bt_uuid128_create(&uuid, char_weight_uuid);
 	atval[0] = 0x82;
 	atval[1] = 0x55;
 	atval[2] = 0x00;
@@ -299,7 +303,7 @@ static int register_attributes(void)
 	attrib_db_add(0x0683, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 4);
 
 	/* Weight: characteristic format */
-	sdp_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID);
 	atval[0] = 0x08;
 	atval[1] = 0xFD;
 	att_put_u16(FMT_KILOGRAM_UUID, &atval[2]);
@@ -308,7 +312,7 @@ static int register_attributes(void)
 	attrib_db_add(0x0684, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 8);
 
 	/* Weight: characteristic user description */
-	sdp_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID);
 	len = strlen(desc_weight);
 	strncpy((char *) atval, desc_weight, len);
 	attrib_db_add(0x0685, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len);
-- 
1.7.1


^ permalink raw reply related

* [PATCH 3/5 v2] Use new UUID functions in GATT
From: Elvis Pfützenreuter @ 2011-03-11 14:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: epx
In-Reply-To: <1299853813-15753-1-git-send-email-epx@signove.com>

This patch puts the new UUID functions into use for GATT-related
code, and adds some convenience functions to ATT API (att.h).
---
 attrib/att.c         |   47 +++++++++++--------------
 attrib/att.h         |   69 +++++++++++++++++++++++++++++++++----
 attrib/client.c      |   26 ++++++--------
 attrib/gatt.c        |   68 +++++++++++++++++++------------------
 attrib/gatt.h        |    4 +-
 attrib/gattrib.c     |    3 +-
 attrib/gatttool.c    |   18 ++++-----
 attrib/interactive.c |   22 +++++------
 attrib/utils.c       |    1 +
 src/adapter.c        |    1 +
 src/attrib-server.c  |   93 +++++++++++++++++++++++++------------------------
 src/attrib-server.h  |    4 +-
 src/device.c         |    1 +
 src/main.c           |    1 +
 14 files changed, 202 insertions(+), 156 deletions(-)

diff --git a/attrib/att.c b/attrib/att.c
index b96b97d..08000e0 100644
--- a/attrib/att.c
+++ b/attrib/att.c
@@ -27,8 +27,7 @@
 #include <stdlib.h>
 
 #include <bluetooth/bluetooth.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
+#include <bluetooth/uuid.h>
 
 #include <glib.h>
 
@@ -110,7 +109,7 @@ struct att_data_list *att_data_list_alloc(uint16_t num, uint16_t len)
 	return list;
 }
 
-uint16_t enc_read_by_grp_req(uint16_t start, uint16_t end, uuid_t *uuid,
+uint16_t enc_read_by_grp_req(uint16_t start, uint16_t end, bt_uuid_t *uuid,
 							uint8_t *pdu, int len)
 {
 	const uint16_t min_len = sizeof(pdu[0]) + sizeof(start) + sizeof(end);
@@ -119,9 +118,9 @@ uint16_t enc_read_by_grp_req(uint16_t start, uint16_t end, uuid_t *uuid,
 	if (!uuid)
 		return 0;
 
-	if (uuid->type == SDP_UUID16)
+	if (uuid->type == BT_UUID16)
 		length = 2;
-	else if (uuid->type == SDP_UUID128)
+	else if (uuid->type == BT_UUID128)
 		length = 16;
 	else
 		return 0;
@@ -133,16 +132,13 @@ uint16_t enc_read_by_grp_req(uint16_t start, uint16_t end, uuid_t *uuid,
 	att_put_u16(start, &pdu[1]);
 	att_put_u16(end, &pdu[3]);
 
-	if (uuid->type == SDP_UUID16)
-		att_put_u16(uuid->value.uuid16, &pdu[5]);
-	else
-		memcpy(&pdu[5], &uuid->value.uuid128, length);
+	att_put_uuid(*uuid, &pdu[5]);
 
 	return min_len + length;
 }
 
 uint16_t dec_read_by_grp_req(const uint8_t *pdu, int len, uint16_t *start,
-						uint16_t *end, uuid_t *uuid)
+						uint16_t *end, bt_uuid_t *uuid)
 {
 	const uint16_t min_len = sizeof(pdu[0]) + sizeof(*start) + sizeof(*end);
 
@@ -161,9 +157,9 @@ uint16_t dec_read_by_grp_req(const uint8_t *pdu, int len, uint16_t *start,
 	*start = att_get_u16(&pdu[1]);
 	*end = att_get_u16(&pdu[3]);
 	if (len == min_len + 2)
-		sdp_uuid16_create(uuid, att_get_u16(&pdu[5]));
+		*uuid = att_get_uuid16(&pdu[5]);
 	else
-		sdp_uuid128_create(uuid, &pdu[5]);
+		*uuid = att_get_uuid128(&pdu[5]);
 
 	return len;
 }
@@ -219,7 +215,7 @@ struct att_data_list *dec_read_by_grp_resp(const uint8_t *pdu, int len)
 	return list;
 }
 
-uint16_t enc_find_by_type_req(uint16_t start, uint16_t end, uuid_t *uuid,
+uint16_t enc_find_by_type_req(uint16_t start, uint16_t end, bt_uuid_t *uuid,
 			const uint8_t *value, int vlen, uint8_t *pdu, int len)
 {
 	uint16_t min_len = sizeof(pdu[0]) + sizeof(start) + sizeof(end) +
@@ -231,7 +227,7 @@ uint16_t enc_find_by_type_req(uint16_t start, uint16_t end, uuid_t *uuid,
 	if (!uuid)
 		return 0;
 
-	if (uuid->type != SDP_UUID16)
+	if (uuid->type != BT_UUID16)
 		return 0;
 
 	if (len < min_len)
@@ -243,7 +239,7 @@ uint16_t enc_find_by_type_req(uint16_t start, uint16_t end, uuid_t *uuid,
 	pdu[0] = ATT_OP_FIND_BY_TYPE_REQ;
 	att_put_u16(start, &pdu[1]);
 	att_put_u16(end, &pdu[3]);
-	att_put_u16(uuid->value.uuid16, &pdu[5]);
+	att_put_uuid16(*uuid, &pdu[5]);
 
 	if (vlen > 0) {
 		memcpy(&pdu[7], value, vlen);
@@ -254,7 +250,7 @@ uint16_t enc_find_by_type_req(uint16_t start, uint16_t end, uuid_t *uuid,
 }
 
 uint16_t dec_find_by_type_req(const uint8_t *pdu, int len, uint16_t *start,
-			uint16_t *end, uuid_t *uuid, uint8_t *value, int *vlen)
+		uint16_t *end, bt_uuid_t *uuid, uint8_t *value, int *vlen)
 {
 	int valuelen;
 	uint16_t min_len = sizeof(pdu[0]) + sizeof(*start) +
@@ -279,7 +275,7 @@ uint16_t dec_find_by_type_req(const uint8_t *pdu, int len, uint16_t *start,
 
 	/* Always UUID16 */
 	if (uuid)
-		sdp_uuid16_create(uuid, att_get_u16(&pdu[5]));
+		*uuid = att_get_uuid16(&pdu[5]);
 
 	valuelen = len - min_len;
 
@@ -337,7 +333,7 @@ GSList *dec_find_by_type_resp(const uint8_t *pdu, int len)
 	return matches;
 }
 
-uint16_t enc_read_by_type_req(uint16_t start, uint16_t end, uuid_t *uuid,
+uint16_t enc_read_by_type_req(uint16_t start, uint16_t end, bt_uuid_t *uuid,
 							uint8_t *pdu, int len)
 {
 	const uint16_t min_len = sizeof(pdu[0]) + sizeof(start) + sizeof(end);
@@ -346,9 +342,9 @@ uint16_t enc_read_by_type_req(uint16_t start, uint16_t end, uuid_t *uuid,
 	if (!uuid)
 		return 0;
 
-	if (uuid->type == SDP_UUID16)
+	if (uuid->type == BT_UUID16)
 		length = 2;
-	else if (uuid->type == SDP_UUID128)
+	else if (uuid->type == BT_UUID128)
 		length = 16;
 	else
 		return 0;
@@ -360,16 +356,13 @@ uint16_t enc_read_by_type_req(uint16_t start, uint16_t end, uuid_t *uuid,
 	att_put_u16(start, &pdu[1]);
 	att_put_u16(end, &pdu[3]);
 
-	if (uuid->type == SDP_UUID16)
-		att_put_u16(uuid->value.uuid16, &pdu[5]);
-	else
-		memcpy(&pdu[5], &uuid->value.uuid128, length);
+	att_put_uuid(*uuid, &pdu[5]);
 
 	return min_len + length;
 }
 
 uint16_t dec_read_by_type_req(const uint8_t *pdu, int len, uint16_t *start,
-						uint16_t *end, uuid_t *uuid)
+						uint16_t *end, bt_uuid_t *uuid)
 {
 	const uint16_t min_len = sizeof(pdu[0]) + sizeof(*start) + sizeof(*end);
 
@@ -389,9 +382,9 @@ uint16_t dec_read_by_type_req(const uint8_t *pdu, int len, uint16_t *start,
 	*end = att_get_u16(&pdu[3]);
 
 	if (len == min_len + 2)
-		sdp_uuid16_create(uuid, att_get_u16(&pdu[5]));
+		*uuid = att_get_uuid16(&pdu[5]);
 	else
-		sdp_uuid128_create(uuid, &pdu[5]);
+		*uuid = att_get_uuid128(&pdu[5]);
 
 	return len;
 }
diff --git a/attrib/att.h b/attrib/att.h
index b62f254..7a83bfa 100644
--- a/attrib/att.h
+++ b/attrib/att.h
@@ -120,7 +120,7 @@ enum {
 
 struct attribute {
 	uint16_t handle;
-	uuid_t uuid;
+	bt_uuid_t uuid;
 	int read_reqs;
 	int write_reqs;
 	uint8_t (*read_cb)(struct attribute *a, gpointer user_data);
@@ -173,6 +173,16 @@ static inline uint32_t att_get_u32(const void *ptr)
 	return btohl(bt_get_unaligned(u32_ptr));
 }
 
+static inline uint128_t att_get_u128(const void *ptr)
+{
+	const uint128_t *u128_ptr = ptr;
+	uint128_t dst;
+
+	btoh128(u128_ptr, &dst);
+
+	return dst;
+}
+
 static inline void att_put_u8(uint8_t src, void *dst)
 {
 	bt_put_unaligned(src, (uint8_t *) dst);
@@ -188,26 +198,71 @@ static inline void att_put_u32(uint32_t src, void *dst)
 	bt_put_unaligned(htobl(src), (uint32_t *) dst);
 }
 
+static inline void att_put_u128(uint128_t src, void *dst)
+{
+	uint128_t *d128 = dst;
+
+	htob128(&src, d128);
+}
+
+static inline void att_put_uuid16(bt_uuid_t src, void *dst)
+{
+	att_put_u16(src.value.u16, dst);
+}
+
+static inline void att_put_uuid128(bt_uuid_t src, void *dst)
+{
+	att_put_u128(src.value.u128, dst);
+}
+
+static inline void att_put_uuid(bt_uuid_t src, void *dst)
+{
+	if (src.type == BT_UUID16)
+		att_put_uuid16(src, dst);
+	else
+		att_put_uuid128(src, dst);
+}
+
+static inline bt_uuid_t att_get_uuid16(const void *ptr)
+{
+	bt_uuid_t uuid;
+
+	bt_uuid16_create(&uuid, att_get_u16(ptr));
+
+	return uuid;
+}
+
+static inline bt_uuid_t att_get_uuid128(const void *ptr)
+{
+	bt_uuid_t uuid;
+	uint128_t value;
+
+	value  = att_get_u128(ptr);
+	bt_uuid128_create(&uuid, value);
+
+	return uuid;
+}
+
 struct att_data_list *att_data_list_alloc(uint16_t num, uint16_t len);
 void att_data_list_free(struct att_data_list *list);
 
 const char *att_ecode2str(uint8_t status);
-uint16_t enc_read_by_grp_req(uint16_t start, uint16_t end, uuid_t *uuid,
+uint16_t enc_read_by_grp_req(uint16_t start, uint16_t end, bt_uuid_t *uuid,
 							uint8_t *pdu, int len);
 uint16_t dec_read_by_grp_req(const uint8_t *pdu, int len, uint16_t *start,
-						uint16_t *end, uuid_t *uuid);
+						uint16_t *end, bt_uuid_t *uuid);
 uint16_t enc_read_by_grp_resp(struct att_data_list *list, uint8_t *pdu, int len);
-uint16_t enc_find_by_type_req(uint16_t start, uint16_t end, uuid_t *uuid,
+uint16_t enc_find_by_type_req(uint16_t start, uint16_t end, bt_uuid_t *uuid,
 			const uint8_t *value, int vlen, uint8_t *pdu, int len);
 uint16_t dec_find_by_type_req(const uint8_t *pdu, int len, uint16_t *start,
-		uint16_t *end, uuid_t *uuid, uint8_t *value, int *vlen);
+		uint16_t *end, bt_uuid_t *uuid, uint8_t *value, int *vlen);
 uint16_t enc_find_by_type_resp(GSList *ranges, uint8_t *pdu, int len);
 GSList *dec_find_by_type_resp(const uint8_t *pdu, int len);
 struct att_data_list *dec_read_by_grp_resp(const uint8_t *pdu, int len);
-uint16_t enc_read_by_type_req(uint16_t start, uint16_t end, uuid_t *uuid,
+uint16_t enc_read_by_type_req(uint16_t start, uint16_t end, bt_uuid_t *uuid,
 							uint8_t *pdu, int len);
 uint16_t dec_read_by_type_req(const uint8_t *pdu, int len, uint16_t *start,
-						uint16_t *end, uuid_t *uuid);
+						uint16_t *end, bt_uuid_t *uuid);
 uint16_t enc_read_by_type_resp(struct att_data_list *list, uint8_t *pdu,
 								int len);
 uint16_t enc_write_cmd(uint16_t handle, const uint8_t *value, int vlen,
diff --git a/attrib/client.c b/attrib/client.c
index 17157cd..2bea9dd 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -32,15 +32,13 @@
 #include <glib.h>
 
 #include <bluetooth/bluetooth.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
+#include <bluetooth/uuid.h>
 
 #include "adapter.h"
 #include "device.h"
 #include "log.h"
 #include "gdbus.h"
 #include "error.h"
-#include "glib-helper.h"
 #include "dbus-common.h"
 #include "btio.h"
 #include "storage.h"
@@ -665,16 +663,14 @@ static void load_characteristics(gpointer data, gpointer user_data)
 static void store_attribute(struct gatt_service *gatt, uint16_t handle,
 				uint16_t type, uint8_t *value, gsize len)
 {
-	uuid_t uuid;
-	char *str, *uuidstr, *tmp;
+	bt_uuid_t uuid;
+	char *str, *tmp;
 	guint i;
 
 	str = g_malloc0(MAX_LEN_UUID_STR + len * 2 + 1);
 
-	sdp_uuid16_create(&uuid, type);
-	uuidstr = bt_uuid2string(&uuid);
-	strcpy(str, uuidstr);
-	g_free(uuidstr);
+	bt_uuid16_create(&uuid, type);
+	bt_uuid_to_string(&uuid, str, MAX_LEN_UUID_STR);
 
 	str[MAX_LEN_UUID_STR - 1] = '#';
 
@@ -770,13 +766,13 @@ static void update_char_value(guint8 status, const guint8 *pdu,
 	g_free(current);
 }
 
-static int uuid_desc16_cmp(uuid_t *uuid, guint16 desc)
+static int uuid_desc16_cmp(bt_uuid_t *uuid, guint16 desc)
 {
-	uuid_t u16;
+	bt_uuid_t u16;
 
-	sdp_uuid16_create(&u16, desc);
+	bt_uuid16_create(&u16, desc);
 
-	return sdp_uuid_cmp(uuid, &u16);
+	return bt_uuid_cmp(uuid, &u16);
 }
 
 static void descriptor_cb(guint8 status, const guint8 *pdu, guint16 plen,
@@ -799,14 +795,14 @@ static void descriptor_cb(guint8 status, const guint8 *pdu, guint16 plen,
 
 	for (i = 0; i < list->num; i++) {
 		guint16 handle;
-		uuid_t uuid;
+		bt_uuid_t uuid;
 		uint8_t *info = list->data[i];
 		struct query_data *qfmt;
 
 		handle = att_get_u16(info);
 
 		if (format == 0x01) {
-			sdp_uuid16_create(&uuid, att_get_u16(&info[2]));
+			uuid = att_get_uuid16(&info[2]);
 		} else {
 			/* Currently, only "user description" and "presentation
 			 * format" descriptors are used, and both have 16-bit
diff --git a/attrib/gatt.c b/attrib/gatt.c
index 2b0d827..befb452 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -24,8 +24,7 @@
 
 #include <stdint.h>
 #include <glib.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
+#include <bluetooth/uuid.h>
 
 #include "att.h"
 #include "gattrib.h"
@@ -33,7 +32,7 @@
 
 struct discover_primary {
 	GAttrib *attrib;
-	uuid_t uuid;
+	bt_uuid_t uuid;
 	GSList *primaries;
 	gatt_cb_t cb;
 	void *user_data;
@@ -41,7 +40,7 @@ struct discover_primary {
 
 struct discover_char {
 	GAttrib *attrib;
-	uuid_t uuid;
+	bt_uuid_t uuid;
 	uint16_t end;
 	GSList *characteristics;
 	gatt_cb_t cb;
@@ -64,31 +63,35 @@ static void discover_char_free(struct discover_char *dc)
 }
 
 static guint16 encode_discover_primary(uint16_t start, uint16_t end,
-					uuid_t *uuid, uint8_t *pdu, size_t len)
+				bt_uuid_t *uuid, uint8_t *pdu, size_t len)
 {
-	uuid_t prim;
+	bt_uuid_t prim;
 	guint16 plen;
 	uint8_t op;
 
-	sdp_uuid16_create(&prim, GATT_PRIM_SVC_UUID);
+	bt_uuid16_create(&prim, GATT_PRIM_SVC_UUID);
 
 	if (uuid == NULL) {
 		/* Discover all primary services */
 		op = ATT_OP_READ_BY_GROUP_REQ;
 		plen = enc_read_by_grp_req(start, end, &prim, pdu, len);
 	} else {
+		uint16_t u16;
+		uint128_t u128;
 		const void *value;
 		int vlen;
 
 		/* Discover primary service by service UUID */
 		op = ATT_OP_FIND_BY_TYPE_REQ;
 
-		if (uuid->type == SDP_UUID16) {
-			value = &uuid->value.uuid16;
-			vlen = sizeof(uuid->value.uuid16);
+		if (uuid->type == BT_UUID16) {
+			u16 = htobs(uuid->value.u16);
+			value = &u16;
+			vlen = sizeof(u16);
 		} else {
-			value = &uuid->value.uuid128;
-			vlen = sizeof(uuid->value.uuid128);
+			htob128(&uuid->value.u128, &u128);
+			value = &u128;
+			vlen = sizeof(u128);
 		}
 
 		plen = enc_find_by_type_req(start, end, &prim, value, vlen,
@@ -163,21 +166,20 @@ static void primary_all_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 	for (i = 0, end = 0; i < list->num; i++) {
 		const uint8_t *data = list->data[i];
 		struct att_primary *primary;
-		uuid_t u128, u16;
+		bt_uuid_t uuid;
 
 		start = att_get_u16(&data[0]);
 		end = att_get_u16(&data[2]);
 
 		if (list->len == 6) {
-			sdp_uuid16_create(&u16,
-					att_get_u16(&data[4]));
-			sdp_uuid16_to_uuid128(&u128, &u16);
-
-		} else if (list->len == 20)
-			sdp_uuid128_create(&u128, &data[4]);
-		else
+			uuid = att_get_uuid16(&data[4]);
+			bt_uuid_to_uuid128(&uuid);
+		} else if (list->len == 20) {
+			uuid = att_get_uuid128(&data[4]);
+		} else {
 			/* Skipping invalid data */
 			continue;
+		}
 
 		primary = g_try_new0(struct att_primary, 1);
 		if (!primary) {
@@ -186,7 +188,7 @@ static void primary_all_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 		}
 		primary->start = start;
 		primary->end = end;
-		sdp_uuid2strn(&u128, primary->uuid, sizeof(primary->uuid));
+		bt_uuid_to_string(&uuid, primary->uuid, sizeof(primary->uuid));
 		dp->primaries = g_slist_append(dp->primaries, primary);
 	}
 
@@ -209,7 +211,7 @@ done:
 	discover_primary_free(dp);
 }
 
-guint gatt_discover_primary(GAttrib *attrib, uuid_t *uuid, gatt_cb_t func,
+guint gatt_discover_primary(GAttrib *attrib, bt_uuid_t *uuid, gatt_cb_t func,
 							gpointer user_data)
 {
 	struct discover_primary *dp;
@@ -230,7 +232,7 @@ guint gatt_discover_primary(GAttrib *attrib, uuid_t *uuid, gatt_cb_t func,
 	dp->user_data = user_data;
 
 	if (uuid) {
-		memcpy(&dp->uuid, uuid, sizeof(uuid_t));
+		memcpy(&dp->uuid, uuid, sizeof(bt_uuid_t));
 		cb = primary_by_uuid_cb;
 	} else
 		cb = primary_all_cb;
@@ -246,7 +248,7 @@ static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 	unsigned int i, err;
 	uint8_t opdu[ATT_DEFAULT_LE_MTU];
 	guint16 oplen;
-	uuid_t uuid;
+	bt_uuid_t uuid;
 	uint16_t last = 0;
 
 	if (status) {
@@ -263,15 +265,15 @@ static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 	for (i = 0; i < list->num; i++) {
 		uint8_t *value = list->data[i];
 		struct att_char *chars;
-		uuid_t u128, u16;
+		bt_uuid_t uuid;
 
 		last = att_get_u16(value);
 
 		if (list->len == 7) {
-			sdp_uuid16_create(&u16, att_get_u16(&value[5]));
-			sdp_uuid16_to_uuid128(&u128, &u16);
+			uuid = att_get_uuid16(&value[5]);
+			bt_uuid_to_uuid128(&uuid);
 		} else
-			sdp_uuid128_create(&u128, &value[5]);
+			uuid = att_get_uuid128(&value[5]);
 
 		chars = g_try_new0(struct att_char, 1);
 		if (!chars) {
@@ -282,7 +284,7 @@ static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 		chars->handle = last;
 		chars->properties = value[2];
 		chars->value_handle = att_get_u16(&value[3]);
-		sdp_uuid2strn(&u128, chars->uuid, sizeof(chars->uuid));
+		bt_uuid_to_string(&uuid, chars->uuid, sizeof(chars->uuid));
 		dc->characteristics = g_slist_append(dc->characteristics,
 									chars);
 	}
@@ -291,7 +293,7 @@ static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 	err = 0;
 
 	if (last != 0) {
-		sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
+		bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
 
 		oplen = enc_read_by_type_req(last + 1, dc->end, &uuid, opdu,
 								sizeof(opdu));
@@ -316,9 +318,9 @@ guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
 	uint8_t pdu[ATT_DEFAULT_LE_MTU];
 	struct discover_char *dc;
 	guint16 plen;
-	uuid_t uuid;
+	bt_uuid_t uuid;
 
-	sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
 
 	plen = enc_read_by_type_req(start, end, &uuid, pdu, sizeof(pdu));
 	if (plen == 0)
@@ -338,7 +340,7 @@ guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
 }
 
 guint gatt_read_char_by_uuid(GAttrib *attrib, uint16_t start, uint16_t end,
-					uuid_t *uuid, GAttribResultFunc func,
+					bt_uuid_t *uuid, GAttribResultFunc func,
 					gpointer user_data)
 {
 	uint8_t pdu[ATT_DEFAULT_LE_MTU];
diff --git a/attrib/gatt.h b/attrib/gatt.h
index b1a46e1..730de7e 100644
--- a/attrib/gatt.h
+++ b/attrib/gatt.h
@@ -26,7 +26,7 @@
 
 typedef void (*gatt_cb_t) (GSList *l, guint8 status, gpointer user_data);
 
-guint gatt_discover_primary(GAttrib *attrib, uuid_t *uuid, gatt_cb_t func,
+guint gatt_discover_primary(GAttrib *attrib, bt_uuid_t *uuid, gatt_cb_t func,
 							gpointer user_data);
 
 guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
@@ -45,5 +45,5 @@ guint gatt_write_cmd(GAttrib *attrib, uint16_t handle, uint8_t *value, int vlen,
 				GDestroyNotify notify, gpointer user_data);
 
 guint gatt_read_char_by_uuid(GAttrib *attrib, uint16_t start, uint16_t end,
-				uuid_t *uuid, GAttribResultFunc func,
+				bt_uuid_t *uuid, GAttribResultFunc func,
 				gpointer user_data);
diff --git a/attrib/gattrib.c b/attrib/gattrib.c
index c4cfd95..07e56de 100644
--- a/attrib/gattrib.c
+++ b/attrib/gattrib.c
@@ -29,8 +29,7 @@
 #include <stdio.h>
 
 #include <bluetooth/bluetooth.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
+#include <bluetooth/uuid.h>
 
 #include "att.h"
 #include "btio.h"
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 4e344ba..729e18d 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -34,13 +34,11 @@
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/hci.h>
 #include <bluetooth/hci_lib.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
+#include <bluetooth/uuid.h>
 
 #include "att.h"
 #include "btio.h"
 #include "gattrib.h"
-#include "glib-helper.h"
 #include "gatt.h"
 #include "gatttool.h"
 
@@ -48,7 +46,7 @@ static gchar *opt_src = NULL;
 static gchar *opt_dst = NULL;
 static gchar *opt_value = NULL;
 static gchar *opt_sec_level = NULL;
-static uuid_t *opt_uuid = NULL;
+static bt_uuid_t *opt_uuid = NULL;
 static int opt_start = 0x0001;
 static int opt_end = 0xffff;
 static int opt_handle = -1;
@@ -427,17 +425,17 @@ static void char_desc_cb(guint8 status, const guint8 *pdu, guint16 plen,
 		char uuidstr[MAX_LEN_UUID_STR];
 		uint16_t handle;
 		uint8_t *value;
-		uuid_t uuid;
+		bt_uuid_t uuid;
 
 		value = list->data[i];
 		handle = att_get_u16(value);
 
 		if (format == 0x01)
-			sdp_uuid16_create(&uuid, att_get_u16(&value[2]));
+			uuid = att_get_uuid16(&value[2]);
 		else
-			sdp_uuid128_create(&uuid, &value[2]);
+			uuid = att_get_uuid128(&value[2]);
 
-		sdp_uuid2strn(&uuid, uuidstr, MAX_LEN_UUID_STR);
+		bt_uuid_to_string(&uuid, uuidstr, MAX_LEN_UUID_STR);
 		g_print("handle = 0x%04x, uuid = %s\n", handle, uuidstr);
 	}
 
@@ -463,11 +461,11 @@ static gboolean parse_uuid(const char *key, const char *value,
 	if (!value)
 		return FALSE;
 
-	opt_uuid = g_try_malloc(sizeof(uuid_t));
+	opt_uuid = g_try_malloc(sizeof(bt_uuid_t));
 	if (opt_uuid == NULL)
 		return FALSE;
 
-	if (bt_string2uuid(opt_uuid, value) < 0)
+	if (bt_string_to_uuid(opt_uuid, value) < 0)
 		return FALSE;
 
 	return TRUE;
diff --git a/attrib/interactive.c b/attrib/interactive.c
index 1d6f42d..99e99c5 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -26,8 +26,7 @@
 #include <stdio.h>
 #include <glib.h>
 
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
+#include <bluetooth/uuid.h>
 
 #include <readline/readline.h>
 #include <readline/history.h>
@@ -35,7 +34,6 @@
 #include "att.h"
 #include "btio.h"
 #include "gattrib.h"
-#include "glib-helper.h"
 #include "gatt.h"
 #include "gatttool.h"
 
@@ -54,7 +52,7 @@ struct characteristic_data {
 	uint16_t orig_start;
 	uint16_t start;
 	uint16_t end;
-	uuid_t uuid;
+	bt_uuid_t uuid;
 };
 
 static void cmd_help(int argcp, char **argvp);
@@ -237,17 +235,17 @@ static void char_desc_cb(guint8 status, const guint8 *pdu, guint16 plen,
 		char uuidstr[MAX_LEN_UUID_STR];
 		uint16_t handle;
 		uint8_t *value;
-		uuid_t uuid;
+		bt_uuid_t uuid;
 
 		value = list->data[i];
 		handle = att_get_u16(value);
 
 		if (format == 0x01)
-			sdp_uuid16_create(&uuid, att_get_u16(&value[2]));
+			uuid = att_get_uuid16(&value[2]);
 		else
-			sdp_uuid128_create(&uuid, &value[2]);
+			uuid = att_get_uuid128(&value[2]);
 
-		sdp_uuid2strn(&uuid, uuidstr, MAX_LEN_UUID_STR);
+		bt_uuid_to_string(&uuid, uuidstr, MAX_LEN_UUID_STR);
 		printf("handle: 0x%04x, uuid: %s\n", handle, uuidstr);
 	}
 
@@ -378,7 +376,7 @@ static void cmd_disconnect(int argcp, char **argvp)
 
 static void cmd_primary(int argcp, char **argvp)
 {
-	uuid_t uuid;
+	bt_uuid_t uuid;
 
 	if (conn_state != STATE_CONNECTED) {
 		printf("Command failed: disconnected\n");
@@ -390,7 +388,7 @@ static void cmd_primary(int argcp, char **argvp)
 		return;
 	}
 
-	if (bt_string2uuid(&uuid, argvp[1]) < 0) {
+	if (bt_string_to_uuid(&uuid, argvp[1]) < 0) {
 		printf("Invalid UUID\n");
 		return;
 	}
@@ -509,7 +507,7 @@ static void cmd_read_uuid(int argcp, char **argvp)
 	struct characteristic_data *char_data;
 	int start = 0x0001;
 	int end = 0xffff;
-	uuid_t uuid;
+	bt_uuid_t uuid;
 
 	if (conn_state != STATE_CONNECTED) {
 		printf("Command failed: disconnected\n");
@@ -521,7 +519,7 @@ static void cmd_read_uuid(int argcp, char **argvp)
 		return;
 	}
 
-	if (bt_string2uuid(&uuid, argvp[1]) < 0) {
+	if (bt_string_to_uuid(&uuid, argvp[1]) < 0) {
 		printf("Invalid UUID\n");
 		return;
 	}
diff --git a/attrib/utils.c b/attrib/utils.c
index 8d1ca74..5f4444a 100644
--- a/attrib/utils.c
+++ b/attrib/utils.c
@@ -27,6 +27,7 @@
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/hci.h>
 #include <bluetooth/hci_lib.h>
+#include <bluetooth/uuid.h>
 #include <bluetooth/sdp.h>
 
 #include "gattrib.h"
diff --git a/src/adapter.c b/src/adapter.c
index e8abf42..8c368fe 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -34,6 +34,7 @@
 #include <sys/ioctl.h>
 
 #include <bluetooth/bluetooth.h>
+#include <bluetooth/uuid.h>
 #include <bluetooth/sdp.h>
 #include <bluetooth/sdp_lib.h>
 
diff --git a/src/attrib-server.c b/src/attrib-server.c
index 8010f1b..8151514 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -33,6 +33,7 @@
 #include <glib.h>
 
 #include <bluetooth/bluetooth.h>
+#include <bluetooth/uuid.h>
 #include <bluetooth/sdp.h>
 #include <bluetooth/sdp_lib.h>
 
@@ -81,13 +82,13 @@ static uint32_t gap_sdp_handle = 0;
 static uint16_t name_handle = 0x0000;
 static uint16_t appearance_handle = 0x0000;
 
-static uuid_t prim_uuid = {
-			.type = SDP_UUID16,
-			.value.uuid16 = GATT_PRIM_SVC_UUID
+static bt_uuid_t prim_uuid = {
+			.type = BT_UUID16,
+			.value.u16 = GATT_PRIM_SVC_UUID
 };
-static uuid_t snd_uuid = {
-			.type = SDP_UUID16,
-			.value.uuid16 = GATT_SND_SVC_UUID
+static bt_uuid_t snd_uuid = {
+			.type = BT_UUID16,
+			.value.u16 = GATT_SND_SVC_UUID
 };
 
 static sdp_record_t *server_record_new(uuid_t *uuid, uint16_t start, uint16_t end)
@@ -199,12 +200,12 @@ static uint8_t client_set_notifications(struct attribute *attr,
 	struct attribute *last_chr_val = NULL;
 	uint16_t cfg_val;
 	uint8_t props;
-	uuid_t uuid;
+	bt_uuid_t uuid;
 	GSList *l;
 
 	cfg_val = att_get_u16(attr->data);
 
-	sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
 	for (l = database, props = 0; l != NULL; l = l->next) {
 		struct attribute *a = l->data;
 		static uint16_t handle = 0;
@@ -212,7 +213,7 @@ static uint8_t client_set_notifications(struct attribute *attr,
 		if (a->handle >= attr->handle)
 			break;
 
-		if (sdp_uuid_cmp(&a->uuid, &uuid) == 0) {
+		if (bt_uuid_cmp(&a->uuid, &uuid) == 0) {
 			props = att_get_u8(&a->data[0]);
 			handle = att_get_u16(&a->data[1]);
 			continue;
@@ -251,11 +252,11 @@ static struct attribute *client_cfg_attribute(struct gatt_channel *channel,
 						const uint8_t *value, int vlen)
 {
 	guint handle = orig_attr->handle;
-	uuid_t uuid;
+	bt_uuid_t uuid;
 	GSList *l;
 
-	sdp_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
-	if (sdp_uuid_cmp(&orig_attr->uuid, &uuid) != 0)
+	bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
+	if (bt_uuid_cmp(&orig_attr->uuid, &uuid) != 0)
 		return NULL;
 
 	/* Value is unchanged, not need to create a private copy yet */
@@ -285,7 +286,7 @@ static struct attribute *client_cfg_attribute(struct gatt_channel *channel,
 }
 
 static uint16_t read_by_group(struct gatt_channel *channel, uint16_t start,
-						uint16_t end, uuid_t *uuid,
+						uint16_t end, bt_uuid_t *uuid,
 						uint8_t *pdu, int len)
 {
 	struct att_data_list *adl;
@@ -305,8 +306,8 @@ static uint16_t read_by_group(struct gatt_channel *channel, uint16_t start,
 	 * types may be used in the Read By Group Type Request.
 	 */
 
-	if (sdp_uuid_cmp(uuid, &prim_uuid) != 0 &&
-		sdp_uuid_cmp(uuid, &snd_uuid) != 0)
+	if (bt_uuid_cmp(uuid, &prim_uuid) != 0 &&
+		bt_uuid_cmp(uuid, &snd_uuid) != 0)
 		return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ, 0x0000,
 					ATT_ECODE_UNSUPP_GRP_TYPE, pdu, len);
 
@@ -323,13 +324,13 @@ static uint16_t read_by_group(struct gatt_channel *channel, uint16_t start,
 			break;
 
 		/* The old group ends when a new one starts */
-		if (old && (sdp_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
-				sdp_uuid_cmp(&a->uuid, &snd_uuid) == 0)) {
+		if (old && (bt_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
+				bt_uuid_cmp(&a->uuid, &snd_uuid) == 0)) {
 			old->end = last_handle;
 			old = NULL;
 		}
 
-		if (sdp_uuid_cmp(&a->uuid, uuid) != 0) {
+		if (bt_uuid_cmp(&a->uuid, uuid) != 0) {
 			/* Still inside a service, update its last handle */
 			if (old)
 				last_handle = a->handle;
@@ -405,7 +406,7 @@ static uint16_t read_by_group(struct gatt_channel *channel, uint16_t start,
 }
 
 static uint16_t read_by_type(struct gatt_channel *channel, uint16_t start,
-						uint16_t end, uuid_t *uuid,
+						uint16_t end, bt_uuid_t *uuid,
 						uint8_t *pdu, int len)
 {
 	struct att_data_list *adl;
@@ -430,7 +431,7 @@ static uint16_t read_by_type(struct gatt_channel *channel, uint16_t start,
 		if (a->handle >= end)
 			break;
 
-		if (sdp_uuid_cmp(&a->uuid, uuid)  != 0)
+		if (bt_uuid_cmp(&a->uuid, uuid)  != 0)
 			continue;
 
 		status = att_check_reqs(channel, ATT_OP_READ_BY_TYPE_REQ,
@@ -495,7 +496,7 @@ static int find_info(uint16_t start, uint16_t end, uint8_t *pdu, int len)
 	struct attribute *a;
 	struct att_data_list *adl;
 	GSList *l, *info;
-	uint8_t format, last_type = SDP_UUID_UNSPEC;
+	uint8_t format, last_type = BT_UUID_UNSPEC;
 	uint16_t length, num;
 	int i;
 
@@ -512,7 +513,7 @@ static int find_info(uint16_t start, uint16_t end, uint8_t *pdu, int len)
 		if (a->handle > end)
 			break;
 
-		if (last_type == SDP_UUID_UNSPEC)
+		if (last_type == BT_UUID_UNSPEC)
 			last_type = a->uuid.type;
 
 		if (a->uuid.type != last_type)
@@ -528,10 +529,10 @@ static int find_info(uint16_t start, uint16_t end, uint8_t *pdu, int len)
 		return enc_error_resp(ATT_OP_FIND_INFO_REQ, start,
 					ATT_ECODE_ATTR_NOT_FOUND, pdu, len);
 
-	if (last_type == SDP_UUID16) {
+	if (last_type == BT_UUID16) {
 		length = 2;
 		format = 0x01;
-	} else if (last_type == SDP_UUID128) {
+	} else if (last_type == BT_UUID128) {
 		length = 16;
 		format = 0x02;
 	}
@@ -548,7 +549,7 @@ static int find_info(uint16_t start, uint16_t end, uint8_t *pdu, int len)
 		att_put_u16(a->handle, value);
 
 		/* Attribute Value */
-		memcpy(&value[2], &a->uuid.value, length);
+		att_put_uuid(a->uuid, &value[2]);
 	}
 
 	length = enc_find_info_resp(format, adl, pdu, len);
@@ -559,7 +560,7 @@ static int find_info(uint16_t start, uint16_t end, uint8_t *pdu, int len)
 	return length;
 }
 
-static int find_by_type(uint16_t start, uint16_t end, uuid_t *uuid,
+static int find_by_type(uint16_t start, uint16_t end, bt_uuid_t *uuid,
 			const uint8_t *value, int vlen, uint8_t *opdu, int mtu)
 {
 	struct attribute *a;
@@ -582,7 +583,7 @@ static int find_by_type(uint16_t start, uint16_t end, uuid_t *uuid,
 			break;
 
 		/* Primary service? Attribute value matches? */
-		if ((sdp_uuid_cmp(&a->uuid, uuid) == 0) && (a->len == vlen) &&
+		if ((bt_uuid_cmp(&a->uuid, uuid) == 0) && (a->len == vlen) &&
 					(memcmp(a->data, value, vlen) == 0)) {
 
 			range = g_new0(struct att_range, 1);
@@ -596,8 +597,8 @@ static int find_by_type(uint16_t start, uint16_t end, uuid_t *uuid,
 			/* Update the last found handle or reset the pointer
 			 * to track that a new group started: Primary or
 			 * Secondary service. */
-			if (sdp_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
-					sdp_uuid_cmp(&a->uuid, &snd_uuid) == 0)
+			if (bt_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
+					bt_uuid_cmp(&a->uuid, &snd_uuid) == 0)
 				range = NULL;
 			else
 				range->end = a->handle;
@@ -632,7 +633,7 @@ static struct attribute *find_primary_range(uint16_t start, uint16_t *end)
 
 	attrib = l->data;
 
-	if (sdp_uuid_cmp(&attrib->uuid, &prim_uuid) != 0)
+	if (bt_uuid_cmp(&attrib->uuid, &prim_uuid) != 0)
 		return NULL;
 
 	*end = start;
@@ -640,8 +641,8 @@ static struct attribute *find_primary_range(uint16_t start, uint16_t *end)
 	for (l = l->next; l; l = l->next) {
 		struct attribute *a = l->data;
 
-		if (sdp_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
-				sdp_uuid_cmp(&a->uuid, &snd_uuid) == 0)
+		if (bt_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
+				bt_uuid_cmp(&a->uuid, &snd_uuid) == 0)
 			break;
 
 		*end = a->handle;
@@ -795,7 +796,7 @@ static void channel_handler(const uint8_t *ipdu, uint16_t len,
 	struct gatt_channel *channel = user_data;
 	uint8_t opdu[ATT_MAX_MTU], value[ATT_MAX_MTU];
 	uint16_t length, start, end, mtu, offset;
-	uuid_t uuid;
+	bt_uuid_t uuid;
 	uint8_t status = 0;
 	int vlen;
 
@@ -1014,37 +1015,37 @@ static void attrib_notify_clients(struct attribute *attr)
 static gboolean register_core_services(void)
 {
 	uint8_t atval[256];
-	uuid_t uuid;
+	bt_uuid_t uuid;
 	uint16_t appearance = 0x0000;
 
 	/* GAP service: primary service definition */
-	sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
+	bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
 	att_put_u16(GENERIC_ACCESS_PROFILE_ID, &atval[0]);
 	attrib_db_add(0x0001, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
 
 	/* GAP service: device name characteristic */
 	name_handle = 0x0006;
-	sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
 	atval[0] = ATT_CHAR_PROPER_READ;
 	att_put_u16(name_handle, &atval[1]);
 	att_put_u16(GATT_CHARAC_DEVICE_NAME, &atval[3]);
 	attrib_db_add(0x0004, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
 
 	/* GAP service: device name attribute */
-	sdp_uuid16_create(&uuid, GATT_CHARAC_DEVICE_NAME);
+	bt_uuid16_create(&uuid, GATT_CHARAC_DEVICE_NAME);
 	attrib_db_add(name_handle, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
 								NULL, 0);
 
 	/* GAP service: device appearance characteristic */
 	appearance_handle = 0x0008;
-	sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
+	bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
 	atval[0] = ATT_CHAR_PROPER_READ;
 	att_put_u16(appearance_handle, &atval[1]);
 	att_put_u16(GATT_CHARAC_APPEARANCE, &atval[3]);
 	attrib_db_add(0x0007, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
 
 	/* GAP service: device appearance attribute */
-	sdp_uuid16_create(&uuid, GATT_CHARAC_APPEARANCE);
+	bt_uuid16_create(&uuid, GATT_CHARAC_APPEARANCE);
 	att_put_u16(appearance, &atval[0]);
 	attrib_db_add(appearance_handle, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
 								atval, 2);
@@ -1056,7 +1057,7 @@ static gboolean register_core_services(void)
 	}
 
 	/* GATT service: primary service definition */
-	sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
+	bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
 	att_put_u16(GENERIC_ATTRIB_PROFILE_ID, &atval[0]);
 	attrib_db_add(0x0010, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
 
@@ -1213,7 +1214,7 @@ void attrib_free_sdp(uint32_t sdp_handle)
 	remove_record_from_server(sdp_handle);
 }
 
-struct attribute *attrib_db_add(uint16_t handle, uuid_t *uuid, int read_reqs,
+struct attribute *attrib_db_add(uint16_t handle, bt_uuid_t *uuid, int read_reqs,
 				int write_reqs, const uint8_t *value, int len)
 {
 	struct attribute *a;
@@ -1222,7 +1223,7 @@ struct attribute *attrib_db_add(uint16_t handle, uuid_t *uuid, int read_reqs,
 
 	a = g_malloc0(sizeof(struct attribute) + len);
 	a->handle = handle;
-	memcpy(&a->uuid, uuid, sizeof(uuid_t));
+	memcpy(&a->uuid, uuid, sizeof(bt_uuid_t));
 	a->read_reqs = read_reqs;
 	a->write_reqs = write_reqs;
 	a->len = len;
@@ -1233,7 +1234,7 @@ struct attribute *attrib_db_add(uint16_t handle, uuid_t *uuid, int read_reqs,
 	return a;
 }
 
-int attrib_db_update(uint16_t handle, uuid_t *uuid, const uint8_t *value,
+int attrib_db_update(uint16_t handle, bt_uuid_t *uuid, const uint8_t *value,
 								int len)
 {
 	struct attribute *a;
@@ -1251,7 +1252,7 @@ int attrib_db_update(uint16_t handle, uuid_t *uuid, const uint8_t *value,
 	l->data = a;
 	a->handle = handle;
 	if (uuid != &a->uuid)
-		memcpy(&a->uuid, uuid, sizeof(uuid_t));
+		memcpy(&a->uuid, uuid, sizeof(bt_uuid_t));
 	a->len = len;
 	memcpy(a->data, value, len);
 
@@ -1279,12 +1280,12 @@ int attrib_db_del(uint16_t handle)
 
 int attrib_gap_set(uint16_t uuid, const uint8_t *value, int len)
 {
-	uuid_t u16;
+	bt_uuid_t u16;
 	uint16_t handle;
 
 	/* FIXME: Missing Privacy and Reconnection Address */
 
-	sdp_uuid16_create(&u16, uuid);
+	bt_uuid16_create(&u16, uuid);
 
 	switch (uuid) {
 	case GATT_CHARAC_DEVICE_NAME:
diff --git a/src/attrib-server.h b/src/attrib-server.h
index 85f3bdb..c03d3c5 100644
--- a/src/attrib-server.h
+++ b/src/attrib-server.h
@@ -25,9 +25,9 @@
 int attrib_server_init(void);
 void attrib_server_exit(void);
 
-struct attribute *attrib_db_add(uint16_t handle, uuid_t *uuid, int read_reqs,
+struct attribute *attrib_db_add(uint16_t handle, bt_uuid_t *uuid, int read_reqs,
 				int write_reqs, const uint8_t *value, int len);
-int attrib_db_update(uint16_t handle, uuid_t *uuid, const uint8_t *value,
+int attrib_db_update(uint16_t handle, bt_uuid_t *uuid, const uint8_t *value,
 								int len);
 int attrib_db_del(uint16_t handle);
 int attrib_gap_set(uint16_t uuid, const uint8_t *value, int len);
diff --git a/src/device.c b/src/device.c
index 529e0de..e9d9e65 100644
--- a/src/device.c
+++ b/src/device.c
@@ -35,6 +35,7 @@
 #include <errno.h>
 
 #include <bluetooth/bluetooth.h>
+#include <bluetooth/uuid.h>
 #include <bluetooth/sdp.h>
 #include <bluetooth/sdp_lib.h>
 
diff --git a/src/main.c b/src/main.c
index 1aaa181..c454327 100644
--- a/src/main.c
+++ b/src/main.c
@@ -39,6 +39,7 @@
 #include <sys/types.h>
 
 #include <bluetooth/bluetooth.h>
+#include <bluetooth/uuid.h>
 
 #include <glib.h>
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH 2/5 v2] Add more functions for new UUID handling
From: Elvis Pfützenreuter @ 2011-03-11 14:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: epx
In-Reply-To: <1299853813-15753-1-git-send-email-epx@signove.com>

This patch adds more functions that are necessary to handle
the new bt_uuid_t type, and moves basic things like
byte-swapping functions and uint128_t type to bluetooth.h.
---
 health/mcap_sync.c |   15 -----
 lib/bluetooth.h    |   54 ++++++++++++++++++
 lib/sdp.c          |   43 --------------
 lib/sdp.h          |    4 +-
 lib/uuid.c         |  159 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/uuid.h         |   12 +++-
 test/hciemu.c      |   16 -----
 7 files changed, 222 insertions(+), 81 deletions(-)

diff --git a/health/mcap_sync.c b/health/mcap_sync.c
index 6f90344..f4b005a 100644
--- a/health/mcap_sync.c
+++ b/health/mcap_sync.c
@@ -92,21 +92,6 @@ struct sync_set_data {
 	gboolean role;
 };
 
-/* Ripped from lib/sdp.c */
-
-#if __BYTE_ORDER == __BIG_ENDIAN
-#define ntoh64(x) (x)
-#else
-static inline uint64_t ntoh64(uint64_t n)
-{
-        uint64_t h;
-        uint64_t tmp = ntohl(n & 0x00000000ffffffff);
-        h = ntohl(n >> 32);
-        h |= tmp << 32;
-        return h;
-}
-#endif
-
 #define hton64(x)     ntoh64(x)
 
 static gboolean csp_caps_initialized = FALSE;
diff --git a/lib/bluetooth.h b/lib/bluetooth.h
index bc0921e..714b2c9 100644
--- a/lib/bluetooth.h
+++ b/lib/bluetooth.h
@@ -35,6 +35,7 @@ extern "C" {
 #include <string.h>
 #include <endian.h>
 #include <byteswap.h>
+#include <netinet/in.h>
 
 #ifndef AF_BLUETOOTH
 #define AF_BLUETOOTH	31
@@ -158,6 +159,59 @@ void bt_free(void *ptr);
 int bt_error(uint16_t code);
 char *bt_compidtostr(int id);
 
+typedef struct {
+	uint8_t data[16];
+} uint128_t;
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+
+#define ntoh64(x) (x)
+
+static inline void ntoh128(const uint128_t *src, uint128_t *dst)
+{
+	memcpy(dst, src, sizeof(uint128_t));
+}
+
+static inline void btoh128(const uint128_t *src, uint128_t *dst)
+{
+	int i;
+	for (i = 0; i < 16; i++)
+		dst->data[15 - i] = src->data[i];
+
+}
+
+#else
+
+static inline uint64_t ntoh64(uint64_t n)
+{
+	uint64_t h;
+	uint64_t tmp = ntohl(n & 0x00000000ffffffff);
+
+	h = ntohl(n >> 32);
+	h |= tmp << 32;
+
+	return h;
+}
+
+static inline void ntoh128(const uint128_t *src, uint128_t *dst)
+{
+	int i;
+
+	for (i = 0; i < 16; i++)
+		dst->data[15 - i] = src->data[i];
+}
+
+static inline void btoh128(const uint128_t *src, uint128_t *dst)
+{
+	memcpy(dst, src, sizeof(uint128_t));
+}
+
+#endif
+
+#define hton64(x)     ntoh64(x)
+#define hton128(x, y) ntoh128(x, y)
+#define htob128(x, y) btoh128(x, y)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/sdp.c b/lib/sdp.c
index e782aec..d24d1e2 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -60,49 +60,6 @@
 #define SDPDBG(fmt...)
 #endif
 
-#if __BYTE_ORDER == __BIG_ENDIAN
-#define ntoh64(x) (x)
-static inline void ntoh128(const uint128_t *src, uint128_t *dst)
-{
-	memcpy(dst, src, sizeof(uint128_t));
-}
-
-static inline void btoh128(const uint128_t *src, uint128_t *dst)
-{
-	int i;
-	for (i = 0; i < 16; i++)
-		dst->data[15 - i] = src->data[i];
-
-}
-
-#else
-static inline uint64_t ntoh64(uint64_t n)
-{
-	uint64_t h;
-	uint64_t tmp = ntohl(n & 0x00000000ffffffff);
-	h = ntohl(n >> 32);
-	h |= tmp << 32;
-	return h;
-}
-
-static inline void ntoh128(const uint128_t *src, uint128_t *dst)
-{
-	int i;
-	for (i = 0; i < 16; i++)
-		dst->data[15 - i] = src->data[i];
-}
-
-static inline void btoh128(const uint128_t *src, uint128_t *dst)
-{
-	memcpy(dst, src, sizeof(uint128_t));
-}
-
-#endif
-
-#define hton64(x)     ntoh64(x)
-#define hton128(x, y) ntoh128(x, y)
-#define htob128(x, y) btoh128(x, y)
-
 #define BASE_UUID "00000000-0000-1000-8000-00805F9B34FB"
 
 static uint128_t bluetooth_base_uuid = {
diff --git a/lib/sdp.h b/lib/sdp.h
index f0758b2..5f7d271 100644
--- a/lib/sdp.h
+++ b/lib/sdp.h
@@ -32,6 +32,7 @@ extern "C" {
 #endif
 
 #include <stdint.h>
+#include <bluetooth/bluetooth.h>
 
 #define SDP_UNIX_PATH "/var/run/sdp"
 #define SDP_RESPONSE_TIMEOUT	20
@@ -420,9 +421,6 @@ typedef struct {
  * Common definitions for attributes in the SDP.
  * Should the type of any of these change, you need only make a change here.
  */
-typedef struct {
-	uint8_t data[16];
-} uint128_t;
 
 typedef struct {
 	uint8_t type;
diff --git a/lib/uuid.c b/lib/uuid.c
index 66ab544..90b42cc 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -27,6 +27,8 @@
 #endif
 
 #include <string.h>
+#include <stdlib.h>
+#include <errno.h>
 
 #include "uuid.h"
 
@@ -73,6 +75,7 @@ static void bt_uuid2uuid128(const bt_uuid_t *uuid, bt_uuid_t *uuid128)
 	switch (uuid->type) {
 	case BT_UUID128:
 		memcpy(uuid128, uuid, sizeof(bt_uuid_t));
+		uuid128->type = BT_UUID128;
 		break;
 	case BT_UUID32:
 		bt_uuid32_to_uuid128(uuid, uuid128);
@@ -80,9 +83,22 @@ static void bt_uuid2uuid128(const bt_uuid_t *uuid, bt_uuid_t *uuid128)
 	case BT_UUID16:
 		bt_uuid16_to_uuid128(uuid, uuid128);
 		break;
+	default:
+		break;
 	}
 }
 
+void bt_uuid_to_uuid128(bt_uuid_t *uuid)
+{
+	bt_uuid_t orig;
+
+	if (uuid->type == BT_UUID128)
+		return;
+
+	memcpy(&orig, uuid, sizeof(bt_uuid_t));
+	bt_uuid2uuid128(&orig, uuid);
+}
+
 static int bt_uuid128_cmp(const bt_uuid_t *u1, const bt_uuid_t *u2)
 {
 	return memcmp(&u1->value.u128, &u2->value.u128, sizeof(uint128_t));
@@ -124,3 +140,146 @@ int bt_uuid_cmp(const bt_uuid_t *uuid1, const bt_uuid_t *uuid2)
 
 	return bt_uuid128_cmp(&u1, &u2);
 }
+
+/*
+ * convert the UUID to string, copying a maximum of n characters.
+ */
+int bt_uuid_to_string(const bt_uuid_t *uuid, char *str, size_t n)
+{
+	if (!uuid) {
+		snprintf(str, n, "NULL");
+		return -EINVAL;
+	}
+
+	switch (uuid->type) {
+	case BT_UUID16:
+		snprintf(str, n, "%.4x", uuid->value.u16);
+		break;
+	case BT_UUID32:
+		snprintf(str, n, "%.8x", uuid->value.u32);
+		break;
+	case BT_UUID128: {
+		unsigned int   data0;
+		unsigned short data1;
+		unsigned short data2;
+		unsigned short data3;
+		unsigned int   data4;
+		unsigned short data5;
+
+		uint128_t nvalue;
+		const uint8_t *data = (uint8_t *) &nvalue;
+
+		hton128(&uuid->value.u128, &nvalue);
+
+		memcpy(&data0, &data[0], 4);
+		memcpy(&data1, &data[4], 2);
+		memcpy(&data2, &data[6], 2);
+		memcpy(&data3, &data[8], 2);
+		memcpy(&data4, &data[10], 4);
+		memcpy(&data5, &data[14], 2);
+
+		snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
+				ntohl(data0), ntohs(data1),
+				ntohs(data2), ntohs(data3),
+				ntohl(data4), ntohs(data5));
+		}
+		break;
+	default:
+		snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type);
+		return -EINVAL;	/* Enum type of UUID not set */
+	}
+
+	return 0;
+}
+
+static inline int is_uuid128(const char *string)
+{
+	return (strlen(string) == 36 &&
+			string[8] == '-' &&
+			string[13] == '-' &&
+			string[18] == '-' &&
+			string[23] == '-');
+}
+
+static inline int is_uuid32(const char *string)
+{
+	return (strlen(string) == 8 || strlen(string) == 10);
+}
+
+static inline int is_uuid16(const char *string)
+{
+	return (strlen(string) == 4 || strlen(string) == 6);
+}
+
+static int bt_string_to_uuid16(bt_uuid_t *uuid, const char *string)
+{
+	uint16_t u16;
+	char *endptr = NULL;
+
+	u16 = strtol(string, &endptr, 16);
+	if (endptr && *endptr == '\0') {
+		bt_uuid16_create(uuid, u16);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int bt_string_to_uuid32(bt_uuid_t *uuid, const char *string)
+{
+	uint32_t u32;
+	char *endptr = NULL;
+
+	u32 = strtol(string, &endptr, 16);
+	if (endptr && *endptr == '\0') {
+		bt_uuid32_create(uuid, u32);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int bt_string_to_uuid128(bt_uuid_t *uuid, const char *string)
+{
+	uint32_t data0, data4;
+	uint16_t data1, data2, data3, data5;
+	uint128_t n128, u128;
+	uint8_t *val = (uint8_t *) &n128;
+
+	if (sscanf(string, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
+				&data0, &data1, &data2,
+				&data3, &data4, &data5) != 6)
+		return -EINVAL;
+
+	data0 = htonl(data0);
+	data1 = htons(data1);
+	data2 = htons(data2);
+	data3 = htons(data3);
+	data4 = htonl(data4);
+	data5 = htons(data5);
+
+	memcpy(&val[0], &data0, 4);
+	memcpy(&val[4], &data1, 2);
+	memcpy(&val[6], &data2, 2);
+	memcpy(&val[8], &data3, 2);
+	memcpy(&val[10], &data4, 4);
+	memcpy(&val[14], &data5, 2);
+
+	ntoh128(&n128, &u128);
+
+	bt_uuid128_create(uuid, u128);
+
+	return 0;
+}
+
+int bt_string_to_uuid(bt_uuid_t *uuid, const char *string)
+{
+	if (is_uuid128(string))
+		return bt_string_to_uuid128(uuid, string);
+	else if (is_uuid32(string))
+		return bt_string_to_uuid32(uuid, string);
+	else if (is_uuid16(string))
+		return bt_string_to_uuid16(uuid, string);
+
+	return -EINVAL;
+}
diff --git a/lib/uuid.h b/lib/uuid.h
index bc9ca31..7d73625 100644
--- a/lib/uuid.h
+++ b/lib/uuid.h
@@ -30,13 +30,11 @@ extern "C" {
 #endif
 
 #include <stdint.h>
-
-typedef struct {
-	uint8_t data[16];
-} uint128_t;
+#include <bluetooth.h>
 
 typedef struct {
 	enum {
+		BT_UUID_UNSPEC = 0,
 		BT_UUID16 = 16,
 		BT_UUID32 = 32,
 		BT_UUID128 = 128,
@@ -53,6 +51,12 @@ int bt_uuid32_create(bt_uuid_t *btuuid, uint32_t value);
 int bt_uuid128_create(bt_uuid_t *btuuid, uint128_t value);
 
 int bt_uuid_cmp(const bt_uuid_t *uuid1, const bt_uuid_t *uuid2);
+void bt_uuid_to_uuid128(bt_uuid_t *uuid);
+
+#define MAX_LEN_UUID_STR 37
+
+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);
 
 #ifdef __cplusplus
 }
diff --git a/test/hciemu.c b/test/hciemu.c
index 9eed9d9..9950372 100644
--- a/test/hciemu.c
+++ b/test/hciemu.c
@@ -52,22 +52,6 @@
 
 #include <glib.h>
 
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-static inline uint64_t ntoh64(uint64_t n)
-{
-	uint64_t h;
-	uint64_t tmp = ntohl(n & 0x00000000ffffffff);
-	h = ntohl(n >> 32);
-	h |= tmp << 32;
-	return h;
-}
-#elif __BYTE_ORDER == __BIG_ENDIAN
-#define ntoh64(x) (x)
-#else
-#error "Unknown byte order"
-#endif
-#define hton64(x) ntoh64(x)
-
 #define GHCI_DEV		"/dev/ghci"
 
 #define VHCI_DEV		"/dev/vhci"
-- 
1.7.1


^ permalink raw reply related

* [PATCH 1/5 v2] Add new UUID utility functions
From: Elvis Pfützenreuter @ 2011-03-11 14:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: epx, Claudio Takahasi

From: Claudio Takahasi <claudio.takahasi@openbossa.org>

New UUID functions will store the UUIDs values on host order. Added
functions to create, compare and convert UUIDs.
---
 Makefile.am |    6 +-
 lib/uuid.c  |  126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/uuid.h  |   61 ++++++++++++++++++++++++++++
 3 files changed, 190 insertions(+), 3 deletions(-)
 create mode 100644 lib/uuid.c
 create mode 100644 lib/uuid.h

diff --git a/Makefile.am b/Makefile.am
index 49c45c1..804ba9d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -43,8 +43,8 @@ plugin_LTLIBRARIES =
 
 
 lib_headers = lib/bluetooth.h lib/hci.h lib/hci_lib.h lib/mgmt.h \
-			lib/sco.h lib/l2cap.h lib/sdp.h lib/sdp_lib.h \
-				lib/rfcomm.h lib/bnep.h lib/cmtp.h lib/hidp.h
+		lib/sco.h lib/l2cap.h lib/sdp.h lib/sdp_lib.h lib/uuid.h \
+			lib/rfcomm.h lib/bnep.h lib/cmtp.h lib/hidp.h
 local_headers = $(foreach file,$(lib_headers), lib/bluetooth/$(notdir $(file)))
 
 include_HEADERS += $(lib_headers)
@@ -52,7 +52,7 @@ include_HEADERS += $(lib_headers)
 lib_LTLIBRARIES += lib/libbluetooth.la
 
 lib_libbluetooth_la_SOURCES = $(lib_headers) \
-					lib/bluetooth.c lib/hci.c lib/sdp.c
+			      lib/bluetooth.c lib/hci.c lib/sdp.c lib/uuid.c
 lib_libbluetooth_la_LDFLAGS = -version-info 13:5:10
 lib_libbluetooth_la_DEPENDENCIES = $(local_headers)
 
diff --git a/lib/uuid.c b/lib/uuid.c
new file mode 100644
index 0000000..66ab544
--- /dev/null
+++ b/lib/uuid.c
@@ -0,0 +1,126 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2011  Nokia Corporation
+ *  Copyright (C) 2011  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  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 <string.h>
+
+#include "uuid.h"
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+static uint128_t bluetooth_base_uuid = {
+	.data = {	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+			0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }
+};
+
+#define BASE_UUID16_OFFSET	2
+#define BASE_UUID32_OFFSET	0
+
+#else
+static uint128_t bluetooth_base_uuid = {
+	.data = {	0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
+			0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+};
+
+#define BASE_UUID16_OFFSET	12
+#define BASE_UUID32_OFFSET	BASE_UUID16_OFFSET
+
+#endif
+
+static void bt_uuid16_to_uuid128(const bt_uuid_t *uuid16, bt_uuid_t *uuid128)
+{
+	uuid128->value.u128 = bluetooth_base_uuid;
+	uuid128->type = BT_UUID128;
+
+	memcpy(&uuid128->value.u128.data[BASE_UUID16_OFFSET],
+			&uuid16->value.u16, sizeof(uuid16->value.u16));
+}
+
+static void bt_uuid32_to_uuid128(const bt_uuid_t *uuid32, bt_uuid_t *uuid128)
+{
+	uuid128->value.u128 = bluetooth_base_uuid;
+	uuid128->type = BT_UUID128;
+
+	memcpy(&uuid128->value.u128.data[BASE_UUID32_OFFSET],
+				&uuid32->value.u32, sizeof(uuid32->value.u32));
+}
+
+static void bt_uuid2uuid128(const bt_uuid_t *uuid, bt_uuid_t *uuid128)
+{
+	switch (uuid->type) {
+	case BT_UUID128:
+		memcpy(uuid128, uuid, sizeof(bt_uuid_t));
+		break;
+	case BT_UUID32:
+		bt_uuid32_to_uuid128(uuid, uuid128);
+		break;
+	case BT_UUID16:
+		bt_uuid16_to_uuid128(uuid, uuid128);
+		break;
+	}
+}
+
+static int bt_uuid128_cmp(const bt_uuid_t *u1, const bt_uuid_t *u2)
+{
+	return memcmp(&u1->value.u128, &u2->value.u128, sizeof(uint128_t));
+}
+
+int bt_uuid16_create(bt_uuid_t *btuuid, uint16_t value)
+{
+	memset(btuuid, 0, sizeof(bt_uuid_t));
+	btuuid->type = BT_UUID16;
+	btuuid->value.u16 = value;
+
+	return 0;
+}
+
+int bt_uuid32_create(bt_uuid_t *btuuid, uint32_t value)
+{
+	memset(btuuid, 0, sizeof(bt_uuid_t));
+	btuuid->type = BT_UUID32;
+	btuuid->value.u32 = value;
+
+	return 0;
+}
+
+int bt_uuid128_create(bt_uuid_t *btuuid, uint128_t value)
+{
+	memset(btuuid, 0, sizeof(bt_uuid_t));
+	btuuid->type = BT_UUID128;
+	btuuid->value.u128 = value;
+
+	return 0;
+}
+
+int bt_uuid_cmp(const bt_uuid_t *uuid1, const bt_uuid_t *uuid2)
+{
+	bt_uuid_t u1, u2;
+
+	bt_uuid2uuid128(uuid1, &u1);
+	bt_uuid2uuid128(uuid2, &u2);
+
+	return bt_uuid128_cmp(&u1, &u2);
+}
diff --git a/lib/uuid.h b/lib/uuid.h
new file mode 100644
index 0000000..bc9ca31
--- /dev/null
+++ b/lib/uuid.h
@@ -0,0 +1,61 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2011  Nokia Corporation
+ *  Copyright (C) 2011  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  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
+ *
+ */
+
+#ifndef __BLUETOOTH_UUID_H
+#define __BLUETOOTH_UUID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+typedef struct {
+	uint8_t data[16];
+} uint128_t;
+
+typedef struct {
+	enum {
+		BT_UUID16 = 16,
+		BT_UUID32 = 32,
+		BT_UUID128 = 128,
+	} type;
+	union {
+		uint16_t  u16;
+		uint32_t  u32;
+		uint128_t u128;
+	} value;
+} bt_uuid_t;
+
+int bt_uuid16_create(bt_uuid_t *btuuid, uint16_t value);
+int bt_uuid32_create(bt_uuid_t *btuuid, uint32_t value);
+int bt_uuid128_create(bt_uuid_t *btuuid, uint128_t value);
+
+int bt_uuid_cmp(const bt_uuid_t *uuid1, const bt_uuid_t *uuid2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BLUETOOTH_UUID_H */
-- 
1.7.1


^ permalink raw reply related

* Re: some questions about Bluez
From: Anderson Lizardo @ 2011-03-11 13:37 UTC (permalink / raw)
  To: loody; +Cc: Arun K. Singh, linux-bluetooth, Gustavo F. Padovan
In-Reply-To: <AANLkTi=AQpgvDG_Ox5bhao3uTkFtTXAA54o8C9P-aZAA@mail.gmail.com>

Hi,

On Fri, Mar 11, 2011 at 2:25 AM, loody <miloody@gmail.com> wrote:
> I did so as below:
> ./configure --host=mipsel-linux-gnu --disable-optimization
> --disable-fortify --disable-pie --disable-network --disable-serial
> --disable-input --disable-audio --disable-service
>
> But it still try to compile ALSA.

Try adding --disable-alsa as well.

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply

* [RFC v2 6/6] Bluetooth: Add a timer to clear the advertising cache
From: Andre Guedes @ 2011-03-11 13:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andre Guedes
In-Reply-To: <1299850377-3734-1-git-send-email-andre.guedes@openbossa.org>

This patch adds a timer to clear adv_entries list after three minutes.

After some amount of time, the advertising entries cached during the
last LE scan should be considered expired and they should be removed
from the adv_entries list.

It was chosen a three minutes timeout as an initial attempt. This value
might change in future.

Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
 include/net/bluetooth/hci_core.h |    2 ++
 net/bluetooth/hci_core.c         |    9 +++++++++
 net/bluetooth/hci_event.c        |    6 +++++-
 3 files changed, 16 insertions(+), 1 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 3ead365..790f839 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -179,6 +179,7 @@ struct hci_dev {
 
 	struct list_head	adv_entries;
 	struct rw_semaphore	adv_entries_rwsem;
+	struct timer_list	adv_timer;
 
 	struct hci_dev_stats	stat;
 
@@ -517,6 +518,7 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
 						u8 *key, u8 type, u8 pin_len);
 int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
 
+#define ADV_CLEAR_TIMEOUT (3*60*HZ) /* Three minutes */
 int hci_adv_entries_clear(struct hci_dev *hdev);
 struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr);
 int hci_add_adv_entry(struct hci_dev *hdev,
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 8f9b3a5..ea8b0c2 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1081,6 +1081,13 @@ static void hci_cmd_timer(unsigned long arg)
 	tasklet_schedule(&hdev->cmd_task);
 }
 
+static void hci_adv_clear(unsigned long arg)
+{
+	struct hci_dev *hdev = (void *) arg;
+
+	hci_adv_entries_clear(hdev);
+}
+
 int hci_adv_entries_clear(struct hci_dev *hdev)
 {
 	struct list_head *p, *n;
@@ -1233,6 +1240,7 @@ int hci_register_dev(struct hci_dev *hdev)
 
 	INIT_LIST_HEAD(&hdev->adv_entries);
 	init_rwsem(&hdev->adv_entries_rwsem);
+	setup_timer(&hdev->adv_timer, hci_adv_clear, (unsigned long) hdev);
 
 	INIT_WORK(&hdev->power_on, hci_power_on);
 	INIT_WORK(&hdev->power_off, hci_power_off);
@@ -1314,6 +1322,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
 	hci_unregister_sysfs(hdev);
 
 	hci_del_off_timer(hdev);
+	del_timer(&hdev->adv_timer);
 
 	destroy_workqueue(hdev->workqueue);
 
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index fa1b43b..03b41a0 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -858,8 +858,12 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
 		return;
 
 	param_scan_enable = *((__u8 *) sent);
-	if (param_scan_enable == 0x01)
+	if (param_scan_enable == 0x01) {
+		del_timer(&hdev->adv_timer);
 		hci_adv_entries_clear(hdev);
+	} else if (param_scan_enable == 0x00) {
+		mod_timer(&hdev->adv_timer, jiffies + ADV_CLEAR_TIMEOUT);
+	}
 }
 
 static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
-- 
1.7.1


^ permalink raw reply related

* [RFC v2 5/6] Bluetooth: Clear advertising cache before scanning
From: Andre Guedes @ 2011-03-11 13:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andre Guedes
In-Reply-To: <1299850377-3734-1-git-send-email-andre.guedes@openbossa.org>

The LE advertising list should be cleared when a LE scanning is
performed. This will force the list to contain only fresh advertising
entries.

In order to achieve that, it was added a handler to the Command
Complete Event generated by the LE Set Scan Enable Command.

Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
 include/net/bluetooth/hci.h      |    2 ++
 include/net/bluetooth/hci_core.h |    1 +
 net/bluetooth/hci_core.c         |    2 +-
 net/bluetooth/hci_event.c        |   23 +++++++++++++++++++++++
 4 files changed, 27 insertions(+), 1 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index de27caa..a936592 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -670,6 +670,8 @@ struct hci_rp_le_read_buffer_size {
 	__u8     le_max_pkt;
 } __packed;
 
+#define HCI_OP_LE_SET_SCAN_ENABLE	0x200c
+
 #define HCI_OP_LE_CREATE_CONN		0x200d
 struct hci_cp_le_create_conn {
 	__le16   scan_interval;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index bf7b5df..3ead365 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -517,6 +517,7 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
 						u8 *key, u8 type, u8 pin_len);
 int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
 
+int hci_adv_entries_clear(struct hci_dev *hdev);
 struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr);
 int hci_add_adv_entry(struct hci_dev *hdev,
 					struct hci_ev_le_advertising_info *ev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 71f8788..8f9b3a5 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1081,7 +1081,7 @@ static void hci_cmd_timer(unsigned long arg)
 	tasklet_schedule(&hdev->cmd_task);
 }
 
-static int hci_adv_entries_clear(struct hci_dev *hdev)
+int hci_adv_entries_clear(struct hci_dev *hdev)
 {
 	struct list_head *p, *n;
 
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 5019b76..fa1b43b 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -843,6 +843,25 @@ static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
 }
 
+static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
+					struct sk_buff *skb)
+{
+	void *sent;
+	__u8 param_scan_enable;
+	__u8 status = *((__u8 *) skb->data);
+
+	if (status)
+		return;
+
+	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
+	if (!sent)
+		return;
+
+	param_scan_enable = *((__u8 *) sent);
+	if (param_scan_enable == 0x01)
+		hci_adv_entries_clear(hdev);
+}
+
 static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
 {
 	BT_DBG("%s status 0x%x", hdev->name, status);
@@ -1799,6 +1818,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
 		hci_cc_le_ltk_neg_reply(hdev, skb);
 		break;
 
+	case HCI_OP_LE_SET_SCAN_ENABLE:
+		hci_cc_le_set_scan_enable(hdev, skb);
+		break;
+
 	default:
 		BT_DBG("%s opcode 0x%x", hdev->name, opcode);
 		break;
-- 
1.7.1


^ permalink raw reply related

* [RFC v2 4/6] Bluetooth: Check advertising cache in hci_connect()
From: Andre Guedes @ 2011-03-11 13:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andre Guedes
In-Reply-To: <1299850377-3734-1-git-send-email-andre.guedes@openbossa.org>

When connecting to a LE device, we need to check the advertising cache
in order to know the bdaddr_type of that device. Additionally,
hci_le_connect() was changed to handle the bdaddr_type info.

Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
 net/bluetooth/hci_conn.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 9a4a769..2d3197a 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -45,7 +45,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
-static void hci_le_connect(struct hci_conn *conn)
+static void hci_le_connect(struct hci_conn *conn, u8 bdaddr_type)
 {
 	struct hci_dev *hdev = conn->hdev;
 	struct hci_cp_le_create_conn cp;
@@ -59,6 +59,7 @@ static void hci_le_connect(struct hci_conn *conn)
 	cp.scan_interval = cpu_to_le16(0x0004);
 	cp.scan_window = cpu_to_le16(0x0004);
 	bacpy(&cp.peer_addr, &conn->dst);
+	cp.peer_addr_type = bdaddr_type;
 	cp.conn_interval_min = cpu_to_le16(0x0008);
 	cp.conn_interval_max = cpu_to_le16(0x0100);
 	cp.supervision_timeout = cpu_to_le16(0x0064);
@@ -482,8 +483,13 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
 		le = hci_conn_add(hdev, LE_LINK, dst);
 		if (!le)
 			return ERR_PTR(-ENOMEM);
-		if (le->state == BT_OPEN)
-			hci_le_connect(le);
+		if (le->state == BT_OPEN) {
+			struct adv_entry *entry = hci_find_adv_entry(hdev, dst);
+			if (!entry)
+				return ERR_PTR(-EHOSTUNREACH);
+
+			hci_le_connect(le, entry->bdaddr_type);
+		}
 
 		hci_conn_hold(le);
 
-- 
1.7.1


^ permalink raw reply related

* [RFC v2 3/6] Bluetooth: Protect adv_entries with a RW semaphore
From: Andre Guedes @ 2011-03-11 13:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andre Guedes
In-Reply-To: <1299850377-3734-1-git-send-email-andre.guedes@openbossa.org>

This patch adds a RW semaphore to protect concurrent operations on
adv_entries list.

Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
 include/net/bluetooth/hci_core.h |    1 +
 net/bluetooth/hci_core.c         |   22 ++++++++++++++++++----
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 970711d..bf7b5df 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -178,6 +178,7 @@ struct hci_dev {
 	struct list_head	link_keys;
 
 	struct list_head	adv_entries;
+	struct rw_semaphore	adv_entries_rwsem;
 
 	struct hci_dev_stats	stat;
 
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index cbff329..71f8788 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -44,6 +44,7 @@
 #include <linux/timer.h>
 #include <linux/crypto.h>
 #include <net/sock.h>
+#include <linux/rwsem.h>
 
 #include <asm/system.h>
 #include <linux/uaccess.h>
@@ -1084,6 +1085,8 @@ static int hci_adv_entries_clear(struct hci_dev *hdev)
 {
 	struct list_head *p, *n;
 
+	down_write(&hdev->adv_entries_rwsem);
+
 	list_for_each_safe(p, n, &hdev->adv_entries) {
 		struct adv_entry *entry;
 
@@ -1093,23 +1096,31 @@ static int hci_adv_entries_clear(struct hci_dev *hdev)
 		kfree(entry);
 	}
 
+	up_write(&hdev->adv_entries_rwsem);
+
 	return 0;
 }
 
 struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr)
 {
 	struct list_head *p;
+	struct adv_entry *res = NULL;
+
+	down_read(&hdev->adv_entries_rwsem);
 
 	list_for_each(p, &hdev->adv_entries) {
 		struct adv_entry *entry;
 
 		entry = list_entry(p, struct adv_entry, list);
 
-		if (bacmp(bdaddr, &entry->bdaddr) == 0)
-			return entry;
+		if (bacmp(bdaddr, &entry->bdaddr) == 0) {
+			res = entry;
+			goto out;
+		}
 	}
-
-	return NULL;
+out:
+	up_read(&hdev->adv_entries_rwsem);
+	return res;
 }
 
 static inline int is_connectable_adv(u8 evt_type)
@@ -1141,7 +1152,9 @@ int hci_add_adv_entry(struct hci_dev *hdev,
 	bacpy(&entry->bdaddr, &ev->bdaddr);
 	entry->bdaddr_type = ev->bdaddr_type;
 
+	down_write(&hdev->adv_entries_rwsem);
 	list_add(&entry->list, &hdev->adv_entries);
+	up_write(&hdev->adv_entries_rwsem);
 
 	return 0;
 }
@@ -1219,6 +1232,7 @@ int hci_register_dev(struct hci_dev *hdev)
 	INIT_LIST_HEAD(&hdev->link_keys);
 
 	INIT_LIST_HEAD(&hdev->adv_entries);
+	init_rwsem(&hdev->adv_entries_rwsem);
 
 	INIT_WORK(&hdev->power_on, hci_power_on);
 	INIT_WORK(&hdev->power_off, hci_power_off);
-- 
1.7.1


^ permalink raw reply related

* [RFC v2 2/6] Bluetooth: LE advertising info caching
From: Andre Guedes @ 2011-03-11 13:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andre Guedes
In-Reply-To: <1299850377-3734-1-git-send-email-andre.guedes@openbossa.org>

This patch adds a list of 'advertising entry' to the struct hci_dev.

The advertising entry (struct adv_entry) stores sensitive information
(bdaddr and bdaddr_type so far) gathered from LE advertising report
events.

A double-linked list (list_head adv_entries) is used to store those
advertising entries. Only advertising entries from connectables devices
are inserted into the list.

Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
 include/net/bluetooth/hci_core.h |   12 ++++++
 net/bluetooth/hci_core.c         |   69 ++++++++++++++++++++++++++++++++++++++
 net/bluetooth/hci_event.c        |    5 +--
 3 files changed, 83 insertions(+), 3 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index c59e857..970711d 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -82,6 +82,12 @@ struct link_key {
 	u8 pin_len;
 };
 
+struct adv_entry {
+	struct list_head list;
+	bdaddr_t bdaddr;
+	u8 bdaddr_type;
+};
+
 #define NUM_REASSEMBLY 4
 struct hci_dev {
 	struct list_head list;
@@ -171,6 +177,8 @@ struct hci_dev {
 
 	struct list_head	link_keys;
 
+	struct list_head	adv_entries;
+
 	struct hci_dev_stats	stat;
 
 	struct sk_buff_head	driver_init;
@@ -508,6 +516,10 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
 						u8 *key, u8 type, u8 pin_len);
 int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
 
+struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr);
+int hci_add_adv_entry(struct hci_dev *hdev,
+					struct hci_ev_le_advertising_info *ev);
+
 void hci_del_off_timer(struct hci_dev *hdev);
 
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index ff67843..cbff329 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1080,6 +1080,72 @@ static void hci_cmd_timer(unsigned long arg)
 	tasklet_schedule(&hdev->cmd_task);
 }
 
+static int hci_adv_entries_clear(struct hci_dev *hdev)
+{
+	struct list_head *p, *n;
+
+	list_for_each_safe(p, n, &hdev->adv_entries) {
+		struct adv_entry *entry;
+
+		entry = list_entry(p, struct adv_entry, list);
+
+		list_del(p);
+		kfree(entry);
+	}
+
+	return 0;
+}
+
+struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr)
+{
+	struct list_head *p;
+
+	list_for_each(p, &hdev->adv_entries) {
+		struct adv_entry *entry;
+
+		entry = list_entry(p, struct adv_entry, list);
+
+		if (bacmp(bdaddr, &entry->bdaddr) == 0)
+			return entry;
+	}
+
+	return NULL;
+}
+
+static inline int is_connectable_adv(u8 evt_type)
+{
+	if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND)
+		return 1;
+
+	return 0;
+}
+
+int hci_add_adv_entry(struct hci_dev *hdev,
+					struct hci_ev_le_advertising_info *ev)
+{
+	struct adv_entry *entry;
+
+	if (!is_connectable_adv(ev->evt_type))
+		return -EINVAL;
+
+	entry = hci_find_adv_entry(hdev, &ev->bdaddr);
+	/* Only new entries should be added to adv_entries. So, if
+	 * bdaddr was found, don't add it. */
+	if (entry)
+		return 0;
+
+	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
+	if (!entry)
+		return -ENOMEM;
+
+	bacpy(&entry->bdaddr, &ev->bdaddr);
+	entry->bdaddr_type = ev->bdaddr_type;
+
+	list_add(&entry->list, &hdev->adv_entries);
+
+	return 0;
+}
+
 static struct crypto_blkcipher *alloc_cypher(void)
 {
 	if (enable_smp)
@@ -1152,6 +1218,8 @@ int hci_register_dev(struct hci_dev *hdev)
 
 	INIT_LIST_HEAD(&hdev->link_keys);
 
+	INIT_LIST_HEAD(&hdev->adv_entries);
+
 	INIT_WORK(&hdev->power_on, hci_power_on);
 	INIT_WORK(&hdev->power_off, hci_power_off);
 	setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev);
@@ -1239,6 +1307,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
 	hci_blacklist_clear(hdev);
 	hci_uuids_clear(hdev);
 	hci_link_keys_clear(hdev);
+	hci_adv_entries_clear(hdev);
 	hci_dev_unlock_bh(hdev);
 
 	__hci_dev_put(hdev);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 55502ac..5019b76 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2564,12 +2564,11 @@ static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
 
 	num_reports = skb->data[0];
 	ev = (void *) &skb->data[1];
-
-	BT_DBG("adv from: %s", batostr(&ev->bdaddr));
+	hci_add_adv_entry(hdev, ev);
 
 	while (--num_reports) {
 		ev = (void *) (ev->data + ev->length + 1);
-		BT_DBG("adv from: %s", batostr(&ev->bdaddr));
+		hci_add_adv_entry(hdev, ev);
 	}
 }
 
-- 
1.7.1


^ permalink raw reply related

* [RFC v2 1/6] Bluetooth: Implement advertising report meta event
From: Andre Guedes @ 2011-03-11 13:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Briglia
In-Reply-To: <1299850377-3734-1-git-send-email-andre.guedes@openbossa.org>

From: Anderson Briglia <anderson.briglia@openbossa.org>

This patch implements new LE meta event in order to handle advertising
reports.

Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
---
 include/net/bluetooth/hci.h |   18 ++++++++++++++++++
 net/bluetooth/hci_event.c   |   21 +++++++++++++++++++++
 2 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index d851f8b..de27caa 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1011,6 +1011,24 @@ struct hci_ev_le_conn_complete {
 	__u8     clk_accurancy;
 } __packed;
 
+#define ADV_IND		0x00
+#define ADV_DIRECT_IND	0x01
+#define ADV_SCAN_IND	0x02
+#define ADV_NONCONN_IND	0x03
+#define ADV_SCAN_RSP	0x04
+
+#define ADDR_LE_DEV_PUBLIC	0x00
+#define ADDR_LE_DEV_RANDOM	0x01
+
+#define HCI_EV_LE_ADVERTISING_REPORT	0x02
+struct hci_ev_le_advertising_info {
+	__u8	 evt_type;
+	__u8	 bdaddr_type;
+	bdaddr_t bdaddr;
+	__u8	 length;
+	__u8	 data[0];
+} __packed;
+
 #define HCI_EV_LE_LTK_REQ		0x05
 struct hci_ev_le_ltk_req {
 	__le16	handle;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 5a2ab2c..55502ac 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2556,6 +2556,23 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
 	hci_dev_unlock(hdev);
 }
 
+static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
+						struct sk_buff *skb)
+{
+	struct hci_ev_le_advertising_info *ev;
+	u8 num_reports;
+
+	num_reports = skb->data[0];
+	ev = (void *) &skb->data[1];
+
+	BT_DBG("adv from: %s", batostr(&ev->bdaddr));
+
+	while (--num_reports) {
+		ev = (void *) (ev->data + ev->length + 1);
+		BT_DBG("adv from: %s", batostr(&ev->bdaddr));
+	}
+}
+
 static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_le_meta *le_ev = (void *) skb->data;
@@ -2571,6 +2588,10 @@ static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_le_ltk_request_evt(hdev, skb);
 		break;
 
+	case HCI_EV_LE_ADVERTISING_REPORT:
+		hci_le_adv_report_evt(hdev, skb);
+		break;
+
 	default:
 		break;
 	}
-- 
1.7.1


^ permalink raw reply related

* [RFC v2 0/6] LE advertising cache
From: Andre Guedes @ 2011-03-11 13:32 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andre Guedes

During a LE connection establishment, the host should be able to infer the
bdaddr type from a given bdaddr.

To achieve that, during the LE scanning, the host stores the bdaddr and the
bdaddr type gathered from advertising reports. The host keeps a list of
advertising entry (bdaddr and bdaddr_type) for later lookup. This list will
be called Advertising Cache.

Since the penality to connect to an unreachable device is relatively high,
we must keep only fresh advertising entries on the advertising cache. So,
before each LE scanning the advertising cache is cleared. Also, after the LE
scanning, a timer is set to clear the cache.

Next steps include removing all advertising cache from userspace and
implementing a mechanism to sync kernel and userspace advertising cache.

Patches are rebased using Vinicius SMP patches, repo:
git://git.infradead.org/users/vcgomes/linux-2.6.git for-next

Anderson Briglia (1):
  Bluetooth: Implement advertising report meta event

Andre Guedes (5):
  Bluetooth: LE advertising info caching
  Bluetooth: Protect adv_entries with a RW semaphore
  Bluetooth: Check advertising cache in hci_connect()
  Bluetooth: Clear advertising cache before scanning
  Bluetooth: Add a timer to clear the advertising cache

 include/net/bluetooth/hci.h      |   20 ++++++++
 include/net/bluetooth/hci_core.h |   16 +++++++
 net/bluetooth/hci_conn.c         |   12 ++++-
 net/bluetooth/hci_core.c         |   92 ++++++++++++++++++++++++++++++++++++++
 net/bluetooth/hci_event.c        |   47 +++++++++++++++++++
 5 files changed, 184 insertions(+), 3 deletions(-)


^ permalink raw reply

* Re: [RFC 0/6] LE advertising cache
From: Andre Guedes @ 2011-03-11 13:27 UTC (permalink / raw)
  To: Brian Gix; +Cc: linux-bluetooth
In-Reply-To: <4D715062.1070508@codeaurora.org>

Hi Brian,

On Fri, Mar 4, 2011 at 5:49 PM, Brian Gix <bgix@codeaurora.org> wrote:
>
> On 11-03-04 12:35 PM, Andre Guedes wrote:
>>
>> During a LE connection establishment, the host should be able to infer the
>> bdaddr type from a given bdaddr.
>>
>> To achieve that, during the LE scanning, the host stores the bdaddr and the
>> bdaddr type gathered from advertising reports. The host keeps a list of
>> advertising entry (bdaddr and bdaddr_type) for later lookup. This list will
>> be called Advertising Cache.
>
> My biggest problem with this is testing purposes.
>
> While it is true that the bdaddr_type can be extracted from the LE Scan data, when you are at an event like UPF, there can be an awful lot of devices very close to you.
>
> It would be nice to be able to explicitly specify both the bdaddr and bdaddr_type during these things.

For testing purposes, hcitool lecc [--random] <bdaddr> command can be
used to explicitly specify both the bdaddr and bdaddr_type.

For the L2CAP socket, we could have extended the "struct sockaddr_l2"
to add the address type field, but we've decided to not add a new
field which is not applied to basic rate.

>
> But I agree that as a deployed device, caching from an LE scan makes the most sense.
>
> Will this also work for (future) private addressing, where the address being connected to may not be the one initially seen in the scan?

Yes. Advertising entries are cached during both active and passive
scanning. We need to define how to put all pieces together: whitelist,
active/passive scanning and address resolution in the kernel.

>>
>> Since the penality to connect to an unreachable device is relatively high,
>> we must keep only fresh advertising entries on the advertising cache. So,
>> before each LE scanning the advertising cache is cleared. Also, after the LE
>> scanning, a timer is set to clear the cache.
>>
>> Next steps include removing all advertising cache from userspace and
>> implementing a mechanism to sync kernel and userspace advertising cache.
>>
>> Patches are rebased using Vinicius SMP patches, repo:
>> git://git.infradead.org/users/vcgomes/linux-2.6.git for-next
>>
>> Anderson Briglia (1):
>>   Bluetooth: Implement advertising report meta event
>>
>> Andre Guedes (5):
>>   Bluetooth: LE advertising info caching
>>   Bluetooth: Protect adv_entries with a RW semaphore
>>   Bluetooth: Check advertising cache in hci_connect()
>>   Bluetooth: Clear advertising cache before scanning
>>   Bluetooth: Add a timer to clear the advertising cache
>>
>>  include/net/bluetooth/hci.h      |   20 ++++++++
>>  include/net/bluetooth/hci_core.h |   16 +++++++
>>  net/bluetooth/hci_conn.c         |   12 ++++-
>>  net/bluetooth/hci_core.c         |   92 ++++++++++++++++++++++++++++++++++++++
>>  net/bluetooth/hci_event.c        |   48 ++++++++++++++++++++
>>  5 files changed, 185 insertions(+), 3 deletions(-)
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
> --
> Brian Gix
> bgix@codeaurora.org
> Employee of Qualcomm Innovation Center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

Regards,

Andre Guedes.

^ permalink raw reply

* Re: [PATCH v2 4/4] Add detection of MAP function in OBEX requests
From: Slawomir Bochenski @ 2011-03-11 11:40 UTC (permalink / raw)
  To: Slawomir Bochenski, linux-bluetooth; +Cc: Johan Hedberg
In-Reply-To: <20110311111313.GA20128@jh-x301>

>> +enum messages_function_id {
>> +     MFID_INVALID = 0,
>> +     MFID_SET_NOTIFICATION_REGISTRATION,
>> +     MFID_GET_FOLDER_LISTING,
>> +     MFID_GET_MESSAGES_LISTING,
>> +     MFID_GET_MESSAGE,
>> +     MFID_SET_MESSAGE_STATUS,
>> +     MFID_PUSH_MESSAGE,
>> +     MFID_UPDATE_INBOX,
>> +};
>
> Since "function" here doesn't seem to be referring to a C function but
> to the type of request, could you call it e.g. request_type instead? Is
> there a reason you you want to have this enum instead of e.g. storing
> the original value of the type header?
Function here refers to function as used in MAP specification (see
chapter 5: Message Access Profile Functions). Functions in MAP are an
abstraction above OBEX requests and types. There is one case where one
type is used for two functions (the difference is whether it is GET or
PUT request).

In 3 (of 9 total) cases type is used solely for selecting function, as
there is no real object transmitted (well, to be exact the body in
this cases consist of single filler byte).

And those MAP functions also accept input parameters and return output
ones, so the name "function" is quite appropriate.

As checking for this MAP function called is needed in more places it
is convenient to store it as a number instead of doing expensive
string comparison each time.

-- 
Slawomir Bochenski

^ permalink raw reply

* Re: [PATCH v2 4/4] Add detection of MAP function in OBEX requests
From: Johan Hedberg @ 2011-03-11 11:13 UTC (permalink / raw)
  To: Slawomir Bochenski; +Cc: linux-bluetooth
In-Reply-To: <1299829612-3704-4-git-send-email-lkslawek@gmail.com>

Hi Slawek,

On Fri, Mar 11, 2011, Slawomir Bochenski wrote:
> There is also first part of mas.c <-> backend API. The mas_request
> structure will be used when calling backend functions.
> ---
>  plugins/mas.c      |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  plugins/messages.h |   15 +++++++++++++
>  2 files changed, 72 insertions(+), 0 deletions(-)

I've pushed 2/4 and 3/4 upstream, but there's at least issue one with
this last patch:

> +enum messages_function_id {
> +	MFID_INVALID = 0,
> +	MFID_SET_NOTIFICATION_REGISTRATION,
> +	MFID_GET_FOLDER_LISTING,
> +	MFID_GET_MESSAGES_LISTING,
> +	MFID_GET_MESSAGE,
> +	MFID_SET_MESSAGE_STATUS,
> +	MFID_PUSH_MESSAGE,
> +	MFID_UPDATE_INBOX,
> +};

Since "function" here doesn't seem to be referring to a C function but
to the type of request, could you call it e.g. request_type instead? Is
there a reason you you want to have this enum instead of e.g. storing
the original value of the type header?

Johan

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox