* [PATCH BlueZ v5 03/18] gatt: Register Manager D-Bus Interface
From: Claudio Takahasi @ 2014-01-27 20:35 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi, Alvaro Silva
In-Reply-To: <1390854924-31904-1-git-send-email-claudio.takahasi@openbossa.org>
From: Alvaro Silva <alvaro.silva@openbossa.org>
This patch registers GATT Service Manager D-Bus Interface. This
interface implements the methods to allow external application register
and unregister GATT Services.
---
Makefile.am | 1 +
src/gatt-dbus.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/gatt-dbus.h | 25 +++++++++++++++++++
src/gatt.c | 9 +++++++
4 files changed, 110 insertions(+)
create mode 100644 src/gatt-dbus.c
create mode 100644 src/gatt-dbus.h
diff --git a/Makefile.am b/Makefile.am
index 101d5de..fbae2c8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -146,6 +146,7 @@ src_bluetoothd_SOURCES = $(builtin_sources) \
src/adapter.h src/adapter.c \
src/profile.h src/profile.c \
src/service.h src/service.c \
+ src/gatt-dbus.h src/gatt-dbus.c \
src/gatt.h src/gatt.c \
src/device.h src/device.c src/attio.h \
src/dbus-common.c src/dbus-common.h \
diff --git a/src/gatt-dbus.c b/src/gatt-dbus.c
new file mode 100644
index 0000000..183c611
--- /dev/null
+++ b/src/gatt-dbus.c
@@ -0,0 +1,75 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2014 Instituto Nokia de Tecnologia - INdT
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdint.h>
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <gdbus/gdbus.h>
+
+#include "dbus-common.h"
+#include "log.h"
+
+#include "gatt-dbus.h"
+
+#define GATT_MGR_IFACE "org.bluez.GattManager1"
+
+static DBusMessage *register_service(DBusConnection *conn,
+ DBusMessage *msg, void *user_data)
+{
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *unregister_service(DBusConnection *conn,
+ DBusMessage *msg, void *user_data)
+{
+ return dbus_message_new_method_return(msg);
+}
+
+static const GDBusMethodTable methods[] = {
+ { GDBUS_EXPERIMENTAL_METHOD("RegisterService",
+ GDBUS_ARGS({ "service", "o"},
+ { "options", "a{sv}"}),
+ NULL, register_service) },
+ { GDBUS_EXPERIMENTAL_METHOD("UnregisterService",
+ GDBUS_ARGS({"service", "o"}),
+ NULL, unregister_service) },
+ { }
+};
+
+gboolean gatt_dbus_manager_register(void)
+{
+ return g_dbus_register_interface(btd_get_dbus_connection(),
+ "/org/bluez", GATT_MGR_IFACE,
+ methods, NULL, NULL, NULL, NULL);
+}
+
+void gatt_dbus_manager_unregister(void)
+{
+ g_dbus_unregister_interface(btd_get_dbus_connection(), "/org/bluez",
+ GATT_MGR_IFACE);
+}
diff --git a/src/gatt-dbus.h b/src/gatt-dbus.h
new file mode 100644
index 0000000..310cfa9
--- /dev/null
+++ b/src/gatt-dbus.h
@@ -0,0 +1,25 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2014 Instituto Nokia de Tecnologia - INdT
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+gboolean gatt_dbus_manager_register(void);
+void gatt_dbus_manager_unregister(void);
diff --git a/src/gatt.c b/src/gatt.c
index 06619f0..e8b691a 100644
--- a/src/gatt.c
+++ b/src/gatt.c
@@ -25,14 +25,23 @@
#include <config.h>
#endif
+#include <glib.h>
+
+#include "log.h"
+
+#include "gatt-dbus.h"
#include "gatt.h"
void gatt_init(void)
{
+ DBG("Starting GATT server");
+ gatt_dbus_manager_register();
}
void gatt_cleanup(void)
{
+ DBG("Stopping GATT server");
+ gatt_dbus_manager_unregister();
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v5 02/18] gatt: Add stub for gatt.{c, h} files
From: Claudio Takahasi @ 2014-01-27 20:35 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi, Alvaro Silva
In-Reply-To: <1390854924-31904-1-git-send-email-claudio.takahasi@openbossa.org>
From: Alvaro Silva <alvaro.silva@openbossa.org>
These files implement functions to handle ATT transactions, and expose
functions to allow other entities to manage GATT based services. It
is a replacement for src/attrib-server.c.
---
Makefile.am | 1 +
src/gatt.c | 38 ++++++++++++++++++++++++++++++++++++++
src/gatt.h | 26 ++++++++++++++++++++++++++
src/main.c | 4 ++++
4 files changed, 69 insertions(+)
create mode 100644 src/gatt.c
create mode 100644 src/gatt.h
diff --git a/Makefile.am b/Makefile.am
index 3a1e6dc..101d5de 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -146,6 +146,7 @@ src_bluetoothd_SOURCES = $(builtin_sources) \
src/adapter.h src/adapter.c \
src/profile.h src/profile.c \
src/service.h src/service.c \
+ src/gatt.h src/gatt.c \
src/device.h src/device.c src/attio.h \
src/dbus-common.c src/dbus-common.h \
src/eir.h src/eir.c \
diff --git a/src/gatt.c b/src/gatt.c
new file mode 100644
index 0000000..06619f0
--- /dev/null
+++ b/src/gatt.c
@@ -0,0 +1,38 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2014 Instituto Nokia de Tecnologia - INdT
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gatt.h"
+
+void gatt_init(void)
+{
+
+}
+
+void gatt_cleanup(void)
+{
+
+}
diff --git a/src/gatt.h b/src/gatt.h
new file mode 100644
index 0000000..3a320b4
--- /dev/null
+++ b/src/gatt.h
@@ -0,0 +1,26 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2014 Instituto Nokia de Tecnologia - INdT
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+void gatt_init(void);
+
+void gatt_cleanup(void);
diff --git a/src/main.c b/src/main.c
index 91d90b4..fccc838 100644
--- a/src/main.c
+++ b/src/main.c
@@ -55,6 +55,7 @@
#include "dbus-common.h"
#include "agent.h"
#include "profile.h"
+#include "gatt.h"
#include "systemd.h"
#define BLUEZ_NAME "org.bluez"
@@ -545,6 +546,8 @@ int main(int argc, char *argv[])
g_dbus_set_flags(gdbus_flags);
+ gatt_init();
+
if (option_compat == TRUE)
sdp_flags |= SDP_SERVER_COMPAT;
@@ -595,6 +598,7 @@ int main(int argc, char *argv[])
btd_profile_cleanup();
btd_agent_cleanup();
btd_device_cleanup();
+ gatt_cleanup();
adapter_cleanup();
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v5 01/18] doc: Add experimental GATT API
From: Claudio Takahasi @ 2014-01-27 20:35 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1390854924-31904-1-git-send-email-claudio.takahasi@openbossa.org>
This patch proposes an unified GATT API for local and remote services.
---
doc/gatt-api.txt | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 142 insertions(+)
create mode 100644 doc/gatt-api.txt
diff --git a/doc/gatt-api.txt b/doc/gatt-api.txt
new file mode 100644
index 0000000..0f6b084
--- /dev/null
+++ b/doc/gatt-api.txt
@@ -0,0 +1,142 @@
+BlueZ D-Bus GATT API description
+********************************
+
+GATT local and remote services share the same high-level D-Bus API. Local
+refers to GATT based service exported by a BlueZ plugin or an external
+application. Remote refers to GATT services exported by the peer.
+
+BlueZ acts as a proxy, translating ATT operations to D-Bus method calls and
+Properties (or the opposite). Support for D-Bus Object Manager is mandatory for
+external services to allow seamless GATT declarations (Service, Characteristic
+and Descriptors) discovery.
+
+Releasing a registered GATT service is not defined yet. Any API extension
+should avoid breaking the defined API, and if possible keep an unified GATT
+remote and local services representation.
+
+Service hierarchy
+=================
+
+GATT remote and local service representation. Object path for local services
+is freely definable.
+
+External applications implementing local services must register the services
+using GattManager1 registration method and must implement the methods and
+properties defined in GattService1 interface.
+
+Service org.bluez
+Interface org.bluez.GattService1 [Experimental]
+Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX
+
+Properties string UUID [read-only]
+
+ 128-bit service UUID.
+
+ array{object} Includes [read-only]: Not implemented
+
+ Array of object paths representing the included
+ services of this service.
+
+
+Characteristic hierarchy
+========================
+
+For local GATT defined services, the object paths need to follow the service
+path hierarchy and are freely definable.
+
+Service org.bluez
+Interface org.bluez.GattCharacteristic1 [Experimental]
+Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY
+
+Properties string UUID [read-only]
+
+ 128-bit characteristic UUID.
+
+ object Service [read-only]
+
+ Object path of the GATT service the characteristc
+ belongs to.
+
+ array{byte} Value [read-write]
+
+ Value read from the remote Bluetooth device or from
+ the external application implementing GATT services.
+
+ array{string} Flags [read-only, optional]
+
+ Defines how the characteristic value can be used. See
+ Core spec page 1898, "Table 3.5: Characteristic
+ Properties bit field" and page 1900, "Table 3.8:
+ Characteristic Extended Properties bit field". Allowed
+ values: "broadcast", "read", "write-without-response",
+ "write", "notify", "indicate",
+ "authenticated-signed-writes", "reliable-write", and
+ "writable-auxiliaries".
+
+
+Characteristic Descriptors hierarchy
+====================================
+
+Local or remote GATT characteristic descriptors hierarchy.
+
+Service org.bluez
+Interface org.bluez.GattDescriptor1 [Experimental]
+Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY/descriptorZZZ
+
+Properties string UUID [read-only]
+
+ 128-bit descriptor UUID.
+
+ object Characteristic [read-only]
+
+ Object path of the GATT characteristc the descriptor
+ belongs to.
+
+ array{byte} Value [read-write]
+
+ Raw characteristic descriptor value read from the
+ remote Bluetooth device or from the external
+ application implementing GATT services.
+
+ string Permissions [read-only]: To be defined
+
+ Defines read/write authentication and authorization
+ requirements.
+
+Service Manager hierarchy
+=============================
+
+Service Manager allows external applications to register GATT based
+services. Services must follow the API for Service and Characteristic
+described above.
+
+Local GATT services, characteristics and characteristic descriptors are
+discovered automatically using the D-Bus Object Manager interface.
+
+Service org.bluez
+Interface org.bluez.GattManager1 [Experimental]
+Object path /org/bluez
+
+Methods RegisterService(object service, dict options)
+
+ Registers remote application service exported under
+ interface GattService1. Characteristic objects must
+ be hierarchical to their service and must use the
+ interface GattCharacteristic1. D-Bus Object Manager
+ is used to fetch the exported objects.
+
+ "service" object path together with the D-Bus system
+ bus connection ID define the identification of the
+ application registering a GATT based service.
+
+ Possible errors: org.bluez.Error.InvalidArguments
+ org.bluez.Error.AlreadyExists
+
+ UnregisterService(object service)
+
+ This unregisters the service that has been
+ previously registered. The object path parameter
+ must match the same value that has been used
+ on registration.
+
+ Possible errors: org.bluez.Error.DoesNotExist
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v5 00/18] GATT API: External Services
From: Claudio Takahasi @ 2014-01-27 20:35 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>
This patchset implements the minimal support for adding local services
declarations.
Limitation: Remove services and multiple services exported by the same
remote will be implemented the next series.
Changes from PATCH v4 to PATCH v5:
* Removed Release() method of GattService1 interface
Changes from PATCH v3 to PATCH v4:
* Rebase
* src/gatt.c: Replaced GIOChannel/GAttrib by "io".
Changes from PATCH v2 to PATCH v3:
* Rebase
* Interfaces renamed: s/GattServiceManager1/GattManager1,
s/Characteristic1/GattCharacteristic1, s/Descriptor/GattDescriptor1
* test/gatt-service.c: s/fprintf/printf
Changes from PATCH v1 to PATCH v2:
* Rebase
* Included patch "doc: Add GATT API"
* Interfaces renamed: s/Service1/GattService1, and
s/ServiceManager1/GattServiceManager1
* Removed patch "gatt: Implement UnregisterService" from this patchset
Changes from PATCH v0 to PATCH v1:
* Rebase
Changes from RFC v0 to PATCH v0:
* Changed copyright year : s/2013/2014
* Fixed coding style
* Added gatt-service binary to gitignore
* Added extra comment in the source code
Features:
* API for internal and external services declaration
* Unix socket for testing purpose: services are exported through unix
sockets to avoid breaking the current attribute server.
How to test:
Run bluetoothd with EXPERIMENTAL flag (-E)
Replace /etc/dbus-1/system.d/bluetooth.conf and reload DBus settings
$gatttool -L --primary (or interactive mode)
Roughly upstreaming plan (steps):
* GATT Server: External Services -> pathset GATT API: External Services
* GATT Server: External Characteristics (Server)
* GATT Server: External Descriptors (Server)
* Replacement for GAttrib: use "io"
* Replace attribute server
* Remove ATTIO and automatic connection mechanism from userspace
* Fix all GATT internal plugins
* GATT Client: Remote Services
Alvaro Silva (6):
gatt: Add stub for gatt.{c, h} files
gatt: Register Manager D-Bus Interface
gatt: Add registering external service
gatt: Add external services tracking
gatt: Register ATT command/event handler
gatt: Add Discover All Primary Services
Andre Guedes (1):
gatt: Add helper for creating GATT services
Claudio Takahasi (11):
doc: Add experimental GATT API
lib: Move GATT UUID to uuid.h
gatt: Add server unix socket
gattrib: Use default ATT LE MTU for non-standard sockets
test: Add external service GATT skeleton
gitignore: Add test/gatt-service
test: Add signal handling for gatt-service
test: Add registering external service
gatttool: Add unix socket connect
gatttool: Add unix socket support for interactive mode
bluetooth.conf: Add ObjectManager interface
.gitignore | 1 +
Makefile.am | 2 +
Makefile.tools | 5 +
attrib/gatt.h | 25 ----
attrib/gattrib.c | 16 +--
attrib/gatttool.c | 27 +++-
attrib/gatttool.h | 1 +
attrib/interactive.c | 19 +--
attrib/utils.c | 54 ++++++++
doc/gatt-api.txt | 142 ++++++++++++++++++++
lib/uuid.h | 30 +++++
src/bluetooth.conf | 1 +
src/gatt-dbus.c | 271 +++++++++++++++++++++++++++++++++++++
src/gatt-dbus.h | 25 ++++
src/gatt.c | 372 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/gatt.h | 36 +++++
src/main.c | 4 +
test/gatt-service.c | 267 ++++++++++++++++++++++++++++++++++++
18 files changed, 1250 insertions(+), 48 deletions(-)
create mode 100644 doc/gatt-api.txt
create mode 100644 src/gatt-dbus.c
create mode 100644 src/gatt-dbus.h
create mode 100644 src/gatt.c
create mode 100644 src/gatt.h
create mode 100644 test/gatt-service.c
--
1.8.3.1
^ permalink raw reply
* [RFC BlueZ] android/AVDTP: Make signalling channel high priority
From: Luiz Augusto von Dentz @ 2014-01-27 20:24 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This makes signalling high priority (6) so it can push commands before
the stream channel, without this the stream channel may be schedule
first and cause the signalling commands to timeout while waiting a slot.
---
android/avdtp.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/android/avdtp.c b/android/avdtp.c
index 4abcd75..4cfffc8 100644
--- a/android/avdtp.c
+++ b/android/avdtp.c
@@ -2057,6 +2057,7 @@ struct avdtp *avdtp_new(int fd, size_t imtu, size_t omtu, uint16_t version)
struct avdtp *session;
GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
int new_fd;
+ int priority;
new_fd = dup(fd);
if (new_fd < 0) {
@@ -2064,6 +2065,14 @@ struct avdtp *avdtp_new(int fd, size_t imtu, size_t omtu, uint16_t version)
return NULL;
}
+ priority = 6;
+ if (setsockopt(new_fd, SOL_SOCKET, SO_PRIORITY,
+ (const void *) &priority, sizeof(priority)) < 0) {
+ error("setsockopt(SO_PRIORITY): %s (%d)", strerror(errno),
+ errno);
+ return NULL;
+ }
+
session = g_new0(struct avdtp, 1);
session->io = g_io_channel_unix_new(new_fd);
session->version = version;
--
1.8.4.2
^ permalink raw reply related
* Re: [PATCH BlueZ 4/4] emulator: Fix crash if socket(AF_ALG) is not supported by the kernel
From: Anderson Lizardo @ 2014-01-27 20:03 UTC (permalink / raw)
To: Anderson Lizardo, BlueZ development
In-Reply-To: <20140127175956.GB2452@x220.p-661hnu-f1>
Hi Johan,
On Mon, Jan 27, 2014 at 1:59 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> This patch has been applied. Thanks.
Any comments on the other patches that touch android/* files?
Best Regards,
--
Anderson Lizardo
http://www.indt.org/?lang=en
INdT - Manaus - Brazil
^ permalink raw reply
* Re: [PATCH] Rename adapter_remove_device to btd_adapter_remove_device
From: Johan Hedberg @ 2014-01-27 19:45 UTC (permalink / raw)
To: Petri Gynther; +Cc: linux-bluetooth
In-Reply-To: <CAGXr9JGm1OUnPHdM=m6nH66xQVjUgL=P3zmwJp-aj2f9whbEpQ@mail.gmail.com>
Hi Petri,
On Mon, Jan 27, 2014, Petri Gynther wrote:
> Once BlueZ host and the remote have been paired successfully the first
> time, the remote has a key combination available that allows it to be
> unpaired and reset to initial state. But, BlueZ won't know about that.
> It still considers the remote paired. Thus, when the BD address
> arrives to the IR-assist plugin again, the plugin needs to clear all
> old state from BlueZ side and start over as if the device had never
> been discovered before.
>
> The old device removal and new device creation are handled in the
> plugin, since the device creation part is not possible over D-Bus.
> However, once the device is created, the pairing is handled in a
> separate Python script.
Fair enough. I've now applied the patch.
Btw, please don't use top-posting on this list. It makes it difficult to
track the discussion when we've got inline quoting and top posting mixed
together.
Johan
^ permalink raw reply
* Re: [PATCH 1/2] unit/avdtp: trivial: Remove empty line
From: Luiz Augusto von Dentz @ 2014-01-27 19:32 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1390838504-25456-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Mon, Jan 27, 2014 at 8:01 AM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> ---
> unit/test-avdtp.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/unit/test-avdtp.c b/unit/test-avdtp.c
> index 4726c4b..8fe5ce3 100644
> --- a/unit/test-avdtp.c
> +++ b/unit/test-avdtp.c
> @@ -216,7 +216,6 @@ static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
> return TRUE;
> }
>
> -
> static struct context *context_new(uint16_t version, uint16_t imtu,
> uint16_t omtu, gconstpointer data)
> {
> --
> 1.8.3.2
Applied, thanks.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH] Rename adapter_remove_device to btd_adapter_remove_device
From: Petri Gynther @ 2014-01-27 19:31 UTC (permalink / raw)
To: linux-bluetooth, johan.hedberg
In-Reply-To: <20140127181307.GB7831@x220.p-661hnu-f1>
Hi Johan,
Once BlueZ host and the remote have been paired successfully the first
time, the remote has a key combination available that allows it to be
unpaired and reset to initial state. But, BlueZ won't know about that.
It still considers the remote paired. Thus, when the BD address
arrives to the IR-assist plugin again, the plugin needs to clear all
old state from BlueZ side and start over as if the device had never
been discovered before.
The old device removal and new device creation are handled in the
plugin, since the device creation part is not possible over D-Bus.
However, once the device is created, the pairing is handled in a
separate Python script.
-- Petri
On Mon, Jan 27, 2014 at 10:13 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Petri,
>
> On Sun, Jan 26, 2014, Petri Gynther wrote:
>> I would need this for the IR-assist device discovery plugin that I'm
>> writing. Basically, I have a HID remote control which is not
>> discoverable (but it is connectable). When this HID remote is in
>> unpaired state, it sends its BD address to the host via IR. The plugin
>> will get the BD address and do the following:
>>
>> device = btd_adapter_find_device(adapter, &device_bdaddr);
>> if (device) {
>> /* remove old pairing and device info */
>> btd_device_set_temporary(device, TRUE);
>> btd_adapter_remove_device(adapter, device);
>> }
>
> If the device is only discoverable through IR why would there be an
> existing device object for it? And if there does exist a device object
> doesn't it mean it's already paired and you don't need to repair?
>
> Johan
^ permalink raw reply
* Re: [PATCH BlueZ v4 01/18] doc: Add GATT API
From: Marcel Holtmann @ 2014-01-27 19:08 UTC (permalink / raw)
To: Claudio Takahasi; +Cc: BlueZ development
In-Reply-To: <CAKT1EBfkLuwMgQbm0TQfuGvWf=w7TN5LnzmMwdP+_zU86e6wmA@mail.gmail.com>
Hi Claudio,
>>> This patch proposes an unified GATT API for local and remote services.
>>> ---
>>> doc/gatt-api.txt | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>> 1 file changed, 145 insertions(+)
>>> create mode 100644 doc/gatt-api.txt
>>>
>>> diff --git a/doc/gatt-api.txt b/doc/gatt-api.txt
>>> new file mode 100644
>>> index 0000000..2d92f03
>>> --- /dev/null
>>> +++ b/doc/gatt-api.txt
>>> @@ -0,0 +1,145 @@
>>> +BlueZ D-Bus GATT API description
>>> +********************************
>>> +
>>> +GATT local and remote services share the same high-level D-Bus API. Local
>>> +refers to GATT based service exported by a BlueZ plugin or an external
>>> +application. Remote refers to GATT services exported by the peer.
>>> +
>>> +BlueZ acts as a proxy, translating ATT operations to D-Bus method calls and
>>> +Properties (or the opposite). Support for D-Bus Object Manager is mandatory for
>>> +external services to allow seamless GATT declarations (Service, Characteristic
>>> +and Descriptors) discovery.
>>> +
>>> +Service hierarchy
>>> +=================
>>> +
>>> +GATT remote and local service representation. Object path for local services
>>> +is freely definable.
>>> +
>>> +External applications implementing local services must register the services
>>> +using GattManager1 registration method and must implement the methods and
>>> +properties defined in GattService1 interface.
>>> +
>>> +Service org.bluez
>>> +Interface org.bluez.GattService1 [Experimental]
>>> +Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX
>>> +
>>> +Methods void Release()
>>> +
>>> + Release this service. At this point, it will not be
>>> + used by BlueZ anymore and can be destroyed by the
>>> + owner. Method applicable to external GATT services
>>> + implementations only (GATT servers).
>>
>> so this is the part I do not like that much. We should not define an interface that has a method that is valid and used only when this is a GATT server.
>>
>> What I am thinking right now (and might need to discuss this a bit further), we leave GattService1 without any methods and use it for both GATT client and server.
>>
>> Then we create some GattServiceAgent1 or GattServiceCollection1 or maybe even GattServer1 that we can register with GattManager1 for the purpose of providing a Release method so that bluetoothd stays in control and can inform applications if it decided to remove a service.
>>
>> I am even fine with allowing to provide multiple services in a collection/server registration. Thoughts?
>
> The "Service Agent" approach was suggested in beginning of our
> discussion. I don't remember anymore why we decided to change it.
>
> Unless you think that it is essential, we could implement the
> Release() method later. When we start the client implementation we
> will have a better understanding of our needs.
> Can I remove the Release() and re-send the patch set?
as long as this is clearly hidden behind our experimental switch, we can get this started without release method.
I want to be cautious since any change would break the GattManager1 interface once we figure out how this should be done best.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH BlueZ v4 01/18] doc: Add GATT API
From: Claudio Takahasi @ 2014-01-27 18:54 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: BlueZ development
In-Reply-To: <FC28B407-F3B2-4969-A5FD-35AB73316DF5@holtmann.org>
Hi Marcel:
On Mon, Jan 27, 2014 at 3:15 PM, Marcel Holtmann <marcel@holtmann.org> wrot=
e:
> Hi Claudio,
>
>> This patch proposes an unified GATT API for local and remote services.
>> ---
>> doc/gatt-api.txt | 145 +++++++++++++++++++++++++++++++++++++++++++++++++=
++++++
>> 1 file changed, 145 insertions(+)
>> create mode 100644 doc/gatt-api.txt
>>
>> diff --git a/doc/gatt-api.txt b/doc/gatt-api.txt
>> new file mode 100644
>> index 0000000..2d92f03
>> --- /dev/null
>> +++ b/doc/gatt-api.txt
>> @@ -0,0 +1,145 @@
>> +BlueZ D-Bus GATT API description
>> +********************************
>> +
>> +GATT local and remote services share the same high-level D-Bus API. Loc=
al
>> +refers to GATT based service exported by a BlueZ plugin or an external
>> +application. Remote refers to GATT services exported by the peer.
>> +
>> +BlueZ acts as a proxy, translating ATT operations to D-Bus method calls=
and
>> +Properties (or the opposite). Support for D-Bus Object Manager is manda=
tory for
>> +external services to allow seamless GATT declarations (Service, Charact=
eristic
>> +and Descriptors) discovery.
>> +
>> +Service hierarchy
>> +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>> +
>> +GATT remote and local service representation. Object path for local ser=
vices
>> +is freely definable.
>> +
>> +External applications implementing local services must register the ser=
vices
>> +using GattManager1 registration method and must implement the methods a=
nd
>> +properties defined in GattService1 interface.
>> +
>> +Service org.bluez
>> +Interface org.bluez.GattService1 [Experimental]
>> +Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/se=
rviceXX
>> +
>> +Methods void Release()
>> +
>> + Release this service. At this point, it will not b=
e
>> + used by BlueZ anymore and can be destroyed by the
>> + owner. Method applicable to external GATT services
>> + implementations only (GATT servers).
>
> so this is the part I do not like that much. We should not define an inte=
rface that has a method that is valid and used only when this is a GATT ser=
ver.
>
> What I am thinking right now (and might need to discuss this a bit furthe=
r), we leave GattService1 without any methods and use it for both GATT clie=
nt and server.
>
> Then we create some GattServiceAgent1 or GattServiceCollection1 or maybe =
even GattServer1 that we can register with GattManager1 for the purpose of =
providing a Release method so that bluetoothd stays in control and can info=
rm applications if it decided to remove a service.
>
> I am even fine with allowing to provide multiple services in a collection=
/server registration. Thoughts?
>
> Regards
>
> Marcel
The "Service Agent" approach was suggested in beginning of our
discussion. I don't remember anymore why we decided to change it.
Unless you think that it is essential, we could implement the
Release() method later. When we start the client implementation we
will have a better understanding of our needs.
Can I remove the Release() and re-send the patchset?
Regards,
Claudio.
^ permalink raw reply
* Re: [PATCHv2] avctp: Fix unchecked return value
From: Luiz Augusto von Dentz @ 2014-01-27 18:41 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1390838375-25264-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Mon, Jan 27, 2014 at 7:59 AM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Refactor code so that ioctl() return value is checked.
> ---
> profiles/audio/avctp.c | 47 +++++++++++++++++++++++++++++++++++++----------
> 1 file changed, 37 insertions(+), 10 deletions(-)
>
> diff --git a/profiles/audio/avctp.c b/profiles/audio/avctp.c
> index 6fd1454..bf44f9c 100644
> --- a/profiles/audio/avctp.c
> +++ b/profiles/audio/avctp.c
> @@ -1027,27 +1027,54 @@ static int uinput_create(char *name)
> err = -errno;
> error("Can't write device information: %s (%d)",
> strerror(-err), -err);
> - close(fd);
> - return err;
> + goto fail;
> + }
> +
> + if (ioctl(fd, UI_SET_EVBIT, EV_KEY) < 0) {
> + err = -errno;
> + error("ioctl UI_SET_EVBIT: %s (%d)", strerror(-err), -err);
> + goto fail;
> }
>
> - ioctl(fd, UI_SET_EVBIT, EV_KEY);
> - ioctl(fd, UI_SET_EVBIT, EV_REL);
> - ioctl(fd, UI_SET_EVBIT, EV_REP);
> - ioctl(fd, UI_SET_EVBIT, EV_SYN);
> + if (ioctl(fd, UI_SET_EVBIT, EV_REL) < 0) {
> + err = -errno;
> + error("ioctl UI_SET_EVBIT: %s (%d)", strerror(-err), -err);
> + goto fail;
> + }
>
> - for (i = 0; key_map[i].name != NULL; i++)
> - ioctl(fd, UI_SET_KEYBIT, key_map[i].uinput);
> + if (ioctl(fd, UI_SET_EVBIT, EV_REP) < 0) {
> + err = -errno;
> + error("ioctl UI_SET_EVBIT: %s (%d)", strerror(-err), -err);
> + goto fail;
> + }
> +
> + if (ioctl(fd, UI_SET_EVBIT, EV_SYN) < 0) {
> + err = -errno;
> + error("ioctl UI_SET_EVBIT: %s (%d)", strerror(-err), -err);
> + goto fail;
> + }
> +
> + for (i = 0; key_map[i].name != NULL; i++) {
> + if (ioctl(fd, UI_SET_KEYBIT, key_map[i].uinput) < 0) {
> + err = -errno;
> + error("ioctl UI_SET_KEYBIT: %s (%d)", strerror(-err),
> + -err);
> + goto fail;
> + }
> + }
>
> if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) {
> err = -errno;
> error("Can't create uinput device: %s (%d)",
> strerror(-err), -err);
> - close(fd);
> - return err;
> + goto fail;
> }
>
> return fd;
> +
> +fail:
> + close(fd);
> + return err;
> }
>
> static void init_uinput(struct avctp *session)
> --
> 1.8.3.2
I start to wonder if there is a better way to set those bits...
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [RFC] Initial avctp test
From: Luiz Augusto von Dentz @ 2014-01-27 18:36 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1390838187-25006-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Mon, Jan 27, 2014 at 7:56 AM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> This is initial invalid packet size test, sent as RFC since I am not
> sure what might be tested for avctp.
>
> Andrei Emeltchenko (1):
> unit/avctp: Add initial AVCTP test setup
>
> Makefile.am | 8 ++
> unit/test-avctp.c | 262 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 270 insertions(+)
> create mode 100644 unit/test-avctp.c
>
> --
> 1.8.3.2
You should follow the testing spec:
https://www.bluetooth.org/docman/handlers/DownloadDoc.ashx?doc_id=40404
Please follow the same name convention that is used by the testing
spec and for now do not introduce any other test that is not part of
the testing spec.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: Paired LE HoG devices are unable to reconnect to BlueZ host when discovery is active
From: Marcel Holtmann @ 2014-01-27 18:35 UTC (permalink / raw)
To: Petri Gynther; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <CAGXr9JEPv+onq6+WZTJ46oRtnrOJBPVQToKA82E84Sg9eSOP5A@mail.gmail.com>
Hi Petri,
> With BlueZ 5.13, I've noticed that previously paired LE HoG devices
> are unable to reconnect to the host when device discovery is active on
> the BT interface.
>
> Steps to reproduce:
> 1. Pair LE HoG device with BlueZ 5.13 host.
> 2. Verify that keypresses from HoG device are delivered to uHID input pipeline.
> 3. Let HoG device disconnect from host (due to inactivity timeout).
> 4. Press key on HoG device. At this point, it reconnects to host fine.
> 5. Let HoG device disconnect from host again.
> 6. Start "test-discovery" script.
> 7. Press key on HoG device => it does not reconnect to host.
> 8. Kill "test-discovery" script.
> 9. Press key on HoG device => it now reconnects to host successfully.
>
> It looks to me that the root cause is in src/adapter.c:update_found_devices()
>
> /*
> * Only if at least one client has requested discovery, maintain
> * list of found devices and name confirming for legacy devices.
> * Otherwise, this is an event from passive discovery and we
> * should check if the device needs connecting to.
> */
> if (!adapter->discovery_list)
> goto connect_le;
>
> if (g_slist_find(adapter->discovery_found, dev))
> return;
>
> When (active) discovery is on, adapter->discovery_list != NULL, and
> g_slist_find(adapter->discovery_found, dev) will obviously find this
> device since it is already paired. So, we end up returning from the
> function without an attempt to reconnect to the previously paired LE
> device.
>
> What would be the right fix here? Stop discovery before attempting to
> reconnect to the LE device?
I think that the intention was to allow the active discovery complete before we try to connect to any known devices. You are obviously correct that a known device is as good when it is found during active discovery as when found during background scan.
So I get the feeling that what should happen is that if we find a known device during the discovery phase (I am talking about the phase from mgmt in the kernel), put it on the list of to be connected devices. Once the kernel completes its discovery, then attempt to connect that found devices. After that continue with the discovery.
Remember that the kernel discovery phase it one-time shot and the one triggered from D-Bus is continues. I think that is why you are seeing this problem in the first place.
This is something that the auto-connect patches for the kernel would obviously fix. Since that is the right place to get this fixed. Inside bluetoothd this gets a bit messy, but we should do our best to interrupt the discovery phase to allow auto-connections.
Just a small warning that this of course only possible for controllers that support scanning and connections at the same time. For some controllers this would be clearly limited. Not that I have seen these controllers used, but potentially they could exist.
That is the best answer I have right now. So yes, we should get this fixed since that behavior is just not helpful for general usage.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH BlueZ v4 01/18] doc: Add GATT API
From: Marcel Holtmann @ 2014-01-27 18:15 UTC (permalink / raw)
To: Claudio Takahasi; +Cc: BlueZ development
In-Reply-To: <1390845656-29880-2-git-send-email-claudio.takahasi@openbossa.org>
Hi Claudio,
> This patch proposes an unified GATT API for local and remote services.
> ---
> doc/gatt-api.txt | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 145 insertions(+)
> create mode 100644 doc/gatt-api.txt
>
> diff --git a/doc/gatt-api.txt b/doc/gatt-api.txt
> new file mode 100644
> index 0000000..2d92f03
> --- /dev/null
> +++ b/doc/gatt-api.txt
> @@ -0,0 +1,145 @@
> +BlueZ D-Bus GATT API description
> +********************************
> +
> +GATT local and remote services share the same high-level D-Bus API. Local
> +refers to GATT based service exported by a BlueZ plugin or an external
> +application. Remote refers to GATT services exported by the peer.
> +
> +BlueZ acts as a proxy, translating ATT operations to D-Bus method calls and
> +Properties (or the opposite). Support for D-Bus Object Manager is mandatory for
> +external services to allow seamless GATT declarations (Service, Characteristic
> +and Descriptors) discovery.
> +
> +Service hierarchy
> +=================
> +
> +GATT remote and local service representation. Object path for local services
> +is freely definable.
> +
> +External applications implementing local services must register the services
> +using GattManager1 registration method and must implement the methods and
> +properties defined in GattService1 interface.
> +
> +Service org.bluez
> +Interface org.bluez.GattService1 [Experimental]
> +Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX
> +
> +Methods void Release()
> +
> + Release this service. At this point, it will not be
> + used by BlueZ anymore and can be destroyed by the
> + owner. Method applicable to external GATT services
> + implementations only (GATT servers).
so this is the part I do not like that much. We should not define an interface that has a method that is valid and used only when this is a GATT server.
What I am thinking right now (and might need to discuss this a bit further), we leave GattService1 without any methods and use it for both GATT client and server.
Then we create some GattServiceAgent1 or GattServiceCollection1 or maybe even GattServer1 that we can register with GattManager1 for the purpose of providing a Release method so that bluetoothd stays in control and can inform applications if it decided to remove a service.
I am even fine with allowing to provide multiple services in a collection/server registration. Thoughts?
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] Rename adapter_remove_device to btd_adapter_remove_device
From: Johan Hedberg @ 2014-01-27 18:13 UTC (permalink / raw)
To: Petri Gynther; +Cc: linux-bluetooth
In-Reply-To: <CAGXr9JHEe+9gu-giUF=iH4LAv=FAAutYPeFY483DQU2r40wmkg@mail.gmail.com>
Hi Petri,
On Sun, Jan 26, 2014, Petri Gynther wrote:
> I would need this for the IR-assist device discovery plugin that I'm
> writing. Basically, I have a HID remote control which is not
> discoverable (but it is connectable). When this HID remote is in
> unpaired state, it sends its BD address to the host via IR. The plugin
> will get the BD address and do the following:
>
> device = btd_adapter_find_device(adapter, &device_bdaddr);
> if (device) {
> /* remove old pairing and device info */
> btd_device_set_temporary(device, TRUE);
> btd_adapter_remove_device(adapter, device);
> }
If the device is only discoverable through IR why would there be an
existing device object for it? And if there does exist a device object
doesn't it mean it's already paired and you don't need to repair?
Johan
^ permalink raw reply
* Re: [PATCH] unit/ringbuf: Fix memory leak
From: Johan Hedberg @ 2014-01-27 18:09 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1390811769-11861-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Mon, Jan 27, 2014, Andrei Emeltchenko wrote:
> free allocated memory before exit
> ---
> src/shared/ringbuf.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
Applied. Thanks.
Johan
^ permalink raw reply
* [PATCH BlueZ v4 18/18] bluetooth.conf: Add ObjectManager interface
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>
---
src/bluetooth.conf | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/bluetooth.conf b/src/bluetooth.conf
index 0495200..ad8891a 100644
--- a/src/bluetooth.conf
+++ b/src/bluetooth.conf
@@ -18,6 +18,7 @@
<allow send_interface="org.bluez.Profile1"/>
<allow send_interface="org.bluez.HeartRateWatcher1"/>
<allow send_interface="org.bluez.CyclingSpeedWatcher1"/>
+ <allow send_interface="org.freedesktop.DBus.ObjectManager"/>
</policy>
<policy at_console="true">
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v4 17/18] gatttool: Add unix socket support for interactive mode
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>
This patch allows running GATT operations over unix socket on
interactive mode.
---
attrib/interactive.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/attrib/interactive.c b/attrib/interactive.c
index 70c091c..67e060e 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -84,7 +84,7 @@ static char *get_prompt(void)
if (opt_dst)
g_string_append_printf(prompt, "[%17s]", opt_dst);
else
- g_string_append_printf(prompt, "[%17s]", "");
+ g_string_append_printf(prompt, "[LOCAL]");
if (conn_state == STATE_CONNECTED)
g_string_append(prompt, COLOR_OFF);
@@ -405,15 +405,18 @@ static void cmd_connect(int argcp, char **argvp)
opt_dst_type = g_strdup("public");
}
- if (opt_dst == NULL) {
- error("Remote Bluetooth address required\n");
- return;
+ if (opt_dst) {
+
+ rl_printf("Attempting to connect to %s\n", opt_dst);
+ set_state(STATE_CONNECTING);
+ iochannel = gatt_connect(opt_src, opt_dst, opt_dst_type,
+ opt_sec_level, opt_psm, opt_mtu,
+ connect_cb, &gerr);
+ } else {
+ rl_printf("Local connection\n");
+ iochannel = unix_connect(connect_cb, &gerr);
}
- rl_printf("Attempting to connect to %s\n", opt_dst);
- set_state(STATE_CONNECTING);
- iochannel = gatt_connect(opt_src, opt_dst, opt_dst_type, opt_sec_level,
- opt_psm, opt_mtu, connect_cb, &gerr);
if (iochannel == NULL) {
set_state(STATE_DISCONNECTED);
error("%s\n", gerr->message);
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v4 16/18] gatttool: Add unix socket connect
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>
This patch adds the initial support for GATT procedures over unix
socket transport on command line mode (one-shot command). Temporary
solution to allow local GATT procedures testing.
---
attrib/gatttool.c | 27 ++++++++++++++++++++-------
attrib/gatttool.h | 1 +
attrib/utils.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 75 insertions(+), 7 deletions(-)
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 9f2ead9..cf106de 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -29,7 +29,6 @@
#include <errno.h>
#include <glib.h>
#include <stdlib.h>
-#include <unistd.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
@@ -53,6 +52,7 @@ static int opt_end = 0xffff;
static int opt_handle = -1;
static int opt_mtu = 0;
static int opt_psm = 0;
+static gboolean opt_local = FALSE;
static gboolean opt_primary = FALSE;
static gboolean opt_characteristics = FALSE;
static gboolean opt_char_read = FALSE;
@@ -511,6 +511,8 @@ static GOptionEntry options[] = {
"Specify local adapter interface", "hciX" },
{ "device", 'b', 0, G_OPTION_ARG_STRING, &opt_dst,
"Specify remote Bluetooth address", "MAC" },
+ { "local", 'L', 0, G_OPTION_ARG_NONE, &opt_local,
+ "Use unix socket transport (local communication)", NULL },
{ "addr-type", 't', 0, G_OPTION_ARG_STRING, &opt_dst_type,
"Set LE address type. Default: public", "[public | random]"},
{ "mtu", 'm', 0, G_OPTION_ARG_INT, &opt_mtu,
@@ -563,6 +565,11 @@ int main(int argc, char *argv[])
g_clear_error(&gerr);
}
+ if (opt_local) {
+ opt_src = NULL;
+ opt_dst = NULL;
+ }
+
if (opt_interactive) {
interactive(opt_src, opt_dst, opt_dst_type, opt_psm);
goto done;
@@ -588,14 +595,20 @@ int main(int argc, char *argv[])
goto done;
}
- if (opt_dst == NULL) {
- g_print("Remote Bluetooth address required\n");
- got_error = TRUE;
- goto done;
+ if (opt_local)
+ chan = unix_connect(connect_cb, &gerr);
+ else {
+ if (opt_dst == NULL) {
+ g_print("Remote Bluetooth address required\n");
+ got_error = TRUE;
+ goto done;
+ }
+
+ chan = gatt_connect(opt_src, opt_dst, opt_dst_type,
+ opt_sec_level, opt_psm, opt_mtu,
+ connect_cb, &gerr);
}
- chan = gatt_connect(opt_src, opt_dst, opt_dst_type, opt_sec_level,
- opt_psm, opt_mtu, connect_cb, &gerr);
if (chan == NULL) {
g_printerr("%s\n", gerr->message);
g_clear_error(&gerr);
diff --git a/attrib/gatttool.h b/attrib/gatttool.h
index 8f0913c..be8e236 100644
--- a/attrib/gatttool.h
+++ b/attrib/gatttool.h
@@ -27,4 +27,5 @@ GIOChannel *gatt_connect(const char *src, const char *dst,
const char *dst_type, const char *sec_level,
int psm, int mtu, BtIOConnect connect_cb,
GError **gerr);
+GIOChannel *unix_connect(BtIOConnect connect_cb, GError **gerr);
size_t gatt_attr_data_from_string(const char *str, uint8_t **data);
diff --git a/attrib/utils.c b/attrib/utils.c
index 17f02be..7d2966f 100644
--- a/attrib/utils.c
+++ b/attrib/utils.c
@@ -25,7 +25,12 @@
#include "config.h"
#endif
+#include <errno.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
#include <glib.h>
#include <bluetooth/bluetooth.h>
@@ -101,6 +106,55 @@ GIOChannel *gatt_connect(const char *src, const char *dst,
return chan;
}
+static gboolean unix_connect_cb(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ BtIOConnect connect_cb = user_data;
+ GError *gerr;
+
+ if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
+ gerr = g_error_new_literal(G_IO_CHANNEL_ERROR,
+ G_IO_CHANNEL_ERROR_FAILED,
+ "connection attempt failed");
+ connect_cb(io, gerr, user_data);
+ g_clear_error(&gerr);
+ } else {
+ connect_cb(io, NULL, user_data);
+ }
+
+ return FALSE;
+}
+
+GIOChannel *unix_connect(BtIOConnect connect_cb, GError **gerr)
+{
+ GIOChannel *io;
+ struct sockaddr_un uaddr = {
+ .sun_family = AF_UNIX,
+ .sun_path = "\0/bluetooth/unix_att",
+ };
+ int sk;
+
+ sk = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC , 0);
+ if (sk < 0) {
+ g_set_error_literal(gerr, G_IO_CHANNEL_ERROR,
+ G_IO_CHANNEL_ERROR_FAILED, strerror(errno));
+ return NULL;
+ }
+
+ if (connect(sk, (struct sockaddr *) &uaddr, sizeof(uaddr)) < 0) {
+ g_set_error_literal(gerr, G_IO_CHANNEL_ERROR,
+ G_IO_CHANNEL_ERROR_FAILED, strerror(errno));
+ close(sk);
+ return NULL;
+ }
+
+ io = g_io_channel_unix_new(sk);
+ g_io_add_watch(io, G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ unix_connect_cb, connect_cb);
+
+ return io;
+}
+
size_t gatt_attr_data_from_string(const char *str, uint8_t **data)
{
char tmp[3];
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v4 15/18] test: Add registering external service
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>
This patch extends gatt-service to call RegisterService() when org.bluez
service gets connected to the system bus.
---
test/gatt-service.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
diff --git a/test/gatt-service.c b/test/gatt-service.c
index 5452599..acecf2a 100644
--- a/test/gatt-service.c
+++ b/test/gatt-service.c
@@ -35,6 +35,7 @@
#include <dbus/dbus.h>
#include <gdbus/gdbus.h>
+#define GATT_MGR_IFACE "org.bluez.GattManager1"
#define SERVICE_IFACE "org.bluez.GattService1"
/* Immediate Alert Service UUID */
@@ -115,6 +116,65 @@ static void create_services(DBusConnection *conn)
printf("Registered service: %s\n", service_path);
}
+static void register_external_service_reply(DBusPendingCall *call,
+ void *user_data)
+{
+ DBusMessage *reply = dbus_pending_call_steal_reply(call);
+ DBusError derr;
+
+ dbus_error_init(&derr);
+ dbus_set_error_from_message(&derr, reply);
+
+ if (dbus_error_is_set(&derr))
+ printf("RegisterService: %s\n", derr.message);
+ else
+ printf("RegisterService: OK\n");
+
+ dbus_message_unref(reply);
+ dbus_error_free(&derr);
+}
+
+static void register_external_service(gpointer a, gpointer b)
+{
+ DBusConnection *conn = b;
+ const char *path = a;
+ DBusMessage *msg;
+ DBusPendingCall *call;
+ DBusMessageIter iter, dict;
+
+ msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
+ GATT_MGR_IFACE, "RegisterService");
+ if (msg == NULL) {
+ printf("Couldn't allocate D-Bus message\n");
+ return;
+ }
+
+ dbus_message_iter_init_append(msg, &iter);
+
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &path);
+
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &dict);
+
+ /* TODO: Add options dictionary */
+
+ dbus_message_iter_close_container(&iter, &dict);
+
+ if (g_dbus_send_message_with_reply(conn, msg, &call, -1) == FALSE) {
+ dbus_message_unref(msg);
+ return;
+ }
+
+ dbus_pending_call_set_notify(call, register_external_service_reply,
+ NULL, NULL);
+
+ dbus_pending_call_unref(call);
+}
+
+static void connect_handler(DBusConnection *conn, void *user_data)
+{
+ g_slist_foreach(services, register_external_service, conn);
+}
+
static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
gpointer user_data)
{
@@ -186,6 +246,7 @@ static guint setup_signalfd(void)
int main(int argc, char *argv[])
{
+ GDBusClient *client;
DBusConnection *dbus_conn;
guint signal;
@@ -204,8 +265,14 @@ int main(int argc, char *argv[])
create_services(dbus_conn);
+ client = g_dbus_client_new(dbus_conn, "org.bluez", "/org/bluez");
+
+ g_dbus_client_set_connect_watch(client, connect_handler, NULL);
+
g_main_loop_run(main_loop);
+ g_dbus_client_unref(client);
+
g_source_remove(signal);
g_slist_free_full(services, g_free);
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v4 14/18] test: Add signal handling for gatt-service
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>
This patch implements signal handling to run cleanup tasks before
exiting.
---
test/gatt-service.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
diff --git a/test/gatt-service.c b/test/gatt-service.c
index 1cb0913..5452599 100644
--- a/test/gatt-service.c
+++ b/test/gatt-service.c
@@ -27,6 +27,9 @@
#include <errno.h>
#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/signalfd.h>
#include <glib.h>
#include <dbus/dbus.h>
@@ -112,9 +115,83 @@ static void create_services(DBusConnection *conn)
printf("Registered service: %s\n", service_path);
}
+static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
+ gpointer user_data)
+{
+ static bool __terminated = false;
+ struct signalfd_siginfo si;
+ ssize_t result;
+ int fd;
+
+ if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP))
+ return FALSE;
+
+ fd = g_io_channel_unix_get_fd(channel);
+
+ result = read(fd, &si, sizeof(si));
+ if (result != sizeof(si))
+ return FALSE;
+
+ switch (si.ssi_signo) {
+ case SIGINT:
+ case SIGTERM:
+ if (!__terminated) {
+ printf("Terminating\n");
+ g_main_loop_quit(main_loop);
+ }
+
+ __terminated = true;
+ break;
+ }
+
+ return TRUE;
+}
+
+static guint setup_signalfd(void)
+{
+ GIOChannel *channel;
+ guint source;
+ sigset_t mask;
+ int fd;
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGINT);
+ sigaddset(&mask, SIGTERM);
+
+ if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
+ perror("Failed to set signal mask");
+ return 0;
+ }
+
+ fd = signalfd(-1, &mask, 0);
+ if (fd < 0) {
+ perror("Failed to create signal descriptor");
+ return 0;
+ }
+
+ channel = g_io_channel_unix_new(fd);
+
+ g_io_channel_set_close_on_unref(channel, TRUE);
+ g_io_channel_set_encoding(channel, NULL, NULL);
+ g_io_channel_set_buffered(channel, FALSE);
+
+ source = g_io_add_watch(channel,
+ G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ signal_handler, NULL);
+
+ g_io_channel_unref(channel);
+
+ return source;
+}
+
int main(int argc, char *argv[])
{
DBusConnection *dbus_conn;
+ guint signal;
+
+ signal = setup_signalfd();
+ if (signal == 0)
+ return -errno;
dbus_conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
@@ -129,6 +206,8 @@ int main(int argc, char *argv[])
g_main_loop_run(main_loop);
+ g_source_remove(signal);
+
g_slist_free_full(services, g_free);
dbus_connection_unref(dbus_conn);
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v4 13/18] gitignore: Add test/gatt-service
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index e2b23fc..5e5880f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -75,6 +75,7 @@ test/sap_client.pyc
test/bluezutils.pyc
unit/test-ringbuf
unit/test-queue
+test/gatt-service
unit/test-eir
unit/test-uuid
unit/test-crc
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v4 12/18] test: Add external service GATT skeleton
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>
This patch adds the initial code for an external GATT service example.
It implements the API defined at doc/gatt-api.txt
---
Makefile.tools | 5 ++
test/gatt-service.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 141 insertions(+)
create mode 100644 test/gatt-service.c
diff --git a/Makefile.tools b/Makefile.tools
index 9199222..a468272 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -374,3 +374,8 @@ test_scripts += test/sap_client.py test/bluezutils.py \
test/test-heartrate test/test-alert test/test-hfp \
test/test-cyclingspeed test/opp-client test/ftp-client \
test/pbap-client test/map-client
+
+noinst_PROGRAMS += test/gatt-service
+
+test_gatt_service_SOURCES = test/gatt-service.c
+test_gatt_service_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ gdbus/libgdbus-internal.la
diff --git a/test/gatt-service.c b/test/gatt-service.c
new file mode 100644
index 0000000..1cb0913
--- /dev/null
+++ b/test/gatt-service.c
@@ -0,0 +1,136 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2013 Instituto Nokia de Tecnologia - INdT
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <gdbus/gdbus.h>
+
+#define SERVICE_IFACE "org.bluez.GattService1"
+
+/* Immediate Alert Service UUID */
+#define IAS_UUID "00001802-0000-1000-8000-00805f9b34fb"
+
+static GMainLoop *main_loop;
+static GSList *services;
+
+static gboolean service_get_uuid(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *user_data)
+{
+ const char *uuid = user_data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &uuid);
+
+ return TRUE;
+}
+
+static gboolean service_get_includes(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *user_data)
+{
+ return TRUE;
+}
+
+static gboolean service_exist_includes(const GDBusPropertyTable *property,
+ void *user_data)
+{
+ return FALSE;
+}
+
+static DBusMessage *service_release(DBusConnection *conn,
+ DBusMessage *msg, void *user_data)
+{
+ printf("Terminating...\n");
+
+ g_main_loop_quit(main_loop);
+
+ return NULL;
+}
+
+static const GDBusMethodTable service_methods[] = {
+ { GDBUS_NOREPLY_METHOD("Release", NULL, NULL, service_release) },
+ { }
+};
+
+static const GDBusPropertyTable service_properties[] = {
+ { "UUID", "s", service_get_uuid },
+ { "Includes", "ao", service_get_includes, NULL,
+ service_exist_includes },
+ { }
+};
+
+static char *register_service(DBusConnection *conn, const char *uuid)
+{
+ static int id = 1;
+ char *path;
+
+ path = g_strdup_printf("/service%d", id++);
+ if (g_dbus_register_interface(conn, path, SERVICE_IFACE,
+ service_methods, NULL, service_properties,
+ g_strdup(uuid), g_free) == FALSE) {
+ printf("Couldn't register service interface\n");
+ g_free(path);
+ return NULL;
+ }
+
+ return path;
+}
+
+static void create_services(DBusConnection *conn)
+{
+ char *service_path;
+
+ service_path = register_service(conn, IAS_UUID);
+
+ services = g_slist_prepend(services, service_path);
+
+ printf("Registered service: %s\n", service_path);
+}
+
+int main(int argc, char *argv[])
+{
+ DBusConnection *dbus_conn;
+
+ dbus_conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
+
+ main_loop = g_main_loop_new(NULL, FALSE);
+
+ g_dbus_attach_object_manager(dbus_conn);
+
+ printf("gatt-service unique name: %s\n",
+ dbus_bus_get_unique_name(dbus_conn));
+
+ create_services(dbus_conn);
+
+ g_main_loop_run(main_loop);
+
+ g_slist_free_full(services, g_free);
+ dbus_connection_unref(dbus_conn);
+
+ return 0;
+}
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ v4 11/18] gatt: Add Discover All Primary Services
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: claudio.takahasi, Alvaro Silva
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>
From: Alvaro Silva <alvaro.silva@openbossa.org>
This patch adds ATT Read By Group request handling to the attribute
server. It is the primitive to implement Discover All Primary Services
procedure.
---
src/gatt.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 131 insertions(+), 4 deletions(-)
diff --git a/src/gatt.c b/src/gatt.c
index 04186b6..42d2440 100644
--- a/src/gatt.c
+++ b/src/gatt.c
@@ -107,14 +107,138 @@ static int send_error(int sk, uint8_t opcode, uint16_t handle, uint8_t ecode)
return write(sk, pdu, plen);
}
+static void read_by_group_resp(int sk, uint16_t start,
+ uint16_t end, bt_uuid_t *pattern)
+{
+ uint8_t opdu[ATT_DEFAULT_LE_MTU];
+ GList *list;
+ struct btd_attribute *last = NULL;
+ uint8_t *group_start, *group_end = NULL, *group_uuid;
+ unsigned int uuid_type = BT_UUID_UNSPEC;
+ size_t group_len = 0, plen = 0;
+
+ /*
+ * Read By Group Type Response format:
+ * Attribute Opcode: 1 byte
+ * Length: 1 byte (size of each group)
+ * Group: start | end | <<UUID>>
+ */
+
+ opdu[0] = ATT_OP_READ_BY_GROUP_RESP;
+ group_start = &opdu[2];
+ group_uuid = &opdu[6];
+
+ for (list = local_attribute_db; list;
+ last = list->data, list = g_list_next(list)) {
+ struct btd_attribute *attr = list->data;
+
+ if (attr->handle < start)
+ continue;
+
+ if (attr->handle > end)
+ break;
+
+ if (bt_uuid_cmp(&attr->type, pattern) != 0)
+ continue;
+
+ if (uuid_type != BT_UUID_UNSPEC &&
+ uuid_type != attr->type.type) {
+ /*
+ * Groups should contain the same length: UUID16 and
+ * UUID128 should be sent on different ATT PDUs
+ */
+ break;
+ }
+
+ /*
+ * MTU checking should not be shifted up, otherwise the
+ * handle of last end group will not be set properly.
+ */
+ if ((plen + group_len) >= ATT_DEFAULT_LE_MTU)
+ break;
+
+ /* Start Grouping handle */
+ att_put_u16(attr->handle, group_start);
+
+ /* Grouping <<UUID>>: Value is little endian */
+ memcpy(group_uuid, attr->value, attr->value_len);
+
+ if (last && group_end) {
+ att_put_u16(last->handle, group_end);
+ group_end += group_len;
+ plen += group_len;
+ }
+
+ /* Grouping initial settings: First grouping */
+ if (uuid_type == BT_UUID_UNSPEC) {
+ uuid_type = attr->type.type;
+
+ /* start(0xXXXX) | end(0xXXXX) | <<UUID>> */
+ group_len = 2 + 2 + bt_uuid_len(&attr->type);
+
+ /* 2: ATT Opcode and Length */
+ plen = 2 + group_len;
+
+ /* Size of each Attribute Data */
+ opdu[1] = group_len;
+
+ group_end = &opdu[4];
+ }
+
+ group_start += group_len;
+ group_uuid += group_len;
+ }
+
+ if (plen == 0) {
+ send_error(sk, ATT_OP_READ_BY_GROUP_REQ, start,
+ ATT_ECODE_ATTR_NOT_FOUND);
+ return;
+ }
+
+ if (group_end)
+ att_put_u16(last->handle, group_end);
+
+ write(sk, opdu, plen);
+}
+
+static void read_by_group(int sk, const uint8_t *ipdu, ssize_t ilen)
+{
+ uint16_t decoded, start, end;
+ bt_uuid_t pattern;
+
+ decoded = dec_read_by_grp_req(ipdu, ilen, &start, &end, &pattern);
+ if (decoded == 0) {
+ send_error(sk, ipdu[0], 0x0000, ATT_ECODE_INVALID_PDU);
+ return;
+ }
+
+ if (start > end || start == 0x0000) {
+ send_error(sk, ipdu[0], start, ATT_ECODE_INVALID_HANDLE);
+ return;
+ }
+
+ /*
+ * Restricting Read By Group Type to <<Primary>>.
+ * Removing the checking below requires changes to support
+ * dynamic values(defined in the upper layer) and additional
+ * security verification.
+ */
+ if (bt_uuid_cmp(&pattern, &primary_uuid) != 0) {
+ send_error(sk, ipdu[0], start, ATT_ECODE_UNSUPP_GRP_TYPE);
+ return;
+ }
+
+ read_by_group_resp(sk, start, end, &pattern);
+}
+
static bool channel_handler_cb(struct io *io, void *user_data)
{
uint8_t ipdu[ATT_DEFAULT_LE_MTU];
- ssize_t len;
+ ssize_t ilen;
int sk = io_get_fd(io);
- len = read(sk, ipdu, sizeof(ipdu));
- if (len < 0) {
+ ilen = read(sk, ipdu, sizeof(ipdu));
+ if (ilen < 0) {
int err = errno;
DBG("ATT channel read: %s(%d)", strerror(err), err);
return false;
@@ -136,11 +260,14 @@ static bool channel_handler_cb(struct io *io, void *user_data)
case ATT_OP_READ_MULTI_REQ:
case ATT_OP_PREP_WRITE_REQ:
case ATT_OP_EXEC_WRITE_REQ:
- case ATT_OP_READ_BY_GROUP_REQ:
case ATT_OP_SIGNED_WRITE_CMD:
send_error(sk, ipdu[0], 0x0000, ATT_ECODE_REQ_NOT_SUPP);
break;
+ case ATT_OP_READ_BY_GROUP_REQ:
+ read_by_group(sk, ipdu, ilen);
+ break;
+
/* Responses */
case ATT_OP_MTU_RESP:
case ATT_OP_FIND_INFO_RESP:
--
1.8.3.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox