All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/14] input: remove unneeded header inclusions
@ 2012-07-09 21:10 Gustavo Padovan
  2012-07-09 21:10 ` [PATCH 02/14] serial: remove the whole serial code Gustavo Padovan
                   ` (7 more replies)
  0 siblings, 8 replies; 10+ messages in thread
From: Gustavo Padovan @ 2012-07-09 21:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

---
 input/device.c  |    5 -----
 input/fakehid.c |    4 ----
 input/manager.c |    3 ---
 3 files changed, 12 deletions(-)

diff --git a/input/device.c b/input/device.c
index 7eac71e..829ca03 100644
--- a/input/device.c
+++ b/input/device.c
@@ -29,9 +29,6 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
 
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/hidp.h>
@@ -39,8 +36,6 @@
 #include <bluetooth/sdp_lib.h>
 #include <bluetooth/uuid.h>
 
-#include <glib.h>
-#include <dbus/dbus.h>
 #include <gdbus.h>
 
 #include "log.h"
diff --git a/input/fakehid.c b/input/fakehid.c
index 3181538..3be1489 100644
--- a/input/fakehid.c
+++ b/input/fakehid.c
@@ -25,12 +25,8 @@
 #include <config.h>
 #endif
 
-#include <stdio.h>
-#include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <stdlib.h>
-#include <sys/types.h>
 
 #include <bluetooth/bluetooth.h>
 
diff --git a/input/manager.c b/input/manager.c
index 01f83ce..928a2f5 100644
--- a/input/manager.c
+++ b/input/manager.c
@@ -28,13 +28,10 @@
 #include <errno.h>
 
 #include <bluetooth/bluetooth.h>
-#include <bluetooth/hci.h>
 #include <bluetooth/sdp.h>
 #include <bluetooth/sdp_lib.h>
 #include <bluetooth/uuid.h>
 
-#include <gdbus.h>
-
 #include "log.h"
 #include "../src/adapter.h"
 #include "../src/device.h"
-- 
1.7.10.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 02/14] serial: remove the whole serial code
  2012-07-09 21:10 [PATCH 01/14] input: remove unneeded header inclusions Gustavo Padovan
@ 2012-07-09 21:10 ` Gustavo Padovan
  2012-07-09 21:10 ` [PATCH 03/14] btmgmt: move to tools folder Gustavo Padovan
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Gustavo Padovan @ 2012-07-09 21:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

---
 Makefile.am        |   20 +-
 acinclude.m4       |    6 -
 doc/serial-api.txt |  138 +-----
 serial/main.c      |   59 ---
 serial/manager.c   |  174 -------
 serial/manager.h   |   25 --
 serial/port.c      |  646 --------------------------
 serial/port.h      |   29 --
 serial/proxy.c     | 1269 ----------------------------------------------------
 serial/proxy.h     |   25 --
 serial/serial.conf |   10 -
 11 files changed, 6 insertions(+), 2395 deletions(-)
 delete mode 100644 serial/main.c
 delete mode 100644 serial/manager.c
 delete mode 100644 serial/manager.h
 delete mode 100644 serial/port.c
 delete mode 100644 serial/port.h
 delete mode 100644 serial/proxy.c
 delete mode 100644 serial/proxy.h
 delete mode 100644 serial/serial.conf

diff --git a/Makefile.am b/Makefile.am
index 97146c9..a2c85e2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -191,14 +191,6 @@ builtin_modules += hog
 builtin_sources += input/hog_device.h input/hog_device.c
 endif
 
-if SERIALPLUGIN
-builtin_modules += serial
-builtin_sources += serial/main.c \
-			serial/manager.h serial/manager.c \
-			serial/proxy.h serial/proxy.c \
-			serial/port.h serial/port.c
-endif
-
 if NETWORKPLUGIN
 builtin_modules += network
 builtin_sources += network/main.c \
@@ -334,11 +326,10 @@ endif
 
 EXTRA_DIST += src/genbuiltin src/bluetooth.conf src/org.bluez.service \
 			src/main.conf network/network.conf \
-			input/input.conf serial/serial.conf \
+			input/input.conf proximity/proximity.conf \
 			audio/audio.conf audio/telephony-dummy.c \
 			audio/telephony-maemo5.c audio/telephony-ofono.c \
-			audio/telephony-maemo6.c sap/sap-dummy.c sap/sap-u8500.c \
-			proximity/proximity.conf
+			audio/telephony-maemo6.c sap/sap-dummy.c sap/sap-u8500.c
 
 if AUDIOPLUGIN
 if GSTREAMER
@@ -392,10 +383,9 @@ EXTRA_DIST += scripts/bluetooth-hid2hci.rules scripts/bluetooth-serial.rules
 EXTRA_DIST += doc/manager-api.txt \
 		doc/adapter-api.txt doc/device-api.txt \
 		doc/service-api.txt doc/agent-api.txt doc/attribute-api.txt \
-		doc/serial-api.txt doc/network-api.txt \
-		doc/input-api.txt doc/audio-api.txt doc/control-api.txt \
-		doc/hfp-api.txt doc/health-api.txt doc/sap-api.txt \
-		doc/media-api.txt doc/assigned-numbers.txt
+		doc/network-api.txt doc/input-api.txt doc/audio-api.txt \
+		doc/control-api.txt doc/hfp-api.txt doc/health-api.txt \
+		doc/sap-api.txt doc/media-api.txt doc/assigned-numbers.txt
 
 AM_YFLAGS = -d
 
diff --git a/acinclude.m4 b/acinclude.m4
index 3a2a50a..842eea3 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -172,7 +172,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	gstreamer_enable=${gstreamer_found}
 	audio_enable=yes
 	input_enable=yes
-	serial_enable=yes
 	network_enable=yes
 	sap_enable=no
 	service_enable=yes
@@ -218,10 +217,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	])
 	AC_SUBST([SAP_DRIVER], [sap-${sap_driver}.c])
 
-	AC_ARG_ENABLE(serial, AC_HELP_STRING([--disable-serial], [disable serial plugin]), [
-		serial_enable=${enableval}
-	])
-
 	AC_ARG_ENABLE(input, AC_HELP_STRING([--disable-input], [disable input plugin]), [
 		input_enable=${enableval}
 	])
@@ -345,7 +340,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	AM_CONDITIONAL(GSTREAMER, test "${gstreamer_enable}" = "yes" && test "${gstreamer_found}" = "yes")
 	AM_CONDITIONAL(AUDIOPLUGIN, test "${audio_enable}" = "yes")
 	AM_CONDITIONAL(INPUTPLUGIN, test "${input_enable}" = "yes")
-	AM_CONDITIONAL(SERIALPLUGIN, test "${serial_enable}" = "yes")
 	AM_CONDITIONAL(NETWORKPLUGIN, test "${network_enable}" = "yes")
 	AM_CONDITIONAL(SAPPLUGIN, test "${sap_enable}" = "yes")
 	AM_CONDITIONAL(SERVICEPLUGIN, test "${service_enable}" = "yes")
diff --git a/doc/serial-api.txt b/doc/serial-api.txt
index 0bdbdcd..9bb0054 100644
--- a/doc/serial-api.txt
+++ b/doc/serial-api.txt
@@ -11,22 +11,7 @@ Service		org.bluez
 Interface	org.bluez.Serial
 Object path	[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX
 
-Methods		string Connect(string pattern)
-
-			Connects to a specific RFCOMM based service on a
-			remote device and then creates a RFCOMM TTY
-			device for it. The RFCOMM TTY device is returned.
-
-			Possible patterns: UUID 128 bit as string
-					   Profile short names, e.g: spp, dun
-					   RFCOMM channel as string, 1-30
-
-			Possible errors: org.bluez.Error.InvalidArguments
-					 org.bluez.Error.InProgress
-					 org.bluez.Error.ConnectionAttemptFailed
-					 org.bluez.Error.NotSupported
-
-Methods		fd ConnectFD(string pattern) [experimental]
+Methods		fd Connect(string pattern)
 
 			Connects to a specific RFCOMM based service on a
 			remote device and returns a file descriptor to talk
@@ -40,124 +25,3 @@ Methods		fd ConnectFD(string pattern) [experimental]
 					 org.bluez.Error.InProgress
 					 org.bluez.Error.ConnectionAttemptFailed
 					 org.bluez.Error.NotSupported
-
-
-		void Disconnect(string device)
-
-			Disconnect a RFCOMM TTY device that has been
-			created by Connect method.
-
-			To abort a connection attempt in case of errors or
-			timeouts in the client it is fine to call this method.
-
-			In that case one of patterns of the Connect method should
-			be supplied instead of the TTY device.
-
-			Possible errors: org.bluez.Error.InvalidArguments
-					 org.bluez.Error.DoesNotExist
-
-Serial Proxy Manager hierarchy [experimental]
-=============================================
-
-Service		org.bluez
-Interface	org.bluez.SerialProxyManager
-Object path	[variable prefix]/{hci0,hci1,...}
-
-Methods		array{string} ListProxies()
-
-			Returns an array of the object path strings of
-			all the proxies created for the adapter.
-
-		string CreateProxy(string pattern, string address)
-
-			Possible patterns: UUID 128 bit as string
-					   Profile short names, e.g: spp, dun
-					   RFCOMM channel as string, 1-30
-
-			Address is the path to the TTY or Unix socket to be used.
-			Only one proxy per address (TTY or Unix socket)
-			is allowed.
-
-			The object path of created proxy is returned.
-			On success this will emit a ProxyCreated signal.
-
-			Possible Errors: org.bluez.Error.InvalidArguments
-					 org.bluez.Error.AlreadyExists
-					 org.bluez.Error.Failed
-
-		void RemoveProxy(string path)
-
-			This removes the proxy object at the given path.
-			On success this will emit a ProxyRemoved signal.
-
-			Possible Errors: org.bluez.Error.DoesNotExist
-					 org.bluez.Error.NotAuthorized
-
-Signals		ProxyCreated(string path)
-
-			This signal indicates a proxy was created.
-			Parameter is object path of created proxy.
-
-		ProxyRemoved(string path)
-
-			This signal indicates a proxy was removed.
-			Parameter is object path of removed proxy.
-
-Serial Proxy hierarchy [experimental]
-=====================================
-
-Service		org.bluez
-Interface	org.bluez.SerialProxy
-Object path	[variable prefix]/{hci0,hci1,...}/{proxy0,proxy1,...}
-
-Methods		void Enable()
-
-			Starts to listen to the TTY or Unix socket, allocates
-			a RFCOMM channel and add record to the server.
-
-			Possible errors: org.bluez.Error.Failed
-
-		void Disable()
-
-			Stops to listen to the TTY or Unix socket, shutdown
-			the RFCOMM channel allocated for the proxy, and remove
-			record from the server.
-
-			Possible errors: org.bluez.Error.Failed
-
-		dict GetInfo()
-
-			Returns all properties for the proxy. See the
-			properties section for available properties.
-
-		void SetSerialParameters(string rate, uint8 data, uint8 stop,
-			string parity)
-
-			Configures serial communication setting baud rate,
-			data bits, stop bits and parity.
-
-			Doesn't allow change TTY settings if it is open.
-
-			Possible errors: org.bluez.Error.InvalidArguments
-					 org.bluez.Error.NotAuthorized
-
-Properties	string uuid [readonly]
-
-			128-bit UUID that represents the available remote service.
-
-		string address [readonly]
-
-			Address is the path to the TTY or Unix socket name used,
-			set when the proxy was created.
-
-		uint8 channel [readonly]
-
-			RFCOMM channel.
-
-		boolean enabled [readonly]
-
-			Indicates if the proxy is currently enabled.
-
-		boolean connected [readonly]
-
-			Indicates if the proxy is currently connected.
diff --git a/serial/main.c b/serial/main.c
deleted file mode 100644
index 38ded03..0000000
--- a/serial/main.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2004-2010  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 <errno.h>
-
-#include <gdbus.h>
-
-#include "plugin.h"
-#include "manager.h"
-
-static DBusConnection *connection;
-
-static int serial_init(void)
-{
-	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
-	if (connection == NULL)
-		return -EIO;
-
-	if (serial_manager_init(connection) < 0) {
-		dbus_connection_unref(connection);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static void serial_exit(void)
-{
-	serial_manager_exit();
-
-	dbus_connection_unref(connection);
-}
-
-BLUETOOTH_PLUGIN_DEFINE(serial, VERSION,
-			BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, serial_init, serial_exit)
diff --git a/serial/manager.c b/serial/manager.c
deleted file mode 100644
index 438ba6c..0000000
--- a/serial/manager.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2004-2010  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 <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-#include <arpa/inet.h>
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/un.h>
-
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
-#include <bluetooth/rfcomm.h>
-#include <bluetooth/uuid.h>
-
-#include <glib.h>
-#include <gdbus.h>
-
-#include "../src/dbus-common.h"
-#include "adapter.h"
-#include "device.h"
-
-#include "log.h"
-
-#include "error.h"
-#include "port.h"
-#include "proxy.h"
-#include "storage.h"
-#include "manager.h"
-#include "sdpd.h"
-#include "glib-helper.h"
-
-static DBusConnection *connection = NULL;
-
-static int serial_probe(struct btd_device *device, const char *uuid)
-{
-	struct btd_adapter *adapter = device_get_adapter(device);
-	const gchar *path = device_get_path(device);
-	sdp_list_t *protos;
-	int ch;
-	bdaddr_t src, dst;
-	const sdp_record_t *rec;
-
-	DBG("path %s: %s", path, uuid);
-
-	rec = btd_device_get_record(device, uuid);
-	if (!rec)
-		return -EINVAL;
-
-	if (sdp_get_access_protos(rec, &protos) < 0)
-		return -EINVAL;
-
-	ch = sdp_get_proto_port(protos, RFCOMM_UUID);
-	sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL);
-	sdp_list_free(protos, NULL);
-
-	if (ch < 1 || ch > 30) {
-		error("Channel out of range: %d", ch);
-		return -EINVAL;
-	}
-
-	adapter_get_address(adapter, &src);
-	device_get_address(device, &dst, NULL);
-
-	return port_register(connection, path, &src, &dst, uuid, ch);
-}
-
-static void serial_remove(struct btd_device *device)
-{
-	const gchar *path = device_get_path(device);
-
-	DBG("path %s", path);
-
-	port_unregister(path);
-}
-
-
-static int port_probe(struct btd_device *device, GSList *uuids)
-{
-	while (uuids) {
-		serial_probe(device, uuids->data);
-		uuids = uuids->next;
-	}
-
-	return 0;
-}
-
-static void port_remove(struct btd_device *device)
-{
-	return serial_remove(device);
-}
-
-static struct btd_device_driver serial_port_driver = {
-	.name	= "serial-port",
-	.uuids	= BTD_UUIDS(RFCOMM_UUID_STR),
-	.probe	= port_probe,
-	.remove	= port_remove,
-};
-
-static int proxy_probe(struct btd_adapter *adapter)
-{
-	const char *path = adapter_get_path(adapter);
-
-	DBG("path %s", path);
-
-	return proxy_register(connection, adapter);
-}
-
-static void proxy_remove(struct btd_adapter *adapter)
-{
-	const char *path = adapter_get_path(adapter);
-
-	DBG("path %s", path);
-
-	proxy_unregister(adapter);
-}
-
-static struct btd_adapter_driver serial_proxy_driver = {
-	.name	= "serial-proxy",
-	.probe	= proxy_probe,
-	.remove	= proxy_remove,
-};
-
-int serial_manager_init(DBusConnection *conn)
-{
-	connection = dbus_connection_ref(conn);
-
-	btd_register_adapter_driver(&serial_proxy_driver);
-	btd_register_device_driver(&serial_port_driver);
-
-	return 0;
-}
-
-void serial_manager_exit(void)
-{
-	btd_unregister_device_driver(&serial_port_driver);
-
-	dbus_connection_unref(connection);
-	connection = NULL;
-}
diff --git a/serial/manager.h b/serial/manager.h
deleted file mode 100644
index c8b96e8..0000000
--- a/serial/manager.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2004-2010  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
- *
- */
-
-int serial_manager_init(DBusConnection *conn);
-void serial_manager_exit(void);
diff --git a/serial/port.c b/serial/port.c
deleted file mode 100644
index f90bb6a..0000000
--- a/serial/port.c
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2004-2010  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 <errno.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/rfcomm.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
-
-#include <glib.h>
-#include <gdbus.h>
-
-#include "../src/dbus-common.h"
-
-#include "log.h"
-#include "glib-helper.h"
-#include "sdp-client.h"
-#include "btio.h"
-
-#include "error.h"
-#include "manager.h"
-#include "adapter.h"
-#include "device.h"
-#include "storage.h"
-#include "port.h"
-
-#define SERIAL_PORT_INTERFACE	"org.bluez.Serial"
-
-#define MAX_OPEN_TRIES		5
-#define OPEN_WAIT		300	/* ms. udev node creation retry wait */
-
-struct serial_device {
-	DBusConnection	*conn;		/* for name listener handling */
-	bdaddr_t	src;		/* Source (local) address */
-	bdaddr_t	dst;		/* Destination address */
-	char		*path;		/* Device path */
-	GSList		*ports;		/* Available ports */
-};
-
-struct serial_port {
-	DBusMessage	*msg;		/* for name listener handling */
-	int16_t		id;		/* RFCOMM device id */
-	uint8_t		channel;	/* RFCOMM channel */
-	char		*uuid;		/* service identification */
-	char		*dev;		/* RFCOMM device name */
-	int		fd;		/* Opened file descriptor */
-	GIOChannel	*io;		/* BtIO channel */
-	guint		listener_id;
-	struct serial_device *device;
-};
-
-static GSList *devices = NULL;
-
-static struct serial_device *find_device(GSList *devices, const char *path)
-{
-	GSList *l;
-
-	for (l = devices; l != NULL; l = l->next) {
-		struct serial_device *device = l->data;
-
-		if (!strcmp(device->path, path))
-			return device;
-	}
-
-	return NULL;
-}
-
-static struct serial_port *find_port(GSList *ports, const char *pattern)
-{
-	GSList *l;
-	int channel;
-	char *endptr = NULL;
-
-	channel = strtol(pattern, &endptr, 10);
-
-	for (l = ports; l != NULL; l = l->next) {
-		struct serial_port *port = l->data;
-		char *uuid_str;
-		int ret;
-
-		if (port->uuid && !strcasecmp(port->uuid, pattern))
-			return port;
-
-		if (endptr && *endptr == '\0' && port->channel == channel)
-			return port;
-
-		if (port->dev && !strcmp(port->dev, pattern))
-			return port;
-
-		if (!port->uuid)
-			continue;
-
-		uuid_str = bt_name2string(pattern);
-		if (!uuid_str)
-			continue;
-
-		ret = strcasecmp(port->uuid, uuid_str);
-		g_free(uuid_str);
-		if (ret == 0)
-			return port;
-	}
-
-	return NULL;
-}
-
-static int port_release(struct serial_port *port)
-{
-	struct rfcomm_dev_req req;
-	int rfcomm_ctl;
-	int err = 0;
-
-	if (port->id < 0) {
-		if (port->io) {
-			g_io_channel_shutdown(port->io, TRUE, NULL);
-			g_io_channel_unref(port->io);
-			port->io = NULL;
-		} else
-			bt_cancel_discovery(&port->device->src,
-						&port->device->dst);
-
-		return 0;
-	}
-
-	DBG("Serial port %s released", port->dev);
-
-	rfcomm_ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM);
-	if (rfcomm_ctl < 0)
-		return -errno;
-
-	if (port->fd >= 0) {
-		close(port->fd);
-		port->fd = -1;
-	}
-
-	memset(&req, 0, sizeof(req));
-	req.dev_id = port->id;
-
-	/*
-	 * We are hitting a kernel bug inside RFCOMM code when
-	 * RFCOMM_HANGUP_NOW bit is set on request's flags passed to
-	 * ioctl(RFCOMMRELEASEDEV)!
-	 */
-	req.flags = (1 << RFCOMM_HANGUP_NOW);
-
-	if (ioctl(rfcomm_ctl, RFCOMMRELEASEDEV, &req) < 0) {
-		err = -errno;
-		error("Can't release device %s: %s (%d)",
-				port->dev, strerror(-err), -err);
-	}
-
-	g_free(port->dev);
-	port->dev = NULL;
-	port->id = -1;
-	close(rfcomm_ctl);
-	return err;
-}
-
-static void serial_port_free(void *data)
-{
-	struct serial_port *port = data;
-	struct serial_device *device = port->device;
-
-	if (device && port->listener_id > 0)
-		g_dbus_remove_watch(device->conn, port->listener_id);
-
-	port_release(port);
-
-	g_free(port->uuid);
-	g_free(port);
-}
-
-static void serial_device_free(void *data)
-{
-	struct serial_device *device = data;
-
-	g_free(device->path);
-	if (device->conn)
-		dbus_connection_unref(device->conn);
-	g_free(device);
-}
-
-static void port_owner_exited(DBusConnection *conn, void *user_data)
-{
-	struct serial_port *port = user_data;
-
-	port_release(port);
-
-	port->listener_id = 0;
-}
-
-static void path_unregister(void *data)
-{
-	struct serial_device *device = data;
-
-	DBG("Unregistered interface %s on path %s", SERIAL_PORT_INTERFACE,
-		device->path);
-
-	devices = g_slist_remove(devices, device);
-	serial_device_free(device);
-}
-
-void port_release_all(void)
-{
-	g_slist_free_full(devices, serial_device_free);
-}
-
-static void open_notify(int fd, int err, struct serial_port *port)
-{
-	struct serial_device *device = port->device;
-	DBusMessage *reply;
-
-	if (err < 0) {
-		/* Max tries exceeded */
-		port_release(port);
-		reply = btd_error_failed(port->msg, strerror(-err));
-	} else {
-		port->fd = fd;
-		reply = g_dbus_create_reply(port->msg,
-				DBUS_TYPE_STRING, &port->dev,
-				DBUS_TYPE_INVALID);
-	}
-
-	/* Reply to the requestor */
-	g_dbus_send_message(device->conn, reply);
-}
-
-static gboolean open_continue(gpointer user_data)
-{
-	struct serial_port *port = user_data;
-	int fd;
-	static int ntries = MAX_OPEN_TRIES;
-
-	if (!port->listener_id)
-		return FALSE; /* Owner exited */
-
-	fd = open(port->dev, O_RDONLY | O_NOCTTY);
-	if (fd < 0) {
-		int err = -errno;
-		error("Could not open %s: %s (%d)",
-				port->dev, strerror(-err), -err);
-		if (!--ntries) {
-			/* Reporting error */
-			open_notify(fd, err, port);
-			ntries = MAX_OPEN_TRIES;
-			return FALSE;
-		}
-		return TRUE;
-	}
-
-	/* Connection succeeded */
-	open_notify(fd, 0, port);
-	return FALSE;
-}
-
-static int port_open(struct serial_port *port)
-{
-	int fd;
-
-	fd = open(port->dev, O_RDONLY | O_NOCTTY);
-	if (fd < 0) {
-		g_timeout_add(OPEN_WAIT, open_continue, port);
-		return -EINPROGRESS;
-	}
-
-	return fd;
-}
-
-static void rfcomm_connect_cb(GIOChannel *chan, GError *conn_err,
-							gpointer user_data)
-{
-	struct serial_port *port = user_data;
-	struct serial_device *device = port->device;
-	struct rfcomm_dev_req req;
-	int sk, fd;
-	DBusMessage *reply;
-
-	/* Owner exited? */
-	if (!port->listener_id)
-		return;
-
-	if (conn_err) {
-		error("%s", conn_err->message);
-		reply = btd_error_failed(port->msg, conn_err->message);
-		goto fail;
-	}
-
-	sk = g_io_channel_unix_get_fd(chan);
-
-	if (dbus_message_has_member(port->msg, "ConnectFD")) {
-		reply = g_dbus_create_reply(port->msg, DBUS_TYPE_UNIX_FD, &sk,
-							DBUS_TYPE_INVALID);
-		g_dbus_send_message(device->conn, reply);
-
-		close(sk);
-
-		g_dbus_remove_watch(device->conn, port->listener_id);
-		port->listener_id = 0;
-
-		return;
-	}
-
-	memset(&req, 0, sizeof(req));
-	req.dev_id = -1;
-	req.flags = (1 << RFCOMM_REUSE_DLC);
-	bacpy(&req.src, &device->src);
-	bacpy(&req.dst, &device->dst);
-	req.channel = port->channel;
-
-	g_io_channel_unref(port->io);
-	port->io = NULL;
-
-	port->id = ioctl(sk, RFCOMMCREATEDEV, &req);
-	if (port->id < 0) {
-		int err = -errno;
-		error("ioctl(RFCOMMCREATEDEV): %s (%d)", strerror(-err), -err);
-		reply = btd_error_failed(port->msg, strerror(-err));
-		g_io_channel_shutdown(chan, TRUE, NULL);
-		goto fail;
-	}
-
-	port->dev = g_strdup_printf("/dev/rfcomm%d", port->id);
-
-	DBG("Serial port %s created", port->dev);
-
-	g_io_channel_shutdown(chan, TRUE, NULL);
-
-	/* Addressing connect port */
-	fd = port_open(port);
-	if (fd < 0)
-		/* Open in progress: Wait the callback */
-		return;
-
-	open_notify(fd, 0, port);
-	return;
-
-fail:
-	g_dbus_send_message(device->conn, reply);
-	g_dbus_remove_watch(device->conn, port->listener_id);
-	port->listener_id = 0;
-}
-
-static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
-{
-	struct serial_port *port = user_data;
-	struct serial_device *device = port->device;
-	sdp_record_t *record = NULL;
-	sdp_list_t *protos;
-	DBusMessage *reply;
-	GError *gerr = NULL;
-
-	if (!port->listener_id)
-		return;
-
-	if (err < 0) {
-		error("Unable to get service record: %s (%d)", strerror(-err),
-			-err);
-		reply = btd_error_failed(port->msg, strerror(-err));
-		goto failed;
-	}
-
-	if (!recs || !recs->data) {
-		error("No record found");
-		reply = btd_error_failed(port->msg, "No record found");
-		goto failed;
-	}
-
-	record = recs->data;
-
-	if (sdp_get_access_protos(record, &protos) < 0) {
-		error("Unable to get access protos from port record");
-		reply = btd_error_failed(port->msg, "Invalid channel");
-		goto failed;
-	}
-
-	port->channel = sdp_get_proto_port(protos, RFCOMM_UUID);
-
-	sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL);
-	sdp_list_free(protos, NULL);
-
-	port->io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, port,
-				NULL, &gerr,
-				BT_IO_OPT_SOURCE_BDADDR, &device->src,
-				BT_IO_OPT_DEST_BDADDR, &device->dst,
-				BT_IO_OPT_CHANNEL, port->channel,
-				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-				BT_IO_OPT_INVALID);
-	if (!port->io) {
-		error("%s", gerr->message);
-		reply = btd_error_failed(port->msg, gerr->message);
-		g_error_free(gerr);
-		goto failed;
-	}
-
-	return;
-
-failed:
-	g_dbus_remove_watch(device->conn, port->listener_id);
-	port->listener_id = 0;
-	g_dbus_send_message(device->conn, reply);
-}
-
-static int connect_port(struct serial_port *port)
-{
-	struct serial_device *device = port->device;
-	uuid_t uuid;
-	int err;
-
-	if (!port->uuid)
-		goto connect;
-
-	err = bt_string2uuid(&uuid, port->uuid);
-	if (err < 0)
-		return err;
-
-	sdp_uuid128_to_uuid(&uuid);
-
-	return bt_search_service(&device->src, &device->dst, &uuid,
-				get_record_cb, port, NULL);
-
-connect:
-	port->io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, port,
-				NULL, NULL,
-				BT_IO_OPT_SOURCE_BDADDR, &device->src,
-				BT_IO_OPT_DEST_BDADDR, &device->dst,
-				BT_IO_OPT_CHANNEL, port->channel,
-				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-				BT_IO_OPT_INVALID);
-	if (port->io == NULL)
-		return -EIO;
-
-	return 0;
-}
-
-static struct serial_port *create_port(struct serial_device *device,
-					const char *uuid, uint8_t channel)
-{
-	struct serial_port *port;
-
-	port = g_new0(struct serial_port, 1);
-	port->uuid = g_strdup(uuid);
-	port->channel = channel;
-	port->device = device;
-	port->id = -1;
-	port->fd = -1;
-
-	device->ports = g_slist_append(device->ports, port);
-
-	return port;
-}
-
-static DBusMessage *port_connect(DBusConnection *conn,
-					DBusMessage *msg, void *user_data)
-{
-	struct serial_device *device = user_data;
-	struct serial_port *port;
-	const char *pattern;
-	int err;
-
-	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
-						DBUS_TYPE_INVALID) == FALSE)
-		return NULL;
-
-	port = find_port(device->ports, pattern);
-	if (!port) {
-		char *endptr = NULL;
-		int channel;
-
-		channel = strtol(pattern, &endptr, 10);
-		if ((endptr && *endptr != '\0') || channel < 1 || channel > 30)
-			return btd_error_does_not_exist(msg);
-
-		port = create_port(device, NULL, channel);
-	}
-
-	if (port->listener_id)
-		return btd_error_failed(msg, "Port already in use");
-
-	port->listener_id = g_dbus_add_disconnect_watch(conn,
-						dbus_message_get_sender(msg),
-						port_owner_exited, port,
-						NULL);
-
-	port->msg = dbus_message_ref(msg);
-
-	err = connect_port(port);
-	if (err < 0) {
-		error("%s", strerror(-err));
-		g_dbus_remove_watch(conn, port->listener_id);
-		port->listener_id = 0;
-
-		return btd_error_failed(msg, strerror(-err));
-	}
-
-	return NULL;
-}
-
-static DBusMessage *port_disconnect(DBusConnection *conn,
-					DBusMessage *msg, void *user_data)
-{
-	struct serial_device *device = user_data;
-	struct serial_port *port;
-	const char *dev, *owner, *caller;
-
-	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &dev,
-						DBUS_TYPE_INVALID) == FALSE)
-		return NULL;
-
-	port = find_port(device->ports, dev);
-	if (!port)
-		return btd_error_does_not_exist(msg);
-
-	if (!port->listener_id)
-		return btd_error_not_connected(msg);
-
-	owner = dbus_message_get_sender(port->msg);
-	caller = dbus_message_get_sender(msg);
-	if (!g_str_equal(owner, caller))
-		return btd_error_not_authorized(msg);
-
-	port_release(port);
-
-	g_dbus_remove_watch(conn, port->listener_id);
-	port->listener_id = 0;
-
-	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
-}
-
-static const GDBusMethodTable port_methods[] = {
-	{ GDBUS_ASYNC_METHOD("Connect",
-		GDBUS_ARGS({ "pattern", "s" }),	GDBUS_ARGS({ "tty", "s" }),
-		port_connect) },
-	{ GDBUS_ASYNC_METHOD("ConnectFD",
-		GDBUS_ARGS({ "pattern", "s" }), GDBUS_ARGS({ "fd", "s" }),
-		port_connect) },
-	{ GDBUS_METHOD("Disconnect",
-		GDBUS_ARGS({ "device", "s" }), NULL,
-		port_disconnect) },
-	{ }
-};
-
-static struct serial_device *create_serial_device(DBusConnection *conn,
-					const char *path, bdaddr_t *src,
-					bdaddr_t *dst)
-{
-	struct serial_device *device;
-
-	device = g_new0(struct serial_device, 1);
-	device->conn = dbus_connection_ref(conn);
-	bacpy(&device->dst, dst);
-	bacpy(&device->src, src);
-	device->path = g_strdup(path);
-
-	if (!g_dbus_register_interface(conn, path,
-				SERIAL_PORT_INTERFACE,
-				port_methods, NULL, NULL,
-				device, path_unregister)) {
-		error("D-Bus failed to register %s interface",
-				SERIAL_PORT_INTERFACE);
-		serial_device_free(device);
-		return NULL;
-	}
-
-	DBG("Registered interface %s on path %s",
-		SERIAL_PORT_INTERFACE, path);
-
-	return device;
-}
-
-int port_register(DBusConnection *conn, const char *path, bdaddr_t *src,
-			bdaddr_t *dst, const char *uuid, uint8_t channel)
-{
-	struct serial_device *device;
-	struct serial_port *port;
-
-	device = find_device(devices, path);
-	if (!device) {
-		device = create_serial_device(conn, path, src, dst);
-		if (!device)
-			return -1;
-		devices = g_slist_append(devices, device);
-	}
-
-	if (find_port(device->ports, uuid))
-		return 0;
-
-	port = g_new0(struct serial_port, 1);
-	port->uuid = g_strdup(uuid);
-	port->channel = channel;
-	port->device = device;
-	port->id = -1;
-	port->fd = -1;
-
-	device->ports = g_slist_append(device->ports, port);
-
-	return 0;
-}
-
-int port_unregister(const char *path)
-{
-	struct serial_device *device;
-
-	device = find_device(devices, path);
-	if (!device)
-		return -ENOENT;
-
-	g_slist_free_full(device->ports, serial_port_free);
-
-	g_dbus_unregister_interface(device->conn, path, SERIAL_PORT_INTERFACE);
-
-	return 0;
-}
diff --git a/serial/port.h b/serial/port.h
deleted file mode 100644
index 74ac9f0..0000000
--- a/serial/port.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2004-2010  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
- *
- */
-
-void port_release_all(void);
-
-int port_register(DBusConnection *conn, const char *path, bdaddr_t *src,
-		  bdaddr_t *dst, const char *name, uint8_t channel);
-
-int port_unregister(const char *path);
diff --git a/serial/proxy.c b/serial/proxy.c
deleted file mode 100644
index dd38317..0000000
--- a/serial/proxy.c
+++ /dev/null
@@ -1,1269 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2004-2010  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 <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-#include <arpa/inet.h>
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/un.h>
-
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
-#include <bluetooth/rfcomm.h>
-
-#include <glib.h>
-#include <gdbus.h>
-
-#include "../src/dbus-common.h"
-#include "../src/adapter.h"
-
-#include "log.h"
-
-#include "error.h"
-#include "sdpd.h"
-#include "glib-helper.h"
-#include "btio.h"
-#include "proxy.h"
-
-#define SERIAL_PROXY_INTERFACE	"org.bluez.SerialProxy"
-#define SERIAL_MANAGER_INTERFACE "org.bluez.SerialProxyManager"
-#define BUF_SIZE		1024
-
-typedef enum {
-	TTY_PROXY,
-	UNIX_SOCKET_PROXY,
-	TCP_SOCKET_PROXY,
-	UNKNOWN_PROXY_TYPE = 0xFF
-} proxy_type_t;
-
-struct serial_adapter {
-	struct btd_adapter	*btd_adapter;	/* Adapter pointer */
-	DBusConnection		*conn;		/* Adapter connection */
-	GSList			*proxies;	/* Proxies list */
-};
-
-struct serial_proxy {
-	bdaddr_t	src;		/* Local address */
-	bdaddr_t	dst;		/* Remote address */
-	char		*path;		/* Proxy path */
-	char		*uuid128;	/* UUID 128 */
-	char		*address;	/* TTY or Unix socket name */
-	char		*owner;		/* Application bus name */
-	guint		watch;		/* Application watch */
-	short int	port;		/* TCP port */
-	proxy_type_t	type;		/* TTY or Unix socket */
-	struct termios  sys_ti;		/* Default TTY setting */
-	struct termios  proxy_ti;	/* Proxy TTY settings */
-	uint8_t		channel;	/* RFCOMM channel */
-	uint32_t	record_id;	/* Service record id */
-	GIOChannel	*io;		/* Server listen */
-	GIOChannel	*rfcomm;	/* Remote RFCOMM channel*/
-	GIOChannel	*local;		/* Local channel: TTY or Unix socket */
-	struct serial_adapter *adapter;	/* Adapter pointer */
-};
-
-static GSList *adapters = NULL;
-static int sk_counter = 0;
-
-static void disable_proxy(struct serial_proxy *prx)
-{
-	if (prx->rfcomm) {
-		g_io_channel_shutdown(prx->rfcomm, TRUE, NULL);
-		g_io_channel_unref(prx->rfcomm);
-		prx->rfcomm = NULL;
-	}
-
-	if (prx->local) {
-		g_io_channel_shutdown(prx->local, TRUE, NULL);
-		g_io_channel_unref(prx->local);
-		prx->local = NULL;
-	}
-
-	remove_record_from_server(prx->record_id);
-	prx->record_id = 0;
-
-	g_io_channel_unref(prx->io);
-	prx->io = NULL;
-}
-
-static void proxy_free(struct serial_proxy *prx)
-{
-	g_free(prx->owner);
-	g_free(prx->path);
-	g_free(prx->address);
-	g_free(prx->uuid128);
-	g_free(prx);
-}
-
-static sdp_record_t *proxy_record_new(const char *uuid128, uint8_t channel)
-{
-	sdp_list_t *apseq, *aproto, *profiles, *proto[2], *root, *svclass_id;
-	uuid_t uuid, root_uuid, l2cap, rfcomm;
-	sdp_profile_desc_t profile;
-	sdp_record_t *record;
-	sdp_data_t *ch;
-
-	record = sdp_record_alloc();
-	if (!record)
-		return NULL;
-
-	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
-	root = sdp_list_append(NULL, &root_uuid);
-	sdp_set_browse_groups(record, root);
-	sdp_list_free(root, NULL);
-
-	bt_string2uuid(&uuid, uuid128);
-	sdp_uuid128_to_uuid(&uuid);
-	svclass_id = sdp_list_append(NULL, &uuid);
-	sdp_set_service_classes(record, svclass_id);
-	sdp_list_free(svclass_id, NULL);
-
-	sdp_uuid16_create(&profile.uuid, SERIAL_PORT_PROFILE_ID);
-	profile.version = 0x0100;
-	profiles = sdp_list_append(NULL, &profile);
-	sdp_set_profile_descs(record, profiles);
-	sdp_list_free(profiles, NULL);
-
-	sdp_uuid16_create(&l2cap, L2CAP_UUID);
-	proto[0] = sdp_list_append(NULL, &l2cap);
-	apseq = sdp_list_append(NULL, proto[0]);
-
-	sdp_uuid16_create(&rfcomm, RFCOMM_UUID);
-	proto[1] = sdp_list_append(NULL, &rfcomm);
-	ch = sdp_data_alloc(SDP_UINT8, &channel);
-	proto[1] = sdp_list_append(proto[1], ch);
-	apseq = sdp_list_append(apseq, proto[1]);
-
-	aproto = sdp_list_append(NULL, apseq);
-	sdp_set_access_protos(record, aproto);
-
-	sdp_add_lang_attr(record);
-
-	sdp_set_info_attr(record, "Serial Proxy", NULL, "Serial Proxy");
-
-	sdp_data_free(ch);
-	sdp_list_free(proto[0], NULL);
-	sdp_list_free(proto[1], NULL);
-	sdp_list_free(apseq, NULL);
-	sdp_list_free(aproto, NULL);
-
-	return record;
-}
-
-static int channel_write(GIOChannel *chan, char *buf, size_t size)
-{
-	size_t wbytes;
-	ssize_t written;
-	int fd;
-
-	fd = g_io_channel_unix_get_fd(chan);
-
-	wbytes = 0;
-	while (wbytes < size) {
-		written = write(fd, buf + wbytes, size - wbytes);
-		if (written < 0)
-			return -errno;
-
-		wbytes += written;
-	}
-
-	return 0;
-}
-
-static gboolean forward_data(GIOChannel *chan, GIOCondition cond, gpointer data)
-{
-	char buf[BUF_SIZE];
-	struct serial_proxy *prx = data;
-	GIOChannel *dest;
-	ssize_t rbytes;
-	int fd, err;
-
-	if (cond & G_IO_NVAL)
-		return FALSE;
-
-	dest = (chan == prx->rfcomm) ? prx->local : prx->rfcomm;
-
-	fd = g_io_channel_unix_get_fd(chan);
-
-	if (cond & (G_IO_HUP | G_IO_ERR)) {
-		/* Try forward remaining data */
-		do {
-			rbytes = read(fd, buf, sizeof(buf));
-			if (rbytes <= 0)
-				break;
-
-			err = channel_write(dest, buf, rbytes);
-		} while (err == 0);
-
-		g_io_channel_shutdown(prx->local, TRUE, NULL);
-		g_io_channel_unref(prx->local);
-		prx->local = NULL;
-
-		g_io_channel_shutdown(prx->rfcomm, TRUE, NULL);
-		g_io_channel_unref(prx->rfcomm);
-		prx->rfcomm = NULL;
-
-		return FALSE;
-	}
-
-	rbytes = read(fd, buf, sizeof(buf));
-	if (rbytes < 0)
-		return FALSE;
-
-	err = channel_write(dest, buf, rbytes);
-	if (err != 0)
-		return FALSE;
-
-	return TRUE;
-}
-
-static inline int unix_socket_connect(const char *address)
-{
-	struct sockaddr_un addr;
-	int err, sk;
-
-	memset(&addr, 0, sizeof(addr));
-	addr.sun_family = PF_UNIX;
-
-	if (strncmp("x00", address, 3) == 0) {
-		/*
-		 * Abstract namespace: first byte NULL, x00
-		 * must be removed from the original address.
-		 */
-		strncpy(addr.sun_path + 1, address + 3,
-						sizeof(addr.sun_path) - 2);
-	} else {
-		/* Filesystem address */
-		strncpy(addr.sun_path, address, sizeof(addr.sun_path) - 1);
-	}
-
-	/* Unix socket */
-	sk = socket(AF_UNIX, SOCK_STREAM, 0);
-	if (sk < 0) {
-		err = -errno;
-		error("Unix socket(%s) create failed: %s(%d)",
-				address, strerror(-err), -err);
-		return err;
-	}
-
-	if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-		err = -errno;
-		error("Unix socket(%s) connect failed: %s(%d)",
-				address, strerror(-err), -err);
-		close(sk);
-		return err;
-	}
-
-	return sk;
-}
-
-static int tcp_socket_connect(const char *address)
-{
-	struct sockaddr_in addr;
-	int err, sk, port;
-
-	memset(&addr, 0, sizeof(addr));
-
-	if (strncmp(address, "localhost", 9) != 0) {
-		error("Address should have the form localhost:port.");
-		return -1;
-	}
-	port = atoi(strchr(address, ':') + 1);
-	if (port <= 0) {
-		error("Invalid port '%d'.", port);
-		return -1;
-	}
-	addr.sin_family = AF_INET;
-	addr.sin_addr.s_addr = inet_addr("127.0.0.1");
-	addr.sin_port = htons(port);
-
-	sk = socket(PF_INET, SOCK_STREAM, 0);
-	if (sk < 0) {
-		err = -errno;
-		error("TCP socket(%s) create failed %s(%d)", address,
-							strerror(-err), -err);
-		return err;
-	}
-	if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-		err = -errno;
-		error("TCP socket(%s) connect failed: %s(%d)",
-						address, strerror(-err), -err);
-		close(sk);
-		return err;
-	}
-	return sk;
-}
-
-static inline int tty_open(const char *tty, struct termios *ti)
-{
-	int err, sk;
-
-	sk = open(tty, O_RDWR | O_NOCTTY);
-	if (sk < 0) {
-		err = -errno;
-		error("Can't open TTY %s: %s(%d)", tty, strerror(-err), -err);
-		return err;
-	}
-
-	if (ti && tcsetattr(sk, TCSANOW, ti) < 0) {
-		err = -errno;
-		error("Can't change serial settings: %s(%d)",
-				strerror(-err), -err);
-		close(sk);
-		return err;
-	}
-
-	return sk;
-}
-
-static void connect_event_cb(GIOChannel *chan, GError *conn_err, gpointer data)
-{
-	struct serial_proxy *prx = data;
-	int sk;
-
-	if (conn_err) {
-		error("%s", conn_err->message);
-		goto drop;
-	}
-
-	/* Connect local */
-	switch (prx->type) {
-	case UNIX_SOCKET_PROXY:
-		sk = unix_socket_connect(prx->address);
-		break;
-	case TTY_PROXY:
-		sk = tty_open(prx->address, &prx->proxy_ti);
-		break;
-	case TCP_SOCKET_PROXY:
-		sk = tcp_socket_connect(prx->address);
-		break;
-	default:
-		sk = -1;
-	}
-
-	if (sk < 0)
-		goto drop;
-
-	prx->local = g_io_channel_unix_new(sk);
-
-	g_io_add_watch(prx->rfcomm,
-			G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-			forward_data, prx);
-
-	g_io_add_watch(prx->local,
-			G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-			forward_data, prx);
-
-	return;
-
-drop:
-	g_io_channel_shutdown(prx->rfcomm, TRUE, NULL);
-	g_io_channel_unref(prx->rfcomm);
-	prx->rfcomm = NULL;
-}
-
-static void auth_cb(DBusError *derr, void *user_data)
-{
-	struct serial_proxy *prx = user_data;
-	GError *err = NULL;
-
-	if (derr) {
-		error("Access denied: %s", derr->message);
-		goto reject;
-	}
-
-	if (!bt_io_accept(prx->rfcomm, connect_event_cb, prx, NULL,
-							&err)) {
-		error("bt_io_accept: %s", err->message);
-		g_error_free(err);
-		goto reject;
-	}
-
-	return;
-
-reject:
-	g_io_channel_shutdown(prx->rfcomm, TRUE, NULL);
-	g_io_channel_unref(prx->rfcomm);
-	prx->rfcomm = NULL;
-}
-
-static void confirm_event_cb(GIOChannel *chan, gpointer user_data)
-{
-	struct serial_proxy *prx = user_data;
-	int perr;
-	char address[18];
-	GError *err = NULL;
-
-	bt_io_get(chan, BT_IO_RFCOMM, &err,
-			BT_IO_OPT_DEST_BDADDR, &prx->dst,
-			BT_IO_OPT_DEST, address,
-			BT_IO_OPT_INVALID);
-	if (err) {
-		error("%s", err->message);
-		g_error_free(err);
-		goto drop;
-	}
-
-	if (prx->rfcomm) {
-		error("Refusing connect from %s: Proxy already in use",
-				address);
-		goto drop;
-	}
-
-	DBG("Serial Proxy: incoming connect from %s", address);
-
-	prx->rfcomm = g_io_channel_ref(chan);
-
-	perr = btd_request_authorization(&prx->src, &prx->dst,
-					prx->uuid128, auth_cb, prx);
-	if (perr < 0) {
-		error("Refusing connect from %s: %s (%d)", address,
-				strerror(-perr), -perr);
-		g_io_channel_unref(prx->rfcomm);
-		prx->rfcomm = NULL;
-		goto drop;
-	}
-
-	return;
-
-drop:
-	g_io_channel_shutdown(chan, TRUE, NULL);
-}
-
-static int enable_proxy(struct serial_proxy *prx)
-{
-	sdp_record_t *record;
-	GError *gerr = NULL;
-	int err;
-
-	if (prx->io)
-		return -EALREADY;
-
-	/* Listen */
-	prx->io = bt_io_listen(BT_IO_RFCOMM, NULL, confirm_event_cb, prx,
-				NULL, &gerr,
-				BT_IO_OPT_SOURCE_BDADDR, &prx->src,
-				BT_IO_OPT_INVALID);
-	if (!prx->io)
-		goto failed;
-
-	bt_io_get(prx->io, BT_IO_RFCOMM, &gerr,
-			BT_IO_OPT_CHANNEL, &prx->channel,
-			BT_IO_OPT_INVALID);
-	if (gerr) {
-		g_io_channel_unref(prx->io);
-		prx->io = NULL;
-		goto failed;
-	}
-
-	DBG("Allocated channel %d", prx->channel);
-
-	g_io_channel_set_close_on_unref(prx->io, TRUE);
-
-	record = proxy_record_new(prx->uuid128, prx->channel);
-	if (!record) {
-		g_io_channel_unref(prx->io);
-		return -ENOMEM;
-	}
-
-	err = add_record_to_server(&prx->src, record);
-	if (err < 0) {
-		sdp_record_free(record);
-		g_io_channel_unref(prx->io);
-		return err;
-	}
-
-	prx->record_id = record->handle;
-
-	return 0;
-
-failed:
-	error("%s", gerr->message);
-	g_error_free(gerr);
-	return -EIO;
-
-}
-static DBusMessage *proxy_enable(DBusConnection *conn,
-				DBusMessage *msg, void *data)
-{
-	struct serial_proxy *prx = data;
-	int err;
-
-	err = enable_proxy(prx);
-	if (err < 0)
-		return btd_error_failed(msg, strerror(-err));
-
-	return dbus_message_new_method_return(msg);
-}
-
-static DBusMessage *proxy_disable(DBusConnection *conn,
-				DBusMessage *msg, void *data)
-{
-	struct serial_proxy *prx = data;
-
-	if (!prx->io)
-		return btd_error_failed(msg, "Not enabled");
-
-	/* Remove the watches and unregister the record */
-	disable_proxy(prx);
-
-	return dbus_message_new_method_return(msg);
-}
-
-static DBusMessage *proxy_get_info(DBusConnection *conn,
-				DBusMessage *msg, void *data)
-{
-	struct serial_proxy *prx = data;
-	DBusMessage *reply;
-	DBusMessageIter iter, dict;
-	dbus_bool_t boolean;
-
-	reply = dbus_message_new_method_return(msg);
-	if (!reply)
-		return NULL;
-
-	dbus_message_iter_init_append(reply, &iter);
-
-	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
-			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
-			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
-			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
-
-	dict_append_entry(&dict, "uuid", DBUS_TYPE_STRING, &prx->uuid128);
-
-	dict_append_entry(&dict, "address", DBUS_TYPE_STRING, &prx->address);
-
-	if (prx->channel)
-		dict_append_entry(&dict, "channel",
-					DBUS_TYPE_BYTE, &prx->channel);
-
-	boolean = (prx->io ? TRUE : FALSE);
-	dict_append_entry(&dict, "enabled", DBUS_TYPE_BOOLEAN, &boolean);
-
-	boolean = (prx->rfcomm ? TRUE : FALSE);
-	dict_append_entry(&dict, "connected", DBUS_TYPE_BOOLEAN, &boolean);
-
-	/* If connected: append the remote address */
-	if (boolean) {
-		char bda[18];
-		const char *pstr = bda;
-
-		ba2str(&prx->dst, bda);
-		dict_append_entry(&dict, "address", DBUS_TYPE_STRING, &pstr);
-	}
-
-	dbus_message_iter_close_container(&iter, &dict);
-
-	return reply;
-}
-
-static struct {
-	const char	*str;
-	speed_t		speed;
-} supported_speed[]  = {
-	{"50",		B50	},
-	{"300",		B300	},
-	{"600",		B600	},
-	{"1200",	B1200	},
-	{"1800",	B1800	},
-	{"2400",	B2400	},
-	{"4800",	B4800	},
-	{"9600",	B9600	},
-	{"19200",	B19200	},
-	{"38400",	B38400	},
-	{"57600",	B57600	},
-	{"115200",	B115200	},
-	{ NULL,		B0	}
-};
-
-static speed_t str2speed(const char *str, speed_t *speed)
-{
-	int i;
-
-	for (i = 0; supported_speed[i].str; i++) {
-		if (strcmp(supported_speed[i].str, str) != 0)
-			continue;
-
-		if (speed)
-			*speed = supported_speed[i].speed;
-
-		return supported_speed[i].speed;
-	}
-
-	return B0;
-}
-
-static int set_parity(const char *str, tcflag_t *ctrl)
-{
-	if (strcasecmp("even", str) == 0) {
-		*ctrl |= PARENB;
-		*ctrl &= ~PARODD;
-	} else if (strcasecmp("odd", str) == 0) {
-		*ctrl |= PARENB;
-		*ctrl |= PARODD;
-	} else if (strcasecmp("mark", str) == 0)
-		*ctrl |= PARENB;
-	else if ((strcasecmp("none", str) == 0) ||
-			(strcasecmp("space", str) == 0))
-		*ctrl &= ~PARENB;
-	else
-		return -1;
-
-	return 0;
-}
-
-static int set_databits(uint8_t databits, tcflag_t *ctrl)
-{
-	if (databits < 5 || databits > 8)
-		return -EINVAL;
-
-	*ctrl &= ~CSIZE;
-	switch (databits) {
-	case 5:
-		*ctrl |= CS5;
-		break;
-	case 6:
-		*ctrl |= CS6;
-		break;
-	case 7:
-		*ctrl |= CS7;
-		break;
-	case 8:
-		*ctrl |= CS8;
-		break;
-	}
-
-	return 0;
-}
-
-static int set_stopbits(uint8_t stopbits, tcflag_t *ctrl)
-{
-	/* 1.5 will not be allowed */
-	switch (stopbits) {
-	case 1:
-		*ctrl &= ~CSTOPB;
-		return 0;
-	case 2:
-		*ctrl |= CSTOPB;
-		return 0;
-	}
-
-	return -EINVAL;
-}
-
-static DBusMessage *proxy_set_serial_params(DBusConnection *conn,
-						DBusMessage *msg, void *data)
-{
-	struct serial_proxy *prx = data;
-	const char *ratestr, *paritystr;
-	uint8_t databits, stopbits;
-	tcflag_t ctrl;		/* Control mode flags */
-	speed_t speed = B0;	/* In/Out speed */
-
-	/* Don't allow change TTY settings if it is open */
-	if (prx->local)
-		return btd_error_not_authorized(msg);
-
-	if (!dbus_message_get_args(msg, NULL,
-				DBUS_TYPE_STRING, &ratestr,
-				DBUS_TYPE_BYTE, &databits,
-				DBUS_TYPE_BYTE, &stopbits,
-				DBUS_TYPE_STRING, &paritystr,
-				DBUS_TYPE_INVALID))
-		return NULL;
-
-	if (str2speed(ratestr, &speed)  == B0)
-		return btd_error_invalid_args(msg);
-
-	ctrl = prx->proxy_ti.c_cflag;
-	if (set_databits(databits, &ctrl) < 0)
-		return btd_error_invalid_args(msg);
-
-	if (set_stopbits(stopbits, &ctrl) < 0)
-		return btd_error_invalid_args(msg);
-
-	if (set_parity(paritystr, &ctrl) < 0)
-		return btd_error_invalid_args(msg);
-
-	prx->proxy_ti.c_cflag = ctrl;
-	prx->proxy_ti.c_cflag |= (CLOCAL | CREAD);
-	cfsetispeed(&prx->proxy_ti, speed);
-	cfsetospeed(&prx->proxy_ti, speed);
-
-	return dbus_message_new_method_return(msg);
-}
-
-static const GDBusMethodTable proxy_methods[] = {
-	{ GDBUS_METHOD("Enable", NULL, NULL, proxy_enable) },
-	{ GDBUS_METHOD("Disable", NULL, NULL, proxy_disable) },
-	{ GDBUS_METHOD("GetInfo",
-			NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
-			proxy_get_info) },
-	{ GDBUS_METHOD("SetSerialParameters",
-			GDBUS_ARGS({ "rate", "s" }, { "data", "y" },
-					{ "stop", "y" }, { "parity", "s" }),
-			NULL, proxy_set_serial_params) },
-	{ },
-};
-
-static void proxy_path_unregister(gpointer data)
-{
-	struct serial_proxy *prx = data;
-	int sk;
-
-	DBG("Unregistered proxy: %s", prx->address);
-
-	if (prx->type != TTY_PROXY)
-		goto done;
-
-	/* Restore the initial TTY configuration */
-	sk = open(prx->address, O_RDWR | O_NOCTTY);
-	if (sk >= 0) {
-		tcsetattr(sk, TCSAFLUSH, &prx->sys_ti);
-		close(sk);
-	}
-done:
-
-	proxy_free(prx);
-}
-
-static int register_proxy_object(struct serial_proxy *prx)
-{
-	struct serial_adapter *adapter = prx->adapter;
-	char path[MAX_PATH_LENGTH + 1];
-
-	snprintf(path, MAX_PATH_LENGTH, "%s/proxy%d",
-			adapter_get_path(adapter->btd_adapter), sk_counter++);
-
-	if (!g_dbus_register_interface(adapter->conn, path,
-					SERIAL_PROXY_INTERFACE,
-					proxy_methods, NULL, NULL,
-					prx, proxy_path_unregister)) {
-		error("D-Bus failed to register %s path", path);
-		return -1;
-	}
-
-	prx->path = g_strdup(path);
-	adapter->proxies = g_slist_append(adapter->proxies, prx);
-
-	DBG("Registered proxy: %s", path);
-
-	return 0;
-}
-
-static int proxy_tty_register(struct serial_adapter *adapter,
-				const char *uuid128, const char *address,
-				struct termios *ti,
-				struct serial_proxy **proxy)
-{
-	struct termios sys_ti;
-	struct serial_proxy *prx;
-	int sk, ret;
-
-	sk = open(address, O_RDONLY | O_NOCTTY);
-	if (sk < 0) {
-		error("Can't open TTY: %s(%d)", strerror(errno), errno);
-		return -EINVAL;
-	}
-
-	prx = g_new0(struct serial_proxy, 1);
-	prx->address = g_strdup(address);
-	prx->uuid128 = g_strdup(uuid128);
-	prx->type = TTY_PROXY;
-	adapter_get_address(adapter->btd_adapter, &prx->src);
-	prx->adapter = adapter;
-
-	/* Current TTY settings */
-	memset(&sys_ti, 0, sizeof(sys_ti));
-	tcgetattr(sk, &sys_ti);
-	memcpy(&prx->sys_ti, &sys_ti, sizeof(sys_ti));
-	close(sk);
-
-	if (!ti) {
-		/* Use current settings */
-		memcpy(&prx->proxy_ti, &sys_ti, sizeof(sys_ti));
-	} else {
-		/* New TTY settings: user provided */
-		memcpy(&prx->proxy_ti, ti, sizeof(*ti));
-	}
-
-	ret = register_proxy_object(prx);
-	if (ret < 0) {
-		proxy_free(prx);
-		return ret;
-	}
-
-	*proxy = prx;
-
-	return ret;
-}
-
-static int proxy_socket_register(struct serial_adapter *adapter,
-				const char *uuid128, const char *address,
-				struct serial_proxy **proxy)
-{
-	struct serial_proxy *prx;
-	int ret;
-
-	prx = g_new0(struct serial_proxy, 1);
-	prx->address = g_strdup(address);
-	prx->uuid128 = g_strdup(uuid128);
-	prx->type = UNIX_SOCKET_PROXY;
-	adapter_get_address(adapter->btd_adapter, &prx->src);
-	prx->adapter = adapter;
-
-	ret = register_proxy_object(prx);
-	if (ret < 0) {
-		proxy_free(prx);
-		return ret;
-	}
-
-	*proxy = prx;
-
-	return ret;
-}
-
-static int proxy_tcp_register(struct serial_adapter *adapter,
-				const char *uuid128, const char *address,
-				struct serial_proxy **proxy)
-{
-	struct serial_proxy *prx;
-	int ret;
-
-	prx = g_new0(struct serial_proxy, 1);
-	prx->address = g_strdup(address);
-	prx->uuid128 = g_strdup(uuid128);
-	prx->type = TCP_SOCKET_PROXY;
-	adapter_get_address(adapter->btd_adapter, &prx->src);
-	prx->adapter = adapter;
-
-	ret = register_proxy_object(prx);
-	if (ret < 0) {
-		proxy_free(prx);
-		return ret;
-	}
-
-	*proxy = prx;
-
-	return ret;
-}
-
-static proxy_type_t addr2type(const char *address)
-{
-	struct stat st;
-
-	if (stat(address, &st) < 0) {
-		/*
-		 * Unix socket: if the sun_path starts with null byte
-		 * it refers to abstract namespace. 'x00' will be used
-		 * to represent the null byte.
-		 */
-		if (strncmp("localhost:", address, 10) == 0)
-			return TCP_SOCKET_PROXY;
-		if (strncmp("x00", address, 3) != 0)
-			return UNKNOWN_PROXY_TYPE;
-		else
-			return UNIX_SOCKET_PROXY;
-	} else {
-		/* Filesystem: char device or unix socket */
-		if (S_ISCHR(st.st_mode) && strncmp("/dev/", address, 4) == 0)
-			return TTY_PROXY;
-		else if (S_ISSOCK(st.st_mode))
-			return UNIX_SOCKET_PROXY;
-		else
-			return UNKNOWN_PROXY_TYPE;
-	}
-}
-
-static int proxy_addrcmp(gconstpointer proxy, gconstpointer addr)
-{
-	const struct serial_proxy *prx = proxy;
-	const char *address = addr;
-
-	return strcmp(prx->address, address);
-}
-
-static int proxy_pathcmp(gconstpointer proxy, gconstpointer p)
-{
-	const struct serial_proxy *prx = proxy;
-	const char *path = p;
-
-	return strcmp(prx->path, path);
-}
-
-static int register_proxy(struct serial_adapter *adapter,
-				const char *uuid_str, const char *address,
-				struct serial_proxy **proxy)
-{
-	proxy_type_t type;
-	int err;
-
-	type = addr2type(address);
-	if (type == UNKNOWN_PROXY_TYPE)
-		return -EINVAL;
-
-	/* Only one proxy per address(TTY or unix socket) is allowed */
-	if (g_slist_find_custom(adapter->proxies, address, proxy_addrcmp))
-		return -EALREADY;
-
-	switch (type) {
-	case UNIX_SOCKET_PROXY:
-		err = proxy_socket_register(adapter, uuid_str, address, proxy);
-		break;
-	case TTY_PROXY:
-		err = proxy_tty_register(adapter, uuid_str, address, NULL,
-					proxy);
-		break;
-	case TCP_SOCKET_PROXY:
-		err = proxy_tcp_register(adapter, uuid_str, address, proxy);
-		break;
-	default:
-		err = -EINVAL;
-	}
-
-	if (err < 0)
-		return err;
-
-	g_dbus_emit_signal(adapter->conn,
-				adapter_get_path(adapter->btd_adapter),
-				SERIAL_MANAGER_INTERFACE, "ProxyCreated",
-				DBUS_TYPE_STRING, &(*proxy)->path,
-				DBUS_TYPE_INVALID);
-
-	return 0;
-}
-
-static void unregister_proxy(struct serial_proxy *proxy)
-{
-	struct serial_adapter *adapter = proxy->adapter;
-	char *path = g_strdup(proxy->path);
-
-	if (proxy->watch > 0)
-		g_dbus_remove_watch(adapter->conn, proxy->watch);
-
-	g_dbus_emit_signal(adapter->conn,
-			adapter_get_path(adapter->btd_adapter),
-			SERIAL_MANAGER_INTERFACE, "ProxyRemoved",
-			DBUS_TYPE_STRING, &path,
-			DBUS_TYPE_INVALID);
-
-	adapter->proxies = g_slist_remove(adapter->proxies, proxy);
-
-	g_dbus_unregister_interface(adapter->conn, path,
-					SERIAL_PROXY_INTERFACE);
-
-	g_free(path);
-}
-
-static void watch_proxy(DBusConnection *connection, void *user_data)
-{
-	struct serial_proxy *proxy = user_data;
-
-	proxy->watch = 0;
-	unregister_proxy(proxy);
-}
-
-static DBusMessage *create_proxy(DBusConnection *conn,
-				DBusMessage *msg, void *data)
-{
-	struct serial_adapter *adapter = data;
-	struct serial_proxy *proxy;
-	const char *pattern, *address;
-	char *uuid_str;
-	int err;
-
-	if (!dbus_message_get_args(msg, NULL,
-				DBUS_TYPE_STRING, &pattern,
-				DBUS_TYPE_STRING, &address,
-				DBUS_TYPE_INVALID))
-		return NULL;
-
-	uuid_str = bt_name2string(pattern);
-	if (!uuid_str)
-		return btd_error_invalid_args(msg);
-
-	err = register_proxy(adapter, uuid_str, address, &proxy);
-	g_free(uuid_str);
-
-	if (err == -EINVAL)
-		return btd_error_invalid_args(msg);
-	else if (err == -EALREADY)
-		return btd_error_already_exists(msg);
-	else if (err < 0)
-		return btd_error_failed(msg, strerror(-err));
-
-	proxy->owner = g_strdup(dbus_message_get_sender(msg));
-	proxy->watch = g_dbus_add_disconnect_watch(conn, proxy->owner,
-						watch_proxy,
-						proxy, NULL);
-
-	return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &proxy->path,
-					DBUS_TYPE_INVALID);
-}
-
-static DBusMessage *list_proxies(DBusConnection *conn,
-				DBusMessage *msg, void *data)
-{
-	struct serial_adapter *adapter = data;
-	const GSList *l;
-	DBusMessage *reply;
-	DBusMessageIter iter, iter_array;
-
-	reply = dbus_message_new_method_return(msg);
-	if (!reply)
-		return NULL;
-
-	dbus_message_iter_init_append(reply, &iter);
-	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
-			DBUS_TYPE_STRING_AS_STRING, &iter_array);
-
-	for (l = adapter->proxies; l; l = l->next) {
-		struct serial_proxy *prx = l->data;
-
-		dbus_message_iter_append_basic(&iter_array,
-				DBUS_TYPE_STRING, &prx->path);
-	}
-
-	dbus_message_iter_close_container(&iter, &iter_array);
-
-	return reply;
-}
-
-static DBusMessage *remove_proxy(DBusConnection *conn,
-				DBusMessage *msg, void *data)
-{
-	struct serial_adapter *adapter = data;
-	struct serial_proxy *prx;
-	const char *path, *sender;
-	GSList *l;
-
-	if (!dbus_message_get_args(msg, NULL,
-				DBUS_TYPE_STRING, &path,
-				DBUS_TYPE_INVALID))
-		return NULL;
-
-	l = g_slist_find_custom(adapter->proxies, path, proxy_pathcmp);
-	if (!l)
-		return btd_error_does_not_exist(msg);
-
-	prx = l->data;
-
-	sender = dbus_message_get_sender(msg);
-	if (g_strcmp0(prx->owner, sender) != 0)
-		return btd_error_not_authorized(msg);
-
-	unregister_proxy(prx);
-
-	return dbus_message_new_method_return(msg);
-}
-
-static void manager_path_unregister(void *data)
-{
-	struct serial_adapter *adapter = data;
-	GSList *l;
-
-	/* Remove proxy objects */
-	for (l = adapter->proxies; l; l = l->next) {
-		struct serial_proxy *prx = l->data;
-		char *path = g_strdup(prx->path);
-
-		g_dbus_unregister_interface(adapter->conn, path,
-					SERIAL_PROXY_INTERFACE);
-		g_free(path);
-	}
-
-	if (adapter->conn)
-		dbus_connection_unref(adapter->conn);
-
-	adapters = g_slist_remove(adapters, adapter);
-	g_slist_free(adapter->proxies);
-	btd_adapter_unref(adapter->btd_adapter);
-	g_free(adapter);
-}
-
-static const GDBusMethodTable manager_methods[] = {
-	{ GDBUS_METHOD("CreateProxy",
-			GDBUS_ARGS({ "pattern", "s" },
-					{ "address", "s" }),
-			GDBUS_ARGS({ "path", "s" }),
-			create_proxy) },
-	{ GDBUS_METHOD("ListProxies",
-			NULL, GDBUS_ARGS({ "paths", "as" }),
-			list_proxies) },
-	{ GDBUS_METHOD("RemoveProxy",
-			GDBUS_ARGS({ "path", "s" }), NULL,
-			remove_proxy) },
-	{ },
-};
-
-static const GDBusSignalTable manager_signals[] = {
-	{ GDBUS_SIGNAL("ProxyCreated", GDBUS_ARGS({ "path", "s" })) },
-	{ GDBUS_SIGNAL("ProxyRemoved", GDBUS_ARGS({ "path", "s" })) },
-	{ }
-};
-
-static struct serial_adapter *find_adapter(GSList *list,
-					struct btd_adapter *btd_adapter)
-{
-	for (; list; list = list->next) {
-		struct serial_adapter *adapter = list->data;
-
-		if (adapter->btd_adapter == btd_adapter)
-			return adapter;
-	}
-
-	return NULL;
-}
-
-static void serial_proxy_init(struct serial_adapter *adapter)
-{
-	GKeyFile *config;
-	GError *gerr = NULL;
-	const char *file = CONFIGDIR "/serial.conf";
-	char **group_list;
-	int i;
-
-	config = g_key_file_new();
-
-	if (!g_key_file_load_from_file(config, file, 0, &gerr)) {
-		error("Parsing %s failed: %s", file, gerr->message);
-		g_error_free(gerr);
-		g_key_file_free(config);
-		return;
-	}
-
-	group_list = g_key_file_get_groups(config, NULL);
-
-	for (i = 0; group_list[i] != NULL; i++) {
-		char *group_str = group_list[i], *uuid_str, *address;
-		int err;
-		struct serial_proxy *prx;
-
-		/* string length of "Proxy" is 5 */
-		if (strlen(group_str) < 5 || strncmp(group_str, "Proxy", 5))
-			continue;
-
-		uuid_str = g_key_file_get_string(config, group_str, "UUID",
-									&gerr);
-		if (gerr) {
-			DBG("%s: %s", file, gerr->message);
-			g_error_free(gerr);
-			g_key_file_free(config);
-			g_strfreev(group_list);
-			return;
-		}
-
-		address = g_key_file_get_string(config, group_str, "Address",
-									&gerr);
-		if (gerr) {
-			DBG("%s: %s", file, gerr->message);
-			g_error_free(gerr);
-			g_key_file_free(config);
-			g_free(uuid_str);
-			g_strfreev(group_list);
-			return;
-		}
-
-		err = register_proxy(adapter, uuid_str, address, &prx);
-		if (err == -EINVAL)
-			error("Invalid address.");
-		else if (err == -EALREADY)
-			DBG("Proxy already exists.");
-		else if (err < 0)
-			error("Proxy creation failed (%s)", strerror(-err));
-		else {
-			err = enable_proxy(prx);
-			if (err < 0)
-				error("Proxy enable failed (%s)",
-						strerror(-err));
-		}
-
-		g_free(uuid_str);
-		g_free(address);
-	}
-
-	g_strfreev(group_list);
-	g_key_file_free(config);
-}
-
-int proxy_register(DBusConnection *conn, struct btd_adapter *btd_adapter)
-{
-	struct serial_adapter *adapter;
-	const char *path;
-
-	adapter = find_adapter(adapters, btd_adapter);
-	if (adapter)
-		return -EINVAL;
-
-	adapter = g_new0(struct serial_adapter, 1);
-	adapter->conn = dbus_connection_ref(conn);
-	adapter->btd_adapter = btd_adapter_ref(btd_adapter);
-
-	path = adapter_get_path(btd_adapter);
-
-	if (!g_dbus_register_interface(conn, path,
-					SERIAL_MANAGER_INTERFACE,
-					manager_methods, manager_signals, NULL,
-					adapter, manager_path_unregister)) {
-		error("Failed to register %s interface to %s",
-				SERIAL_MANAGER_INTERFACE, path);
-		return -1;
-	}
-
-	adapters = g_slist_append(adapters, adapter);
-
-	DBG("Registered interface %s on path %s",
-		SERIAL_MANAGER_INTERFACE, path);
-
-	serial_proxy_init(adapter);
-
-	return 0;
-}
-
-void proxy_unregister(struct btd_adapter *btd_adapter)
-{
-	struct serial_adapter *adapter;
-
-	adapter = find_adapter(adapters, btd_adapter);
-	if (!adapter)
-		return;
-
-	g_dbus_unregister_interface(adapter->conn,
-			adapter_get_path(btd_adapter),
-			SERIAL_MANAGER_INTERFACE);
-}
diff --git a/serial/proxy.h b/serial/proxy.h
deleted file mode 100644
index 7871665..0000000
--- a/serial/proxy.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2004-2010  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
- *
- */
-
-int proxy_register(DBusConnection *conn, struct btd_adapter *btd_adapter);
-void proxy_unregister(struct btd_adapter *btd_adapter);
diff --git a/serial/serial.conf b/serial/serial.conf
deleted file mode 100644
index 43ee6af..0000000
--- a/serial/serial.conf
+++ /dev/null
@@ -1,10 +0,0 @@
-# Configuration file for serial
-
-# There could be multiple proxy sections, the format is [Proxy <user chosen name>]
-#[Proxy DUN]
-
-# UUID for DUN proxy service
-#UUID=00001103-0000-1000-8000-00805F9B34FB
-
-# Address for device node
-#Address=/dev/ttyx
-- 
1.7.10.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 03/14] btmgmt: move to tools folder
  2012-07-09 21:10 [PATCH 01/14] input: remove unneeded header inclusions Gustavo Padovan
  2012-07-09 21:10 ` [PATCH 02/14] serial: remove the whole serial code Gustavo Padovan
@ 2012-07-09 21:10 ` Gustavo Padovan
  2012-07-10  2:36   ` Vinicius Costa Gomes
  2012-07-09 21:10 ` [PATCH 04/14] alert: move alert to profiles dir Gustavo Padovan
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 10+ messages in thread
From: Gustavo Padovan @ 2012-07-09 21:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

---
 .gitignore     |    2 +-
 Makefile.tools |    6 +-
 mgmt/main.c    | 1933 --------------------------------------------------------
 3 files changed, 4 insertions(+), 1937 deletions(-)
 delete mode 100644 mgmt/main.c

diff --git a/.gitignore b/.gitignore
index c7d079e..bc65dcf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -86,7 +86,7 @@ compat/dund
 compat/hidd
 compat/pand
 unit/test-eir
-mgmt/btmgmt
+tools/mgmt/btmgmt
 monitor/btmon
 emulator/btvirt
 
diff --git a/Makefile.tools b/Makefile.tools
index 3cb105c..56839b7 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -50,10 +50,10 @@ tools_ppporc_LDADD = lib/libbluetooth-private.la
 
 tools_hcieventmask_LDADD = lib/libbluetooth-private.la
 
-noinst_PROGRAMS += mgmt/btmgmt monitor/btmon emulator/btvirt
+noinst_PROGRAMS += tools/btmgmt monitor/btmon emulator/btvirt
 
-mgmt_btmgmt_SOURCES = mgmt/main.c src/glib-helper.c
-mgmt_btmgmt_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@
+tools_btmgmt_SOURCES = tools/btmgmt.c src/glib-helper.c
+tools_btmgmt_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@
 
 monitor_btmon_SOURCES = monitor/main.c monitor/bt.h \
 					monitor/mainloop.h monitor/mainloop.c \
diff --git a/mgmt/main.c b/mgmt/main.c
deleted file mode 100644
index b2d6c3c..0000000
--- a/mgmt/main.c
+++ /dev/null
@@ -1,1933 +0,0 @@
-/*
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2011  Intel Corporation. All rights reserved.
- *
- *  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 <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <poll.h>
-#include <getopt.h>
-#include <stdbool.h>
-
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/hci.h>
-#include <bluetooth/hci_lib.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
-#include <bluetooth/mgmt.h>
-
-#include <glib.h>
-#include "glib-helper.h"
-
-static bool monitor = false;
-static bool discovery = false;
-static bool resolve_names = true;
-
-typedef void (*cmd_cb)(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data);
-
-static struct pending_cmd {
-	uint16_t op;
-	uint16_t id;
-	cmd_cb cb;
-	void *user_data;
-	struct pending_cmd *next;
-} *pending = NULL;
-
-static int mgmt_send_cmd(int mgmt_sk, uint16_t op, uint16_t id, void *data,
-				size_t len, cmd_cb func, void *user_data)
-{
-	char buf[1024];
-	struct pending_cmd *cmd;
-	struct mgmt_hdr *hdr = (void *) buf;
-
-	if (len + MGMT_HDR_SIZE > sizeof(buf))
-		return -EINVAL;
-
-	cmd = calloc(1, sizeof(struct pending_cmd));
-	if (cmd == NULL)
-		return -errno;
-
-	cmd->op = op;
-	cmd->id = id;
-	cmd->cb = func;
-	cmd->user_data = user_data;
-
-	memset(buf, 0, sizeof(buf));
-	hdr->opcode = htobs(op);
-	hdr->index = htobs(id);
-	hdr->len = htobs(len);
-	memcpy(buf + MGMT_HDR_SIZE, data, len);
-
-	if (write(mgmt_sk, buf, MGMT_HDR_SIZE + len) < 0) {
-		fprintf(stderr, "Unable to write to socket: %s\n",
-							strerror(errno));
-		free(cmd);
-		return -1;
-	}
-
-	cmd->next = pending;
-	pending = cmd;
-
-	return 0;
-}
-
-static int mgmt_open(void)
-{
-	struct sockaddr_hci addr;
-	int sk;
-
-	sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
-	if (sk < 0) {
-		fprintf(stderr, "socket: %s\n", strerror(errno));
-		return sk;
-	}
-
-	memset(&addr, 0, sizeof(addr));
-	addr.hci_family = AF_BLUETOOTH;
-	addr.hci_dev = HCI_DEV_NONE;
-	addr.hci_channel = HCI_CHANNEL_CONTROL;
-
-	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-		fprintf(stderr, "bind: %s\n", strerror(errno));
-		close(sk);
-		return -1;
-	}
-
-	return sk;
-}
-
-static void mgmt_check_pending(int mgmt_sk, uint16_t op, uint16_t index,
-				uint16_t status, void *data, uint16_t len)
-{
-	struct pending_cmd *c, *prev;
-
-	for (c = pending, prev = NULL; c != NULL; prev = c, c = c->next) {
-		if (c->op != op)
-			continue;
-		if (c->id != index)
-			continue;
-
-		if (c == pending)
-			pending = c->next;
-		else
-			prev->next = c->next;
-
-		c->cb(mgmt_sk, op, index, status, data, len, c->user_data);
-
-		free(c);
-		break;
-	}
-}
-
-static int mgmt_cmd_complete(int mgmt_sk, uint16_t index,
-				struct mgmt_ev_cmd_complete *ev, uint16_t len)
-{
-	uint16_t op;
-
-	if (len < sizeof(*ev)) {
-		fprintf(stderr, "Too short (%u bytes) cmd complete event\n",
-									len);
-		return -EINVAL;
-	}
-
-	op = bt_get_le16(&ev->opcode);
-
-	len -= sizeof(*ev);
-
-	if (monitor)
-		printf("%s complete, opcode 0x%04x len %u\n", mgmt_opstr(op),
-								op, len);
-
-	mgmt_check_pending(mgmt_sk, op, index, ev->status, ev->data, len);
-
-	return 0;
-}
-
-static int mgmt_cmd_status(int mgmt_sk, uint16_t index,
-				struct mgmt_ev_cmd_status *ev, uint16_t len)
-{
-	uint16_t opcode;
-
-	if (len < sizeof(*ev)) {
-		fprintf(stderr, "Too short (%u bytes) cmd status event\n",
-									len);
-		return -EINVAL;
-	}
-
-	opcode = bt_get_le16(&ev->opcode);
-
-	if (monitor)
-		printf("cmd status, opcode 0x%04x status 0x%02x (%s)\n",
-				opcode, ev->status, mgmt_errstr(ev->status));
-
-	if (ev->status != 0)
-		mgmt_check_pending(mgmt_sk, opcode, index, ev->status,
-								NULL, 0);
-
-	return 0;
-}
-
-static int mgmt_controller_error(uint16_t index,
-					struct mgmt_ev_controller_error *ev,
-					uint16_t len)
-{
-	if (len < sizeof(*ev)) {
-		fprintf(stderr,
-			"Too short (%u bytes) controller error event\n", len);
-		return -EINVAL;
-	}
-
-	if (monitor)
-		printf("hci%u error 0x%02x\n", index, ev->error_code);
-
-	return 0;
-}
-
-static int mgmt_index_added(int mgmt_sk, uint16_t index)
-{
-	if (monitor)
-		printf("hci%u added\n", index);
-	return 0;
-}
-
-static int mgmt_index_removed(int mgmt_sk, uint16_t index)
-{
-	if (monitor)
-		printf("hci%u removed\n", index);
-	return 0;
-}
-
-static const char *settings_str[] = {
-				"powered",
-				"connectable",
-				"fast-connectable",
-				"discoverable",
-				"pairable",
-				"link-security",
-				"ssp",
-				"br/edr",
-				"hs",
-				"le" ,
-};
-
-static void print_settings(uint32_t settings)
-{
-	unsigned i;
-
-	for (i = 0; i < NELEM(settings_str); i++) {
-		if ((settings & (1 << i)) != 0)
-			printf("%s ", settings_str[i]);
-	}
-}
-
-static int mgmt_new_settings(int mgmt_sk, uint16_t index,
-					uint32_t *ev, uint16_t len)
-{
-	if (len < sizeof(*ev)) {
-		fprintf(stderr, "Too short new_settings event (%u)\n", len);
-		return -EINVAL;
-	}
-
-	if (monitor) {
-		printf("hci%u new_settings: ", index);
-		print_settings(bt_get_le32(ev));
-		printf("\n");
-	}
-
-	return 0;
-}
-
-static int mgmt_discovering(int mgmt_sk, uint16_t index,
-				struct mgmt_ev_discovering *ev, uint16_t len)
-{
-	if (len < sizeof(*ev)) {
-		fprintf(stderr, "Too short (%u bytes) discovering event\n",
-									len);
-		return -EINVAL;
-	}
-
-	if (ev->discovering == 0 && discovery)
-		exit(EXIT_SUCCESS);
-
-	if (monitor)
-		printf("hci%u type %u discovering %s\n", index,
-				ev->type, ev->discovering ? "on" : "off");
-
-	return 0;
-}
-
-static int mgmt_new_link_key(int mgmt_sk, uint16_t index,
-				struct mgmt_ev_new_link_key *ev, uint16_t len)
-{
-
-	if (len != sizeof(*ev)) {
-		fprintf(stderr, "Invalid new_link_key length (%u bytes)\n",
-									len);
-		return -EINVAL;
-	}
-
-	if (monitor) {
-		char addr[18];
-		ba2str(&ev->key.addr.bdaddr, addr);
-		printf("hci%u new_link_key %s type 0x%02x pin_len %d "
-				"store_hint %u\n", index, addr, ev->key.type,
-				ev->key.pin_len, ev->store_hint);
-	}
-
-	return 0;
-}
-
-static const char *typestr(uint8_t type)
-{
-	const char *str[] = { "BR/EDR", "LE Public", "LE Random" };
-
-	if (type <= BDADDR_LE_RANDOM)
-		return str[type];
-
-	return "(unknown)";
-}
-
-static int mgmt_connected(int mgmt_sk, uint16_t index,
-					struct mgmt_ev_device_connected *ev,
-					uint16_t len)
-{
-	uint16_t eir_len;
-
-	if (len < sizeof(*ev)) {
-		fprintf(stderr,
-			"Invalid connected event length (%u bytes)\n", len);
-		return -EINVAL;
-	}
-
-	eir_len = bt_get_le16(&ev->eir_len);
-	if (len != sizeof(*ev) + eir_len) {
-		fprintf(stderr, "Invalid connected event length "
-			"(%u bytes, eir_len %u bytes)\n", len, eir_len);
-		return -EINVAL;
-	}
-
-	if (monitor) {
-		char addr[18];
-		ba2str(&ev->addr.bdaddr, addr);
-		printf("hci%u %s type %s connected eir_len %u\n", index, addr,
-					typestr(ev->addr.type), eir_len);
-	}
-
-	return 0;
-}
-
-static int mgmt_disconnected(int mgmt_sk, uint16_t index,
-				struct mgmt_addr_info *ev, uint16_t len)
-{
-	if (len != sizeof(*ev)) {
-		fprintf(stderr,
-			"Invalid disconnected event length (%u bytes)\n", len);
-		return -EINVAL;
-	}
-
-	if (monitor) {
-		char addr[18];
-		ba2str(&ev->bdaddr, addr);
-		printf("hci%u %s type %s disconnected\n", index, addr,
-							typestr(ev->type));
-	}
-
-	return 0;
-}
-
-static int mgmt_conn_failed(int mgmt_sk, uint16_t index,
-				struct mgmt_ev_connect_failed *ev,
-				uint16_t len)
-{
-	if (len != sizeof(*ev)) {
-		fprintf(stderr,
-			"Invalid connect_failed event length (%u bytes)\n", len);
-		return -EINVAL;
-	}
-
-	if (monitor) {
-		char addr[18];
-		ba2str(&ev->addr.bdaddr, addr);
-		printf("hci%u %s type %s connect failed (status 0x%02x, %s)\n",
-				index, addr, typestr(ev->addr.type), ev->status,
-				mgmt_errstr(ev->status));
-	}
-
-	return 0;
-}
-
-static int mgmt_auth_failed(int mgmt_sk, uint16_t index,
-				struct mgmt_ev_auth_failed *ev,
-				uint16_t len)
-{
-	if (len != sizeof(*ev)) {
-		fprintf(stderr,
-			"Invalid auth_failed event length (%u bytes)\n", len);
-		return -EINVAL;
-	}
-
-	if (monitor) {
-		char addr[18];
-		ba2str(&ev->addr.bdaddr, addr);
-		printf("hci%u %s auth failed with status 0x%02x (%s)\n",
-			index, addr, ev->status, mgmt_errstr(ev->status));
-	}
-
-	return 0;
-}
-
-static int mgmt_name_changed(int mgmt_sk, uint16_t index,
-				struct mgmt_ev_local_name_changed *ev,
-				uint16_t len)
-{
-	if (len != sizeof(*ev)) {
-		fprintf(stderr,
-			"Invalid local_name_changed length (%u bytes)\n", len);
-		return -EINVAL;
-	}
-
-	if (monitor)
-		printf("hci%u name changed: %s\n", index, ev->name);
-
-	return 0;
-}
-
-static void confirm_name_rsp(int mgmt_sk, uint16_t op, uint16_t id,
-				uint8_t status, void *rsp, uint16_t len,
-				void *user_data)
-{
-	struct mgmt_rp_confirm_name *rp = rsp;
-	char addr[18];
-
-	if (len == 0 && status != 0) {
-		fprintf(stderr,
-			"hci%u confirm_name failed with status 0x%02x (%s)\n",
-					id, status, mgmt_errstr(status));
-		return;
-	}
-
-	if (len != sizeof(*rp)) {
-		fprintf(stderr,
-			"hci%u confirm_name rsp length %u instead of %zu\n",
-			id, len, sizeof(*rp));
-		return;
-	}
-
-	ba2str(&rp->addr.bdaddr, addr);
-
-	if (status != 0)
-		fprintf(stderr,
-			"hci%u confirm_name for %s failed: 0x%02x (%s)\n",
-			id, addr, status, mgmt_errstr(status));
-	else
-		printf("hci%u confirm_name succeeded for %s\n", id, addr);
-}
-
-static int mgmt_device_found(int mgmt_sk, uint16_t index,
-				struct mgmt_ev_device_found *ev, uint16_t len)
-{
-	uint32_t flags;
-	uint16_t eir_len;
-
-	if (len < sizeof(*ev)) {
-		fprintf(stderr,
-			"Too short device_found length (%u bytes)\n", len);
-		return -EINVAL;
-	}
-
-	flags = btohs(ev->flags);
-
-	eir_len = bt_get_le16(&ev->eir_len);
-	if (len != sizeof(*ev) + eir_len) {
-		fprintf(stderr, "dev_found: expected %zu bytes, got %u bytes",
-						sizeof(*ev) + eir_len, len);
-		return -EINVAL;
-	}
-
-	if (monitor || discovery) {
-		char addr[18];
-		ba2str(&ev->addr.bdaddr, addr);
-		printf("hci%u dev_found: %s type %s rssi %d "
-			"flags 0x%04x eir_len %u\n", index, addr,
-			typestr(ev->addr.type), ev->rssi, flags, eir_len);
-	}
-
-	if (discovery && (flags & MGMT_DEV_FOUND_CONFIRM_NAME)) {
-		struct mgmt_cp_confirm_name cp;
-
-		memset(&cp, 0, sizeof(cp));
-		memcpy(&cp.addr, &ev->addr, sizeof(cp.addr));
-		if (resolve_names)
-			cp.name_known = 0;
-		else
-			cp.name_known = 1;
-
-		mgmt_send_cmd(mgmt_sk, MGMT_OP_CONFIRM_NAME, index,
-					&cp, sizeof(cp), confirm_name_rsp,
-					NULL);
-	}
-
-	return 0;
-}
-
-static void pin_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data)
-{
-	if (status != 0) {
-		fprintf(stderr,
-			"hci%u PIN Code reply failed with status 0x%02x (%s)",
-					id, status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	printf("hci%u PIN Reply successful\n", id);
-}
-
-static int mgmt_pin_reply(int mgmt_sk, uint16_t index,
-						struct mgmt_addr_info *addr,
-						const char *pin, size_t len)
-{
-	struct mgmt_cp_pin_code_reply cp;
-
-	memset(&cp, 0, sizeof(cp));
-	memcpy(&cp.addr, addr, sizeof(cp.addr));
-	cp.pin_len = len;
-	memcpy(cp.pin_code, pin, len);
-
-	return mgmt_send_cmd(mgmt_sk, MGMT_OP_PIN_CODE_REPLY, index,
-					&cp, sizeof(cp), pin_rsp, NULL);
-}
-
-static void pin_neg_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data)
-{
-	if (status != 0) {
-		fprintf(stderr,
-			"hci%u PIN Neg reply failed with status 0x%02x (%s)",
-					id, status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	printf("hci%u PIN Negative Reply successful\n", id);
-}
-
-static int mgmt_pin_neg_reply(int mgmt_sk, uint16_t index,
-						struct mgmt_addr_info *addr)
-{
-	struct mgmt_cp_pin_code_neg_reply cp;
-
-	memset(&cp, 0, sizeof(cp));
-	memcpy(&cp.addr, addr, sizeof(cp.addr));
-
-	return mgmt_send_cmd(mgmt_sk, MGMT_OP_PIN_CODE_NEG_REPLY, index,
-					&cp, sizeof(cp), pin_neg_rsp, NULL);
-}
-
-static int mgmt_request_pin(int mgmt_sk, uint16_t index,
-				struct mgmt_ev_pin_code_request *ev,
-				uint16_t len)
-{
-	char pin[18];
-	size_t pin_len;
-
-	if (len != sizeof(*ev)) {
-		fprintf(stderr,
-			"Invalid pin_code request length (%u bytes)\n", len);
-		return -EINVAL;
-	}
-
-	if (monitor) {
-		char addr[18];
-		ba2str(&ev->addr.bdaddr, addr);
-		printf("hci%u %s request PIN\n", index, addr);
-	}
-
-	printf("PIN Request (press enter to reject) >> ");
-	fflush(stdout);
-
-	memset(pin, 0, sizeof(pin));
-
-	if (fgets(pin, sizeof(pin), stdin) == NULL || pin[0] == '\n')
-		return mgmt_pin_neg_reply(mgmt_sk, index, &ev->addr);
-
-	pin_len = strlen(pin);
-	if (pin[pin_len - 1] == '\n') {
-		pin[pin_len - 1] = '\0';
-		pin_len--;
-	}
-
-	return mgmt_pin_reply(mgmt_sk, index, &ev->addr, pin, pin_len);
-}
-
-static void confirm_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data)
-{
-	if (status != 0) {
-		fprintf(stderr,
-			"hci%u User Confirm reply failed. status 0x%02x (%s)",
-					id, status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	printf("hci%u User Confirm Reply successful\n", id);
-}
-
-static int mgmt_confirm_reply(int mgmt_sk, uint16_t index, bdaddr_t *bdaddr)
-{
-	struct mgmt_cp_user_confirm_reply cp;
-
-	memset(&cp, 0, sizeof(cp));
-	bacpy(&cp.addr.bdaddr, bdaddr);
-
-	return mgmt_send_cmd(mgmt_sk, MGMT_OP_USER_CONFIRM_REPLY, index,
-					&cp, sizeof(cp), confirm_rsp, NULL);
-}
-
-static void confirm_neg_rsp(int mgmt_sk, uint16_t op, uint16_t id,
-				uint8_t status, void *rsp, uint16_t len,
-				void *user_data)
-{
-	if (status != 0) {
-		fprintf(stderr,
-			"hci%u Confirm Neg reply failed. status 0x%02x (%s)",
-					id, status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	printf("hci%u User Confirm Negative Reply successful\n", id);
-}
-
-static int mgmt_confirm_neg_reply(int mgmt_sk, uint16_t index,
-							bdaddr_t *bdaddr)
-{
-	struct mgmt_cp_user_confirm_reply cp;
-
-	memset(&cp, 0, sizeof(cp));
-	bacpy(&cp.addr.bdaddr, bdaddr);
-
-	return mgmt_send_cmd(mgmt_sk, MGMT_OP_USER_CONFIRM_NEG_REPLY, index,
-				&cp, sizeof(cp), confirm_neg_rsp, NULL);
-}
-
-
-static int mgmt_user_confirm(int mgmt_sk, uint16_t index,
-				struct mgmt_ev_user_confirm_request *ev,
-				uint16_t len)
-{
-	char rsp[5];
-	size_t rsp_len;
-	uint32_t val;
-	char addr[18];
-
-	if (len != sizeof(*ev)) {
-		fprintf(stderr,
-			"Invalid user_confirm request length (%u)\n", len);
-		return -EINVAL;
-	}
-
-	ba2str(&ev->addr.bdaddr, addr);
-	val = bt_get_le32(&ev->value);
-
-	if (monitor)
-		printf("hci%u %s User Confirm %06u hint %u\n", index, addr,
-							val, ev->confirm_hint);
-
-	if (ev->confirm_hint)
-		printf("Accept pairing with %s (yes/no) >> ", addr);
-	else
-		printf("Confirm value %06u for %s (yes/no) >> ", val, addr);
-
-	fflush(stdout);
-
-	memset(rsp, 0, sizeof(rsp));
-
-	if (fgets(rsp, sizeof(rsp), stdin) == NULL || rsp[0] == '\n')
-		return mgmt_confirm_neg_reply(mgmt_sk, index, &ev->addr.bdaddr);
-
-	rsp_len = strlen(rsp);
-	if (rsp[rsp_len - 1] == '\n') {
-		rsp[rsp_len - 1] = '\0';
-		rsp_len--;
-	}
-
-	if (rsp[0] == 'y' || rsp[0] == 'Y')
-		return mgmt_confirm_reply(mgmt_sk, index, &ev->addr.bdaddr);
-	else
-		return mgmt_confirm_neg_reply(mgmt_sk, index, &ev->addr.bdaddr);
-}
-
-static int mgmt_handle_event(int mgmt_sk, uint16_t ev, uint16_t index,
-						void *data, uint16_t len)
-{
-	if (monitor)
-		printf("event: %s\n", mgmt_evstr(ev));
-
-	switch (ev) {
-	case MGMT_EV_CMD_COMPLETE:
-		return mgmt_cmd_complete(mgmt_sk, index, data, len);
-	case MGMT_EV_CMD_STATUS:
-		return mgmt_cmd_status(mgmt_sk, index, data, len);
-	case MGMT_EV_CONTROLLER_ERROR:
-		return mgmt_controller_error(index, data, len);
-	case MGMT_EV_INDEX_ADDED:
-		return mgmt_index_added(mgmt_sk, index);
-	case MGMT_EV_INDEX_REMOVED:
-		return mgmt_index_removed(mgmt_sk, index);
-	case MGMT_EV_NEW_SETTINGS:
-		return mgmt_new_settings(mgmt_sk, index, data, len);
-	case MGMT_EV_DISCOVERING:
-		return mgmt_discovering(mgmt_sk, index, data, len);
-	case MGMT_EV_NEW_LINK_KEY:
-		return mgmt_new_link_key(mgmt_sk, index, data, len);
-	case MGMT_EV_DEVICE_CONNECTED:
-		return mgmt_connected(mgmt_sk, index, data, len);
-	case MGMT_EV_DEVICE_DISCONNECTED:
-		return mgmt_disconnected(mgmt_sk, index, data, len);
-	case MGMT_EV_CONNECT_FAILED:
-		return mgmt_conn_failed(mgmt_sk, index, data, len);
-	case MGMT_EV_AUTH_FAILED:
-		return mgmt_auth_failed(mgmt_sk, index, data, len);
-	case MGMT_EV_LOCAL_NAME_CHANGED:
-		return mgmt_name_changed(mgmt_sk, index, data, len);
-	case MGMT_EV_DEVICE_FOUND:
-		return mgmt_device_found(mgmt_sk, index, data, len);
-	case MGMT_EV_PIN_CODE_REQUEST:
-		return mgmt_request_pin(mgmt_sk, index, data, len);
-	case MGMT_EV_USER_CONFIRM_REQUEST:
-		return mgmt_user_confirm(mgmt_sk, index, data, len);
-	default:
-		if (monitor)
-			printf("Unhandled event 0x%04x (%s)\n", ev, mgmt_evstr(ev));
-		return 0;
-	}
-}
-
-static int mgmt_process_data(int mgmt_sk)
-{
-	char buf[1024];
-	struct mgmt_hdr *hdr = (void *) buf;
-	uint16_t len, ev, index;
-	ssize_t ret;
-
-	ret = read(mgmt_sk, buf, sizeof(buf));
-	if (ret < 0) {
-		fprintf(stderr, "read: %s\n", strerror(errno));
-		return ret;
-	}
-
-	if (ret < MGMT_HDR_SIZE) {
-		fprintf(stderr, "Too small mgmt packet (%zd bytes)\n", ret);
-		return 0;
-	}
-
-	ev = bt_get_le16(&hdr->opcode);
-	index = bt_get_le16(&hdr->index);
-	len = bt_get_le16(&hdr->len);
-
-	if (monitor)
-		printf("event 0x%04x len 0x%04x index 0x%04x\n", ev, len, index);
-
-	if (ret != MGMT_HDR_SIZE + len) {
-		fprintf(stderr, "Packet length mismatch. ret %zd len %u",
-								ret, len);
-		return 0;
-	}
-
-	mgmt_handle_event(mgmt_sk, ev, index, buf + MGMT_HDR_SIZE, len);
-
-	return 0;
-}
-
-static void cmd_monitor(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	printf("Monitoring mgmt events...\n");
-	monitor = true;
-}
-
-static void version_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data)
-{
-	struct mgmt_rp_read_version *rp = rsp;
-
-	if (status != 0) {
-		fprintf(stderr, "Reading mgmt version failed with status"
-			" 0x%02x (%s)\n", status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	if (len < sizeof(*rp)) {
-		fprintf(stderr, "Too small version reply (%u bytes)\n", len);
-		exit(EXIT_FAILURE);
-	}
-
-	printf("MGMT Version %u, revision %u\n", rp->version,
-						bt_get_le16(&rp->revision));
-
-	exit(EXIT_SUCCESS);
-}
-
-static void cmd_version(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE,
-					NULL, 0, version_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send read_version cmd\n");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void commands_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data)
-{
-	struct mgmt_rp_read_commands *rp = rsp;
-	uint16_t num_commands, num_events, *opcode;
-	size_t expected_len;
-	int i;
-
-	if (status != 0) {
-		fprintf(stderr, "Reading supported commands failed with status"
-			" 0x%02x (%s)\n", status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	if (len < sizeof(*rp)) {
-		fprintf(stderr, "Too small commands reply (%u bytes)\n", len);
-		exit(EXIT_FAILURE);
-	}
-
-	num_commands = bt_get_le16(&rp->num_commands);
-	num_events = bt_get_le16(&rp->num_events);
-
-	expected_len = sizeof(*rp) + num_commands * sizeof(uint16_t) +
-						num_events * sizeof(uint16_t);
-
-	if (len < expected_len) {
-		fprintf(stderr, "Too small commands reply (%u != %zu)\n",
-							len, expected_len);
-		exit(EXIT_FAILURE);
-	}
-
-	opcode = rp->opcodes;
-
-	printf("%u commands:\n", num_commands);
-	for (i = 0; i < num_commands; i++) {
-		uint16_t op = bt_get_le16(opcode++);
-		printf("\t%s (0x%04x)\n", mgmt_opstr(op), op);
-	}
-
-	printf("%u events:\n", num_events);
-	for (i = 0; i < num_events; i++) {
-		uint16_t ev = bt_get_le16(opcode++);
-		printf("\t%s (0x%04x)\n", mgmt_evstr(ev), ev);
-	}
-
-	exit(EXIT_SUCCESS);
-}
-
-static void cmd_commands(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE,
-					NULL, 0, commands_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send read_commands cmd\n");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void info_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data)
-{
-	struct mgmt_rp_read_info *rp = rsp;
-	char addr[18];
-
-	if (status != 0) {
-		fprintf(stderr,
-			"Reading hci%u info failed with status 0x%02x (%s)\n",
-					id, status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	if (len < sizeof(*rp)) {
-		fprintf(stderr, "Too small info reply (%u bytes)\n", len);
-		exit(EXIT_FAILURE);
-	}
-
-	ba2str(&rp->bdaddr, addr);
-	printf("hci%u:\taddr %s version %u manufacturer %u"
-			" class 0x%02x%02x%02x\n",
-			id, addr, rp->version, bt_get_le16(&rp->manufacturer),
-			rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
-
-	printf("\tsupported settings: ");
-	print_settings(bt_get_le32(&rp->supported_settings));
-
-	printf("\n\tcurrent settings: ");
-	print_settings(bt_get_le32(&rp->current_settings));
-
-	printf("\n\tname %s\n", rp->name);
-	printf("\tshort name %s\n", rp->short_name);
-
-	if (pending == NULL)
-		exit(EXIT_SUCCESS);
-}
-
-static void index_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data)
-{
-	struct mgmt_rp_read_index_list *rp = rsp;
-	uint16_t count;
-	unsigned int i;
-
-	if (status != 0) {
-		fprintf(stderr,
-			"Reading index list failed with status 0x%02x (%s)\n",
-						status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	if (len < sizeof(*rp)) {
-		fprintf(stderr, "Too small index list reply (%u bytes)\n",
-									len);
-		exit(EXIT_FAILURE);
-	}
-
-	count = bt_get_le16(&rp->num_controllers);
-
-	if (len < sizeof(*rp) + count * sizeof(uint16_t)) {
-		fprintf(stderr,
-			"Index count (%u) doesn't match reply length (%u)\n",
-								count, len);
-		exit(EXIT_FAILURE);
-	}
-
-	if (monitor)
-		printf("Index list with %u item%s\n",
-						count, count > 1 ? "s" : "");
-
-	if (count == 0)
-		exit(EXIT_SUCCESS);
-
-	if (monitor && count > 0)
-		printf("\t");
-
-	for (i = 0; i < count; i++) {
-		uint16_t index;
-
-		index = bt_get_le16(&rp->index[i]);
-
-		if (monitor)
-			printf("hci%u ", index);
-
-		if (mgmt_send_cmd(mgmt_sk, MGMT_OP_READ_INFO, index, NULL,
-					0, info_rsp, NULL) < 0) {
-			fprintf(stderr, "Unable to send read_info cmd\n");
-			exit(EXIT_FAILURE);
-		}
-	}
-
-	if (monitor && count > 0)
-		printf("\n");
-}
-
-static void cmd_info(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	if (index == MGMT_INDEX_NONE) {
-		if (mgmt_send_cmd(mgmt_sk, MGMT_OP_READ_INDEX_LIST,
-					MGMT_INDEX_NONE, NULL, 0,
-					index_rsp, NULL) < 0) {
-			fprintf(stderr, "Unable to send index_list cmd\n");
-			exit(EXIT_FAILURE);
-		}
-
-		return;
-	}
-
-	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_READ_INFO, index, NULL,
-						0, info_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send read_info cmd\n");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void setting_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data)
-{
-	uint32_t *rp = rsp;
-
-	if (status != 0) {
-		fprintf(stderr,
-			"%s for hci%u failed with status 0x%02x (%s)\n",
-			mgmt_opstr(op), id, status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	if (len < sizeof(*rp)) {
-		fprintf(stderr, "Too small %s response (%u bytes)\n",
-							mgmt_opstr(op), len);
-		exit(EXIT_FAILURE);
-	}
-
-	printf("hci%u %s complete, settings: ", id, mgmt_opstr(op));
-	print_settings(bt_get_le32(rp));
-	printf("\n");
-
-	exit(EXIT_SUCCESS);
-}
-
-static void cmd_setting(int mgmt_sk, uint16_t index, uint16_t op,
-							int argc, char **argv)
-{
-	uint8_t val;
-
-	if (argc < 2) {
-		printf("Specify \"on\" or \"off\"\n");
-		exit(EXIT_FAILURE);
-	}
-
-	if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
-		val = 1;
-	else if (strcasecmp(argv[1], "off") == 0)
-		val = 0;
-	else
-		val = atoi(argv[1]);
-
-	if (index == MGMT_INDEX_NONE)
-		index = 0;
-
-	if (mgmt_send_cmd(mgmt_sk, op, index, &val, sizeof(val),
-						setting_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send %s cmd\n", mgmt_opstr(op));
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void cmd_power(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	cmd_setting(mgmt_sk, index, MGMT_OP_SET_POWERED, argc, argv);
-}
-
-static void cmd_discov(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	struct mgmt_cp_set_discoverable cp;
-
-	if (argc < 2) {
-		printf("Usage: btmgmt %s <yes/no> [timeout]\n", argv[0]);
-		exit(EXIT_FAILURE);
-	}
-
-	memset(&cp, 0, sizeof(cp));
-
-	if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
-		cp.val = 1;
-	else if (strcasecmp(argv[1], "off") == 0)
-		cp.val = 0;
-	else
-		cp.val = atoi(argv[1]);
-
-	if (argc > 2)
-		cp.timeout = htobs(atoi(argv[2]));
-
-	if (index == MGMT_INDEX_NONE)
-		index = 0;
-
-	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_SET_DISCOVERABLE, index,
-				&cp, sizeof(cp), setting_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send set_discoverable cmd\n");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void cmd_connectable(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	cmd_setting(mgmt_sk, index, MGMT_OP_SET_CONNECTABLE, argc, argv);
-}
-
-static void cmd_pairable(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	cmd_setting(mgmt_sk, index, MGMT_OP_SET_PAIRABLE, argc, argv);
-}
-
-static void cmd_linksec(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	cmd_setting(mgmt_sk, index, MGMT_OP_SET_LINK_SECURITY, argc, argv);
-}
-
-static void cmd_ssp(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	cmd_setting(mgmt_sk, index, MGMT_OP_SET_SSP, argc, argv);
-}
-
-static void cmd_hs(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	cmd_setting(mgmt_sk, index, MGMT_OP_SET_HS, argc, argv);
-}
-
-static void cmd_le(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	cmd_setting(mgmt_sk, index, MGMT_OP_SET_LE, argc, argv);
-}
-
-static void class_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data)
-{
-	struct mgmt_ev_class_of_dev_changed *rp = rsp;
-
-	if (len == 0 && status != 0) {
-		fprintf(stderr, "%s failed, status 0x%02x (%s)\n",
-				mgmt_opstr(op), status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	if (len != sizeof(*rp)) {
-		fprintf(stderr, "Unexpected %s len %u\n", mgmt_opstr(op), len);
-		exit(EXIT_FAILURE);
-	}
-
-	printf("%s succeeded. Class 0x%02x%02x%02x\n", mgmt_opstr(op),
-		rp->class_of_dev[2], rp->class_of_dev[1], rp->class_of_dev[0]);
-
-	exit(EXIT_SUCCESS);
-}
-
-static void cmd_class(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	uint8_t class[2];
-
-	if (argc < 3) {
-		printf("Usage: btmgmt %s <major> <minor>\n", argv[0]);
-		exit(EXIT_FAILURE);
-	}
-
-	class[0] = atoi(argv[1]);
-	class[1] = atoi(argv[2]);
-
-	if (index == MGMT_INDEX_NONE)
-		index = 0;
-
-	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_SET_DEV_CLASS, index,
-				class, sizeof(class), class_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send set_dev_class cmd\n");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void disconnect_rsp(int mgmt_sk, uint16_t op, uint16_t id,
-				uint8_t status, void *rsp, uint16_t len,
-				void *user_data)
-{
-	struct mgmt_rp_disconnect *rp = rsp;
-	char addr[18];
-
-	if (len == 0 && status != 0) {
-		fprintf(stderr, "Disconnect failed with status 0x%02x (%s)\n",
-						status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	if (len != sizeof(*rp)) {
-		fprintf(stderr, "Invalid disconnect response length (%u)\n",
-									len);
-		exit(EXIT_FAILURE);
-	}
-
-	ba2str(&rp->addr.bdaddr, addr);
-
-	if (status == 0) {
-		printf("%s disconnected\n", addr);
-		exit(EXIT_SUCCESS);
-	} else {
-		fprintf(stderr,
-			"Disconnecting %s failed with status 0x%02x (%s)\n",
-				addr, status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void cmd_disconnect(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	struct mgmt_cp_disconnect cp;
-
-	if (argc < 2) {
-		printf("Usage: btmgmt %s <address>\n", argv[0]);
-		exit(EXIT_FAILURE);
-	}
-
-	str2ba(argv[1], &cp.addr.bdaddr);
-
-	if (index == MGMT_INDEX_NONE)
-		index = 0;
-
-	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_DISCONNECT, index,
-				&cp, sizeof(cp), disconnect_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send disconnect cmd\n");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void con_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data)
-{
-	struct mgmt_rp_get_connections *rp = rsp;
-	uint16_t count, i;
-
-	if (len < sizeof(*rp)) {
-		fprintf(stderr, "Too small (%u bytes) get_connections rsp\n",
-									len);
-		exit(EXIT_FAILURE);
-	}
-
-	count = bt_get_le16(&rp->conn_count);
-	if (len != sizeof(*rp) + count * sizeof(struct mgmt_addr_info)) {
-		fprintf(stderr, "Invalid get_connections length "
-					" (count=%u, len=%u)\n", count, len);
-		exit(EXIT_FAILURE);
-	}
-
-	for (i = 0; i < count; i++) {
-		char addr[18];
-
-		ba2str(&rp->addr[i].bdaddr, addr);
-
-		printf("%s type %s\n", addr, typestr(rp->addr[i].type));
-	}
-
-	exit(EXIT_SUCCESS);
-}
-
-static void cmd_con(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	if (index == MGMT_INDEX_NONE)
-		index = 0;
-
-	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_GET_CONNECTIONS, index, NULL, 0,
-							con_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send get_connections cmd\n");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void find_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data)
-{
-	if (status != 0) {
-		fprintf(stderr,
-			"Unable to start discovery. status 0x%02x (%s)\n",
-						status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	printf("Discovery started\n");
-	discovery = true;
-}
-
-static void find_usage(void)
-{
-	printf("Usage: btmgmt find [-l|-b]>\n");
-}
-
-static struct option find_options[] = {
-	{ "help",	0, 0, 'h' },
-	{ "le-only",	1, 0, 'l' },
-	{ "bredr-only",	1, 0, 'b' },
-	{ 0, 0, 0, 0 }
-};
-
-static void cmd_find(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	struct mgmt_cp_start_discovery cp;
-	uint8_t type;
-	int opt;
-
-	if (index == MGMT_INDEX_NONE)
-		index = 0;
-
-	type = 0;
-	hci_set_bit(BDADDR_BREDR, &type);
-	hci_set_bit(BDADDR_LE_PUBLIC, &type);
-	hci_set_bit(BDADDR_LE_RANDOM, &type);
-
-	while ((opt = getopt_long(argc, argv, "+lbh", find_options,
-								NULL)) != -1) {
-		switch (opt) {
-		case 'l':
-			hci_clear_bit(BDADDR_BREDR, &type);
-			hci_set_bit(BDADDR_LE_PUBLIC, &type);
-			hci_set_bit(BDADDR_LE_RANDOM, &type);
-			break;
-		case 'b':
-			hci_set_bit(BDADDR_BREDR, &type);
-			hci_clear_bit(BDADDR_LE_PUBLIC, &type);
-			hci_clear_bit(BDADDR_LE_RANDOM, &type);
-			break;
-		case 'h':
-		default:
-			find_usage();
-			exit(EXIT_SUCCESS);
-		}
-	}
-
-	argc -= optind;
-	argv += optind;
-	optind = 0;
-
-	memset(&cp, 0, sizeof(cp));
-	cp.type = type;
-
-	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_START_DISCOVERY, index,
-				&cp, sizeof(cp), find_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send start_discovery cmd\n");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void name_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data)
-{
-	if (status != 0) {
-		fprintf(stderr, "Unable to set local name. status 0x%02x (%s)",
-						status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	exit(EXIT_SUCCESS);
-}
-
-static void cmd_name(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	struct mgmt_cp_set_local_name cp;
-
-	if (argc < 2) {
-		printf("Usage: btmgmt %s <name> [shortname]\n", argv[0]);
-		exit(EXIT_FAILURE);
-	}
-
-	if (index == MGMT_INDEX_NONE)
-		index = 0;
-
-	memset(&cp, 0, sizeof(cp));
-	strncpy((char *) cp.name, argv[1], HCI_MAX_NAME_LENGTH);
-	if (argc > 2)
-		strncpy((char *) cp.short_name, argv[2],
-					MGMT_MAX_SHORT_NAME_LENGTH);
-
-	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_SET_LOCAL_NAME, index,
-					&cp, sizeof(cp), name_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send set_name cmd\n");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void pair_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data)
-{
-	struct mgmt_rp_pair_device *rp = rsp;
-	char addr[18];
-
-	if (len == 0 && status != 0) {
-		fprintf(stderr, "Pairing failed with status 0x%02x (%s)\n",
-						status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	if (len != sizeof(*rp)) {
-		fprintf(stderr, "Unexpected pair_rsp len %u\n", len);
-		exit(EXIT_FAILURE);
-	}
-
-	ba2str(&rp->addr.bdaddr, addr);
-
-	if (status != 0) {
-		fprintf(stderr,
-			"Pairing with %s (%s) failed. status 0x%02x (%s)\n",
-			addr, typestr(rp->addr.type), status,
-			mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	printf("Paired with %s\n", addr);
-
-	exit(EXIT_SUCCESS);
-}
-
-static void pair_usage(void)
-{
-	printf("Usage: btmgmt pair [-c cap] [-t type] <remote address>\n");
-}
-
-static struct option pair_options[] = {
-	{ "help",	0, 0, 'h' },
-	{ "capability",	1, 0, 'c' },
-	{ "type",	1, 0, 't' },
-	{ 0, 0, 0, 0 }
-};
-
-static void cmd_pair(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	struct mgmt_cp_pair_device cp;
-	uint8_t cap = 0x01;
-	uint8_t type = BDADDR_BREDR;
-	int opt;
-
-	while ((opt = getopt_long(argc, argv, "+c:t:h", pair_options,
-								NULL)) != -1) {
-		switch (opt) {
-		case 'c':
-			cap = strtol(optarg, NULL, 0);
-			break;
-		case 't':
-			type = strtol(optarg, NULL, 0);
-			break;
-		case 'h':
-		default:
-			pair_usage();
-			exit(EXIT_SUCCESS);
-		}
-	}
-
-	argc -= optind;
-	argv += optind;
-	optind = 0;
-
-	if (argc < 1) {
-		pair_usage();
-		exit(EXIT_FAILURE);
-	}
-
-	if (index == MGMT_INDEX_NONE)
-		index = 0;
-
-	memset(&cp, 0, sizeof(cp));
-	str2ba(argv[0], &cp.addr.bdaddr);
-	cp.addr.type = type;
-	cp.io_cap = cap;
-
-	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_PAIR_DEVICE, index, &cp, sizeof(cp),
-							pair_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send pair_device cmd\n");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void unpair_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data)
-{
-	struct mgmt_rp_unpair_device *rp = rsp;
-	char addr[18];
-
-	if (len == 0 && status != 0) {
-		fprintf(stderr, "Unpair device failed. status 0x%02x (%s)\n",
-						status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	if (len != sizeof(*rp)) {
-		fprintf(stderr, "Unexpected unpair_device_rsp len %u\n", len);
-		exit(EXIT_FAILURE);
-	}
-
-	ba2str(&rp->addr.bdaddr, addr);
-
-	if (status != 0) {
-		fprintf(stderr,
-			"Unpairing %s failed. status 0x%02x (%s)\n",
-				addr, status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	printf("%s unpaired\n", addr);
-
-	exit(EXIT_SUCCESS);
-}
-
-static void cmd_unpair(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	struct mgmt_cp_unpair_device cp;
-
-	if (argc < 2) {
-		printf("Usage: btmgmt %s <remote address>\n", argv[0]);
-		exit(EXIT_FAILURE);
-	}
-
-	if (index == MGMT_INDEX_NONE)
-		index = 0;
-
-	memset(&cp, 0, sizeof(cp));
-	str2ba(argv[1], &cp.addr.bdaddr);
-	cp.disconnect = 1;
-
-	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_UNPAIR_DEVICE, index, &cp,
-					sizeof(cp), unpair_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send unpair_device cmd\n");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void keys_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data)
-{
-	if (status != 0) {
-		fprintf(stderr, "Load keys failed with status 0x%02x (%s)\n",
-						status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	printf("Keys successfully loaded\n");
-
-	exit(EXIT_SUCCESS);
-}
-
-static void cmd_keys(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	struct mgmt_cp_load_link_keys cp;
-
-	if (index == MGMT_INDEX_NONE)
-		index = 0;
-
-	memset(&cp, 0, sizeof(cp));
-
-	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_LOAD_LINK_KEYS, index,
-				&cp, sizeof(cp), keys_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send load_keys cmd\n");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void block_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data)
-{
-	struct mgmt_addr_info *rp = rsp;
-	char addr[18];
-
-	if (len == 0 && status != 0) {
-		fprintf(stderr, "%s failed, status 0x%02x (%s)\n",
-				mgmt_opstr(op), status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	if (len != sizeof(*rp)) {
-		fprintf(stderr, "Unexpected %s len %u\n", mgmt_opstr(op), len);
-		exit(EXIT_FAILURE);
-	}
-
-	ba2str(&rp->bdaddr, addr);
-
-	if (status != 0) {
-		fprintf(stderr, "%s %s (%s) failed. status 0x%02x (%s)\n",
-				mgmt_opstr(op), addr, typestr(rp->type),
-				status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	printf("%s %s succeeded\n", mgmt_opstr(op), addr);
-
-	exit(EXIT_SUCCESS);
-}
-
-static void block_usage(void)
-{
-	printf("Usage: btmgmt block [-t type] <remote address>\n");
-}
-
-static struct option block_options[] = {
-	{ "help",	0, 0, 'h' },
-	{ "type",	1, 0, 't' },
-	{ 0, 0, 0, 0 }
-};
-
-static void cmd_block(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	struct mgmt_cp_block_device cp;
-	uint8_t type = BDADDR_BREDR;
-	int opt;
-
-	while ((opt = getopt_long(argc, argv, "+t:h", block_options,
-							NULL)) != -1) {
-		switch (opt) {
-		case 't':
-			type = strtol(optarg, NULL, 0);
-			break;
-		case 'h':
-		default:
-			block_usage();
-			exit(EXIT_SUCCESS);
-		}
-	}
-
-	argc -= optind;
-	argv += optind;
-	optind = 0;
-
-	if (argc < 1) {
-		block_usage();
-		exit(EXIT_FAILURE);
-	}
-
-	if (index == MGMT_INDEX_NONE)
-		index = 0;
-
-	memset(&cp, 0, sizeof(cp));
-	str2ba(argv[0], &cp.addr.bdaddr);
-	cp.addr.type = type;
-
-	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_BLOCK_DEVICE, index,
-				&cp, sizeof(cp), block_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send block_device cmd\n");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void unblock_usage(void)
-{
-	printf("Usage: btmgmt unblock [-t type] <remote address>\n");
-}
-
-static void cmd_unblock(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	struct mgmt_cp_unblock_device cp;
-	uint8_t type = BDADDR_BREDR;
-	int opt;
-
-	while ((opt = getopt_long(argc, argv, "+t:h", block_options,
-							NULL)) != -1) {
-		switch (opt) {
-		case 't':
-			type = strtol(optarg, NULL, 0);
-			break;
-		case 'h':
-		default:
-			unblock_usage();
-			exit(EXIT_SUCCESS);
-		}
-	}
-
-	argc -= optind;
-	argv += optind;
-	optind = 0;
-
-	if (argc < 1) {
-		unblock_usage();
-		exit(EXIT_FAILURE);
-	}
-
-	if (index == MGMT_INDEX_NONE)
-		index = 0;
-
-	memset(&cp, 0, sizeof(cp));
-	str2ba(argv[0], &cp.addr.bdaddr);
-	cp.addr.type = type;
-
-	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_UNBLOCK_DEVICE, index,
-				&cp, sizeof(cp), block_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send unblock_device cmd\n");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void uuid_to_uuid128(uuid_t *uuid128, const uuid_t *uuid)
-{
-	if (uuid->type == SDP_UUID16)
-		sdp_uuid16_to_uuid128(uuid128, uuid);
-	else if (uuid->type == SDP_UUID32)
-		sdp_uuid32_to_uuid128(uuid128, uuid);
-	else
-		memcpy(uuid128, uuid, sizeof(*uuid));
-}
-
-static void cmd_add_uuid(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	struct mgmt_cp_add_uuid cp;
-	uint128_t uint128;
-	uuid_t uuid, uuid128;
-
-	if (argc < 3) {
-		printf("UUID and service hint needed\n");
-		exit(EXIT_FAILURE);
-	}
-
-	if (index == MGMT_INDEX_NONE)
-		index = 0;
-
-	if (bt_string2uuid(&uuid, argv[1]) < 0) {
-		printf("Invalid UUID: %s\n", argv[1]);
-		exit(EXIT_FAILURE);
-	}
-
-	memset(&cp, 0, sizeof(cp));
-
-	uuid_to_uuid128(&uuid128, &uuid);
-	ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
-	htob128(&uint128, (uint128_t *) cp.uuid);
-
-	cp.svc_hint = atoi(argv[2]);
-
-	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_ADD_UUID, index,
-				&cp, sizeof(cp), class_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send add_uuid cmd\n");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void cmd_remove_uuid(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	struct mgmt_cp_remove_uuid cp;
-	uint128_t uint128;
-	uuid_t uuid, uuid128;
-
-	if (argc < 2) {
-		printf("UUID needed\n");
-		exit(EXIT_FAILURE);
-	}
-
-	if (index == MGMT_INDEX_NONE)
-		index = 0;
-
-	if (bt_string2uuid(&uuid, argv[1]) < 0) {
-		printf("Invalid UUID: %s\n", argv[1]);
-		exit(EXIT_FAILURE);
-	}
-
-	memset(&cp, 0, sizeof(cp));
-
-	uuid_to_uuid128(&uuid128, &uuid);
-	ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
-	htob128(&uint128, (uint128_t *) cp.uuid);
-
-	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_REMOVE_UUID, index,
-				&cp, sizeof(cp), class_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send remove_uuid cmd\n");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static void cmd_clr_uuids(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	char *uuid_any = "00000000-0000-0000-0000-000000000000";
-	char *rm_argv[] = { "rm-uuid", uuid_any, NULL };
-
-	cmd_remove_uuid(mgmt_sk, index, 2, rm_argv);
-}
-
-static void did_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
-				void *rsp, uint16_t len, void *user_data)
-{
-	if (status != 0) {
-		fprintf(stderr, "Set Device ID failed with status 0x%02x (%s)\n",
-						status, mgmt_errstr(status));
-		exit(EXIT_FAILURE);
-	}
-
-	printf("Device ID successfully set\n");
-
-	exit(EXIT_SUCCESS);
-}
-
-static void did_usage(void)
-{
-	printf("Usage: btmgmt did <source>:<vendor>:<product>:<version>\n");
-	printf("       possible source values: bluetooth, usb\n");
-}
-
-static void cmd_did(int mgmt_sk, uint16_t index, int argc, char **argv)
-{
-	struct mgmt_cp_set_device_id cp;
-	uint16_t vendor, product, version , source;
-	int result;
-
-	if (argc < 2) {
-		did_usage();
-		exit(EXIT_FAILURE);
-	}
-
-	result = sscanf(argv[1], "bluetooth:%4hx:%4hx:%4hx", &vendor, &product,
-								&version);
-	if (result == 3) {
-		source = 0x0001;
-		goto done;
-	}
-
-	result = sscanf(argv[1], "usb:%4hx:%4hx:%4hx", &vendor, &product,
-								&version);
-	if (result == 3) {
-		source = 0x0002;
-		goto done;
-	}
-
-	did_usage();
-	exit(EXIT_FAILURE);
-
-done:
-	if (index == MGMT_INDEX_NONE)
-		index = 0;
-
-	cp.source = htobs(source);
-	cp.vendor = htobs(vendor);
-	cp.product = htobs(product);
-	cp.version = htobs(version);
-
-	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_SET_DEVICE_ID, index,
-				&cp, sizeof(cp), did_rsp, NULL) < 0) {
-		fprintf(stderr, "Unable to send set_dev_class cmd\n");
-		exit(EXIT_FAILURE);
-	}
-}
-
-static struct {
-	char *cmd;
-	void (*func)(int mgmt_sk, uint16_t index, int argc, char **argv);
-	char *doc;
-} command[] = {
-	{ "monitor",	cmd_monitor,	"Monitor events"		},
-	{ "version",	cmd_version,	"Get the MGMT Version"		},
-	{ "commands",	cmd_commands,	"List supported commands"	},
-	{ "info",	cmd_info,	"Show controller info"		},
-	{ "power",	cmd_power,	"Toggle powered state"		},
-	{ "discov",	cmd_discov,	"Toggle discoverable state"	},
-	{ "connectable",cmd_connectable,"Toggle connectable state"	},
-	{ "pairable",	cmd_pairable,	"Toggle pairable state"		},
-	{ "linksec",	cmd_linksec,	"Toggle link level security"	},
-	{ "ssp",	cmd_ssp,	"Toggle SSP mode"		},
-	{ "hs",		cmd_hs,		"Toggle HS Support"		},
-	{ "le",		cmd_le,		"Toggle LE Support"		},
-	{ "class",	cmd_class,	"Set device major/minor class"	},
-	{ "disconnect", cmd_disconnect, "Disconnect device"		},
-	{ "con",	cmd_con,	"List connections"		},
-	{ "find",	cmd_find,	"Discover nearby devices"	},
-	{ "name",	cmd_name,	"Set local name"		},
-	{ "pair",	cmd_pair,	"Pair with a remote device"	},
-	{ "unpair",	cmd_unpair,	"Unpair device"			},
-	{ "keys",	cmd_keys,	"Load Keys"			},
-	{ "block",	cmd_block,	"Block Device"			},
-	{ "unblock",	cmd_unblock,	"Unblock Device"		},
-	{ "add-uuid",	cmd_add_uuid,	"Add UUID"			},
-	{ "rm-uuid",	cmd_add_uuid,	"Remove UUID"			},
-	{ "clr-uuids",	cmd_clr_uuids,	"Clear UUIDs",			},
-	{ "did",	cmd_did,	"Set Device ID",		},
-	{ NULL, NULL, 0 }
-};
-
-static void usage(void)
-{
-	int i;
-
-	printf("btmgmt ver %s\n", VERSION);
-	printf("Usage:\n"
-		"\tbtmgmt [options] <command> [command parameters]\n");
-
-	printf("Options:\n"
-		"\t--index <id>\tSpecify adapter index\n"
-		"\t--verbose\tEnable extra logging\n"
-		"\t--help\tDisplay help\n");
-
-	printf("Commands:\n");
-	for (i = 0; command[i].cmd; i++)
-		printf("\t%-15s\t%s\n", command[i].cmd, command[i].doc);
-
-	printf("\n"
-		"For more information on the usage of each command use:\n"
-		"\tbtmgmt <command> --help\n" );
-}
-
-static struct option main_options[] = {
-	{ "index",	1, 0, 'i' },
-	{ "verbose",	0, 0, 'v' },
-	{ "help",	0, 0, 'h' },
-	{ 0, 0, 0, 0 }
-};
-
-int main(int argc, char *argv[])
-{
-	int opt, i, mgmt_sk;
-	uint16_t index = MGMT_INDEX_NONE;
-	struct pollfd pollfd;
-
-	while ((opt = getopt_long(argc, argv, "+hvi:",
-						main_options, NULL)) != -1) {
-		switch (opt) {
-		case 'i':
-			if (strlen(optarg) > 3 &&
-					strncasecmp(optarg, "hci", 3) == 0)
-				index = atoi(&optarg[4]);
-			else
-				index = atoi(optarg);
-			break;
-		case 'v':
-			monitor = true;
-			break;
-		case 'h':
-		default:
-			usage();
-			return 0;
-		}
-	}
-
-	argc -= optind;
-	argv += optind;
-	optind = 0;
-
-	if (argc < 1) {
-		usage();
-		return 0;
-	}
-
-	mgmt_sk = mgmt_open();
-	if (mgmt_sk < 0) {
-		fprintf(stderr, "Unable to open mgmt socket\n");
-		return -1;
-	}
-
-	for (i = 0; command[i].cmd; i++) {
-		if (strcmp(command[i].cmd, argv[0]) != 0)
-			continue;
-
-		command[i].func(mgmt_sk, index, argc, argv);
-		break;
-	}
-
-	if (command[i].cmd == NULL) {
-		fprintf(stderr, "Unknown command: %s\n", argv[0]);
-		close(mgmt_sk);
-		return -1;
-	}
-
-	pollfd.fd = mgmt_sk;
-	pollfd.events = POLLIN;
-	pollfd.revents = 0;
-
-	while (poll(&pollfd, 1, -1) >= 0) {
-		if (pollfd.revents & (POLLHUP | POLLERR | POLLNVAL))
-			break;
-
-		if (pollfd.revents & POLLIN)
-			mgmt_process_data(mgmt_sk);
-
-		pollfd.revents = 0;
-	}
-
-	close(mgmt_sk);
-
-	return 0;
-}
-- 
1.7.10.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 04/14] alert: move alert to profiles dir
  2012-07-09 21:10 [PATCH 01/14] input: remove unneeded header inclusions Gustavo Padovan
  2012-07-09 21:10 ` [PATCH 02/14] serial: remove the whole serial code Gustavo Padovan
  2012-07-09 21:10 ` [PATCH 03/14] btmgmt: move to tools folder Gustavo Padovan
@ 2012-07-09 21:10 ` Gustavo Padovan
  2012-07-09 21:10 ` [PATCH 05/14] deviceinfo: move to profiles folder Gustavo Padovan
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Gustavo Padovan @ 2012-07-09 21:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

---
 Makefile.am             |    3 ++-
 alert/main.c            |   58 -----------------------------------------------
 alert/server.c          |   38 -------------------------------
 alert/server.h          |   26 ---------------------
 profiles/alert/main.c   |   58 +++++++++++++++++++++++++++++++++++++++++++++++
 profiles/alert/server.c |   38 +++++++++++++++++++++++++++++++
 profiles/alert/server.h |   26 +++++++++++++++++++++
 7 files changed, 124 insertions(+), 123 deletions(-)
 delete mode 100644 alert/main.c
 delete mode 100644 alert/server.c
 delete mode 100644 alert/server.h
 create mode 100644 profiles/alert/main.c
 create mode 100644 profiles/alert/server.c
 create mode 100644 profiles/alert/server.h

diff --git a/Makefile.am b/Makefile.am
index a2c85e2..f0e82d1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -219,7 +219,8 @@ builtin_modules += thermometer alert time gatt_example proximity \
 builtin_sources += thermometer/main.c \
 			thermometer/manager.h thermometer/manager.c \
 			thermometer/thermometer.h thermometer/thermometer.c \
-			alert/main.c alert/server.h alert/server.c \
+			profiles/alert/main.c profiles/alert/server.h \
+			profiles/alert/server.c \
 			time/main.c time/server.h time/server.c \
 			time/manager.h time/manager.c \
 			plugins/gatt-example.c \
diff --git a/alert/main.c b/alert/main.c
deleted file mode 100644
index ec4ab6d..0000000
--- a/alert/main.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *
- *  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 <stdint.h>
-#include <glib.h>
-#include <errno.h>
-
-#include "plugin.h"
-#include "hcid.h"
-#include "log.h"
-#include "server.h"
-
-static int alert_init(void)
-{
-	if (!main_opts.gatt_enabled) {
-		DBG("GATT is disabled");
-		return -ENOTSUP;
-	}
-
-	return alert_server_init();
-}
-
-static void alert_exit(void)
-{
-	if (!main_opts.gatt_enabled)
-		return;
-
-	alert_server_exit();
-}
-
-BLUETOOTH_PLUGIN_DEFINE(alert, VERSION,
-			BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
-			alert_init, alert_exit)
diff --git a/alert/server.c b/alert/server.c
deleted file mode 100644
index d91b156..0000000
--- a/alert/server.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *
- *  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 "server.h"
-
-int alert_server_init(void)
-{
-	return 0;
-}
-
-void alert_server_exit(void)
-{
-}
diff --git a/alert/server.h b/alert/server.h
deleted file mode 100644
index e59bdb1..0000000
--- a/alert/server.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *
- *  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
- *
- */
-
-int alert_server_init(void);
-void alert_server_exit(void);
diff --git a/profiles/alert/main.c b/profiles/alert/main.c
new file mode 100644
index 0000000..ec4ab6d
--- /dev/null
+++ b/profiles/alert/main.c
@@ -0,0 +1,58 @@
+/*
+ *
+ *  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 <stdint.h>
+#include <glib.h>
+#include <errno.h>
+
+#include "plugin.h"
+#include "hcid.h"
+#include "log.h"
+#include "server.h"
+
+static int alert_init(void)
+{
+	if (!main_opts.gatt_enabled) {
+		DBG("GATT is disabled");
+		return -ENOTSUP;
+	}
+
+	return alert_server_init();
+}
+
+static void alert_exit(void)
+{
+	if (!main_opts.gatt_enabled)
+		return;
+
+	alert_server_exit();
+}
+
+BLUETOOTH_PLUGIN_DEFINE(alert, VERSION,
+			BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
+			alert_init, alert_exit)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
new file mode 100644
index 0000000..d91b156
--- /dev/null
+++ b/profiles/alert/server.c
@@ -0,0 +1,38 @@
+/*
+ *
+ *  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 "server.h"
+
+int alert_server_init(void)
+{
+	return 0;
+}
+
+void alert_server_exit(void)
+{
+}
diff --git a/profiles/alert/server.h b/profiles/alert/server.h
new file mode 100644
index 0000000..e59bdb1
--- /dev/null
+++ b/profiles/alert/server.h
@@ -0,0 +1,26 @@
+/*
+ *
+ *  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
+ *
+ */
+
+int alert_server_init(void);
+void alert_server_exit(void);
-- 
1.7.10.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 05/14] deviceinfo: move to profiles folder
  2012-07-09 21:10 [PATCH 01/14] input: remove unneeded header inclusions Gustavo Padovan
                   ` (2 preceding siblings ...)
  2012-07-09 21:10 ` [PATCH 04/14] alert: move alert to profiles dir Gustavo Padovan
@ 2012-07-09 21:10 ` Gustavo Padovan
  2012-07-09 21:10 ` [PATCH 07/14] thermometer: move to the " Gustavo Padovan
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Gustavo Padovan @ 2012-07-09 21:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

---
 Makefile.am                      |   11 ++-
 deviceinfo/deviceinfo.c          |  195 --------------------------------------
 deviceinfo/deviceinfo.h          |   24 -----
 deviceinfo/main.c                |   52 ----------
 deviceinfo/manager.c             |   80 ----------------
 deviceinfo/manager.h             |   24 -----
 profiles/deviceinfo/deviceinfo.c |  195 ++++++++++++++++++++++++++++++++++++++
 profiles/deviceinfo/deviceinfo.h |   24 +++++
 profiles/deviceinfo/main.c       |   52 ++++++++++
 profiles/deviceinfo/manager.c    |   80 ++++++++++++++++
 profiles/deviceinfo/manager.h    |   24 +++++
 11 files changed, 381 insertions(+), 380 deletions(-)
 delete mode 100644 deviceinfo/deviceinfo.c
 delete mode 100644 deviceinfo/deviceinfo.h
 delete mode 100644 deviceinfo/main.c
 delete mode 100644 deviceinfo/manager.c
 delete mode 100644 deviceinfo/manager.h
 create mode 100644 profiles/deviceinfo/deviceinfo.c
 create mode 100644 profiles/deviceinfo/deviceinfo.h
 create mode 100644 profiles/deviceinfo/main.c
 create mode 100644 profiles/deviceinfo/manager.c
 create mode 100644 profiles/deviceinfo/manager.h

diff --git a/Makefile.am b/Makefile.am
index f0e82d1..2487368 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -214,8 +214,7 @@ builtin_sources += health/hdp_main.c health/hdp_types.h \
 endif
 
 if GATTMODULES
-builtin_modules += thermometer alert time gatt_example proximity \
-			deviceinfo
+builtin_modules += thermometer alert time gatt_example proximity deviceinfo
 builtin_sources += thermometer/main.c \
 			thermometer/manager.h thermometer/manager.c \
 			thermometer/thermometer.h thermometer/thermometer.c \
@@ -229,9 +228,11 @@ builtin_sources += thermometer/main.c \
 			proximity/reporter.h proximity/reporter.c \
 			proximity/linkloss.h proximity/linkloss.c \
 			proximity/immalert.h proximity/immalert.c \
-			deviceinfo/main.c \
-			deviceinfo/manager.h deviceinfo/manager.c \
-			deviceinfo/deviceinfo.h deviceinfo/deviceinfo.c
+			profiles/deviceinfo/main.c \
+			profiles/deviceinfo/manager.h \
+			profiles/deviceinfo/manager.c \
+			profiles/deviceinfo/deviceinfo.h \
+			profiles/deviceinfo/deviceinfo.c
 endif
 
 
diff --git a/deviceinfo/deviceinfo.c b/deviceinfo/deviceinfo.c
deleted file mode 100644
index 4548553..0000000
--- a/deviceinfo/deviceinfo.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2012 Texas Instruments, Inc.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-#include <bluetooth/uuid.h>
-
-#include "adapter.h"
-#include "device.h"
-#include "gattrib.h"
-#include "attio.h"
-#include "att.h"
-#include "gattrib.h"
-#include "gatt.h"
-#include "log.h"
-#include "deviceinfo.h"
-
-#define PNP_ID_SIZE	7
-
-struct deviceinfo {
-	struct btd_device	*dev;		/* Device reference */
-	GAttrib			*attrib;	/* GATT connection */
-	guint			attioid;	/* Att watcher id */
-	struct att_range	*svc_range;	/* DeviceInfo range */
-	GSList			*chars;		/* Characteristics */
-};
-
-static GSList *servers = NULL;
-
-struct characteristic {
-	struct gatt_char	attr;	/* Characteristic */
-	struct deviceinfo	*d;	/* deviceinfo where the char belongs */
-};
-
-static void deviceinfo_free(gpointer user_data)
-{
-	struct deviceinfo *d = user_data;
-
-	if (d->attioid > 0)
-		btd_device_remove_attio_callback(d->dev, d->attioid);
-
-	if (d->attrib != NULL)
-		g_attrib_unref(d->attrib);
-
-	g_slist_free_full(d->chars, g_free);
-
-	btd_device_unref(d->dev);
-	g_free(d->svc_range);
-	g_free(d);
-}
-
-static gint cmp_device(gconstpointer a, gconstpointer b)
-{
-	const struct deviceinfo *d = a;
-	const struct btd_device *dev = b;
-
-	if (dev == d->dev)
-		return 0;
-
-	return -1;
-}
-
-static void read_pnpid_cb(guint8 status, const guint8 *pdu, guint16 len,
-							gpointer user_data)
-{
-	struct characteristic *ch = user_data;
-	uint8_t value[PNP_ID_SIZE];
-	ssize_t vlen;
-
-	if (status != 0) {
-		error("Error reading PNP_ID value: %s", att_ecode2str(status));
-		return;
-	}
-
-	vlen = dec_read_resp(pdu, len, value, sizeof(value));
-	if (vlen < 0) {
-		error("Error reading PNP_ID: Protocol error");
-		return;
-	}
-
-	if (vlen < 7) {
-		error("Error reading PNP_ID: Invalid pdu length received");
-		return;
-	}
-
-	device_set_pnpid(ch->d->dev, value[0], att_get_u16(&value[1]),
-				att_get_u16(&value[3]), att_get_u16(&value[5]));
-}
-
-static void process_deviceinfo_char(struct characteristic *ch)
-{
-	if (g_strcmp0(ch->attr.uuid, PNPID_UUID) == 0)
-		gatt_read_char(ch->d->attrib, ch->attr.value_handle, 0,
-							read_pnpid_cb, ch);
-}
-
-static void configure_deviceinfo_cb(GSList *characteristics, guint8 status,
-							gpointer user_data)
-{
-	struct deviceinfo *d = user_data;
-	GSList *l;
-
-	if (status != 0) {
-		error("Discover deviceinfo characteristics: %s",
-							att_ecode2str(status));
-		return;
-	}
-
-	for (l = characteristics; l; l = l->next) {
-		struct gatt_char *c = l->data;
-		struct characteristic *ch;
-
-		ch = g_new0(struct characteristic, 1);
-		ch->attr.handle = c->handle;
-		ch->attr.properties = c->properties;
-		ch->attr.value_handle = c->value_handle;
-		memcpy(ch->attr.uuid, c->uuid, MAX_LEN_UUID_STR + 1);
-		ch->d = d;
-
-		d->chars = g_slist_append(d->chars, ch);
-
-		process_deviceinfo_char(ch);
-	}
-}
-static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
-{
-	struct deviceinfo *d = user_data;
-
-	d->attrib = g_attrib_ref(attrib);
-
-	gatt_discover_char(d->attrib, d->svc_range->start, d->svc_range->end,
-					NULL, configure_deviceinfo_cb, d);
-}
-
-static void attio_disconnected_cb(gpointer user_data)
-{
-	struct deviceinfo *d = user_data;
-
-	g_attrib_unref(d->attrib);
-	d->attrib = NULL;
-}
-
-int deviceinfo_register(struct btd_device *device, struct gatt_primary *prim)
-{
-	struct deviceinfo *d;
-
-	d = g_new0(struct deviceinfo, 1);
-	d->dev = btd_device_ref(device);
-	d->svc_range = g_new0(struct att_range, 1);
-	d->svc_range->start = prim->range.start;
-	d->svc_range->end = prim->range.end;
-
-	servers = g_slist_prepend(servers, d);
-
-	d->attioid = btd_device_add_attio_callback(device, attio_connected_cb,
-						attio_disconnected_cb, d);
-	return 0;
-}
-
-void deviceinfo_unregister(struct btd_device *device)
-{
-	struct deviceinfo *d;
-	GSList *l;
-
-	l = g_slist_find_custom(servers, device, cmp_device);
-	if (l == NULL)
-		return;
-
-	d = l->data;
-	servers = g_slist_remove(servers, d);
-
-	deviceinfo_free(d);
-}
diff --git a/deviceinfo/deviceinfo.h b/deviceinfo/deviceinfo.h
deleted file mode 100644
index 7a804a5..0000000
--- a/deviceinfo/deviceinfo.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2012 Texas Instruments, Inc.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-int deviceinfo_register(struct btd_device *device, struct gatt_primary *prim);
-void deviceinfo_unregister(struct btd_device *device);
diff --git a/deviceinfo/main.c b/deviceinfo/main.c
deleted file mode 100644
index 82ecc82..0000000
--- a/deviceinfo/main.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2012 Texas Instruments, Inc.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-#include <errno.h>
-#include <stdint.h>
-
-#include "plugin.h"
-#include "manager.h"
-#include "hcid.h"
-#include "log.h"
-
-static int deviceinfo_init(void)
-{
-	if (!main_opts.gatt_enabled) {
-		error("DIS cannot start: GATT is disabled");
-		return -ENOTSUP;
-	}
-
-	return deviceinfo_manager_init();
-}
-
-static void deviceinfo_exit(void)
-{
-	deviceinfo_manager_exit();
-}
-
-BLUETOOTH_PLUGIN_DEFINE(deviceinfo, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
-					deviceinfo_init, deviceinfo_exit)
diff --git a/deviceinfo/manager.c b/deviceinfo/manager.c
deleted file mode 100644
index 1d59918..0000000
--- a/deviceinfo/manager.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2012 Texas Instruments, Inc.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include <glib.h>
-#include <errno.h>
-#include <bluetooth/uuid.h>
-
-#include "adapter.h"
-#include "device.h"
-#include "att.h"
-#include "gattrib.h"
-#include "gatt.h"
-#include "deviceinfo.h"
-#include "manager.h"
-
-static gint primary_uuid_cmp(gconstpointer a, gconstpointer b)
-{
-	const struct gatt_primary *prim = a;
-	const char *uuid = b;
-
-	return g_strcmp0(prim->uuid, uuid);
-}
-
-static int deviceinfo_driver_probe(struct btd_device *device, GSList *uuids)
-{
-	struct gatt_primary *prim;
-	GSList *primaries, *l;
-
-	primaries = btd_device_get_primaries(device);
-
-	l = g_slist_find_custom(primaries, DEVICE_INFORMATION_UUID,
-							primary_uuid_cmp);
-	if (l == NULL)
-		return -EINVAL;
-
-	prim = l->data;
-
-	return deviceinfo_register(device, prim);
-}
-
-static void deviceinfo_driver_remove(struct btd_device *device)
-{
-	deviceinfo_unregister(device);
-}
-
-static struct btd_device_driver deviceinfo_device_driver = {
-	.name	= "deviceinfo-driver",
-	.uuids	= BTD_UUIDS(DEVICE_INFORMATION_UUID),
-	.probe	= deviceinfo_driver_probe,
-	.remove	= deviceinfo_driver_remove
-};
-
-int deviceinfo_manager_init(void)
-{
-	return btd_register_device_driver(&deviceinfo_device_driver);
-}
-
-void deviceinfo_manager_exit(void)
-{
-	btd_unregister_device_driver(&deviceinfo_device_driver);
-}
diff --git a/deviceinfo/manager.h b/deviceinfo/manager.h
deleted file mode 100644
index 0f742ca..0000000
--- a/deviceinfo/manager.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2012 Texas Instruments, Inc.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-int deviceinfo_manager_init(void);
-void deviceinfo_manager_exit(void);
diff --git a/profiles/deviceinfo/deviceinfo.c b/profiles/deviceinfo/deviceinfo.c
new file mode 100644
index 0000000..4548553
--- /dev/null
+++ b/profiles/deviceinfo/deviceinfo.c
@@ -0,0 +1,195 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <bluetooth/uuid.h>
+
+#include "adapter.h"
+#include "device.h"
+#include "gattrib.h"
+#include "attio.h"
+#include "att.h"
+#include "gattrib.h"
+#include "gatt.h"
+#include "log.h"
+#include "deviceinfo.h"
+
+#define PNP_ID_SIZE	7
+
+struct deviceinfo {
+	struct btd_device	*dev;		/* Device reference */
+	GAttrib			*attrib;	/* GATT connection */
+	guint			attioid;	/* Att watcher id */
+	struct att_range	*svc_range;	/* DeviceInfo range */
+	GSList			*chars;		/* Characteristics */
+};
+
+static GSList *servers = NULL;
+
+struct characteristic {
+	struct gatt_char	attr;	/* Characteristic */
+	struct deviceinfo	*d;	/* deviceinfo where the char belongs */
+};
+
+static void deviceinfo_free(gpointer user_data)
+{
+	struct deviceinfo *d = user_data;
+
+	if (d->attioid > 0)
+		btd_device_remove_attio_callback(d->dev, d->attioid);
+
+	if (d->attrib != NULL)
+		g_attrib_unref(d->attrib);
+
+	g_slist_free_full(d->chars, g_free);
+
+	btd_device_unref(d->dev);
+	g_free(d->svc_range);
+	g_free(d);
+}
+
+static gint cmp_device(gconstpointer a, gconstpointer b)
+{
+	const struct deviceinfo *d = a;
+	const struct btd_device *dev = b;
+
+	if (dev == d->dev)
+		return 0;
+
+	return -1;
+}
+
+static void read_pnpid_cb(guint8 status, const guint8 *pdu, guint16 len,
+							gpointer user_data)
+{
+	struct characteristic *ch = user_data;
+	uint8_t value[PNP_ID_SIZE];
+	ssize_t vlen;
+
+	if (status != 0) {
+		error("Error reading PNP_ID value: %s", att_ecode2str(status));
+		return;
+	}
+
+	vlen = dec_read_resp(pdu, len, value, sizeof(value));
+	if (vlen < 0) {
+		error("Error reading PNP_ID: Protocol error");
+		return;
+	}
+
+	if (vlen < 7) {
+		error("Error reading PNP_ID: Invalid pdu length received");
+		return;
+	}
+
+	device_set_pnpid(ch->d->dev, value[0], att_get_u16(&value[1]),
+				att_get_u16(&value[3]), att_get_u16(&value[5]));
+}
+
+static void process_deviceinfo_char(struct characteristic *ch)
+{
+	if (g_strcmp0(ch->attr.uuid, PNPID_UUID) == 0)
+		gatt_read_char(ch->d->attrib, ch->attr.value_handle, 0,
+							read_pnpid_cb, ch);
+}
+
+static void configure_deviceinfo_cb(GSList *characteristics, guint8 status,
+							gpointer user_data)
+{
+	struct deviceinfo *d = user_data;
+	GSList *l;
+
+	if (status != 0) {
+		error("Discover deviceinfo characteristics: %s",
+							att_ecode2str(status));
+		return;
+	}
+
+	for (l = characteristics; l; l = l->next) {
+		struct gatt_char *c = l->data;
+		struct characteristic *ch;
+
+		ch = g_new0(struct characteristic, 1);
+		ch->attr.handle = c->handle;
+		ch->attr.properties = c->properties;
+		ch->attr.value_handle = c->value_handle;
+		memcpy(ch->attr.uuid, c->uuid, MAX_LEN_UUID_STR + 1);
+		ch->d = d;
+
+		d->chars = g_slist_append(d->chars, ch);
+
+		process_deviceinfo_char(ch);
+	}
+}
+static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
+{
+	struct deviceinfo *d = user_data;
+
+	d->attrib = g_attrib_ref(attrib);
+
+	gatt_discover_char(d->attrib, d->svc_range->start, d->svc_range->end,
+					NULL, configure_deviceinfo_cb, d);
+}
+
+static void attio_disconnected_cb(gpointer user_data)
+{
+	struct deviceinfo *d = user_data;
+
+	g_attrib_unref(d->attrib);
+	d->attrib = NULL;
+}
+
+int deviceinfo_register(struct btd_device *device, struct gatt_primary *prim)
+{
+	struct deviceinfo *d;
+
+	d = g_new0(struct deviceinfo, 1);
+	d->dev = btd_device_ref(device);
+	d->svc_range = g_new0(struct att_range, 1);
+	d->svc_range->start = prim->range.start;
+	d->svc_range->end = prim->range.end;
+
+	servers = g_slist_prepend(servers, d);
+
+	d->attioid = btd_device_add_attio_callback(device, attio_connected_cb,
+						attio_disconnected_cb, d);
+	return 0;
+}
+
+void deviceinfo_unregister(struct btd_device *device)
+{
+	struct deviceinfo *d;
+	GSList *l;
+
+	l = g_slist_find_custom(servers, device, cmp_device);
+	if (l == NULL)
+		return;
+
+	d = l->data;
+	servers = g_slist_remove(servers, d);
+
+	deviceinfo_free(d);
+}
diff --git a/profiles/deviceinfo/deviceinfo.h b/profiles/deviceinfo/deviceinfo.h
new file mode 100644
index 0000000..7a804a5
--- /dev/null
+++ b/profiles/deviceinfo/deviceinfo.h
@@ -0,0 +1,24 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+int deviceinfo_register(struct btd_device *device, struct gatt_primary *prim);
+void deviceinfo_unregister(struct btd_device *device);
diff --git a/profiles/deviceinfo/main.c b/profiles/deviceinfo/main.c
new file mode 100644
index 0000000..82ecc82
--- /dev/null
+++ b/profiles/deviceinfo/main.c
@@ -0,0 +1,52 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include "plugin.h"
+#include "manager.h"
+#include "hcid.h"
+#include "log.h"
+
+static int deviceinfo_init(void)
+{
+	if (!main_opts.gatt_enabled) {
+		error("DIS cannot start: GATT is disabled");
+		return -ENOTSUP;
+	}
+
+	return deviceinfo_manager_init();
+}
+
+static void deviceinfo_exit(void)
+{
+	deviceinfo_manager_exit();
+}
+
+BLUETOOTH_PLUGIN_DEFINE(deviceinfo, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
+					deviceinfo_init, deviceinfo_exit)
diff --git a/profiles/deviceinfo/manager.c b/profiles/deviceinfo/manager.c
new file mode 100644
index 0000000..1d59918
--- /dev/null
+++ b/profiles/deviceinfo/manager.c
@@ -0,0 +1,80 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <glib.h>
+#include <errno.h>
+#include <bluetooth/uuid.h>
+
+#include "adapter.h"
+#include "device.h"
+#include "att.h"
+#include "gattrib.h"
+#include "gatt.h"
+#include "deviceinfo.h"
+#include "manager.h"
+
+static gint primary_uuid_cmp(gconstpointer a, gconstpointer b)
+{
+	const struct gatt_primary *prim = a;
+	const char *uuid = b;
+
+	return g_strcmp0(prim->uuid, uuid);
+}
+
+static int deviceinfo_driver_probe(struct btd_device *device, GSList *uuids)
+{
+	struct gatt_primary *prim;
+	GSList *primaries, *l;
+
+	primaries = btd_device_get_primaries(device);
+
+	l = g_slist_find_custom(primaries, DEVICE_INFORMATION_UUID,
+							primary_uuid_cmp);
+	if (l == NULL)
+		return -EINVAL;
+
+	prim = l->data;
+
+	return deviceinfo_register(device, prim);
+}
+
+static void deviceinfo_driver_remove(struct btd_device *device)
+{
+	deviceinfo_unregister(device);
+}
+
+static struct btd_device_driver deviceinfo_device_driver = {
+	.name	= "deviceinfo-driver",
+	.uuids	= BTD_UUIDS(DEVICE_INFORMATION_UUID),
+	.probe	= deviceinfo_driver_probe,
+	.remove	= deviceinfo_driver_remove
+};
+
+int deviceinfo_manager_init(void)
+{
+	return btd_register_device_driver(&deviceinfo_device_driver);
+}
+
+void deviceinfo_manager_exit(void)
+{
+	btd_unregister_device_driver(&deviceinfo_device_driver);
+}
diff --git a/profiles/deviceinfo/manager.h b/profiles/deviceinfo/manager.h
new file mode 100644
index 0000000..0f742ca
--- /dev/null
+++ b/profiles/deviceinfo/manager.h
@@ -0,0 +1,24 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+int deviceinfo_manager_init(void);
+void deviceinfo_manager_exit(void);
-- 
1.7.10.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 07/14] thermometer: move to the profiles folder
  2012-07-09 21:10 [PATCH 01/14] input: remove unneeded header inclusions Gustavo Padovan
                   ` (3 preceding siblings ...)
  2012-07-09 21:10 ` [PATCH 05/14] deviceinfo: move to profiles folder Gustavo Padovan
@ 2012-07-09 21:10 ` Gustavo Padovan
  2012-07-09 21:10 ` [PATCH 08/14] time: " Gustavo Padovan
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Gustavo Padovan @ 2012-07-09 21:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

---
 Makefile.am                        |    8 +-
 profiles/thermometer/main.c        |   70 ++
 profiles/thermometer/manager.c     |   92 +++
 profiles/thermometer/manager.h     |   24 +
 profiles/thermometer/thermometer.c | 1274 ++++++++++++++++++++++++++++++++++++
 profiles/thermometer/thermometer.h |   25 +
 thermometer/main.c                 |   70 --
 thermometer/manager.c              |   92 ---
 thermometer/manager.h              |   24 -
 thermometer/thermometer.c          | 1274 ------------------------------------
 thermometer/thermometer.h          |   25 -
 11 files changed, 1490 insertions(+), 1488 deletions(-)
 create mode 100644 profiles/thermometer/main.c
 create mode 100644 profiles/thermometer/manager.c
 create mode 100644 profiles/thermometer/manager.h
 create mode 100644 profiles/thermometer/thermometer.c
 create mode 100644 profiles/thermometer/thermometer.h
 delete mode 100644 thermometer/main.c
 delete mode 100644 thermometer/manager.c
 delete mode 100644 thermometer/manager.h
 delete mode 100644 thermometer/thermometer.c
 delete mode 100644 thermometer/thermometer.h

diff --git a/Makefile.am b/Makefile.am
index 2f6d539..c8b2475 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -215,9 +215,11 @@ endif
 
 if GATTMODULES
 builtin_modules += thermometer alert time gatt_example proximity deviceinfo
-builtin_sources += thermometer/main.c \
-			thermometer/manager.h thermometer/manager.c \
-			thermometer/thermometer.h thermometer/thermometer.c \
+builtin_sources += profiles/thermometer/main.c \
+			profiles/thermometer/manager.h \
+			profiles/thermometer/manager.c \
+			profiles/thermometer/thermometer.h \
+		       	profiles/thermometer/thermometer.c \
 			profiles/alert/main.c profiles/alert/server.h \
 			profiles/alert/server.c \
 			time/main.c time/server.h time/server.c \
diff --git a/profiles/thermometer/main.c b/profiles/thermometer/main.c
new file mode 100644
index 0000000..4447b52
--- /dev/null
+++ b/profiles/thermometer/main.c
@@ -0,0 +1,70 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2011 GSyC/LibreSoft, Universidad Rey Juan Carlos.
+ *
+ *  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 <errno.h>
+#include <gdbus.h>
+
+#include "plugin.h"
+#include "manager.h"
+#include "hcid.h"
+#include "log.h"
+
+static DBusConnection *connection = NULL;
+
+static int thermometer_init(void)
+{
+	if (!main_opts.gatt_enabled) {
+		DBG("GATT is disabled");
+		return -ENOTSUP;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+	if (connection == NULL)
+		return -EIO;
+
+	if (thermometer_manager_init(connection) < 0) {
+		dbus_connection_unref(connection);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void thermometer_exit(void)
+{
+	if (!main_opts.gatt_enabled)
+		return;
+
+	thermometer_manager_exit();
+
+	dbus_connection_unref(connection);
+	connection = NULL;
+}
+
+BLUETOOTH_PLUGIN_DEFINE(thermometer, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
+					thermometer_init, thermometer_exit)
diff --git a/profiles/thermometer/manager.c b/profiles/thermometer/manager.c
new file mode 100644
index 0000000..3d5452b
--- /dev/null
+++ b/profiles/thermometer/manager.c
@@ -0,0 +1,92 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2011 GSyC/LibreSoft, Universidad Rey Juan Carlos.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <gdbus.h>
+#include <errno.h>
+#include <bluetooth/uuid.h>
+
+#include "adapter.h"
+#include "device.h"
+#include "att.h"
+#include "gattrib.h"
+#include "gatt.h"
+#include "thermometer.h"
+#include "manager.h"
+
+static DBusConnection *connection = NULL;
+
+static gint primary_uuid_cmp(gconstpointer a, gconstpointer b)
+{
+	const struct gatt_primary *prim = a;
+	const char *uuid = b;
+
+	return g_strcmp0(prim->uuid, uuid);
+}
+
+static int thermometer_driver_probe(struct btd_device *device, GSList *uuids)
+{
+	struct gatt_primary *tattr;
+	GSList *primaries, *l;
+
+	primaries = btd_device_get_primaries(device);
+
+	l = g_slist_find_custom(primaries, HEALTH_THERMOMETER_UUID,
+							primary_uuid_cmp);
+	if (l == NULL)
+		return -EINVAL;
+
+	tattr = l->data;
+
+	return thermometer_register(connection, device, tattr);
+}
+
+static void thermometer_driver_remove(struct btd_device *device)
+{
+	thermometer_unregister(device);
+}
+
+static struct btd_device_driver thermometer_device_driver = {
+	.name	= "thermometer-device-driver",
+	.uuids	= BTD_UUIDS(HEALTH_THERMOMETER_UUID),
+	.probe	= thermometer_driver_probe,
+	.remove	= thermometer_driver_remove
+};
+
+int thermometer_manager_init(DBusConnection *conn)
+{
+	int ret;
+
+	ret = btd_register_device_driver(&thermometer_device_driver);
+	if (ret < 0)
+                return ret;
+
+	connection = dbus_connection_ref(conn);
+	return 0;
+}
+
+void thermometer_manager_exit(void)
+{
+	btd_unregister_device_driver(&thermometer_device_driver);
+
+	dbus_connection_unref(connection);
+	connection = NULL;
+}
diff --git a/profiles/thermometer/manager.h b/profiles/thermometer/manager.h
new file mode 100644
index 0000000..ed928ad
--- /dev/null
+++ b/profiles/thermometer/manager.h
@@ -0,0 +1,24 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2011 GSyC/LibreSoft, Universidad Rey Juan Carlos.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+int thermometer_manager_init(DBusConnection *conn);
+void thermometer_manager_exit(void);
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
new file mode 100644
index 0000000..087662e
--- /dev/null
+++ b/profiles/thermometer/thermometer.c
@@ -0,0 +1,1274 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2011 GSyC/LibreSoft, Universidad Rey Juan Carlos.
+ *
+ *  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 <gdbus.h>
+#include <errno.h>
+#include <bluetooth/uuid.h>
+
+#include "dbus-common.h"
+#include "adapter.h"
+#include "device.h"
+#include "error.h"
+#include "log.h"
+#include "gattrib.h"
+#include "attio.h"
+#include "att.h"
+#include "gatt.h"
+#include "thermometer.h"
+
+#define THERMOMETER_INTERFACE "org.bluez.Thermometer"
+
+/* Temperature measurement flag fields */
+#define TEMP_UNITS		0x01
+#define TEMP_TIME_STAMP		0x02
+#define TEMP_TYPE		0x04
+
+#define FLOAT_MAX_MANTISSA	16777216 /* 2^24 */
+
+#define VALID_RANGE_DESC_SIZE	4
+#define TEMPERATURE_TYPE_SIZE	1
+#define MEASUREMENT_INTERVAL_SIZE	2
+
+struct thermometer {
+	DBusConnection		*conn;		/* The connection to the bus */
+	struct btd_device	*dev;		/* Device reference */
+	GAttrib			*attrib;	/* GATT connection */
+	struct att_range	*svc_range;	/* Thermometer range */
+	guint			attioid;	/* Att watcher id */
+	guint			attindid;	/* Att incications id */
+	guint			attnotid;	/* Att notifications id */
+	GSList			*chars;		/* Characteristics */
+	GSList			*fwatchers;     /* Final measurements */
+	GSList			*iwatchers;     /* Intermediate measurements */
+	gboolean		intermediate;
+	uint8_t			type;
+	uint16_t		interval;
+	uint16_t		max;
+	uint16_t		min;
+	gboolean		has_type;
+	gboolean		has_interval;
+};
+
+struct characteristic {
+	struct gatt_char		attr;	/* Characteristic */
+	GSList			*desc;	/* Descriptors */
+	struct thermometer	*t;	/* Thermometer where the char belongs */
+};
+
+struct descriptor {
+	struct characteristic	*ch;
+	uint16_t		handle;
+	bt_uuid_t		uuid;
+};
+
+struct watcher {
+	struct thermometer	*t;
+	guint			id;
+	char			*srv;
+	char			*path;
+};
+
+struct measurement {
+	int16_t		exp;
+	int32_t		mant;
+	uint64_t	time;
+	gboolean	suptime;
+	char		*unit;
+	char		*type;
+	char		*value;
+};
+
+struct tmp_interval_data {
+	struct thermometer	*thermometer;
+	uint16_t		interval;
+};
+
+static GSList *thermometers = NULL;
+
+const char *temp_type[] = {
+	"<reserved>",
+	"Armpit",
+	"Body",
+	"Ear",
+	"Finger",
+	"Intestines",
+	"Mouth",
+	"Rectum",
+	"Toe",
+	"Tympanum"
+};
+
+static const gchar *temptype2str(uint8_t value)
+{
+	 if (value > 0 && value < G_N_ELEMENTS(temp_type))
+		return temp_type[value];
+
+	error("Temperature type %d reserved for future use", value);
+	return NULL;
+}
+
+static void destroy_watcher(gpointer user_data)
+{
+	struct watcher *watcher = user_data;
+
+	g_free(watcher->path);
+	g_free(watcher->srv);
+	g_free(watcher);
+}
+
+static void remove_watcher(gpointer user_data)
+{
+	struct watcher *watcher = user_data;
+
+	g_dbus_remove_watch(watcher->t->conn, watcher->id);
+}
+
+static void destroy_char(gpointer user_data)
+{
+	struct characteristic *c = user_data;
+
+	g_slist_free_full(c->desc, g_free);
+	g_free(c);
+}
+
+static void destroy_thermometer(gpointer user_data)
+{
+	struct thermometer *t = user_data;
+
+	if (t->attioid > 0)
+		btd_device_remove_attio_callback(t->dev, t->attioid);
+
+	if (t->attindid > 0)
+		g_attrib_unregister(t->attrib, t->attindid);
+
+	if (t->attnotid > 0)
+		g_attrib_unregister(t->attrib, t->attnotid);
+
+	if (t->attrib != NULL)
+		g_attrib_unref(t->attrib);
+
+	if (t->chars != NULL)
+		g_slist_free_full(t->chars, destroy_char);
+
+	if (t->fwatchers != NULL)
+		g_slist_free_full(t->fwatchers, remove_watcher);
+
+	dbus_connection_unref(t->conn);
+	btd_device_unref(t->dev);
+	g_free(t->svc_range);
+	g_free(t);
+}
+
+static gint cmp_device(gconstpointer a, gconstpointer b)
+{
+	const struct thermometer *t = a;
+	const struct btd_device *dev = b;
+
+	if (dev == t->dev)
+		return 0;
+
+	return -1;
+}
+
+static gint cmp_watcher(gconstpointer a, gconstpointer b)
+{
+	const struct watcher *watcher = a;
+	const struct watcher *match = b;
+	int ret;
+
+	ret = g_strcmp0(watcher->srv, match->srv);
+	if (ret != 0)
+		return ret;
+
+	return g_strcmp0(watcher->path, match->path);
+}
+
+static gint cmp_char_uuid(gconstpointer a, gconstpointer b)
+{
+	const struct characteristic *ch = a;
+	const char *uuid = b;
+
+	return g_strcmp0(ch->attr.uuid, uuid);
+}
+
+static gint cmp_char_val_handle(gconstpointer a, gconstpointer b)
+{
+	const struct characteristic *ch = a;
+	const uint16_t *handle = b;
+
+	return ch->attr.value_handle - *handle;
+}
+
+static gint cmp_descriptor(gconstpointer a, gconstpointer b)
+{
+	const struct descriptor *desc = a;
+	const bt_uuid_t *uuid = b;
+
+	return bt_uuid_cmp(&desc->uuid, uuid);
+}
+
+static struct characteristic *get_characteristic(struct thermometer *t,
+							const char *uuid)
+{
+	GSList *l;
+
+	l = g_slist_find_custom(t->chars, uuid, cmp_char_uuid);
+	if (l == NULL)
+		return NULL;
+
+	return l->data;
+}
+
+static struct descriptor *get_descriptor(struct characteristic *ch,
+							const bt_uuid_t *uuid)
+{
+	GSList *l;
+
+	l = g_slist_find_custom(ch->desc, uuid, cmp_descriptor);
+	if (l == NULL)
+		return NULL;
+
+	return l->data;
+}
+
+static void change_property(struct thermometer *t, const char *name,
+							gpointer value) {
+	if (g_strcmp0(name, "Intermediate") == 0) {
+		gboolean *intermediate = value;
+		if (t->intermediate == *intermediate)
+			return;
+
+		t->intermediate = *intermediate;
+		emit_property_changed(t->conn, device_get_path(t->dev),
+					THERMOMETER_INTERFACE, name,
+					DBUS_TYPE_BOOLEAN, &t->intermediate);
+	} else if (g_strcmp0(name, "Interval") == 0) {
+		uint16_t *interval = value;
+		if (t->has_interval && t->interval == *interval)
+			return;
+
+		t->has_interval = TRUE;
+		t->interval = *interval;
+		emit_property_changed(t->conn, device_get_path(t->dev),
+					THERMOMETER_INTERFACE, name,
+					DBUS_TYPE_UINT16, &t->interval);
+	} else if (g_strcmp0(name, "Maximum") == 0) {
+		uint16_t *max = value;
+		if (t->max == *max)
+			return;
+
+		t->max = *max;
+		emit_property_changed(t->conn, device_get_path(t->dev),
+					THERMOMETER_INTERFACE, name,
+					DBUS_TYPE_UINT16, &t->max);
+	} else if (g_strcmp0(name, "Minimum") == 0) {
+		uint16_t *min = value;
+		if (t->min == *min)
+			return;
+
+		t->min = *min;
+		emit_property_changed(t->conn, device_get_path(t->dev),
+					THERMOMETER_INTERFACE, name,
+					DBUS_TYPE_UINT16, &t->min);
+	} else
+		DBG("%s is not a thermometer property", name);
+}
+
+static void valid_range_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
+							gpointer user_data)
+{
+	struct descriptor *desc = user_data;
+	uint8_t value[VALID_RANGE_DESC_SIZE];
+	uint16_t max, min;
+	ssize_t vlen;
+
+	if (status != 0) {
+		DBG("Valid Range descriptor read failed: %s",
+							att_ecode2str(status));
+		return;
+	}
+
+	vlen = dec_read_resp(pdu, len, value, sizeof(value));
+	if (vlen < 0) {
+		DBG("Protocol error\n");
+		return;
+	}
+
+	if (vlen < 4) {
+		DBG("Invalid range received");
+		return;
+	}
+
+	min = att_get_u16(&value[0]);
+	max = att_get_u16(&value[2]);
+
+	if (min == 0 || min > max) {
+		DBG("Invalid range");
+		return;
+	}
+
+	change_property(desc->ch->t, "Maximum", &max);
+	change_property(desc->ch->t, "Minimum", &min);
+}
+
+static void measurement_cb(guint8 status, const guint8 *pdu,
+						guint16 len, gpointer user_data)
+{
+	char *msg = user_data;
+
+	if (status != 0)
+		error("%s failed", msg);
+
+	g_free(msg);
+}
+
+static void process_thermometer_desc(struct descriptor *desc)
+{
+	struct characteristic *ch = desc->ch;
+	char uuidstr[MAX_LEN_UUID_STR];
+	bt_uuid_t btuuid;
+
+	bt_uuid16_create(&btuuid, GATT_CLIENT_CHARAC_CFG_UUID);
+
+	if (bt_uuid_cmp(&desc->uuid, &btuuid) == 0) {
+		uint8_t atval[2];
+		uint16_t val;
+		char *msg;
+
+		if (g_strcmp0(ch->attr.uuid,
+					TEMPERATURE_MEASUREMENT_UUID) == 0) {
+			if (g_slist_length(ch->t->fwatchers) == 0)
+				return;
+
+			val = GATT_CLIENT_CHARAC_CFG_IND_BIT;
+			msg = g_strdup("Enable Temperature Measurement "
+								"indication");
+		} else if (g_strcmp0(ch->attr.uuid,
+					INTERMEDIATE_TEMPERATURE_UUID) == 0) {
+			if (g_slist_length(ch->t->iwatchers) == 0)
+				return;
+
+			val = GATT_CLIENT_CHARAC_CFG_NOTIF_BIT;
+			msg = g_strdup("Enable Intermediate Temperature "
+								"notification");
+		} else if (g_strcmp0(ch->attr.uuid,
+					MEASUREMENT_INTERVAL_UUID) == 0) {
+			val = GATT_CLIENT_CHARAC_CFG_IND_BIT;
+			msg = g_strdup("Enable Measurement Interval "
+								"indication");
+		} else
+			goto done;
+
+		att_put_u16(val, atval);
+		gatt_write_char(ch->t->attrib, desc->handle, atval, 2,
+							measurement_cb, msg);
+		return;
+	}
+
+	bt_uuid16_create(&btuuid, GATT_CHARAC_VALID_RANGE_UUID);
+
+	if (bt_uuid_cmp(&desc->uuid, &btuuid) == 0 && g_strcmp0(ch->attr.uuid,
+					MEASUREMENT_INTERVAL_UUID) == 0) {
+		gatt_read_char(ch->t->attrib, desc->handle, 0,
+						valid_range_desc_cb, desc);
+		return;
+	}
+
+done:
+	bt_uuid_to_string(&desc->uuid, uuidstr, MAX_LEN_UUID_STR);
+	DBG("Ignored descriptor %s in characteristic %s", uuidstr,
+								ch->attr.uuid);
+}
+
+static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
+							gpointer user_data)
+{
+	struct characteristic *ch = user_data;
+	struct att_data_list *list;
+	uint8_t format;
+	int i;
+
+	if (status != 0) {
+		error("Discover all characteristic descriptors failed [%s]: %s",
+					ch->attr.uuid, att_ecode2str(status));
+		return;
+	}
+
+	list = dec_find_info_resp(pdu, len, &format);
+	if (list == NULL)
+		return;
+
+	for (i = 0; i < list->num; i++) {
+		struct descriptor *desc;
+		uint8_t *value;
+
+		value = list->data[i];
+		desc = g_new0(struct descriptor, 1);
+		desc->handle = att_get_u16(value);
+		desc->ch = ch;
+
+		if (format == 0x01)
+			desc->uuid = att_get_uuid16(&value[2]);
+		else
+			desc->uuid = att_get_uuid128(&value[2]);
+
+		ch->desc = g_slist_append(ch->desc, desc);
+		process_thermometer_desc(desc);
+	}
+
+	att_data_list_free(list);
+}
+
+static void read_temp_type_cb(guint8 status, const guint8 *pdu, guint16 len,
+							gpointer user_data)
+{
+	struct characteristic *ch = user_data;
+	struct thermometer *t = ch->t;
+	uint8_t value[TEMPERATURE_TYPE_SIZE];
+	ssize_t vlen;
+
+	if (status != 0) {
+		DBG("Temperature Type value read failed: %s",
+							att_ecode2str(status));
+		return;
+	}
+
+	vlen = dec_read_resp(pdu, len, value, sizeof(value));
+	if (vlen < 0) {
+		DBG("Protocol error.");
+		return;
+	}
+
+	if (vlen != 1) {
+		DBG("Invalid length for Temperature type");
+		return;
+	}
+
+	t->has_type = TRUE;
+	t->type = value[0];
+}
+
+static void read_interval_cb(guint8 status, const guint8 *pdu, guint16 len,
+							gpointer user_data)
+{
+	struct characteristic *ch = user_data;
+	uint8_t value[MEASUREMENT_INTERVAL_SIZE];
+	uint16_t interval;
+	ssize_t vlen;
+
+	if (status != 0) {
+		DBG("Measurement Interval value read failed: %s",
+							att_ecode2str(status));
+		return;
+	}
+
+	vlen = dec_read_resp(pdu, len, value, sizeof(value));
+	if (vlen < 0) {
+		DBG("Protocol error\n");
+		return;
+	}
+
+	if (vlen < 2) {
+		DBG("Invalid Interval received");
+		return;
+	}
+
+	interval = att_get_u16(&value[0]);
+	change_property(ch->t, "Interval", &interval);
+}
+
+static void process_thermometer_char(struct characteristic *ch)
+{
+	if (g_strcmp0(ch->attr.uuid, INTERMEDIATE_TEMPERATURE_UUID) == 0) {
+		gboolean intermediate = TRUE;
+		change_property(ch->t, "Intermediate", &intermediate);
+		return;
+	} else if (g_strcmp0(ch->attr.uuid, TEMPERATURE_TYPE_UUID) == 0)
+		gatt_read_char(ch->t->attrib, ch->attr.value_handle, 0,
+							read_temp_type_cb, ch);
+	else if (g_strcmp0(ch->attr.uuid, MEASUREMENT_INTERVAL_UUID) == 0)
+		gatt_read_char(ch->t->attrib, ch->attr.value_handle, 0,
+							read_interval_cb, ch);
+}
+
+static void configure_thermometer_cb(GSList *characteristics, guint8 status,
+							gpointer user_data)
+{
+	struct thermometer *t = user_data;
+	GSList *l;
+
+	if (status != 0) {
+		error("Discover thermometer characteristics: %s",
+							att_ecode2str(status));
+		return;
+	}
+
+	for (l = characteristics; l; l = l->next) {
+		struct gatt_char *c = l->data;
+		struct characteristic *ch;
+		uint16_t start, end;
+
+		ch = g_new0(struct characteristic, 1);
+		ch->attr.handle = c->handle;
+		ch->attr.properties = c->properties;
+		ch->attr.value_handle = c->value_handle;
+		memcpy(ch->attr.uuid, c->uuid, MAX_LEN_UUID_STR + 1);
+		ch->t = t;
+
+		t->chars = g_slist_append(t->chars, ch);
+
+		process_thermometer_char(ch);
+
+		start = c->value_handle + 1;
+
+		if (l->next != NULL) {
+			struct gatt_char *c = l->next->data;
+			if (start == c->handle)
+				continue;
+			end = c->handle - 1;
+		} else if (c->value_handle != t->svc_range->end)
+			end = t->svc_range->end;
+		else
+			continue;
+
+		gatt_find_info(t->attrib, start, end, discover_desc_cb, ch);
+	}
+}
+
+static DBusMessage *get_properties(DBusConnection *conn, DBusMessage *msg,
+								void *data)
+{
+	struct thermometer *t = data;
+	DBusMessageIter iter;
+	DBusMessageIter dict;
+	DBusMessage *reply;
+
+	reply = dbus_message_new_method_return(msg);
+	if (reply == NULL)
+		return NULL;
+
+	dbus_message_iter_init_append(reply, &iter);
+
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+	dict_append_entry(&dict, "Intermediate", DBUS_TYPE_BOOLEAN,
+							&t->intermediate);
+
+	if (t->has_interval) {
+		dict_append_entry(&dict, "Interval", DBUS_TYPE_UINT16,
+								&t->interval);
+		dict_append_entry(&dict, "Maximum", DBUS_TYPE_UINT16, &t->max);
+		dict_append_entry(&dict, "Minimum", DBUS_TYPE_UINT16, &t->min);
+	}
+
+	dbus_message_iter_close_container(&iter, &dict);
+
+	return reply;
+}
+
+static void write_interval_cb (guint8 status, const guint8 *pdu, guint16 len,
+							gpointer user_data)
+{
+	struct tmp_interval_data *data = user_data;
+
+	if (status != 0) {
+		error("Interval Write Request failed %s",
+							att_ecode2str(status));
+		goto done;
+	}
+
+	if (!dec_write_resp(pdu, len)) {
+		error("Interval Write Request: protocol error");
+		goto done;
+	}
+
+	change_property(data->thermometer, "Interval", &data->interval);
+
+done:
+	g_free(user_data);
+}
+
+static DBusMessage *write_attr_interval(struct thermometer *t, DBusMessage *msg,
+								uint16_t value)
+{
+	struct tmp_interval_data *data;
+	struct characteristic *ch;
+	uint8_t atval[2];
+
+	if (t->attrib == NULL)
+		return btd_error_not_connected(msg);
+
+	ch = get_characteristic(t, MEASUREMENT_INTERVAL_UUID);
+	if (ch == NULL)
+		return btd_error_not_available(msg);
+
+	if (value < t->min || value > t->max)
+		return btd_error_invalid_args(msg);
+
+	att_put_u16(value, &atval[0]);
+
+	data = g_new0(struct tmp_interval_data, 1);
+	data->thermometer = t;
+	data->interval = value;
+	gatt_write_char(t->attrib, ch->attr.value_handle, atval, 2,
+						write_interval_cb, data);
+
+	return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg,
+								void *data)
+{
+	struct thermometer *t = data;
+	const char *property;
+	DBusMessageIter iter;
+	DBusMessageIter sub;
+	uint16_t value;
+
+	if (!dbus_message_iter_init(msg, &iter))
+		return btd_error_invalid_args(msg);
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+		return btd_error_invalid_args(msg);
+
+	dbus_message_iter_get_basic(&iter, &property);
+	if (g_strcmp0("Interval", property) != 0)
+		return btd_error_invalid_args(msg);
+
+	if (!t->has_interval)
+		return btd_error_not_available(msg);
+
+	dbus_message_iter_next(&iter);
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
+		return btd_error_invalid_args(msg);
+
+	dbus_message_iter_recurse(&iter, &sub);
+
+	if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_UINT16)
+		return btd_error_invalid_args(msg);
+
+	dbus_message_iter_get_basic(&sub, &value);
+
+	return write_attr_interval(t, msg, value);
+}
+
+static void enable_final_measurement(struct thermometer *t)
+{
+	struct characteristic *ch;
+	struct descriptor *desc;
+	bt_uuid_t btuuid;
+	uint8_t atval[2];
+	char *msg;
+
+	if (t->attrib == NULL)
+		return;
+
+	ch = get_characteristic(t, TEMPERATURE_MEASUREMENT_UUID);
+	if (ch == NULL) {
+		DBG("Temperature measurement characteristic not found");
+		return;
+	}
+
+	bt_uuid16_create(&btuuid, GATT_CLIENT_CHARAC_CFG_UUID);
+	desc = get_descriptor(ch, &btuuid);
+	if (desc == NULL) {
+		DBG("Client characteristic configuration descriptor not found");
+		return;
+	}
+
+	atval[0] = 0x02;
+	atval[1] = 0x00;
+	msg = g_strdup("Enable final measurement");
+	gatt_write_char(t->attrib, desc->handle, atval, 2, measurement_cb, msg);
+}
+
+static void enable_intermediate_measurement(struct thermometer *t)
+{
+	struct characteristic *ch;
+	struct descriptor *desc;
+	bt_uuid_t btuuid;
+	uint8_t atval[2];
+	char *msg;
+
+	if (t->attrib == NULL)
+		return;
+
+	ch = get_characteristic(t, INTERMEDIATE_TEMPERATURE_UUID);
+	if (ch == NULL) {
+		DBG("Intermediate measurement characteristic not found");
+		return;
+	}
+
+	bt_uuid16_create(&btuuid, GATT_CLIENT_CHARAC_CFG_UUID);
+	desc = get_descriptor(ch, &btuuid);
+	if (desc == NULL) {
+		DBG("Client characteristic configuration descriptor not found");
+		return;
+	}
+
+	atval[0] = 0x01;
+	atval[1] = 0x00;
+	msg = g_strdup("Enable intermediate measurement");
+	gatt_write_char(t->attrib, desc->handle, atval, 2, measurement_cb, msg);
+}
+
+static void disable_final_measurement(struct thermometer *t)
+{
+	struct characteristic *ch;
+	struct descriptor *desc;
+	bt_uuid_t btuuid;
+	uint8_t atval[2];
+	char *msg;
+
+	if (t->attrib == NULL)
+		return;
+
+	ch = get_characteristic(t, TEMPERATURE_MEASUREMENT_UUID);
+	if (ch == NULL) {
+		DBG("Temperature measurement characteristic not found");
+		return;
+	}
+
+	bt_uuid16_create(&btuuid, GATT_CLIENT_CHARAC_CFG_UUID);
+	desc = get_descriptor(ch, &btuuid);
+	if (desc == NULL) {
+		DBG("Client characteristic configuration descriptor not found");
+		return;
+	}
+
+	atval[0] = 0x00;
+	atval[1] = 0x00;
+	msg = g_strdup("Disable final measurement");
+	gatt_write_char(t->attrib, desc->handle, atval, 2, measurement_cb, msg);
+}
+
+static void disable_intermediate_measurement(struct thermometer *t)
+{
+	struct characteristic *ch;
+	struct descriptor *desc;
+	bt_uuid_t btuuid;
+	uint8_t atval[2];
+	char *msg;
+
+	if (t->attrib == NULL)
+		return;
+
+	ch = get_characteristic(t, INTERMEDIATE_TEMPERATURE_UUID);
+	if (ch == NULL) {
+		DBG("Intermediate measurement characteristic not found");
+		return;
+	}
+
+	bt_uuid16_create(&btuuid, GATT_CLIENT_CHARAC_CFG_UUID);
+	desc = get_descriptor(ch, &btuuid);
+	if (desc == NULL) {
+		DBG("Client characteristic configuration descriptor not found");
+		return;
+	}
+
+	atval[0] = 0x00;
+	atval[1] = 0x00;
+	msg = g_strdup("Disable intermediate measurement");
+	gatt_write_char(t->attrib, desc->handle, atval, 2, measurement_cb, msg);
+}
+
+static void remove_int_watcher(struct thermometer *t, struct watcher *w)
+{
+	if (!g_slist_find(t->iwatchers, w))
+		return;
+
+	t->iwatchers = g_slist_remove(t->iwatchers, w);
+
+	if (g_slist_length(t->iwatchers) == 0)
+		disable_intermediate_measurement(t);
+}
+
+static void watcher_exit(DBusConnection *conn, void *user_data)
+{
+	struct watcher *watcher = user_data;
+	struct thermometer *t = watcher->t;
+
+	DBG("Thermometer watcher %s disconnected", watcher->path);
+
+	remove_int_watcher(t, watcher);
+
+	t->fwatchers = g_slist_remove(t->fwatchers, watcher);
+	g_dbus_remove_watch(watcher->t->conn, watcher->id);
+
+	if (g_slist_length(t->fwatchers) == 0)
+		disable_final_measurement(t);
+}
+
+static struct watcher *find_watcher(GSList *list, const char *sender,
+							const char *path)
+{
+	struct watcher *match;
+	GSList *l;
+
+	match = g_new0(struct watcher, 1);
+	match->srv = g_strdup(sender);
+	match->path = g_strdup(path);
+
+	l = g_slist_find_custom(list, match, cmp_watcher);
+	destroy_watcher(match);
+
+	if (l != NULL)
+		return l->data;
+
+	return NULL;
+}
+
+static DBusMessage *register_watcher(DBusConnection *conn, DBusMessage *msg,
+								void *data)
+{
+	const char *sender = dbus_message_get_sender(msg);
+	struct thermometer *t = data;
+	struct watcher *watcher;
+	char *path;
+
+	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+							DBUS_TYPE_INVALID))
+		return btd_error_invalid_args(msg);
+
+	watcher = find_watcher(t->fwatchers, sender, path);
+	if (watcher != NULL)
+		return btd_error_already_exists(msg);
+
+	DBG("Thermometer watcher %s registered", path);
+
+	watcher = g_new0(struct watcher, 1);
+	watcher->srv = g_strdup(sender);
+	watcher->path = g_strdup(path);
+	watcher->t = t;
+	watcher->id = g_dbus_add_disconnect_watch(conn, sender, watcher_exit,
+						watcher, destroy_watcher);
+
+	if (g_slist_length(t->fwatchers) == 0)
+		enable_final_measurement(t);
+
+	t->fwatchers = g_slist_prepend(t->fwatchers, watcher);
+
+	return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *unregister_watcher(DBusConnection *conn, DBusMessage *msg,
+								void *data)
+{
+	const char *sender = dbus_message_get_sender(msg);
+	struct thermometer *t = data;
+	struct watcher *watcher;
+	char *path;
+
+	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+							DBUS_TYPE_INVALID))
+		return btd_error_invalid_args(msg);
+
+	watcher = find_watcher(t->fwatchers, sender, path);
+	if (watcher == NULL)
+		return btd_error_does_not_exist(msg);
+
+	DBG("Thermometer watcher %s unregistered", path);
+
+	remove_int_watcher(t, watcher);
+
+	t->fwatchers = g_slist_remove(t->fwatchers, watcher);
+	g_dbus_remove_watch(watcher->t->conn, watcher->id);
+
+	if (g_slist_length(t->fwatchers) == 0)
+		disable_final_measurement(t);
+
+	return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *enable_intermediate(DBusConnection *conn, DBusMessage *msg,
+								void *data)
+{
+	const char *sender = dbus_message_get_sender(msg);
+	struct thermometer *t = data;
+	struct watcher *watcher;
+	char *path;
+
+	if (!t->intermediate)
+		return btd_error_not_supported(msg);
+
+	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+							DBUS_TYPE_INVALID))
+		return btd_error_invalid_args(msg);
+
+	watcher = find_watcher(t->fwatchers, sender, path);
+	if (watcher == NULL)
+		return btd_error_does_not_exist(msg);
+
+	if (find_watcher(t->iwatchers, sender, path))
+		return btd_error_already_exists(msg);
+
+	DBG("Intermediate measurement watcher %s registered", path);
+
+	if (g_slist_length(t->iwatchers) == 0)
+		enable_intermediate_measurement(t);
+
+	t->iwatchers = g_slist_prepend(t->iwatchers, watcher);
+
+	return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *disable_intermediate(DBusConnection *conn, DBusMessage *msg,
+								void *data)
+{
+	const char *sender = dbus_message_get_sender(msg);
+	struct thermometer *t = data;
+	struct watcher *watcher;
+	char *path;
+
+	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+							DBUS_TYPE_INVALID))
+		return btd_error_invalid_args(msg);
+
+	watcher = find_watcher(t->iwatchers, sender, path);
+	if (watcher == NULL)
+		return btd_error_does_not_exist(msg);
+
+	DBG("Intermediate measurement %s unregistered", path);
+
+	remove_int_watcher(t, watcher);
+
+	return dbus_message_new_method_return(msg);
+}
+
+static const GDBusMethodTable thermometer_methods[] = {
+	{ GDBUS_METHOD("GetProperties",
+			NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
+			get_properties) },
+	{ GDBUS_ASYNC_METHOD("SetProperty",
+			GDBUS_ARGS({ "name", "s" }, { "value", "v" }), NULL,
+			set_property) },
+	{ GDBUS_METHOD("RegisterWatcher",
+			GDBUS_ARGS({ "agent", "o" }), NULL,
+			register_watcher) },
+	{ GDBUS_METHOD("UnregisterWatcher",
+			GDBUS_ARGS({ "agent", "o" }), NULL,
+			unregister_watcher) },
+	{ GDBUS_METHOD("EnableIntermediateMeasurement",
+			GDBUS_ARGS({ "agent", "o" }), NULL,
+			enable_intermediate) },
+	{ GDBUS_METHOD("DisableIntermediateMeasurement",
+			GDBUS_ARGS({ "agent", "o" }), NULL,
+			disable_intermediate) },
+	{ }
+};
+
+static const GDBusSignalTable thermometer_signals[] = {
+	{ GDBUS_SIGNAL("PropertyChanged",
+			GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
+	{ }
+};
+
+static void update_watcher(gpointer data, gpointer user_data)
+{
+	struct watcher *w = data;
+	struct measurement *m = user_data;
+	DBusConnection *conn = w->t->conn;
+	DBusMessageIter iter;
+	DBusMessageIter dict;
+	DBusMessage *msg;
+
+	msg = dbus_message_new_method_call(w->srv, w->path,
+				"org.bluez.ThermometerWatcher",
+				"MeasurementReceived");
+	if (msg == NULL)
+		return;
+
+	dbus_message_iter_init_append(msg, &iter);
+
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+	dict_append_entry(&dict, "Exponent", DBUS_TYPE_INT16, &m->exp);
+	dict_append_entry(&dict, "Mantissa", DBUS_TYPE_INT32, &m->mant);
+	dict_append_entry(&dict, "Unit", DBUS_TYPE_STRING, &m->unit);
+
+	if (m->suptime)
+		dict_append_entry(&dict, "Time", DBUS_TYPE_UINT64, &m->time);
+
+	dict_append_entry(&dict, "Type", DBUS_TYPE_STRING, &m->type);
+	dict_append_entry(&dict, "Measurement", DBUS_TYPE_STRING, &m->value);
+
+	dbus_message_iter_close_container(&iter, &dict);
+
+	dbus_message_set_no_reply(msg, TRUE);
+	g_dbus_send_message(conn, msg);
+}
+
+static void recv_measurement(struct thermometer *t, struct measurement *m)
+{
+	GSList *wlist;
+
+	if (g_strcmp0(m->value, "Intermediate") == 0)
+		wlist = t->iwatchers;
+	else
+		wlist = t->fwatchers;
+
+	g_slist_foreach(wlist, update_watcher, m);
+}
+
+static void proc_measurement(struct thermometer *t, const uint8_t *pdu,
+						uint16_t len, gboolean final)
+{
+	struct measurement m;
+	const char *type;
+	uint8_t flags;
+	uint32_t raw;
+
+	if (len < 4) {
+		DBG("Mandatory flags are not provided");
+		return;
+	}
+
+	flags = pdu[3];
+	if (flags & TEMP_UNITS)
+		m.unit = "Fahrenheit";
+	else
+		m.unit = "Celsius";
+
+	if (len < 8) {
+		DBG("Temperature measurement value is not provided");
+		return;
+	}
+
+	raw = att_get_u32(&pdu[4]);
+	m.mant = raw & 0x00FFFFFF;
+	m.exp = ((int32_t) raw) >> 24;
+
+	if (m.mant & 0x00800000) {
+		/* convert to C2 negative value */
+		m.mant = m.mant - FLOAT_MAX_MANTISSA;
+	}
+
+	if (flags & TEMP_TIME_STAMP) {
+		struct tm ts;
+		time_t time;
+
+		if (len < 15) {
+			DBG("Can't get time stamp value");
+			return;
+		}
+
+		ts.tm_year = att_get_u16(&pdu[8]) - 1900;
+		ts.tm_mon = pdu[10] - 1;
+		ts.tm_mday = pdu[11];
+		ts.tm_hour = pdu[12];
+		ts.tm_min = pdu[13];
+		ts.tm_sec = pdu[14];
+		ts.tm_isdst = -1;
+
+		time = mktime(&ts);
+		m.time = (uint64_t) time;
+		m.suptime = TRUE;
+	} else
+		m.suptime = FALSE;
+
+	if (flags & TEMP_TYPE) {
+		uint8_t index;
+
+		if (m.suptime && len >= 16)
+			index = 15;
+		else if (!m.suptime && len >= 9)
+			index = 9;
+		else {
+			DBG("Can't get temperature type");
+			return;
+		}
+
+		type = temptype2str(pdu[index]);
+	} else if (t->has_type)
+		type = temptype2str(t->type);
+	else
+		type = NULL;
+
+	m.type = type ? g_strdup(type) : NULL;
+	m.value = final ? "Final" : "Intermediate";
+
+	recv_measurement(t, &m);
+	g_free(m.type);
+}
+
+static void proc_measurement_interval(struct thermometer *t, const uint8_t *pdu,
+								uint16_t len)
+{
+	uint16_t interval;
+
+	if (len < 5) {
+		DBG("Measurement interval value is not provided");
+		return;
+	}
+
+	interval = att_get_u16(&pdu[3]);
+
+	change_property(t, "Interval", &interval);
+}
+
+static void ind_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
+{
+	struct thermometer *t = user_data;
+	const struct characteristic *ch;
+	uint8_t *opdu;
+	uint16_t handle, olen;
+	GSList *l;
+	int plen;
+
+	if (len < 3) {
+		DBG("Bad pdu received");
+		return;
+	}
+
+	handle = att_get_u16(&pdu[1]);
+	l = g_slist_find_custom(t->chars, &handle, cmp_char_val_handle);
+	if (l == NULL) {
+		DBG("Unexpected handle: 0x%04x", handle);
+		return;
+	}
+
+	ch = l->data;
+
+	if (g_strcmp0(ch->attr.uuid, TEMPERATURE_MEASUREMENT_UUID) == 0)
+		proc_measurement(t, pdu, len, TRUE);
+	else if (g_strcmp0(ch->attr.uuid, MEASUREMENT_INTERVAL_UUID) == 0)
+		proc_measurement_interval(t, pdu, len);
+
+	opdu = g_attrib_get_buffer(t->attrib, &plen);
+	olen = enc_confirmation(opdu, plen);
+
+	if (olen > 0)
+		g_attrib_send(t->attrib, 0, opdu[0], opdu, olen, NULL, NULL,
+									NULL);
+}
+
+static void notif_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
+{
+	struct thermometer *t = user_data;
+	const struct characteristic *ch;
+	uint16_t handle;
+	GSList *l;
+
+	if (len < 3) {
+		DBG("Bad pdu received");
+		return;
+	}
+
+	handle = att_get_u16(&pdu[1]);
+	l = g_slist_find_custom(t->chars, &handle, cmp_char_val_handle);
+	if (l == NULL) {
+		DBG("Unexpected handle: 0x%04x", handle);
+		return;
+	}
+
+	ch = l->data;
+	if (g_strcmp0(ch->attr.uuid, INTERMEDIATE_TEMPERATURE_UUID) == 0)
+		proc_measurement(t, pdu, len, FALSE);
+}
+
+static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
+{
+	struct thermometer *t = user_data;
+
+	t->attrib = g_attrib_ref(attrib);
+
+	t->attindid = g_attrib_register(t->attrib, ATT_OP_HANDLE_IND,
+							ind_handler, t, NULL);
+	t->attnotid = g_attrib_register(t->attrib, ATT_OP_HANDLE_NOTIFY,
+							notif_handler, t, NULL);
+	gatt_discover_char(t->attrib, t->svc_range->start, t->svc_range->end,
+					NULL, configure_thermometer_cb, t);
+}
+
+static void attio_disconnected_cb(gpointer user_data)
+{
+	struct thermometer *t = user_data;
+
+	DBG("GATT Disconnected");
+
+	if (t->attindid > 0) {
+		g_attrib_unregister(t->attrib, t->attindid);
+		t->attindid = 0;
+	}
+
+	if (t->attnotid > 0) {
+		g_attrib_unregister(t->attrib, t->attnotid);
+		t->attnotid = 0;
+	}
+
+	g_attrib_unref(t->attrib);
+	t->attrib = NULL;
+}
+
+int thermometer_register(DBusConnection *connection, struct btd_device *device,
+						struct gatt_primary *tattr)
+{
+	const gchar *path = device_get_path(device);
+	struct thermometer *t;
+
+	t = g_new0(struct thermometer, 1);
+	t->conn = dbus_connection_ref(connection);
+	t->dev = btd_device_ref(device);
+	t->svc_range = g_new0(struct att_range, 1);
+	t->svc_range->start = tattr->range.start;
+	t->svc_range->end = tattr->range.end;
+
+	if (!g_dbus_register_interface(t->conn, path, THERMOMETER_INTERFACE,
+				thermometer_methods, thermometer_signals,
+				NULL, t, destroy_thermometer)) {
+		error("D-Bus failed to register %s interface",
+							THERMOMETER_INTERFACE);
+		destroy_thermometer(t);
+		return -EIO;
+	}
+
+	thermometers = g_slist_prepend(thermometers, t);
+
+	t->attioid = btd_device_add_attio_callback(device, attio_connected_cb,
+						attio_disconnected_cb, t);
+	return 0;
+}
+
+void thermometer_unregister(struct btd_device *device)
+{
+	struct thermometer *t;
+	GSList *l;
+
+	l = g_slist_find_custom(thermometers, device, cmp_device);
+	if (l == NULL)
+		return;
+
+	t = l->data;
+	thermometers = g_slist_remove(thermometers, t);
+	g_dbus_unregister_interface(t->conn, device_get_path(t->dev),
+							THERMOMETER_INTERFACE);
+}
diff --git a/profiles/thermometer/thermometer.h b/profiles/thermometer/thermometer.h
new file mode 100644
index 0000000..330503c
--- /dev/null
+++ b/profiles/thermometer/thermometer.h
@@ -0,0 +1,25 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2011 GSyC/LibreSoft, Universidad Rey Juan Carlos.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+int thermometer_register(DBusConnection *connection, struct btd_device *device,
+						struct gatt_primary *tattr);
+void thermometer_unregister(struct btd_device *device);
diff --git a/thermometer/main.c b/thermometer/main.c
deleted file mode 100644
index 4447b52..0000000
--- a/thermometer/main.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2011 GSyC/LibreSoft, Universidad Rey Juan Carlos.
- *
- *  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 <errno.h>
-#include <gdbus.h>
-
-#include "plugin.h"
-#include "manager.h"
-#include "hcid.h"
-#include "log.h"
-
-static DBusConnection *connection = NULL;
-
-static int thermometer_init(void)
-{
-	if (!main_opts.gatt_enabled) {
-		DBG("GATT is disabled");
-		return -ENOTSUP;
-	}
-
-	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
-	if (connection == NULL)
-		return -EIO;
-
-	if (thermometer_manager_init(connection) < 0) {
-		dbus_connection_unref(connection);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static void thermometer_exit(void)
-{
-	if (!main_opts.gatt_enabled)
-		return;
-
-	thermometer_manager_exit();
-
-	dbus_connection_unref(connection);
-	connection = NULL;
-}
-
-BLUETOOTH_PLUGIN_DEFINE(thermometer, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
-					thermometer_init, thermometer_exit)
diff --git a/thermometer/manager.c b/thermometer/manager.c
deleted file mode 100644
index 3d5452b..0000000
--- a/thermometer/manager.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2011 GSyC/LibreSoft, Universidad Rey Juan Carlos.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include <gdbus.h>
-#include <errno.h>
-#include <bluetooth/uuid.h>
-
-#include "adapter.h"
-#include "device.h"
-#include "att.h"
-#include "gattrib.h"
-#include "gatt.h"
-#include "thermometer.h"
-#include "manager.h"
-
-static DBusConnection *connection = NULL;
-
-static gint primary_uuid_cmp(gconstpointer a, gconstpointer b)
-{
-	const struct gatt_primary *prim = a;
-	const char *uuid = b;
-
-	return g_strcmp0(prim->uuid, uuid);
-}
-
-static int thermometer_driver_probe(struct btd_device *device, GSList *uuids)
-{
-	struct gatt_primary *tattr;
-	GSList *primaries, *l;
-
-	primaries = btd_device_get_primaries(device);
-
-	l = g_slist_find_custom(primaries, HEALTH_THERMOMETER_UUID,
-							primary_uuid_cmp);
-	if (l == NULL)
-		return -EINVAL;
-
-	tattr = l->data;
-
-	return thermometer_register(connection, device, tattr);
-}
-
-static void thermometer_driver_remove(struct btd_device *device)
-{
-	thermometer_unregister(device);
-}
-
-static struct btd_device_driver thermometer_device_driver = {
-	.name	= "thermometer-device-driver",
-	.uuids	= BTD_UUIDS(HEALTH_THERMOMETER_UUID),
-	.probe	= thermometer_driver_probe,
-	.remove	= thermometer_driver_remove
-};
-
-int thermometer_manager_init(DBusConnection *conn)
-{
-	int ret;
-
-	ret = btd_register_device_driver(&thermometer_device_driver);
-	if (ret < 0)
-                return ret;
-
-	connection = dbus_connection_ref(conn);
-	return 0;
-}
-
-void thermometer_manager_exit(void)
-{
-	btd_unregister_device_driver(&thermometer_device_driver);
-
-	dbus_connection_unref(connection);
-	connection = NULL;
-}
diff --git a/thermometer/manager.h b/thermometer/manager.h
deleted file mode 100644
index ed928ad..0000000
--- a/thermometer/manager.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2011 GSyC/LibreSoft, Universidad Rey Juan Carlos.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-int thermometer_manager_init(DBusConnection *conn);
-void thermometer_manager_exit(void);
diff --git a/thermometer/thermometer.c b/thermometer/thermometer.c
deleted file mode 100644
index 087662e..0000000
--- a/thermometer/thermometer.c
+++ /dev/null
@@ -1,1274 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2011 GSyC/LibreSoft, Universidad Rey Juan Carlos.
- *
- *  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 <gdbus.h>
-#include <errno.h>
-#include <bluetooth/uuid.h>
-
-#include "dbus-common.h"
-#include "adapter.h"
-#include "device.h"
-#include "error.h"
-#include "log.h"
-#include "gattrib.h"
-#include "attio.h"
-#include "att.h"
-#include "gatt.h"
-#include "thermometer.h"
-
-#define THERMOMETER_INTERFACE "org.bluez.Thermometer"
-
-/* Temperature measurement flag fields */
-#define TEMP_UNITS		0x01
-#define TEMP_TIME_STAMP		0x02
-#define TEMP_TYPE		0x04
-
-#define FLOAT_MAX_MANTISSA	16777216 /* 2^24 */
-
-#define VALID_RANGE_DESC_SIZE	4
-#define TEMPERATURE_TYPE_SIZE	1
-#define MEASUREMENT_INTERVAL_SIZE	2
-
-struct thermometer {
-	DBusConnection		*conn;		/* The connection to the bus */
-	struct btd_device	*dev;		/* Device reference */
-	GAttrib			*attrib;	/* GATT connection */
-	struct att_range	*svc_range;	/* Thermometer range */
-	guint			attioid;	/* Att watcher id */
-	guint			attindid;	/* Att incications id */
-	guint			attnotid;	/* Att notifications id */
-	GSList			*chars;		/* Characteristics */
-	GSList			*fwatchers;     /* Final measurements */
-	GSList			*iwatchers;     /* Intermediate measurements */
-	gboolean		intermediate;
-	uint8_t			type;
-	uint16_t		interval;
-	uint16_t		max;
-	uint16_t		min;
-	gboolean		has_type;
-	gboolean		has_interval;
-};
-
-struct characteristic {
-	struct gatt_char		attr;	/* Characteristic */
-	GSList			*desc;	/* Descriptors */
-	struct thermometer	*t;	/* Thermometer where the char belongs */
-};
-
-struct descriptor {
-	struct characteristic	*ch;
-	uint16_t		handle;
-	bt_uuid_t		uuid;
-};
-
-struct watcher {
-	struct thermometer	*t;
-	guint			id;
-	char			*srv;
-	char			*path;
-};
-
-struct measurement {
-	int16_t		exp;
-	int32_t		mant;
-	uint64_t	time;
-	gboolean	suptime;
-	char		*unit;
-	char		*type;
-	char		*value;
-};
-
-struct tmp_interval_data {
-	struct thermometer	*thermometer;
-	uint16_t		interval;
-};
-
-static GSList *thermometers = NULL;
-
-const char *temp_type[] = {
-	"<reserved>",
-	"Armpit",
-	"Body",
-	"Ear",
-	"Finger",
-	"Intestines",
-	"Mouth",
-	"Rectum",
-	"Toe",
-	"Tympanum"
-};
-
-static const gchar *temptype2str(uint8_t value)
-{
-	 if (value > 0 && value < G_N_ELEMENTS(temp_type))
-		return temp_type[value];
-
-	error("Temperature type %d reserved for future use", value);
-	return NULL;
-}
-
-static void destroy_watcher(gpointer user_data)
-{
-	struct watcher *watcher = user_data;
-
-	g_free(watcher->path);
-	g_free(watcher->srv);
-	g_free(watcher);
-}
-
-static void remove_watcher(gpointer user_data)
-{
-	struct watcher *watcher = user_data;
-
-	g_dbus_remove_watch(watcher->t->conn, watcher->id);
-}
-
-static void destroy_char(gpointer user_data)
-{
-	struct characteristic *c = user_data;
-
-	g_slist_free_full(c->desc, g_free);
-	g_free(c);
-}
-
-static void destroy_thermometer(gpointer user_data)
-{
-	struct thermometer *t = user_data;
-
-	if (t->attioid > 0)
-		btd_device_remove_attio_callback(t->dev, t->attioid);
-
-	if (t->attindid > 0)
-		g_attrib_unregister(t->attrib, t->attindid);
-
-	if (t->attnotid > 0)
-		g_attrib_unregister(t->attrib, t->attnotid);
-
-	if (t->attrib != NULL)
-		g_attrib_unref(t->attrib);
-
-	if (t->chars != NULL)
-		g_slist_free_full(t->chars, destroy_char);
-
-	if (t->fwatchers != NULL)
-		g_slist_free_full(t->fwatchers, remove_watcher);
-
-	dbus_connection_unref(t->conn);
-	btd_device_unref(t->dev);
-	g_free(t->svc_range);
-	g_free(t);
-}
-
-static gint cmp_device(gconstpointer a, gconstpointer b)
-{
-	const struct thermometer *t = a;
-	const struct btd_device *dev = b;
-
-	if (dev == t->dev)
-		return 0;
-
-	return -1;
-}
-
-static gint cmp_watcher(gconstpointer a, gconstpointer b)
-{
-	const struct watcher *watcher = a;
-	const struct watcher *match = b;
-	int ret;
-
-	ret = g_strcmp0(watcher->srv, match->srv);
-	if (ret != 0)
-		return ret;
-
-	return g_strcmp0(watcher->path, match->path);
-}
-
-static gint cmp_char_uuid(gconstpointer a, gconstpointer b)
-{
-	const struct characteristic *ch = a;
-	const char *uuid = b;
-
-	return g_strcmp0(ch->attr.uuid, uuid);
-}
-
-static gint cmp_char_val_handle(gconstpointer a, gconstpointer b)
-{
-	const struct characteristic *ch = a;
-	const uint16_t *handle = b;
-
-	return ch->attr.value_handle - *handle;
-}
-
-static gint cmp_descriptor(gconstpointer a, gconstpointer b)
-{
-	const struct descriptor *desc = a;
-	const bt_uuid_t *uuid = b;
-
-	return bt_uuid_cmp(&desc->uuid, uuid);
-}
-
-static struct characteristic *get_characteristic(struct thermometer *t,
-							const char *uuid)
-{
-	GSList *l;
-
-	l = g_slist_find_custom(t->chars, uuid, cmp_char_uuid);
-	if (l == NULL)
-		return NULL;
-
-	return l->data;
-}
-
-static struct descriptor *get_descriptor(struct characteristic *ch,
-							const bt_uuid_t *uuid)
-{
-	GSList *l;
-
-	l = g_slist_find_custom(ch->desc, uuid, cmp_descriptor);
-	if (l == NULL)
-		return NULL;
-
-	return l->data;
-}
-
-static void change_property(struct thermometer *t, const char *name,
-							gpointer value) {
-	if (g_strcmp0(name, "Intermediate") == 0) {
-		gboolean *intermediate = value;
-		if (t->intermediate == *intermediate)
-			return;
-
-		t->intermediate = *intermediate;
-		emit_property_changed(t->conn, device_get_path(t->dev),
-					THERMOMETER_INTERFACE, name,
-					DBUS_TYPE_BOOLEAN, &t->intermediate);
-	} else if (g_strcmp0(name, "Interval") == 0) {
-		uint16_t *interval = value;
-		if (t->has_interval && t->interval == *interval)
-			return;
-
-		t->has_interval = TRUE;
-		t->interval = *interval;
-		emit_property_changed(t->conn, device_get_path(t->dev),
-					THERMOMETER_INTERFACE, name,
-					DBUS_TYPE_UINT16, &t->interval);
-	} else if (g_strcmp0(name, "Maximum") == 0) {
-		uint16_t *max = value;
-		if (t->max == *max)
-			return;
-
-		t->max = *max;
-		emit_property_changed(t->conn, device_get_path(t->dev),
-					THERMOMETER_INTERFACE, name,
-					DBUS_TYPE_UINT16, &t->max);
-	} else if (g_strcmp0(name, "Minimum") == 0) {
-		uint16_t *min = value;
-		if (t->min == *min)
-			return;
-
-		t->min = *min;
-		emit_property_changed(t->conn, device_get_path(t->dev),
-					THERMOMETER_INTERFACE, name,
-					DBUS_TYPE_UINT16, &t->min);
-	} else
-		DBG("%s is not a thermometer property", name);
-}
-
-static void valid_range_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
-							gpointer user_data)
-{
-	struct descriptor *desc = user_data;
-	uint8_t value[VALID_RANGE_DESC_SIZE];
-	uint16_t max, min;
-	ssize_t vlen;
-
-	if (status != 0) {
-		DBG("Valid Range descriptor read failed: %s",
-							att_ecode2str(status));
-		return;
-	}
-
-	vlen = dec_read_resp(pdu, len, value, sizeof(value));
-	if (vlen < 0) {
-		DBG("Protocol error\n");
-		return;
-	}
-
-	if (vlen < 4) {
-		DBG("Invalid range received");
-		return;
-	}
-
-	min = att_get_u16(&value[0]);
-	max = att_get_u16(&value[2]);
-
-	if (min == 0 || min > max) {
-		DBG("Invalid range");
-		return;
-	}
-
-	change_property(desc->ch->t, "Maximum", &max);
-	change_property(desc->ch->t, "Minimum", &min);
-}
-
-static void measurement_cb(guint8 status, const guint8 *pdu,
-						guint16 len, gpointer user_data)
-{
-	char *msg = user_data;
-
-	if (status != 0)
-		error("%s failed", msg);
-
-	g_free(msg);
-}
-
-static void process_thermometer_desc(struct descriptor *desc)
-{
-	struct characteristic *ch = desc->ch;
-	char uuidstr[MAX_LEN_UUID_STR];
-	bt_uuid_t btuuid;
-
-	bt_uuid16_create(&btuuid, GATT_CLIENT_CHARAC_CFG_UUID);
-
-	if (bt_uuid_cmp(&desc->uuid, &btuuid) == 0) {
-		uint8_t atval[2];
-		uint16_t val;
-		char *msg;
-
-		if (g_strcmp0(ch->attr.uuid,
-					TEMPERATURE_MEASUREMENT_UUID) == 0) {
-			if (g_slist_length(ch->t->fwatchers) == 0)
-				return;
-
-			val = GATT_CLIENT_CHARAC_CFG_IND_BIT;
-			msg = g_strdup("Enable Temperature Measurement "
-								"indication");
-		} else if (g_strcmp0(ch->attr.uuid,
-					INTERMEDIATE_TEMPERATURE_UUID) == 0) {
-			if (g_slist_length(ch->t->iwatchers) == 0)
-				return;
-
-			val = GATT_CLIENT_CHARAC_CFG_NOTIF_BIT;
-			msg = g_strdup("Enable Intermediate Temperature "
-								"notification");
-		} else if (g_strcmp0(ch->attr.uuid,
-					MEASUREMENT_INTERVAL_UUID) == 0) {
-			val = GATT_CLIENT_CHARAC_CFG_IND_BIT;
-			msg = g_strdup("Enable Measurement Interval "
-								"indication");
-		} else
-			goto done;
-
-		att_put_u16(val, atval);
-		gatt_write_char(ch->t->attrib, desc->handle, atval, 2,
-							measurement_cb, msg);
-		return;
-	}
-
-	bt_uuid16_create(&btuuid, GATT_CHARAC_VALID_RANGE_UUID);
-
-	if (bt_uuid_cmp(&desc->uuid, &btuuid) == 0 && g_strcmp0(ch->attr.uuid,
-					MEASUREMENT_INTERVAL_UUID) == 0) {
-		gatt_read_char(ch->t->attrib, desc->handle, 0,
-						valid_range_desc_cb, desc);
-		return;
-	}
-
-done:
-	bt_uuid_to_string(&desc->uuid, uuidstr, MAX_LEN_UUID_STR);
-	DBG("Ignored descriptor %s in characteristic %s", uuidstr,
-								ch->attr.uuid);
-}
-
-static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
-							gpointer user_data)
-{
-	struct characteristic *ch = user_data;
-	struct att_data_list *list;
-	uint8_t format;
-	int i;
-
-	if (status != 0) {
-		error("Discover all characteristic descriptors failed [%s]: %s",
-					ch->attr.uuid, att_ecode2str(status));
-		return;
-	}
-
-	list = dec_find_info_resp(pdu, len, &format);
-	if (list == NULL)
-		return;
-
-	for (i = 0; i < list->num; i++) {
-		struct descriptor *desc;
-		uint8_t *value;
-
-		value = list->data[i];
-		desc = g_new0(struct descriptor, 1);
-		desc->handle = att_get_u16(value);
-		desc->ch = ch;
-
-		if (format == 0x01)
-			desc->uuid = att_get_uuid16(&value[2]);
-		else
-			desc->uuid = att_get_uuid128(&value[2]);
-
-		ch->desc = g_slist_append(ch->desc, desc);
-		process_thermometer_desc(desc);
-	}
-
-	att_data_list_free(list);
-}
-
-static void read_temp_type_cb(guint8 status, const guint8 *pdu, guint16 len,
-							gpointer user_data)
-{
-	struct characteristic *ch = user_data;
-	struct thermometer *t = ch->t;
-	uint8_t value[TEMPERATURE_TYPE_SIZE];
-	ssize_t vlen;
-
-	if (status != 0) {
-		DBG("Temperature Type value read failed: %s",
-							att_ecode2str(status));
-		return;
-	}
-
-	vlen = dec_read_resp(pdu, len, value, sizeof(value));
-	if (vlen < 0) {
-		DBG("Protocol error.");
-		return;
-	}
-
-	if (vlen != 1) {
-		DBG("Invalid length for Temperature type");
-		return;
-	}
-
-	t->has_type = TRUE;
-	t->type = value[0];
-}
-
-static void read_interval_cb(guint8 status, const guint8 *pdu, guint16 len,
-							gpointer user_data)
-{
-	struct characteristic *ch = user_data;
-	uint8_t value[MEASUREMENT_INTERVAL_SIZE];
-	uint16_t interval;
-	ssize_t vlen;
-
-	if (status != 0) {
-		DBG("Measurement Interval value read failed: %s",
-							att_ecode2str(status));
-		return;
-	}
-
-	vlen = dec_read_resp(pdu, len, value, sizeof(value));
-	if (vlen < 0) {
-		DBG("Protocol error\n");
-		return;
-	}
-
-	if (vlen < 2) {
-		DBG("Invalid Interval received");
-		return;
-	}
-
-	interval = att_get_u16(&value[0]);
-	change_property(ch->t, "Interval", &interval);
-}
-
-static void process_thermometer_char(struct characteristic *ch)
-{
-	if (g_strcmp0(ch->attr.uuid, INTERMEDIATE_TEMPERATURE_UUID) == 0) {
-		gboolean intermediate = TRUE;
-		change_property(ch->t, "Intermediate", &intermediate);
-		return;
-	} else if (g_strcmp0(ch->attr.uuid, TEMPERATURE_TYPE_UUID) == 0)
-		gatt_read_char(ch->t->attrib, ch->attr.value_handle, 0,
-							read_temp_type_cb, ch);
-	else if (g_strcmp0(ch->attr.uuid, MEASUREMENT_INTERVAL_UUID) == 0)
-		gatt_read_char(ch->t->attrib, ch->attr.value_handle, 0,
-							read_interval_cb, ch);
-}
-
-static void configure_thermometer_cb(GSList *characteristics, guint8 status,
-							gpointer user_data)
-{
-	struct thermometer *t = user_data;
-	GSList *l;
-
-	if (status != 0) {
-		error("Discover thermometer characteristics: %s",
-							att_ecode2str(status));
-		return;
-	}
-
-	for (l = characteristics; l; l = l->next) {
-		struct gatt_char *c = l->data;
-		struct characteristic *ch;
-		uint16_t start, end;
-
-		ch = g_new0(struct characteristic, 1);
-		ch->attr.handle = c->handle;
-		ch->attr.properties = c->properties;
-		ch->attr.value_handle = c->value_handle;
-		memcpy(ch->attr.uuid, c->uuid, MAX_LEN_UUID_STR + 1);
-		ch->t = t;
-
-		t->chars = g_slist_append(t->chars, ch);
-
-		process_thermometer_char(ch);
-
-		start = c->value_handle + 1;
-
-		if (l->next != NULL) {
-			struct gatt_char *c = l->next->data;
-			if (start == c->handle)
-				continue;
-			end = c->handle - 1;
-		} else if (c->value_handle != t->svc_range->end)
-			end = t->svc_range->end;
-		else
-			continue;
-
-		gatt_find_info(t->attrib, start, end, discover_desc_cb, ch);
-	}
-}
-
-static DBusMessage *get_properties(DBusConnection *conn, DBusMessage *msg,
-								void *data)
-{
-	struct thermometer *t = data;
-	DBusMessageIter iter;
-	DBusMessageIter dict;
-	DBusMessage *reply;
-
-	reply = dbus_message_new_method_return(msg);
-	if (reply == NULL)
-		return NULL;
-
-	dbus_message_iter_init_append(reply, &iter);
-
-	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
-			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
-			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
-			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
-
-	dict_append_entry(&dict, "Intermediate", DBUS_TYPE_BOOLEAN,
-							&t->intermediate);
-
-	if (t->has_interval) {
-		dict_append_entry(&dict, "Interval", DBUS_TYPE_UINT16,
-								&t->interval);
-		dict_append_entry(&dict, "Maximum", DBUS_TYPE_UINT16, &t->max);
-		dict_append_entry(&dict, "Minimum", DBUS_TYPE_UINT16, &t->min);
-	}
-
-	dbus_message_iter_close_container(&iter, &dict);
-
-	return reply;
-}
-
-static void write_interval_cb (guint8 status, const guint8 *pdu, guint16 len,
-							gpointer user_data)
-{
-	struct tmp_interval_data *data = user_data;
-
-	if (status != 0) {
-		error("Interval Write Request failed %s",
-							att_ecode2str(status));
-		goto done;
-	}
-
-	if (!dec_write_resp(pdu, len)) {
-		error("Interval Write Request: protocol error");
-		goto done;
-	}
-
-	change_property(data->thermometer, "Interval", &data->interval);
-
-done:
-	g_free(user_data);
-}
-
-static DBusMessage *write_attr_interval(struct thermometer *t, DBusMessage *msg,
-								uint16_t value)
-{
-	struct tmp_interval_data *data;
-	struct characteristic *ch;
-	uint8_t atval[2];
-
-	if (t->attrib == NULL)
-		return btd_error_not_connected(msg);
-
-	ch = get_characteristic(t, MEASUREMENT_INTERVAL_UUID);
-	if (ch == NULL)
-		return btd_error_not_available(msg);
-
-	if (value < t->min || value > t->max)
-		return btd_error_invalid_args(msg);
-
-	att_put_u16(value, &atval[0]);
-
-	data = g_new0(struct tmp_interval_data, 1);
-	data->thermometer = t;
-	data->interval = value;
-	gatt_write_char(t->attrib, ch->attr.value_handle, atval, 2,
-						write_interval_cb, data);
-
-	return dbus_message_new_method_return(msg);
-}
-
-static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg,
-								void *data)
-{
-	struct thermometer *t = data;
-	const char *property;
-	DBusMessageIter iter;
-	DBusMessageIter sub;
-	uint16_t value;
-
-	if (!dbus_message_iter_init(msg, &iter))
-		return btd_error_invalid_args(msg);
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
-		return btd_error_invalid_args(msg);
-
-	dbus_message_iter_get_basic(&iter, &property);
-	if (g_strcmp0("Interval", property) != 0)
-		return btd_error_invalid_args(msg);
-
-	if (!t->has_interval)
-		return btd_error_not_available(msg);
-
-	dbus_message_iter_next(&iter);
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
-		return btd_error_invalid_args(msg);
-
-	dbus_message_iter_recurse(&iter, &sub);
-
-	if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_UINT16)
-		return btd_error_invalid_args(msg);
-
-	dbus_message_iter_get_basic(&sub, &value);
-
-	return write_attr_interval(t, msg, value);
-}
-
-static void enable_final_measurement(struct thermometer *t)
-{
-	struct characteristic *ch;
-	struct descriptor *desc;
-	bt_uuid_t btuuid;
-	uint8_t atval[2];
-	char *msg;
-
-	if (t->attrib == NULL)
-		return;
-
-	ch = get_characteristic(t, TEMPERATURE_MEASUREMENT_UUID);
-	if (ch == NULL) {
-		DBG("Temperature measurement characteristic not found");
-		return;
-	}
-
-	bt_uuid16_create(&btuuid, GATT_CLIENT_CHARAC_CFG_UUID);
-	desc = get_descriptor(ch, &btuuid);
-	if (desc == NULL) {
-		DBG("Client characteristic configuration descriptor not found");
-		return;
-	}
-
-	atval[0] = 0x02;
-	atval[1] = 0x00;
-	msg = g_strdup("Enable final measurement");
-	gatt_write_char(t->attrib, desc->handle, atval, 2, measurement_cb, msg);
-}
-
-static void enable_intermediate_measurement(struct thermometer *t)
-{
-	struct characteristic *ch;
-	struct descriptor *desc;
-	bt_uuid_t btuuid;
-	uint8_t atval[2];
-	char *msg;
-
-	if (t->attrib == NULL)
-		return;
-
-	ch = get_characteristic(t, INTERMEDIATE_TEMPERATURE_UUID);
-	if (ch == NULL) {
-		DBG("Intermediate measurement characteristic not found");
-		return;
-	}
-
-	bt_uuid16_create(&btuuid, GATT_CLIENT_CHARAC_CFG_UUID);
-	desc = get_descriptor(ch, &btuuid);
-	if (desc == NULL) {
-		DBG("Client characteristic configuration descriptor not found");
-		return;
-	}
-
-	atval[0] = 0x01;
-	atval[1] = 0x00;
-	msg = g_strdup("Enable intermediate measurement");
-	gatt_write_char(t->attrib, desc->handle, atval, 2, measurement_cb, msg);
-}
-
-static void disable_final_measurement(struct thermometer *t)
-{
-	struct characteristic *ch;
-	struct descriptor *desc;
-	bt_uuid_t btuuid;
-	uint8_t atval[2];
-	char *msg;
-
-	if (t->attrib == NULL)
-		return;
-
-	ch = get_characteristic(t, TEMPERATURE_MEASUREMENT_UUID);
-	if (ch == NULL) {
-		DBG("Temperature measurement characteristic not found");
-		return;
-	}
-
-	bt_uuid16_create(&btuuid, GATT_CLIENT_CHARAC_CFG_UUID);
-	desc = get_descriptor(ch, &btuuid);
-	if (desc == NULL) {
-		DBG("Client characteristic configuration descriptor not found");
-		return;
-	}
-
-	atval[0] = 0x00;
-	atval[1] = 0x00;
-	msg = g_strdup("Disable final measurement");
-	gatt_write_char(t->attrib, desc->handle, atval, 2, measurement_cb, msg);
-}
-
-static void disable_intermediate_measurement(struct thermometer *t)
-{
-	struct characteristic *ch;
-	struct descriptor *desc;
-	bt_uuid_t btuuid;
-	uint8_t atval[2];
-	char *msg;
-
-	if (t->attrib == NULL)
-		return;
-
-	ch = get_characteristic(t, INTERMEDIATE_TEMPERATURE_UUID);
-	if (ch == NULL) {
-		DBG("Intermediate measurement characteristic not found");
-		return;
-	}
-
-	bt_uuid16_create(&btuuid, GATT_CLIENT_CHARAC_CFG_UUID);
-	desc = get_descriptor(ch, &btuuid);
-	if (desc == NULL) {
-		DBG("Client characteristic configuration descriptor not found");
-		return;
-	}
-
-	atval[0] = 0x00;
-	atval[1] = 0x00;
-	msg = g_strdup("Disable intermediate measurement");
-	gatt_write_char(t->attrib, desc->handle, atval, 2, measurement_cb, msg);
-}
-
-static void remove_int_watcher(struct thermometer *t, struct watcher *w)
-{
-	if (!g_slist_find(t->iwatchers, w))
-		return;
-
-	t->iwatchers = g_slist_remove(t->iwatchers, w);
-
-	if (g_slist_length(t->iwatchers) == 0)
-		disable_intermediate_measurement(t);
-}
-
-static void watcher_exit(DBusConnection *conn, void *user_data)
-{
-	struct watcher *watcher = user_data;
-	struct thermometer *t = watcher->t;
-
-	DBG("Thermometer watcher %s disconnected", watcher->path);
-
-	remove_int_watcher(t, watcher);
-
-	t->fwatchers = g_slist_remove(t->fwatchers, watcher);
-	g_dbus_remove_watch(watcher->t->conn, watcher->id);
-
-	if (g_slist_length(t->fwatchers) == 0)
-		disable_final_measurement(t);
-}
-
-static struct watcher *find_watcher(GSList *list, const char *sender,
-							const char *path)
-{
-	struct watcher *match;
-	GSList *l;
-
-	match = g_new0(struct watcher, 1);
-	match->srv = g_strdup(sender);
-	match->path = g_strdup(path);
-
-	l = g_slist_find_custom(list, match, cmp_watcher);
-	destroy_watcher(match);
-
-	if (l != NULL)
-		return l->data;
-
-	return NULL;
-}
-
-static DBusMessage *register_watcher(DBusConnection *conn, DBusMessage *msg,
-								void *data)
-{
-	const char *sender = dbus_message_get_sender(msg);
-	struct thermometer *t = data;
-	struct watcher *watcher;
-	char *path;
-
-	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
-							DBUS_TYPE_INVALID))
-		return btd_error_invalid_args(msg);
-
-	watcher = find_watcher(t->fwatchers, sender, path);
-	if (watcher != NULL)
-		return btd_error_already_exists(msg);
-
-	DBG("Thermometer watcher %s registered", path);
-
-	watcher = g_new0(struct watcher, 1);
-	watcher->srv = g_strdup(sender);
-	watcher->path = g_strdup(path);
-	watcher->t = t;
-	watcher->id = g_dbus_add_disconnect_watch(conn, sender, watcher_exit,
-						watcher, destroy_watcher);
-
-	if (g_slist_length(t->fwatchers) == 0)
-		enable_final_measurement(t);
-
-	t->fwatchers = g_slist_prepend(t->fwatchers, watcher);
-
-	return dbus_message_new_method_return(msg);
-}
-
-static DBusMessage *unregister_watcher(DBusConnection *conn, DBusMessage *msg,
-								void *data)
-{
-	const char *sender = dbus_message_get_sender(msg);
-	struct thermometer *t = data;
-	struct watcher *watcher;
-	char *path;
-
-	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
-							DBUS_TYPE_INVALID))
-		return btd_error_invalid_args(msg);
-
-	watcher = find_watcher(t->fwatchers, sender, path);
-	if (watcher == NULL)
-		return btd_error_does_not_exist(msg);
-
-	DBG("Thermometer watcher %s unregistered", path);
-
-	remove_int_watcher(t, watcher);
-
-	t->fwatchers = g_slist_remove(t->fwatchers, watcher);
-	g_dbus_remove_watch(watcher->t->conn, watcher->id);
-
-	if (g_slist_length(t->fwatchers) == 0)
-		disable_final_measurement(t);
-
-	return dbus_message_new_method_return(msg);
-}
-
-static DBusMessage *enable_intermediate(DBusConnection *conn, DBusMessage *msg,
-								void *data)
-{
-	const char *sender = dbus_message_get_sender(msg);
-	struct thermometer *t = data;
-	struct watcher *watcher;
-	char *path;
-
-	if (!t->intermediate)
-		return btd_error_not_supported(msg);
-
-	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
-							DBUS_TYPE_INVALID))
-		return btd_error_invalid_args(msg);
-
-	watcher = find_watcher(t->fwatchers, sender, path);
-	if (watcher == NULL)
-		return btd_error_does_not_exist(msg);
-
-	if (find_watcher(t->iwatchers, sender, path))
-		return btd_error_already_exists(msg);
-
-	DBG("Intermediate measurement watcher %s registered", path);
-
-	if (g_slist_length(t->iwatchers) == 0)
-		enable_intermediate_measurement(t);
-
-	t->iwatchers = g_slist_prepend(t->iwatchers, watcher);
-
-	return dbus_message_new_method_return(msg);
-}
-
-static DBusMessage *disable_intermediate(DBusConnection *conn, DBusMessage *msg,
-								void *data)
-{
-	const char *sender = dbus_message_get_sender(msg);
-	struct thermometer *t = data;
-	struct watcher *watcher;
-	char *path;
-
-	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
-							DBUS_TYPE_INVALID))
-		return btd_error_invalid_args(msg);
-
-	watcher = find_watcher(t->iwatchers, sender, path);
-	if (watcher == NULL)
-		return btd_error_does_not_exist(msg);
-
-	DBG("Intermediate measurement %s unregistered", path);
-
-	remove_int_watcher(t, watcher);
-
-	return dbus_message_new_method_return(msg);
-}
-
-static const GDBusMethodTable thermometer_methods[] = {
-	{ GDBUS_METHOD("GetProperties",
-			NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
-			get_properties) },
-	{ GDBUS_ASYNC_METHOD("SetProperty",
-			GDBUS_ARGS({ "name", "s" }, { "value", "v" }), NULL,
-			set_property) },
-	{ GDBUS_METHOD("RegisterWatcher",
-			GDBUS_ARGS({ "agent", "o" }), NULL,
-			register_watcher) },
-	{ GDBUS_METHOD("UnregisterWatcher",
-			GDBUS_ARGS({ "agent", "o" }), NULL,
-			unregister_watcher) },
-	{ GDBUS_METHOD("EnableIntermediateMeasurement",
-			GDBUS_ARGS({ "agent", "o" }), NULL,
-			enable_intermediate) },
-	{ GDBUS_METHOD("DisableIntermediateMeasurement",
-			GDBUS_ARGS({ "agent", "o" }), NULL,
-			disable_intermediate) },
-	{ }
-};
-
-static const GDBusSignalTable thermometer_signals[] = {
-	{ GDBUS_SIGNAL("PropertyChanged",
-			GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
-	{ }
-};
-
-static void update_watcher(gpointer data, gpointer user_data)
-{
-	struct watcher *w = data;
-	struct measurement *m = user_data;
-	DBusConnection *conn = w->t->conn;
-	DBusMessageIter iter;
-	DBusMessageIter dict;
-	DBusMessage *msg;
-
-	msg = dbus_message_new_method_call(w->srv, w->path,
-				"org.bluez.ThermometerWatcher",
-				"MeasurementReceived");
-	if (msg == NULL)
-		return;
-
-	dbus_message_iter_init_append(msg, &iter);
-
-	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
-			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
-			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
-			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
-
-	dict_append_entry(&dict, "Exponent", DBUS_TYPE_INT16, &m->exp);
-	dict_append_entry(&dict, "Mantissa", DBUS_TYPE_INT32, &m->mant);
-	dict_append_entry(&dict, "Unit", DBUS_TYPE_STRING, &m->unit);
-
-	if (m->suptime)
-		dict_append_entry(&dict, "Time", DBUS_TYPE_UINT64, &m->time);
-
-	dict_append_entry(&dict, "Type", DBUS_TYPE_STRING, &m->type);
-	dict_append_entry(&dict, "Measurement", DBUS_TYPE_STRING, &m->value);
-
-	dbus_message_iter_close_container(&iter, &dict);
-
-	dbus_message_set_no_reply(msg, TRUE);
-	g_dbus_send_message(conn, msg);
-}
-
-static void recv_measurement(struct thermometer *t, struct measurement *m)
-{
-	GSList *wlist;
-
-	if (g_strcmp0(m->value, "Intermediate") == 0)
-		wlist = t->iwatchers;
-	else
-		wlist = t->fwatchers;
-
-	g_slist_foreach(wlist, update_watcher, m);
-}
-
-static void proc_measurement(struct thermometer *t, const uint8_t *pdu,
-						uint16_t len, gboolean final)
-{
-	struct measurement m;
-	const char *type;
-	uint8_t flags;
-	uint32_t raw;
-
-	if (len < 4) {
-		DBG("Mandatory flags are not provided");
-		return;
-	}
-
-	flags = pdu[3];
-	if (flags & TEMP_UNITS)
-		m.unit = "Fahrenheit";
-	else
-		m.unit = "Celsius";
-
-	if (len < 8) {
-		DBG("Temperature measurement value is not provided");
-		return;
-	}
-
-	raw = att_get_u32(&pdu[4]);
-	m.mant = raw & 0x00FFFFFF;
-	m.exp = ((int32_t) raw) >> 24;
-
-	if (m.mant & 0x00800000) {
-		/* convert to C2 negative value */
-		m.mant = m.mant - FLOAT_MAX_MANTISSA;
-	}
-
-	if (flags & TEMP_TIME_STAMP) {
-		struct tm ts;
-		time_t time;
-
-		if (len < 15) {
-			DBG("Can't get time stamp value");
-			return;
-		}
-
-		ts.tm_year = att_get_u16(&pdu[8]) - 1900;
-		ts.tm_mon = pdu[10] - 1;
-		ts.tm_mday = pdu[11];
-		ts.tm_hour = pdu[12];
-		ts.tm_min = pdu[13];
-		ts.tm_sec = pdu[14];
-		ts.tm_isdst = -1;
-
-		time = mktime(&ts);
-		m.time = (uint64_t) time;
-		m.suptime = TRUE;
-	} else
-		m.suptime = FALSE;
-
-	if (flags & TEMP_TYPE) {
-		uint8_t index;
-
-		if (m.suptime && len >= 16)
-			index = 15;
-		else if (!m.suptime && len >= 9)
-			index = 9;
-		else {
-			DBG("Can't get temperature type");
-			return;
-		}
-
-		type = temptype2str(pdu[index]);
-	} else if (t->has_type)
-		type = temptype2str(t->type);
-	else
-		type = NULL;
-
-	m.type = type ? g_strdup(type) : NULL;
-	m.value = final ? "Final" : "Intermediate";
-
-	recv_measurement(t, &m);
-	g_free(m.type);
-}
-
-static void proc_measurement_interval(struct thermometer *t, const uint8_t *pdu,
-								uint16_t len)
-{
-	uint16_t interval;
-
-	if (len < 5) {
-		DBG("Measurement interval value is not provided");
-		return;
-	}
-
-	interval = att_get_u16(&pdu[3]);
-
-	change_property(t, "Interval", &interval);
-}
-
-static void ind_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
-{
-	struct thermometer *t = user_data;
-	const struct characteristic *ch;
-	uint8_t *opdu;
-	uint16_t handle, olen;
-	GSList *l;
-	int plen;
-
-	if (len < 3) {
-		DBG("Bad pdu received");
-		return;
-	}
-
-	handle = att_get_u16(&pdu[1]);
-	l = g_slist_find_custom(t->chars, &handle, cmp_char_val_handle);
-	if (l == NULL) {
-		DBG("Unexpected handle: 0x%04x", handle);
-		return;
-	}
-
-	ch = l->data;
-
-	if (g_strcmp0(ch->attr.uuid, TEMPERATURE_MEASUREMENT_UUID) == 0)
-		proc_measurement(t, pdu, len, TRUE);
-	else if (g_strcmp0(ch->attr.uuid, MEASUREMENT_INTERVAL_UUID) == 0)
-		proc_measurement_interval(t, pdu, len);
-
-	opdu = g_attrib_get_buffer(t->attrib, &plen);
-	olen = enc_confirmation(opdu, plen);
-
-	if (olen > 0)
-		g_attrib_send(t->attrib, 0, opdu[0], opdu, olen, NULL, NULL,
-									NULL);
-}
-
-static void notif_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
-{
-	struct thermometer *t = user_data;
-	const struct characteristic *ch;
-	uint16_t handle;
-	GSList *l;
-
-	if (len < 3) {
-		DBG("Bad pdu received");
-		return;
-	}
-
-	handle = att_get_u16(&pdu[1]);
-	l = g_slist_find_custom(t->chars, &handle, cmp_char_val_handle);
-	if (l == NULL) {
-		DBG("Unexpected handle: 0x%04x", handle);
-		return;
-	}
-
-	ch = l->data;
-	if (g_strcmp0(ch->attr.uuid, INTERMEDIATE_TEMPERATURE_UUID) == 0)
-		proc_measurement(t, pdu, len, FALSE);
-}
-
-static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
-{
-	struct thermometer *t = user_data;
-
-	t->attrib = g_attrib_ref(attrib);
-
-	t->attindid = g_attrib_register(t->attrib, ATT_OP_HANDLE_IND,
-							ind_handler, t, NULL);
-	t->attnotid = g_attrib_register(t->attrib, ATT_OP_HANDLE_NOTIFY,
-							notif_handler, t, NULL);
-	gatt_discover_char(t->attrib, t->svc_range->start, t->svc_range->end,
-					NULL, configure_thermometer_cb, t);
-}
-
-static void attio_disconnected_cb(gpointer user_data)
-{
-	struct thermometer *t = user_data;
-
-	DBG("GATT Disconnected");
-
-	if (t->attindid > 0) {
-		g_attrib_unregister(t->attrib, t->attindid);
-		t->attindid = 0;
-	}
-
-	if (t->attnotid > 0) {
-		g_attrib_unregister(t->attrib, t->attnotid);
-		t->attnotid = 0;
-	}
-
-	g_attrib_unref(t->attrib);
-	t->attrib = NULL;
-}
-
-int thermometer_register(DBusConnection *connection, struct btd_device *device,
-						struct gatt_primary *tattr)
-{
-	const gchar *path = device_get_path(device);
-	struct thermometer *t;
-
-	t = g_new0(struct thermometer, 1);
-	t->conn = dbus_connection_ref(connection);
-	t->dev = btd_device_ref(device);
-	t->svc_range = g_new0(struct att_range, 1);
-	t->svc_range->start = tattr->range.start;
-	t->svc_range->end = tattr->range.end;
-
-	if (!g_dbus_register_interface(t->conn, path, THERMOMETER_INTERFACE,
-				thermometer_methods, thermometer_signals,
-				NULL, t, destroy_thermometer)) {
-		error("D-Bus failed to register %s interface",
-							THERMOMETER_INTERFACE);
-		destroy_thermometer(t);
-		return -EIO;
-	}
-
-	thermometers = g_slist_prepend(thermometers, t);
-
-	t->attioid = btd_device_add_attio_callback(device, attio_connected_cb,
-						attio_disconnected_cb, t);
-	return 0;
-}
-
-void thermometer_unregister(struct btd_device *device)
-{
-	struct thermometer *t;
-	GSList *l;
-
-	l = g_slist_find_custom(thermometers, device, cmp_device);
-	if (l == NULL)
-		return;
-
-	t = l->data;
-	thermometers = g_slist_remove(thermometers, t);
-	g_dbus_unregister_interface(t->conn, device_get_path(t->dev),
-							THERMOMETER_INTERFACE);
-}
diff --git a/thermometer/thermometer.h b/thermometer/thermometer.h
deleted file mode 100644
index 330503c..0000000
--- a/thermometer/thermometer.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2011 GSyC/LibreSoft, Universidad Rey Juan Carlos.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-int thermometer_register(DBusConnection *connection, struct btd_device *device,
-						struct gatt_primary *tattr);
-void thermometer_unregister(struct btd_device *device);
-- 
1.7.10.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 08/14] time: move to the profiles folder
  2012-07-09 21:10 [PATCH 01/14] input: remove unneeded header inclusions Gustavo Padovan
                   ` (4 preceding siblings ...)
  2012-07-09 21:10 ` [PATCH 07/14] thermometer: move to the " Gustavo Padovan
@ 2012-07-09 21:10 ` Gustavo Padovan
  2012-07-09 21:10 ` [PATCH 12/14] cups: move it to " Gustavo Padovan
  2012-07-09 21:10 ` [PATCH 14/14] plugins: remove unmaintained plugins Gustavo Padovan
  7 siblings, 0 replies; 10+ messages in thread
From: Gustavo Padovan @ 2012-07-09 21:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

---
 Makefile.am             |    5 +-
 profiles/time/main.c    |   58 ++++++++++++
 profiles/time/manager.c |   49 ++++++++++
 profiles/time/manager.h |   26 ++++++
 profiles/time/server.c  |  234 +++++++++++++++++++++++++++++++++++++++++++++++
 profiles/time/server.h  |   45 +++++++++
 time/main.c             |   58 ------------
 time/manager.c          |   49 ----------
 time/manager.h          |   26 ------
 time/server.c           |  234 -----------------------------------------------
 time/server.h           |   45 ---------
 11 files changed, 415 insertions(+), 414 deletions(-)
 create mode 100644 profiles/time/main.c
 create mode 100644 profiles/time/manager.c
 create mode 100644 profiles/time/manager.h
 create mode 100644 profiles/time/server.c
 create mode 100644 profiles/time/server.h
 delete mode 100644 time/main.c
 delete mode 100644 time/manager.c
 delete mode 100644 time/manager.h
 delete mode 100644 time/server.c
 delete mode 100644 time/server.h

diff --git a/Makefile.am b/Makefile.am
index c8b2475..7e23f5f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -222,8 +222,9 @@ builtin_sources += profiles/thermometer/main.c \
 		       	profiles/thermometer/thermometer.c \
 			profiles/alert/main.c profiles/alert/server.h \
 			profiles/alert/server.c \
-			time/main.c time/server.h time/server.c \
-			time/manager.h time/manager.c \
+			profiles/time/main.c profiles/time/server.h \
+			profiles/time/server.c profiles/time/manager.c \
+			profiles/time/manager.h \
 			plugins/gatt-example.c \
 			profiles/proximity/main.c profiles/proximity/manager.h \
 		       	profiles/proximity/manager.c \
diff --git a/profiles/time/main.c b/profiles/time/main.c
new file mode 100644
index 0000000..9ef5bf1
--- /dev/null
+++ b/profiles/time/main.c
@@ -0,0 +1,58 @@
+/*
+ *
+ *  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 <stdint.h>
+#include <glib.h>
+#include <errno.h>
+
+#include "plugin.h"
+#include "hcid.h"
+#include "log.h"
+#include "manager.h"
+
+static int time_init(void)
+{
+	if (!main_opts.gatt_enabled) {
+		DBG("GATT is disabled");
+		return -ENOTSUP;
+	}
+
+	return time_manager_init();
+}
+
+static void time_exit(void)
+{
+	if (!main_opts.gatt_enabled)
+		return;
+
+	time_manager_exit();
+}
+
+BLUETOOTH_PLUGIN_DEFINE(time, VERSION,
+			BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
+			time_init, time_exit)
diff --git a/profiles/time/manager.c b/profiles/time/manager.c
new file mode 100644
index 0000000..285c7b1
--- /dev/null
+++ b/profiles/time/manager.c
@@ -0,0 +1,49 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2012  Nokia Corporation
+ *  Copyright (C) 2012  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 "adapter.h"
+#include "manager.h"
+#include "server.h"
+
+struct btd_adapter_driver time_server_driver = {
+	.name = "gatt-time-server",
+	.probe = time_server_init,
+	.remove = time_server_exit,
+};
+
+int time_manager_init(void)
+{
+	btd_register_adapter_driver(&time_server_driver);
+
+	return 0;
+}
+
+void time_manager_exit(void)
+{
+	btd_unregister_adapter_driver(&time_server_driver);
+}
diff --git a/profiles/time/manager.h b/profiles/time/manager.h
new file mode 100644
index 0000000..74641d6
--- /dev/null
+++ b/profiles/time/manager.h
@@ -0,0 +1,26 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2012  Nokia Corporation
+ *  Copyright (C) 2012  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
+ *
+ */
+
+int time_manager_init(void);
+void time_manager_exit(void);
diff --git a/profiles/time/server.c b/profiles/time/server.c
new file mode 100644
index 0000000..be6e196
--- /dev/null
+++ b/profiles/time/server.c
@@ -0,0 +1,234 @@
+/*
+ *
+ *  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 <glib.h>
+#include <time.h>
+#include <errno.h>
+#include <bluetooth/uuid.h>
+#include <adapter.h>
+
+#include "gattrib.h"
+#include "att.h"
+#include "gatt.h"
+#include "att-database.h"
+#include "attrib-server.h"
+#include "gatt-service.h"
+#include "log.h"
+#include "server.h"
+
+#define CURRENT_TIME_SVC_UUID		0x1805
+#define REF_TIME_UPDATE_SVC_UUID	0x1806
+
+#define LOCAL_TIME_INFO_CHR_UUID	0x2A0F
+#define TIME_UPDATE_CTRL_CHR_UUID	0x2A16
+#define TIME_UPDATE_STAT_CHR_UUID	0x2A17
+#define CT_TIME_CHR_UUID		0x2A2B
+
+static int encode_current_time(uint8_t value[10])
+{
+	struct timespec tp;
+	struct tm tm;
+
+	if (clock_gettime(CLOCK_REALTIME, &tp) == -1) {
+		int err = -errno;
+
+		error("clock_gettime: %s", strerror(-err));
+		return err;
+	}
+
+	if (localtime_r(&tp.tv_sec, &tm) == NULL) {
+		error("localtime_r() failed");
+		/* localtime_r() does not set errno */
+		return -EINVAL;
+	}
+
+	att_put_u16(1900 + tm.tm_year, &value[0]); /* Year */
+	value[2] = tm.tm_mon + 1; /* Month */
+	value[3] = tm.tm_mday; /* Day */
+	value[4] = tm.tm_hour; /* Hours */
+	value[5] = tm.tm_min; /* Minutes */
+	value[6] = tm.tm_sec; /* Seconds */
+	value[7] = tm.tm_wday == 0 ? 7 : tm.tm_wday; /* Day of Week */
+	/* From Time Profile spec: "The number of 1/256 fractions of a second."
+	 * In 1s there are 256 fractions, in 1ns there are 256/10^9 fractions.
+	 * To avoid integer overflow, we use the equivalent 1/3906250 ratio. */
+	value[8] = tp.tv_nsec / 3906250; /* Fractions256 */
+	value[9] = 0x00; /* Adjust Reason */
+
+	return 0;
+}
+
+static uint8_t current_time_read(struct attribute *a,
+				 struct btd_device *device, gpointer user_data)
+{
+	struct btd_adapter *adapter = user_data;
+	uint8_t value[10];
+
+	if (encode_current_time(value) < 0)
+		return ATT_ECODE_IO;
+
+	attrib_db_update(adapter, a->handle, NULL, value, sizeof(value), NULL);
+
+	return 0;
+}
+
+static uint8_t local_time_info_read(struct attribute *a,
+				struct btd_device *device, gpointer user_data)
+{
+	struct btd_adapter *adapter = user_data;
+	uint8_t value[2];
+
+	DBG("a=%p", a);
+
+	tzset();
+
+	/* FIXME: POSIX "daylight" variable only indicates whether there is DST
+	 * for the local time or not. The offset is unknown. */
+	value[0] = daylight ? 0xff : 0x00;
+
+	/* Convert POSIX "timezone" (seconds West of GMT) to Time Profile
+	 * format (offset from UTC in number of 15 minutes increments). */
+	value[1] = (uint8_t) (-1 * timezone / (60 * 15));
+
+	attrib_db_update(adapter, a->handle, NULL, value, sizeof(value), NULL);
+
+	return 0;
+}
+
+static gboolean register_current_time_service(struct btd_adapter *adapter)
+{
+	bt_uuid_t uuid;
+
+	bt_uuid16_create(&uuid, CURRENT_TIME_SVC_UUID);
+
+	/* Current Time service */
+	return gatt_service_add(adapter, GATT_PRIM_SVC_UUID, &uuid,
+				/* CT Time characteristic */
+				GATT_OPT_CHR_UUID, CT_TIME_CHR_UUID,
+				GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ |
+							ATT_CHAR_PROPER_NOTIFY,
+				GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
+						current_time_read, adapter,
+
+				/* Local Time Information characteristic */
+				GATT_OPT_CHR_UUID, LOCAL_TIME_INFO_CHR_UUID,
+				GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ,
+				GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
+						local_time_info_read, adapter,
+
+				GATT_OPT_INVALID);
+}
+
+static uint8_t time_update_control(struct attribute *a,
+						struct btd_device *device,
+						gpointer user_data)
+{
+	DBG("handle 0x%04x", a->handle);
+
+	if (a->len != 1)
+		DBG("Invalid control point value size: %d", a->len);
+
+	switch (a->data[0]) {
+	case GET_REFERENCE_UPDATE:
+		DBG("Get Reference Update");
+		break;
+	case CANCEL_REFERENCE_UPDATE:
+		DBG("Cancel Reference Update");
+		break;
+	default:
+		DBG("Unknown command: 0x%02x", a->data[0]);
+	}
+
+	return 0;
+}
+
+static uint8_t time_update_status(struct attribute *a,
+						struct btd_device *device,
+						gpointer user_data)
+{
+	struct btd_adapter *adapter = user_data;
+	uint8_t value[2];
+
+	DBG("handle 0x%04x", a->handle);
+
+	value[0] = UPDATE_STATE_IDLE;
+	value[1] = UPDATE_RESULT_SUCCESSFUL;
+	attrib_db_update(adapter, a->handle, NULL, value, sizeof(value), NULL);
+
+	return 0;
+}
+
+static gboolean register_ref_time_update_service(struct btd_adapter *adapter)
+{
+	bt_uuid_t uuid;
+
+	bt_uuid16_create(&uuid, REF_TIME_UPDATE_SVC_UUID);
+
+	/* Reference Time Update service */
+	return gatt_service_add(adapter, GATT_PRIM_SVC_UUID, &uuid,
+				/* Time Update control point */
+				GATT_OPT_CHR_UUID, TIME_UPDATE_CTRL_CHR_UUID,
+				GATT_OPT_CHR_PROPS,
+					ATT_CHAR_PROPER_WRITE_WITHOUT_RESP,
+				GATT_OPT_CHR_VALUE_CB, ATTRIB_WRITE,
+						time_update_control, adapter,
+
+				/* Time Update status */
+				GATT_OPT_CHR_UUID, TIME_UPDATE_STAT_CHR_UUID,
+				GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ,
+				GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
+						time_update_status, adapter,
+
+				GATT_OPT_INVALID);
+}
+
+int time_server_init(struct btd_adapter *adapter)
+{
+	const char *path = adapter_get_path(adapter);
+
+	DBG("path %s", path);
+
+	if (!register_current_time_service(adapter)) {
+		error("Current Time Service could not be registered");
+		return -EIO;
+	}
+
+	if (!register_ref_time_update_service(adapter)) {
+		error("Reference Time Update Service could not be registered");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+void time_server_exit(struct btd_adapter *adapter)
+{
+	const char *path = adapter_get_path(adapter);
+
+	DBG("path %s", path);
+}
diff --git a/profiles/time/server.h b/profiles/time/server.h
new file mode 100644
index 0000000..c7b997d
--- /dev/null
+++ b/profiles/time/server.h
@@ -0,0 +1,45 @@
+/*
+ *
+ *  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
+ *
+ */
+
+enum {
+	UPDATE_RESULT_SUCCESSFUL = 0,
+	UPDATE_RESULT_CANCELED = 1,
+	UPDATE_RESULT_NO_CONN = 2,
+	UPDATE_RESULT_ERROR = 3,
+	UPDATE_RESULT_TIMEOUT = 4,
+	UPDATE_RESULT_NOT_ATTEMPTED = 5,
+};
+
+enum {
+	UPDATE_STATE_IDLE = 0,
+	UPDATE_STATE_PENDING = 1,
+};
+
+enum {
+	GET_REFERENCE_UPDATE = 1,
+	CANCEL_REFERENCE_UPDATE = 2,
+};
+
+int time_server_init(struct btd_adapter *adapter);
+void time_server_exit(struct btd_adapter *adapter);
diff --git a/time/main.c b/time/main.c
deleted file mode 100644
index 9ef5bf1..0000000
--- a/time/main.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *
- *  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 <stdint.h>
-#include <glib.h>
-#include <errno.h>
-
-#include "plugin.h"
-#include "hcid.h"
-#include "log.h"
-#include "manager.h"
-
-static int time_init(void)
-{
-	if (!main_opts.gatt_enabled) {
-		DBG("GATT is disabled");
-		return -ENOTSUP;
-	}
-
-	return time_manager_init();
-}
-
-static void time_exit(void)
-{
-	if (!main_opts.gatt_enabled)
-		return;
-
-	time_manager_exit();
-}
-
-BLUETOOTH_PLUGIN_DEFINE(time, VERSION,
-			BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
-			time_init, time_exit)
diff --git a/time/manager.c b/time/manager.c
deleted file mode 100644
index 285c7b1..0000000
--- a/time/manager.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2012  Nokia Corporation
- *  Copyright (C) 2012  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 "adapter.h"
-#include "manager.h"
-#include "server.h"
-
-struct btd_adapter_driver time_server_driver = {
-	.name = "gatt-time-server",
-	.probe = time_server_init,
-	.remove = time_server_exit,
-};
-
-int time_manager_init(void)
-{
-	btd_register_adapter_driver(&time_server_driver);
-
-	return 0;
-}
-
-void time_manager_exit(void)
-{
-	btd_unregister_adapter_driver(&time_server_driver);
-}
diff --git a/time/manager.h b/time/manager.h
deleted file mode 100644
index 74641d6..0000000
--- a/time/manager.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2012  Nokia Corporation
- *  Copyright (C) 2012  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
- *
- */
-
-int time_manager_init(void);
-void time_manager_exit(void);
diff --git a/time/server.c b/time/server.c
deleted file mode 100644
index be6e196..0000000
--- a/time/server.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- *
- *  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 <glib.h>
-#include <time.h>
-#include <errno.h>
-#include <bluetooth/uuid.h>
-#include <adapter.h>
-
-#include "gattrib.h"
-#include "att.h"
-#include "gatt.h"
-#include "att-database.h"
-#include "attrib-server.h"
-#include "gatt-service.h"
-#include "log.h"
-#include "server.h"
-
-#define CURRENT_TIME_SVC_UUID		0x1805
-#define REF_TIME_UPDATE_SVC_UUID	0x1806
-
-#define LOCAL_TIME_INFO_CHR_UUID	0x2A0F
-#define TIME_UPDATE_CTRL_CHR_UUID	0x2A16
-#define TIME_UPDATE_STAT_CHR_UUID	0x2A17
-#define CT_TIME_CHR_UUID		0x2A2B
-
-static int encode_current_time(uint8_t value[10])
-{
-	struct timespec tp;
-	struct tm tm;
-
-	if (clock_gettime(CLOCK_REALTIME, &tp) == -1) {
-		int err = -errno;
-
-		error("clock_gettime: %s", strerror(-err));
-		return err;
-	}
-
-	if (localtime_r(&tp.tv_sec, &tm) == NULL) {
-		error("localtime_r() failed");
-		/* localtime_r() does not set errno */
-		return -EINVAL;
-	}
-
-	att_put_u16(1900 + tm.tm_year, &value[0]); /* Year */
-	value[2] = tm.tm_mon + 1; /* Month */
-	value[3] = tm.tm_mday; /* Day */
-	value[4] = tm.tm_hour; /* Hours */
-	value[5] = tm.tm_min; /* Minutes */
-	value[6] = tm.tm_sec; /* Seconds */
-	value[7] = tm.tm_wday == 0 ? 7 : tm.tm_wday; /* Day of Week */
-	/* From Time Profile spec: "The number of 1/256 fractions of a second."
-	 * In 1s there are 256 fractions, in 1ns there are 256/10^9 fractions.
-	 * To avoid integer overflow, we use the equivalent 1/3906250 ratio. */
-	value[8] = tp.tv_nsec / 3906250; /* Fractions256 */
-	value[9] = 0x00; /* Adjust Reason */
-
-	return 0;
-}
-
-static uint8_t current_time_read(struct attribute *a,
-				 struct btd_device *device, gpointer user_data)
-{
-	struct btd_adapter *adapter = user_data;
-	uint8_t value[10];
-
-	if (encode_current_time(value) < 0)
-		return ATT_ECODE_IO;
-
-	attrib_db_update(adapter, a->handle, NULL, value, sizeof(value), NULL);
-
-	return 0;
-}
-
-static uint8_t local_time_info_read(struct attribute *a,
-				struct btd_device *device, gpointer user_data)
-{
-	struct btd_adapter *adapter = user_data;
-	uint8_t value[2];
-
-	DBG("a=%p", a);
-
-	tzset();
-
-	/* FIXME: POSIX "daylight" variable only indicates whether there is DST
-	 * for the local time or not. The offset is unknown. */
-	value[0] = daylight ? 0xff : 0x00;
-
-	/* Convert POSIX "timezone" (seconds West of GMT) to Time Profile
-	 * format (offset from UTC in number of 15 minutes increments). */
-	value[1] = (uint8_t) (-1 * timezone / (60 * 15));
-
-	attrib_db_update(adapter, a->handle, NULL, value, sizeof(value), NULL);
-
-	return 0;
-}
-
-static gboolean register_current_time_service(struct btd_adapter *adapter)
-{
-	bt_uuid_t uuid;
-
-	bt_uuid16_create(&uuid, CURRENT_TIME_SVC_UUID);
-
-	/* Current Time service */
-	return gatt_service_add(adapter, GATT_PRIM_SVC_UUID, &uuid,
-				/* CT Time characteristic */
-				GATT_OPT_CHR_UUID, CT_TIME_CHR_UUID,
-				GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ |
-							ATT_CHAR_PROPER_NOTIFY,
-				GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
-						current_time_read, adapter,
-
-				/* Local Time Information characteristic */
-				GATT_OPT_CHR_UUID, LOCAL_TIME_INFO_CHR_UUID,
-				GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ,
-				GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
-						local_time_info_read, adapter,
-
-				GATT_OPT_INVALID);
-}
-
-static uint8_t time_update_control(struct attribute *a,
-						struct btd_device *device,
-						gpointer user_data)
-{
-	DBG("handle 0x%04x", a->handle);
-
-	if (a->len != 1)
-		DBG("Invalid control point value size: %d", a->len);
-
-	switch (a->data[0]) {
-	case GET_REFERENCE_UPDATE:
-		DBG("Get Reference Update");
-		break;
-	case CANCEL_REFERENCE_UPDATE:
-		DBG("Cancel Reference Update");
-		break;
-	default:
-		DBG("Unknown command: 0x%02x", a->data[0]);
-	}
-
-	return 0;
-}
-
-static uint8_t time_update_status(struct attribute *a,
-						struct btd_device *device,
-						gpointer user_data)
-{
-	struct btd_adapter *adapter = user_data;
-	uint8_t value[2];
-
-	DBG("handle 0x%04x", a->handle);
-
-	value[0] = UPDATE_STATE_IDLE;
-	value[1] = UPDATE_RESULT_SUCCESSFUL;
-	attrib_db_update(adapter, a->handle, NULL, value, sizeof(value), NULL);
-
-	return 0;
-}
-
-static gboolean register_ref_time_update_service(struct btd_adapter *adapter)
-{
-	bt_uuid_t uuid;
-
-	bt_uuid16_create(&uuid, REF_TIME_UPDATE_SVC_UUID);
-
-	/* Reference Time Update service */
-	return gatt_service_add(adapter, GATT_PRIM_SVC_UUID, &uuid,
-				/* Time Update control point */
-				GATT_OPT_CHR_UUID, TIME_UPDATE_CTRL_CHR_UUID,
-				GATT_OPT_CHR_PROPS,
-					ATT_CHAR_PROPER_WRITE_WITHOUT_RESP,
-				GATT_OPT_CHR_VALUE_CB, ATTRIB_WRITE,
-						time_update_control, adapter,
-
-				/* Time Update status */
-				GATT_OPT_CHR_UUID, TIME_UPDATE_STAT_CHR_UUID,
-				GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ,
-				GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
-						time_update_status, adapter,
-
-				GATT_OPT_INVALID);
-}
-
-int time_server_init(struct btd_adapter *adapter)
-{
-	const char *path = adapter_get_path(adapter);
-
-	DBG("path %s", path);
-
-	if (!register_current_time_service(adapter)) {
-		error("Current Time Service could not be registered");
-		return -EIO;
-	}
-
-	if (!register_ref_time_update_service(adapter)) {
-		error("Reference Time Update Service could not be registered");
-		return -EIO;
-	}
-
-	return 0;
-}
-
-void time_server_exit(struct btd_adapter *adapter)
-{
-	const char *path = adapter_get_path(adapter);
-
-	DBG("path %s", path);
-}
diff --git a/time/server.h b/time/server.h
deleted file mode 100644
index c7b997d..0000000
--- a/time/server.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *
- *  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
- *
- */
-
-enum {
-	UPDATE_RESULT_SUCCESSFUL = 0,
-	UPDATE_RESULT_CANCELED = 1,
-	UPDATE_RESULT_NO_CONN = 2,
-	UPDATE_RESULT_ERROR = 3,
-	UPDATE_RESULT_TIMEOUT = 4,
-	UPDATE_RESULT_NOT_ATTEMPTED = 5,
-};
-
-enum {
-	UPDATE_STATE_IDLE = 0,
-	UPDATE_STATE_PENDING = 1,
-};
-
-enum {
-	GET_REFERENCE_UPDATE = 1,
-	CANCEL_REFERENCE_UPDATE = 2,
-};
-
-int time_server_init(struct btd_adapter *adapter);
-void time_server_exit(struct btd_adapter *adapter);
-- 
1.7.10.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 12/14] cups: move it to profiles folder
  2012-07-09 21:10 [PATCH 01/14] input: remove unneeded header inclusions Gustavo Padovan
                   ` (5 preceding siblings ...)
  2012-07-09 21:10 ` [PATCH 08/14] time: " Gustavo Padovan
@ 2012-07-09 21:10 ` Gustavo Padovan
  2012-07-09 21:10 ` [PATCH 14/14] plugins: remove unmaintained plugins Gustavo Padovan
  7 siblings, 0 replies; 10+ messages in thread
From: Gustavo Padovan @ 2012-07-09 21:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

---
 Makefile.tools       |   12 +-
 cups/cups.h          |   38 ---
 cups/hcrp.c          |  368 ---------------------
 cups/main.c          |  896 --------------------------------------------------
 cups/sdp.c           |  119 -------
 cups/spp.c           |  118 -------
 profiles/cups/cups.h |   38 +++
 profiles/cups/hcrp.c |  368 +++++++++++++++++++++
 profiles/cups/main.c |  896 ++++++++++++++++++++++++++++++++++++++++++++++++++
 profiles/cups/sdp.c  |  119 +++++++
 profiles/cups/spp.c  |  118 +++++++
 11 files changed, 1547 insertions(+), 1543 deletions(-)
 delete mode 100644 cups/cups.h
 delete mode 100644 cups/hcrp.c
 delete mode 100644 cups/main.c
 delete mode 100644 cups/sdp.c
 delete mode 100644 cups/spp.c
 create mode 100644 profiles/cups/cups.h
 create mode 100644 profiles/cups/hcrp.c
 create mode 100644 profiles/cups/main.c
 create mode 100644 profiles/cups/sdp.c
 create mode 100644 profiles/cups/spp.c

diff --git a/Makefile.tools b/Makefile.tools
index 56839b7..fccac2d 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -148,12 +148,16 @@ EXTRA_DIST += tools/dfubabel.1 tools/avctrl.8
 if CUPS
 cupsdir = $(libdir)/cups/backend
 
-cups_PROGRAMS = cups/bluetooth
+cups_PROGRAMS = profiles/cups/bluetooth
 
-cups_bluetooth_SOURCES = $(gdbus_sources) cups/main.c cups/cups.h \
-					cups/sdp.c cups/spp.c cups/hcrp.c
+profiles_cups_bluetooth_SOURCES = $(gdbus_sources) profiles/cups/main.c \
+					profiles/cups/cups.h \
+					profiles/cups/sdp.c \
+					profiles/cups/spp.c \
+					profiles/cups/hcrp.c
 
-cups_bluetooth_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ lib/libbluetooth-private.la
+profiles_cups_bluetooth_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ \
+				lib/libbluetooth-private.la
 endif
 
 
diff --git a/cups/cups.h b/cups/cups.h
deleted file mode 100644
index f4e0c01..0000000
--- a/cups/cups.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2003-2010  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
- *
- */
-
-enum {					/**** Backend exit codes ****/
-	CUPS_BACKEND_OK = 0,		/* Job completed successfully */
-	CUPS_BACKEND_FAILED = 1,	/* Job failed, use error-policy */
-	CUPS_BACKEND_AUTH_REQUIRED = 2,	/* Job failed, authentication required */
-	CUPS_BACKEND_HOLD = 3,		/* Job failed, hold job */
-	CUPS_BACKEND_STOP = 4,		/* Job failed, stop queue */
-	CUPS_BACKEND_CANCEL = 5,	/* Job failed, cancel job */
-	CUPS_BACKEND_RETRY = 6,		/* Failure requires us to retry (BlueZ specific) */
-};
-
-int sdp_search_spp(sdp_session_t *sdp, uint8_t *channel);
-int sdp_search_hcrp(sdp_session_t *sdp, unsigned short *ctrl_psm, unsigned short *data_psm);
-
-int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies, const char *cups_class);
-int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned short data_psm, int fd, int copies, const char *cups_class);
diff --git a/cups/hcrp.c b/cups/hcrp.c
deleted file mode 100644
index a93dda0..0000000
--- a/cups/hcrp.c
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2003-2010  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 <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/socket.h>
-
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/l2cap.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
-
-#include <netinet/in.h>
-
-#include "cups.h"
-
-#define HCRP_PDU_CREDIT_GRANT		0x0001
-#define HCRP_PDU_CREDIT_REQUEST		0x0002
-#define HCRP_PDU_GET_LPT_STATUS		0x0005
-
-#define HCRP_STATUS_FEATURE_UNSUPPORTED	0x0000
-#define HCRP_STATUS_SUCCESS		0x0001
-#define HCRP_STATUS_CREDIT_SYNC_ERROR	0x0002
-#define HCRP_STATUS_GENERIC_FAILURE	0xffff
-
-struct hcrp_pdu_hdr {
-	uint16_t pid;
-	uint16_t tid;
-	uint16_t plen;
-} __attribute__ ((packed));
-#define HCRP_PDU_HDR_SIZE 6
-
-struct hcrp_credit_grant_cp {
-	uint32_t credit;
-} __attribute__ ((packed));
-#define HCRP_CREDIT_GRANT_CP_SIZE 4
-
-struct hcrp_credit_grant_rp {
-	uint16_t status;
-} __attribute__ ((packed));
-#define HCRP_CREDIT_GRANT_RP_SIZE 2
-
-struct hcrp_credit_request_rp {
-	uint16_t status;
-	uint32_t credit;
-} __attribute__ ((packed));
-#define HCRP_CREDIT_REQUEST_RP_SIZE 6
-
-struct hcrp_get_lpt_status_rp {
-	uint16_t status;
-	uint8_t  lpt_status;
-} __attribute__ ((packed));
-#define HCRP_GET_LPT_STATUS_RP_SIZE 3
-
-static int hcrp_credit_grant(int sk, uint16_t tid, uint32_t credit)
-{
-	struct hcrp_pdu_hdr hdr;
-	struct hcrp_credit_grant_cp cp;
-	struct hcrp_credit_grant_rp rp;
-	unsigned char buf[128];
-	int len;
-
-	hdr.pid = htons(HCRP_PDU_CREDIT_GRANT);
-	hdr.tid = htons(tid);
-	hdr.plen = htons(HCRP_CREDIT_GRANT_CP_SIZE);
-	cp.credit = credit;
-	memcpy(buf, &hdr, HCRP_PDU_HDR_SIZE);
-	memcpy(buf + HCRP_PDU_HDR_SIZE, &cp, HCRP_CREDIT_GRANT_CP_SIZE);
-	len = write(sk, buf, HCRP_PDU_HDR_SIZE + HCRP_CREDIT_GRANT_CP_SIZE);
-	if (len < 0)
-		return len;
-
-	len = read(sk, buf, sizeof(buf));
-	if (len < 0)
-		return len;
-
-	memcpy(&hdr, buf, HCRP_PDU_HDR_SIZE);
-	memcpy(&rp, buf + HCRP_PDU_HDR_SIZE, HCRP_CREDIT_GRANT_RP_SIZE);
-
-	if (ntohs(rp.status) != HCRP_STATUS_SUCCESS) {
-		errno = EIO;
-		return -1;
-	}
-
-	return 0;
-}
-
-static int hcrp_credit_request(int sk, uint16_t tid, uint32_t *credit)
-{
-	struct hcrp_pdu_hdr hdr;
-	struct hcrp_credit_request_rp rp;
-	unsigned char buf[128];
-	int len;
-
-	hdr.pid = htons(HCRP_PDU_CREDIT_REQUEST);
-	hdr.tid = htons(tid);
-	hdr.plen = htons(0);
-	memcpy(buf, &hdr, HCRP_PDU_HDR_SIZE);
-	len = write(sk, buf, HCRP_PDU_HDR_SIZE);
-	if (len < 0)
-		return len;
-
-	len = read(sk, buf, sizeof(buf));
-	if (len < 0)
-		return len;
-
-	memcpy(&hdr, buf, HCRP_PDU_HDR_SIZE);
-	memcpy(&rp, buf + HCRP_PDU_HDR_SIZE, HCRP_CREDIT_REQUEST_RP_SIZE);
-
-	if (ntohs(rp.status) != HCRP_STATUS_SUCCESS) {
-		errno = EIO;
-		return -1;
-	}
-
-	if (credit)
-		*credit = ntohl(rp.credit);
-
-	return 0;
-}
-
-static int hcrp_get_lpt_status(int sk, uint16_t tid, uint8_t *lpt_status)
-{
-	struct hcrp_pdu_hdr hdr;
-	struct hcrp_get_lpt_status_rp rp;
-	unsigned char buf[128];
-	int len;
-
-	hdr.pid = htons(HCRP_PDU_GET_LPT_STATUS);
-	hdr.tid = htons(tid);
-	hdr.plen = htons(0);
-	memcpy(buf, &hdr, HCRP_PDU_HDR_SIZE);
-	len = write(sk, buf, HCRP_PDU_HDR_SIZE);
-	if (len < 0)
-		return len;
-
-	len = read(sk, buf, sizeof(buf));
-	if (len < 0)
-		return len;
-
-	memcpy(&hdr, buf, HCRP_PDU_HDR_SIZE);
-	memcpy(&rp, buf + HCRP_PDU_HDR_SIZE, HCRP_GET_LPT_STATUS_RP_SIZE);
-
-	if (ntohs(rp.status) != HCRP_STATUS_SUCCESS) {
-		errno = EIO;
-		return -1;
-	}
-
-	if (lpt_status)
-		*lpt_status = rp.lpt_status;
-
-	return 0;
-}
-
-static inline int hcrp_get_next_tid(int tid)
-{
-	if (tid > 0xf000)
-		return 0;
-	else
-		return tid + 1;
-}
-
-int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned short data_psm, int fd, int copies, const char *cups_class)
-{
-	struct sockaddr_l2 addr;
-	struct l2cap_options opts;
-	socklen_t size;
-	unsigned char buf[2048];
-	int i, ctrl_sk, data_sk, count, len, timeout = 0;
-	unsigned int mtu;
-	uint8_t status;
-	uint16_t tid = 0;
-	uint32_t tmp, credit = 0;
-
-	if ((ctrl_sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) {
-		perror("ERROR: Can't create socket");
-		if (cups_class)
-			return CUPS_BACKEND_FAILED;
-		else
-			return CUPS_BACKEND_RETRY;
-	}
-
-	memset(&addr, 0, sizeof(addr));
-	addr.l2_family = AF_BLUETOOTH;
-	bacpy(&addr.l2_bdaddr, src);
-
-	if (bind(ctrl_sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-		perror("ERROR: Can't bind socket");
-		close(ctrl_sk);
-		if (cups_class)
-			return CUPS_BACKEND_FAILED;
-		else
-			return CUPS_BACKEND_RETRY;
-	}
-
-	memset(&addr, 0, sizeof(addr));
-	addr.l2_family = AF_BLUETOOTH;
-	bacpy(&addr.l2_bdaddr, dst);
-	addr.l2_psm = htobs(ctrl_psm);
-
-	if (connect(ctrl_sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-		perror("ERROR: Can't connect to device");
-		close(ctrl_sk);
-		if (cups_class)
-			return CUPS_BACKEND_FAILED;
-		else
-			return CUPS_BACKEND_RETRY;
-	}
-
-	if ((data_sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) {
-		perror("ERROR: Can't create socket");
-		close(ctrl_sk);
-		if (cups_class)
-			return CUPS_BACKEND_FAILED;
-		else
-			return CUPS_BACKEND_RETRY;
-	}
-
-	memset(&addr, 0, sizeof(addr));
-	addr.l2_family = AF_BLUETOOTH;
-	bacpy(&addr.l2_bdaddr, src);
-
-	if (bind(data_sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-		perror("ERROR: Can't bind socket");
-		close(data_sk);
-		close(ctrl_sk);
-		if (cups_class)
-			return CUPS_BACKEND_FAILED;
-		else
-			return CUPS_BACKEND_RETRY;
-	}
-
-	memset(&addr, 0, sizeof(addr));
-	addr.l2_family = AF_BLUETOOTH;
-	bacpy(&addr.l2_bdaddr, dst);
-	addr.l2_psm = htobs(data_psm);
-
-	if (connect(data_sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-		perror("ERROR: Can't connect to device");
-		close(data_sk);
-		close(ctrl_sk);
-		if (cups_class)
-			return CUPS_BACKEND_FAILED;
-		else
-			return CUPS_BACKEND_RETRY;
-	}
-
-	fputs("STATE: -connecting-to-device\n", stderr);
-
-	memset(&opts, 0, sizeof(opts));
-	size = sizeof(opts);
-
-	if (getsockopt(data_sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &size) < 0) {
-		perror("ERROR: Can't get socket options");
-		close(data_sk);
-		close(ctrl_sk);
-		if (cups_class)
-			return CUPS_BACKEND_FAILED;
-		else
-			return CUPS_BACKEND_RETRY;
-	}
-
-	mtu = opts.omtu;
-
-	/* Ignore SIGTERM signals if printing from stdin */
-	if (fd == 0) {
-#ifdef HAVE_SIGSET
-		sigset(SIGTERM, SIG_IGN);
-#elif defined(HAVE_SIGACTION)
-		memset(&action, 0, sizeof(action));
-		sigemptyset(&action.sa_mask);
-		action.sa_handler = SIG_IGN;
-		sigaction(SIGTERM, &action, NULL);
-#else
-		signal(SIGTERM, SIG_IGN);
-#endif /* HAVE_SIGSET */
-	}
-
-	tid = hcrp_get_next_tid(tid);
-	if (hcrp_credit_grant(ctrl_sk, tid, 0) < 0) {
-		fprintf(stderr, "ERROR: Can't grant initial credits\n");
-		close(data_sk);
-		close(ctrl_sk);
-		if (cups_class)
-			return CUPS_BACKEND_FAILED;
-		else
-			return CUPS_BACKEND_RETRY;
-	}
-
-	for (i = 0; i < copies; i++) {
-
-		if (fd != 0) {
-			fprintf(stderr, "PAGE: 1 1\n");
-			lseek(fd, 0, SEEK_SET);
-		}
-
-		while (1) {
-			if (credit < mtu) {
-				tid = hcrp_get_next_tid(tid);
-				if (!hcrp_credit_request(ctrl_sk, tid, &tmp)) {
-					credit += tmp;
-					timeout = 0;
-				}
-			}
-
-			if (!credit) {
-				if (timeout++ > 300) {
-					tid = hcrp_get_next_tid(tid);
-					if (!hcrp_get_lpt_status(ctrl_sk, tid, &status))
-						fprintf(stderr, "ERROR: LPT status 0x%02x\n", status);
-					break;
-				}
-
-				sleep(1);
-				continue;
-			}
-
-			count = read(fd, buf, (credit > mtu) ? mtu : credit);
-			if (count <= 0)
-				break;
-
-			len = write(data_sk, buf, count);
-			if (len < 0) {
-				perror("ERROR: Error writing to device");
-				close(data_sk);
-				close(ctrl_sk);
-				return CUPS_BACKEND_FAILED;
-			}
-
-			if (len != count)
-				fprintf(stderr, "ERROR: Can't send complete data\n");
-
-			credit -= len;
-		}
-
-	}
-
-	close(data_sk);
-	close(ctrl_sk);
-
-	return CUPS_BACKEND_OK;
-}
diff --git a/cups/main.c b/cups/main.c
deleted file mode 100644
index a884c6e..0000000
--- a/cups/main.c
+++ /dev/null
@@ -1,896 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2003-2010  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 <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/socket.h>
-#include <glib.h>
-
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
-
-#include <gdbus.h>
-
-#include "cups.h"
-
-struct cups_device {
-	char *bdaddr;
-	char *name;
-	char *id;
-};
-
-static GSList *device_list = NULL;
-static GMainLoop *loop = NULL;
-static DBusConnection *conn = NULL;
-static gboolean doing_disco = FALSE;
-
-#define ATTRID_1284ID 0x0300
-
-struct context_data {
-	gboolean found;
-	char *id;
-};
-
-static void element_start(GMarkupParseContext *context,
-				const gchar *element_name,
-				const gchar **attribute_names,
-				const gchar **attribute_values,
-				gpointer user_data, GError **err)
-{
-	struct context_data *ctx_data = user_data;
-
-	if (!strcmp(element_name, "record"))
-		return;
-
-	if (!strcmp(element_name, "attribute")) {
-		int i;
-		for (i = 0; attribute_names[i]; i++) {
-			if (strcmp(attribute_names[i], "id") != 0)
-				continue;
-			if (strtol(attribute_values[i], 0, 0) == ATTRID_1284ID)
-				ctx_data->found = TRUE;
-			break;
-		}
-		return;
-	}
-
-	if (ctx_data->found  && !strcmp(element_name, "text")) {
-		int i;
-		for (i = 0; attribute_names[i]; i++) {
-			if (!strcmp(attribute_names[i], "value")) {
-				ctx_data->id = g_strdup(attribute_values[i] + 2);
-				ctx_data->found = FALSE;
-			}
-		}
-	}
-}
-
-static GMarkupParser parser = {
-	element_start, NULL, NULL, NULL, NULL
-};
-
-static char *sdp_xml_parse_record(const char *data)
-{
-	GMarkupParseContext *ctx;
-	struct context_data ctx_data;
-	int size;
-
-	size = strlen(data);
-	ctx_data.found = FALSE;
-	ctx_data.id = NULL;
-	ctx = g_markup_parse_context_new(&parser, 0, &ctx_data, NULL);
-
-	if (g_markup_parse_context_parse(ctx, data, size, NULL) == FALSE) {
-		g_markup_parse_context_free(ctx);
-		g_free(ctx_data.id);
-		return NULL;
-	}
-
-	g_markup_parse_context_free(ctx);
-
-	return ctx_data.id;
-}
-
-static char *device_get_ieee1284_id(const char *adapter, const char *device)
-{
-	DBusMessage *message, *reply;
-	DBusMessageIter iter, reply_iter;
-	DBusMessageIter reply_iter_entry;
-	const char *hcr_print = "00001126-0000-1000-8000-00805f9b34fb";
-	const char *xml;
-	char *id = NULL;
-
-	/* Look for the service handle of the HCRP service */
-	message = dbus_message_new_method_call("org.bluez", device,
-						"org.bluez.Device",
-						"DiscoverServices");
-	dbus_message_iter_init_append(message, &iter);
-	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &hcr_print);
-
-	reply = dbus_connection_send_with_reply_and_block(conn,
-							message, -1, NULL);
-
-	dbus_message_unref(message);
-
-	if (!reply)
-		return NULL;
-
-	dbus_message_iter_init(reply, &reply_iter);
-
-	if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) {
-		dbus_message_unref(reply);
-		return NULL;
-	}
-
-	dbus_message_iter_recurse(&reply_iter, &reply_iter_entry);
-
-	/* Hopefully we only get one handle, or take a punt */
-	while (dbus_message_iter_get_arg_type(&reply_iter_entry) ==
-							DBUS_TYPE_DICT_ENTRY) {
-		guint32 key;
-		DBusMessageIter dict_entry;
-
-		dbus_message_iter_recurse(&reply_iter_entry, &dict_entry);
-
-		/* Key ? */
-		dbus_message_iter_get_basic(&dict_entry, &key);
-		if (!key) {
-			dbus_message_iter_next(&reply_iter_entry);
-			continue;
-		}
-
-		/* Try to get the value */
-		if (!dbus_message_iter_next(&dict_entry)) {
-			dbus_message_iter_next(&reply_iter_entry);
-			continue;
-		}
-
-		dbus_message_iter_get_basic(&dict_entry, &xml);
-
-		id = sdp_xml_parse_record(xml);
-		if (id != NULL)
-			break;
-		dbus_message_iter_next(&reply_iter_entry);
-	}
-
-	dbus_message_unref(reply);
-
-	return id;
-}
-
-static void print_printer_details(const char *name, const char *bdaddr,
-								const char *id)
-{
-	char *uri, *escaped;
-
-	escaped = g_strdelimit(g_strdup(name), "\"", '\'');
-	uri = g_strdup_printf("bluetooth://%c%c%c%c%c%c%c%c%c%c%c%c",
-				bdaddr[0], bdaddr[1],
-				bdaddr[3], bdaddr[4],
-				bdaddr[6], bdaddr[7],
-				bdaddr[9], bdaddr[10],
-				bdaddr[12], bdaddr[13],
-				bdaddr[15], bdaddr[16]);
-	printf("direct %s \"%s\" \"%s (Bluetooth)\"", uri, escaped, escaped);
-	if (id != NULL)
-		printf(" \"%s\"\n", id);
-	else
-		printf("\n");
-	g_free(escaped);
-	g_free(uri);
-}
-
-static void add_device_to_list(const char *name, const char *bdaddr,
-								const char *id)
-{
-	struct cups_device *device;
-	GSList *l;
-
-	/* Look for the device in the list */
-	for (l = device_list; l != NULL; l = l->next) {
-		device = (struct cups_device *) l->data;
-
-		if (strcmp(device->bdaddr, bdaddr) == 0) {
-			if (device->name != name) {
-				g_free(device->name);
-				device->name = g_strdup(name);
-			}
-			g_free(device->id);
-			device->id = g_strdup(id);
-			return;
-		}
-	}
-
-	/* Or add it to the list if it's not there */
-	device = g_new0(struct cups_device, 1);
-	device->bdaddr = g_strdup(bdaddr);
-	device->name = g_strdup(name);
-	device->id = g_strdup(id);
-
-	device_list = g_slist_prepend(device_list, device);
-	print_printer_details(device->name, device->bdaddr, device->id);
-}
-
-static gboolean parse_device_properties(DBusMessageIter *reply_iter,
-						char **name, char **bdaddr)
-{
-	guint32 class = 0;
-	DBusMessageIter reply_iter_entry;
-
-	if (dbus_message_iter_get_arg_type(reply_iter) != DBUS_TYPE_ARRAY)
-		return FALSE;
-
-	dbus_message_iter_recurse(reply_iter, &reply_iter_entry);
-
-	while (dbus_message_iter_get_arg_type(&reply_iter_entry) ==
-							DBUS_TYPE_DICT_ENTRY) {
-		const char *key;
-		DBusMessageIter dict_entry, iter_dict_val;
-
-		dbus_message_iter_recurse(&reply_iter_entry, &dict_entry);
-
-		/* Key == Class ? */
-		dbus_message_iter_get_basic(&dict_entry, &key);
-		if (!key) {
-			dbus_message_iter_next(&reply_iter_entry);
-			continue;
-		}
-
-		if (strcmp(key, "Class") != 0 &&
-				strcmp(key, "Alias") != 0 &&
-				strcmp(key, "Address") != 0) {
-			dbus_message_iter_next(&reply_iter_entry);
-			continue;
-		}
-
-		/* Try to get the value */
-		if (!dbus_message_iter_next(&dict_entry)) {
-			dbus_message_iter_next(&reply_iter_entry);
-			continue;
-		}
-		dbus_message_iter_recurse(&dict_entry, &iter_dict_val);
-		if (strcmp(key, "Class") == 0) {
-			dbus_message_iter_get_basic(&iter_dict_val, &class);
-		} else {
-			const char *value;
-			dbus_message_iter_get_basic(&iter_dict_val, &value);
-			if (strcmp(key, "Alias") == 0) {
-				*name = g_strdup(value);
-			} else if (bdaddr) {
-				*bdaddr = g_strdup(value);
-			}
-		}
-		dbus_message_iter_next(&reply_iter_entry);
-	}
-
-	if (class == 0)
-		return FALSE;
-	if (((class & 0x1f00) >> 8) == 0x06 && (class & 0x80))
-		return TRUE;
-
-	return FALSE;
-}
-
-static gboolean device_is_printer(const char *adapter, const char *device_path, char **name, char **bdaddr)
-{
-	DBusMessage *message, *reply;
-	DBusMessageIter reply_iter;
-	gboolean retval;
-
-	message = dbus_message_new_method_call("org.bluez", device_path,
-							"org.bluez.Device",
-							"GetProperties");
-
-	reply = dbus_connection_send_with_reply_and_block(conn,
-							message, -1, NULL);
-
-	dbus_message_unref(message);
-
-	if (!reply)
-		return FALSE;
-
-	dbus_message_iter_init(reply, &reply_iter);
-
-	retval = parse_device_properties(&reply_iter, name, bdaddr);
-
-	dbus_message_unref(reply);
-
-	return retval;
-}
-
-static void remote_device_found(const char *adapter, const char *bdaddr,
-							const char *name)
-{
-	DBusMessage *message, *reply, *adapter_reply;
-	DBusMessageIter iter;
-	char *object_path = NULL;
-	char *id;
-
-	adapter_reply = NULL;
-
-	if (adapter == NULL) {
-		message = dbus_message_new_method_call("org.bluez", "/",
-							"org.bluez.Manager",
-							"DefaultAdapter");
-
-		adapter_reply = dbus_connection_send_with_reply_and_block(conn,
-							message, -1, NULL);
-
-		dbus_message_unref(message);
-
-		if (!adapter_reply)
-			return;
-
-		if (dbus_message_get_args(adapter_reply, NULL,
-					DBUS_TYPE_OBJECT_PATH, &adapter,
-					DBUS_TYPE_INVALID) == FALSE) {
-			dbus_message_unref(adapter_reply);
-			return;
-		}
-	}
-
-	message = dbus_message_new_method_call("org.bluez", adapter,
-							"org.bluez.Adapter",
-							"FindDevice");
-	dbus_message_iter_init_append(message, &iter);
-	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);
-
-	if (adapter_reply != NULL)
-		dbus_message_unref(adapter_reply);
-
-	reply = dbus_connection_send_with_reply_and_block(conn,
-							message, -1, NULL);
-
-	dbus_message_unref(message);
-
-	if (!reply) {
-		message = dbus_message_new_method_call("org.bluez", adapter,
-							"org.bluez.Adapter",
-							"CreateDevice");
-		dbus_message_iter_init_append(message, &iter);
-		dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);
-
-		reply = dbus_connection_send_with_reply_and_block(conn,
-							message, -1, NULL);
-
-		dbus_message_unref(message);
-
-		if (!reply)
-			return;
-	}
-
-	if (dbus_message_get_args(reply, NULL,
-					DBUS_TYPE_OBJECT_PATH, &object_path,
-					DBUS_TYPE_INVALID) == FALSE) {
-		dbus_message_unref(reply);
-		return;
-	}
-
-	id = device_get_ieee1284_id(adapter, object_path);
-	add_device_to_list(name, bdaddr, id);
-	g_free(id);
-
-	dbus_message_unref(reply);
-}
-
-static void discovery_completed(void)
-{
-	g_slist_free(device_list);
-	device_list = NULL;
-
-	g_main_loop_quit(loop);
-}
-
-static void remote_device_disappeared(const char *bdaddr)
-{
-	GSList *l;
-
-	for (l = device_list; l != NULL; l = l->next) {
-		struct cups_device *device = l->data;
-
-		if (strcmp(device->bdaddr, bdaddr) == 0) {
-			g_free(device->name);
-			g_free(device->bdaddr);
-			g_free(device);
-			device_list = g_slist_delete_link(device_list, l);
-			return;
-		}
-	}
-}
-
-static gboolean list_known_printers(const char *adapter)
-{
-	DBusMessageIter reply_iter, iter_array;
-	DBusError error;
-	DBusMessage *message, *reply;
-
-	message = dbus_message_new_method_call("org.bluez", adapter,
-						"org.bluez.Adapter",
-						"ListDevices");
-	if (message == NULL)
-		return FALSE;
-
-	dbus_error_init(&error);
-	reply = dbus_connection_send_with_reply_and_block(conn, message,
-								-1, &error);
-
-	dbus_message_unref(message);
-
-	if (dbus_error_is_set(&error))
-		return FALSE;
-
-	dbus_message_iter_init(reply, &reply_iter);
-	if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) {
-		dbus_message_unref(reply);
-		return FALSE;
-	}
-
-	dbus_message_iter_recurse(&reply_iter, &iter_array);
-	while (dbus_message_iter_get_arg_type(&iter_array) ==
-						DBUS_TYPE_OBJECT_PATH) {
-		const char *object_path;
-		char *name = NULL;
-		char *bdaddr = NULL;
-
-		dbus_message_iter_get_basic(&iter_array, &object_path);
-		if (device_is_printer(adapter, object_path, &name, &bdaddr)) {
-			char *id;
-
-			id = device_get_ieee1284_id(adapter, object_path);
-			add_device_to_list(name, bdaddr, id);
-			g_free(id);
-		}
-		g_free(name);
-		g_free(bdaddr);
-		dbus_message_iter_next(&iter_array);
-	}
-
-	dbus_message_unref(reply);
-
-	return FALSE;
-}
-
-static DBusHandlerResult filter_func(DBusConnection *connection,
-					DBusMessage *message, void *user_data)
-{
-	if (dbus_message_is_signal(message, "org.bluez.Adapter",
-						"DeviceFound")) {
-		const char *adapter, *bdaddr;
-		char *name;
-		DBusMessageIter iter;
-
-		dbus_message_iter_init(message, &iter);
-		dbus_message_iter_get_basic(&iter, &bdaddr);
-		dbus_message_iter_next(&iter);
-
-		adapter = dbus_message_get_path(message);
-		if (parse_device_properties(&iter, &name, NULL))
-			remote_device_found(adapter, bdaddr, name);
-		g_free (name);
-	} else if (dbus_message_is_signal(message, "org.bluez.Adapter",
-						"DeviceDisappeared")) {
-		const char *bdaddr;
-
-		dbus_message_get_args(message, NULL,
-					DBUS_TYPE_STRING, &bdaddr,
-					DBUS_TYPE_INVALID);
-		remote_device_disappeared(bdaddr);
-	} else if (dbus_message_is_signal(message, "org.bluez.Adapter",
-						"PropertyChanged")) {
-		DBusMessageIter iter, value_iter;
-		const char *name;
-		gboolean discovering;
-
-		dbus_message_iter_init(message, &iter);
-		dbus_message_iter_get_basic(&iter, &name);
-		if (name == NULL || strcmp(name, "Discovering") != 0)
-			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-		dbus_message_iter_next(&iter);
-		dbus_message_iter_recurse(&iter, &value_iter);
-		dbus_message_iter_get_basic(&value_iter, &discovering);
-
-		if (discovering == FALSE && doing_disco) {
-			doing_disco = FALSE;
-			discovery_completed();
-		}
-	}
-
-	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-static gboolean list_printers(void)
-{
-	/* 1. Connect to the bus
-	 * 2. Get the manager
-	 * 3. Get the default adapter
-	 * 4. Get a list of devices
-	 * 5. Get the class of each device
-	 * 6. Print the details from each printer device
-	 */
-	DBusError error;
-	dbus_bool_t hcid_exists;
-	DBusMessage *reply, *message;
-	DBusMessageIter reply_iter;
-	char *adapter, *match;
-
-	conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
-	if (conn == NULL)
-		return TRUE;
-
-	dbus_error_init(&error);
-	hcid_exists = dbus_bus_name_has_owner(conn, "org.bluez", &error);
-	if (dbus_error_is_set(&error))
-		return TRUE;
-
-	if (!hcid_exists)
-		return TRUE;
-
-	/* Get the default adapter */
-	message = dbus_message_new_method_call("org.bluez", "/",
-						"org.bluez.Manager",
-						"DefaultAdapter");
-	if (message == NULL) {
-		dbus_connection_unref(conn);
-		return FALSE;
-	}
-
-	reply = dbus_connection_send_with_reply_and_block(conn,
-							message, -1, &error);
-
-	dbus_message_unref(message);
-
-	if (dbus_error_is_set(&error)) {
-		dbus_connection_unref(conn);
-		/* No adapter */
-		return TRUE;
-	}
-
-	dbus_message_iter_init(reply, &reply_iter);
-	if (dbus_message_iter_get_arg_type(&reply_iter) !=
-						DBUS_TYPE_OBJECT_PATH) {
-		dbus_message_unref(reply);
-		dbus_connection_unref(conn);
-		return FALSE;
-	}
-
-	dbus_message_iter_get_basic(&reply_iter, &adapter);
-	adapter = g_strdup(adapter);
-	dbus_message_unref(reply);
-
-	if (!dbus_connection_add_filter(conn, filter_func, adapter, g_free)) {
-		g_free(adapter);
-		dbus_connection_unref(conn);
-		return FALSE;
-	}
-
-#define MATCH_FORMAT				\
-	"type='signal',"			\
-	"interface='org.bluez.Adapter',"	\
-	"sender='org.bluez',"			\
-	"path='%s'"
-
-	match = g_strdup_printf(MATCH_FORMAT, adapter);
-	dbus_bus_add_match(conn, match, &error);
-	g_free(match);
-
-	/* Add the the recent devices */
-	list_known_printers(adapter);
-
-	doing_disco = TRUE;
-	message = dbus_message_new_method_call("org.bluez", adapter,
-					"org.bluez.Adapter",
-					"StartDiscovery");
-
-	if (!dbus_connection_send_with_reply(conn, message, NULL, -1)) {
-		dbus_message_unref(message);
-		dbus_connection_unref(conn);
-		g_free(adapter);
-		return FALSE;
-	}
-	dbus_message_unref(message);
-
-	loop = g_main_loop_new(NULL, TRUE);
-	g_main_loop_run(loop);
-
-	g_free(adapter);
-	dbus_connection_unref(conn);
-
-	return TRUE;
-}
-
-static gboolean print_ieee1284(const char *bdaddr)
-{
-	DBusMessage *message, *reply, *adapter_reply;
-	DBusMessageIter iter;
-	char *object_path = NULL;
-	char *adapter;
-	char *id;
-
-	adapter_reply = NULL;
-
-	conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
-	if (conn == NULL)
-		return FALSE;
-
-	message = dbus_message_new_method_call("org.bluez", "/",
-			"org.bluez.Manager",
-			"DefaultAdapter");
-
-	adapter_reply = dbus_connection_send_with_reply_and_block(conn,
-			message, -1, NULL);
-
-	dbus_message_unref(message);
-
-	if (!adapter_reply)
-		return FALSE;
-
-	if (dbus_message_get_args(adapter_reply, NULL,
-			DBUS_TYPE_OBJECT_PATH, &adapter,
-			DBUS_TYPE_INVALID) == FALSE) {
-		dbus_message_unref(adapter_reply);
-		return FALSE;
-	}
-
-	message = dbus_message_new_method_call("org.bluez", adapter,
-			"org.bluez.Adapter",
-			"FindDevice");
-	dbus_message_iter_init_append(message, &iter);
-	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);
-
-	if (adapter_reply != NULL)
-		dbus_message_unref(adapter_reply);
-
-	reply = dbus_connection_send_with_reply_and_block(conn,
-			message, -1, NULL);
-
-	dbus_message_unref(message);
-
-	if (!reply) {
-		message = dbus_message_new_method_call("org.bluez", adapter,
-				"org.bluez.Adapter",
-				"CreateDevice");
-		dbus_message_iter_init_append(message, &iter);
-		dbus_message_iter_append_basic(&iter,
-				DBUS_TYPE_STRING, &bdaddr);
-
-		reply = dbus_connection_send_with_reply_and_block(conn,
-				message, -1, NULL);
-
-		dbus_message_unref(message);
-
-		if (!reply)
-			return FALSE;
-	}
-
-	if (dbus_message_get_args(reply, NULL,
-					DBUS_TYPE_OBJECT_PATH, &object_path,
-					DBUS_TYPE_INVALID) == FALSE) {
-		dbus_message_unref(reply);
-		return FALSE;
-	}
-
-	id = device_get_ieee1284_id(adapter, object_path);
-	if (id == NULL) {
-		dbus_message_unref(reply);
-		return FALSE;
-	}
-	printf("%s", id);
-	g_free(id);
-
-	dbus_message_unref(reply);
-
-	return TRUE;
-}
-
-/*
- *  Usage: printer-uri job-id user title copies options [file]
- *
- */
-
-int main(int argc, char *argv[])
-{
-	sdp_session_t *sdp;
-	bdaddr_t bdaddr;
-	unsigned short ctrl_psm, data_psm;
-	uint8_t channel, b[6];
-	char *ptr, str[3], device[18], service[12];
-	const char *uri, *cups_class;
-	int i, err, fd, copies, proto;
-
-	/* Make sure status messages are not buffered */
-	setbuf(stderr, NULL);
-
-	/* Make sure output is not buffered */
-	setbuf(stdout, NULL);
-
-	/* Ignore SIGPIPE signals */
-#ifdef HAVE_SIGSET
-	sigset(SIGPIPE, SIG_IGN);
-#elif defined(HAVE_SIGACTION)
-	memset(&action, 0, sizeof(action));
-	action.sa_handler = SIG_IGN;
-	sigaction(SIGPIPE, &action, NULL);
-#else
-	signal(SIGPIPE, SIG_IGN);
-#endif /* HAVE_SIGSET */
-
-	if (argc == 1) {
-		if (list_printers() == TRUE)
-			return CUPS_BACKEND_OK;
-		else
-			return CUPS_BACKEND_FAILED;
-	} else if (argc == 3 && strcmp(argv[1], "--get-deviceid") == 0) {
-		if (bachk(argv[2]) < 0) {
-			fprintf(stderr, "Invalid Bluetooth address '%s'\n",
-					argv[2]);
-			return CUPS_BACKEND_FAILED;
-		}
-		if (print_ieee1284(argv[2]) == FALSE)
-			return CUPS_BACKEND_FAILED;
-		return CUPS_BACKEND_OK;
-	}
-
-	if (argc < 6 || argc > 7) {
-		fprintf(stderr, "Usage: bluetooth job-id user title copies"
-				" options [file]\n");
-		fprintf(stderr, "       bluetooth --get-deviceid [bdaddr]\n");
-		return CUPS_BACKEND_FAILED;
-	}
-
-	if (argc == 6) {
-		fd = 0;
-		copies = 1;
-	} else {
-		if ((fd = open(argv[6], O_RDONLY)) < 0) {
-			perror("ERROR: Unable to open print file");
-			return CUPS_BACKEND_FAILED;
-		}
-		copies = atoi(argv[4]);
-	}
-
-	uri = getenv("DEVICE_URI");
-	if (!uri)
-		uri = argv[0];
-
-	if (strncasecmp(uri, "bluetooth://", 12)) {
-		fprintf(stderr, "ERROR: No device URI found\n");
-		return CUPS_BACKEND_FAILED;
-	}
-
-	ptr = argv[0] + 12;
-	for (i = 0; i < 6; i++) {
-		strncpy(str, ptr, 2);
-		b[i] = (uint8_t) strtol(str, NULL, 16);
-		ptr += 2;
-	}
-	sprintf(device, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
-			b[0], b[1], b[2], b[3], b[4], b[5]);
-
-	str2ba(device, &bdaddr);
-
-	ptr = strchr(ptr, '/');
-	if (ptr) {
-		strncpy(service, ptr + 1, 12);
-
-		if (!strncasecmp(ptr + 1, "spp", 3))
-			proto = 1;
-		else if (!strncasecmp(ptr + 1, "hcrp", 4))
-			proto = 2;
-		else
-			proto = 0;
-	} else {
-		strcpy(service, "auto");
-		proto = 0;
-	}
-
-	cups_class = getenv("CLASS");
-
-	fprintf(stderr,
-		"DEBUG: %s device %s service %s fd %d copies %d class %s\n",
-			argv[0], device, service, fd, copies,
-			cups_class ? cups_class : "(none)");
-
-	fputs("STATE: +connecting-to-device\n", stderr);
-
-service_search:
-	sdp = sdp_connect(BDADDR_ANY, &bdaddr, SDP_RETRY_IF_BUSY);
-	if (!sdp) {
-		fprintf(stderr, "ERROR: Can't open Bluetooth connection\n");
-		return CUPS_BACKEND_FAILED;
-	}
-
-	switch (proto) {
-	case 1:
-		err = sdp_search_spp(sdp, &channel);
-		break;
-	case 2:
-		err = sdp_search_hcrp(sdp, &ctrl_psm, &data_psm);
-		break;
-	default:
-		proto = 2;
-		err = sdp_search_hcrp(sdp, &ctrl_psm, &data_psm);
-		if (err) {
-			proto = 1;
-			err = sdp_search_spp(sdp, &channel);
-		}
-		break;
-	}
-
-	sdp_close(sdp);
-
-	if (err) {
-		if (cups_class) {
-			fputs("INFO: Unable to contact printer, queuing on "
-					"next printer in class...\n", stderr);
-			sleep(5);
-			return CUPS_BACKEND_FAILED;
-		}
-		sleep(20);
-		fprintf(stderr, "ERROR: Can't get service information\n");
-		goto service_search;
-	}
-
-connect:
-	switch (proto) {
-	case 1:
-		err = spp_print(BDADDR_ANY, &bdaddr, channel,
-						fd, copies, cups_class);
-		break;
-	case 2:
-		err = hcrp_print(BDADDR_ANY, &bdaddr, ctrl_psm, data_psm,
-						fd, copies, cups_class);
-		break;
-	default:
-		err = CUPS_BACKEND_FAILED;
-		fprintf(stderr, "ERROR: Unsupported protocol\n");
-		break;
-	}
-
-	if (err == CUPS_BACKEND_FAILED && cups_class) {
-		fputs("INFO: Unable to contact printer, queuing on "
-					"next printer in class...\n", stderr);
-		sleep(5);
-		return CUPS_BACKEND_FAILED;
-	} else if (err == CUPS_BACKEND_RETRY) {
-		sleep(20);
-		goto connect;
-	}
-
-	if (fd != 0)
-		close(fd);
-
-	if (!err)
-		fprintf(stderr, "INFO: Ready to print\n");
-
-	return err;
-}
diff --git a/cups/sdp.c b/cups/sdp.c
deleted file mode 100644
index c7f17a4..0000000
--- a/cups/sdp.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2003-2010  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 <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sys/socket.h>
-
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
-
-#include "cups.h"
-
-int sdp_search_hcrp(sdp_session_t *sdp, unsigned short *ctrl_psm, unsigned short *data_psm)
-{
-	sdp_list_t *srch, *attrs, *rsp;
-	uuid_t svclass;
-	uint16_t attr1, attr2;
-	int err;
-
-	if (!sdp)
-		return -1;
-
-	sdp_uuid16_create(&svclass, HCR_PRINT_SVCLASS_ID);
-	srch = sdp_list_append(NULL, &svclass);
-
-	attr1 = SDP_ATTR_PROTO_DESC_LIST;
-	attrs = sdp_list_append(NULL, &attr1);
-	attr2 = SDP_ATTR_ADD_PROTO_DESC_LIST;
-	attrs = sdp_list_append(attrs, &attr2);
-
-	err = sdp_service_search_attr_req(sdp, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp);
-	if (err)
-		return -1;
-
-	for (; rsp; rsp = rsp->next) {
-		sdp_record_t *rec = (sdp_record_t *) rsp->data;
-		sdp_list_t *protos;
-
-		if (!sdp_get_access_protos(rec, &protos)) {
-			unsigned short psm = sdp_get_proto_port(protos, L2CAP_UUID);
-			if (psm > 0) {
-				*ctrl_psm = psm;
-			}
-		}
-
-		if (!sdp_get_add_access_protos(rec, &protos)) {
-			unsigned short psm = sdp_get_proto_port(protos, L2CAP_UUID);
-			if (psm > 0 && *ctrl_psm > 0) {
-				*data_psm = psm;
-				return 0;
-			}
-		}
-	}
-
-	return -1;
-}
-
-int sdp_search_spp(sdp_session_t *sdp, uint8_t *channel)
-{
-	sdp_list_t *srch, *attrs, *rsp;
-	uuid_t svclass;
-	uint16_t attr;
-	int err;
-
-	if (!sdp)
-		return -1;
-
-	sdp_uuid16_create(&svclass, SERIAL_PORT_SVCLASS_ID);
-	srch = sdp_list_append(NULL, &svclass);
-
-	attr = SDP_ATTR_PROTO_DESC_LIST;
-	attrs = sdp_list_append(NULL, &attr);
-
-	err = sdp_service_search_attr_req(sdp, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp);
-	if (err)
-		return -1;
-
-	for (; rsp; rsp = rsp->next) {
-		sdp_record_t *rec = (sdp_record_t *) rsp->data;
-		sdp_list_t *protos;
-
-		if (!sdp_get_access_protos(rec, &protos)) {
-			uint8_t ch = sdp_get_proto_port(protos, RFCOMM_UUID);
-			if (ch > 0) {
-				*channel = ch;
-				return 0;
-			}
-		}
-	}
-
-	return -1;
-}
diff --git a/cups/spp.c b/cups/spp.c
deleted file mode 100644
index d906ed2..0000000
--- a/cups/spp.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2003-2010  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 <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sys/socket.h>
-
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/rfcomm.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
-
-#include "cups.h"
-
-int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies, const char *cups_class)
-{
-	struct sockaddr_rc addr;
-	unsigned char buf[2048];
-	int i, sk, err, len;
-
-	if ((sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) {
-		perror("ERROR: Can't create socket");
-		if (cups_class)
-			return CUPS_BACKEND_FAILED;
-		else
-			return CUPS_BACKEND_RETRY;
-	}
-
-	addr.rc_family = AF_BLUETOOTH;
-	bacpy(&addr.rc_bdaddr, src);
-	addr.rc_channel = 0;
-
-	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-		perror("ERROR: Can't bind socket");
-		close(sk);
-		if (cups_class)
-			return CUPS_BACKEND_FAILED;
-		else
-			return CUPS_BACKEND_RETRY;
-	}
-
-	addr.rc_family = AF_BLUETOOTH;
-	bacpy(&addr.rc_bdaddr, dst);
-	addr.rc_channel = channel;
-
-	if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-		perror("ERROR: Can't connect to device");
-		close(sk);
-		if (cups_class)
-			return CUPS_BACKEND_FAILED;
-		else
-			return CUPS_BACKEND_RETRY;
-	}
-
-	fputs("STATE: -connecting-to-device\n", stderr);
-
-	/* Ignore SIGTERM signals if printing from stdin */
-	if (fd == 0) {
-#ifdef HAVE_SIGSET
-		sigset(SIGTERM, SIG_IGN);
-#elif defined(HAVE_SIGACTION)
-		memset(&action, 0, sizeof(action));
-		sigemptyset(&action.sa_mask);
-		action.sa_handler = SIG_IGN;
-		sigaction(SIGTERM, &action, NULL);
-#else
-		signal(SIGTERM, SIG_IGN);
-#endif /* HAVE_SIGSET */
-	}
-
-	for (i = 0; i < copies; i++) {
-
-		if (fd != 0) {
-			fprintf(stderr, "PAGE: 1 1\n");
-			lseek(fd, 0, SEEK_SET);
-		}
-
-		while ((len = read(fd, buf, sizeof(buf))) > 0) {
-			err = write(sk, buf, len);
-			if (err < 0) {
-				perror("ERROR: Error writing to device");
-				close(sk);
-				return CUPS_BACKEND_FAILED;
-			}
-		}
-
-	}
-
-	close(sk);
-
-	return CUPS_BACKEND_OK;
-}
diff --git a/profiles/cups/cups.h b/profiles/cups/cups.h
new file mode 100644
index 0000000..f4e0c01
--- /dev/null
+++ b/profiles/cups/cups.h
@@ -0,0 +1,38 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2003-2010  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
+ *
+ */
+
+enum {					/**** Backend exit codes ****/
+	CUPS_BACKEND_OK = 0,		/* Job completed successfully */
+	CUPS_BACKEND_FAILED = 1,	/* Job failed, use error-policy */
+	CUPS_BACKEND_AUTH_REQUIRED = 2,	/* Job failed, authentication required */
+	CUPS_BACKEND_HOLD = 3,		/* Job failed, hold job */
+	CUPS_BACKEND_STOP = 4,		/* Job failed, stop queue */
+	CUPS_BACKEND_CANCEL = 5,	/* Job failed, cancel job */
+	CUPS_BACKEND_RETRY = 6,		/* Failure requires us to retry (BlueZ specific) */
+};
+
+int sdp_search_spp(sdp_session_t *sdp, uint8_t *channel);
+int sdp_search_hcrp(sdp_session_t *sdp, unsigned short *ctrl_psm, unsigned short *data_psm);
+
+int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies, const char *cups_class);
+int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned short data_psm, int fd, int copies, const char *cups_class);
diff --git a/profiles/cups/hcrp.c b/profiles/cups/hcrp.c
new file mode 100644
index 0000000..a93dda0
--- /dev/null
+++ b/profiles/cups/hcrp.c
@@ -0,0 +1,368 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2003-2010  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 <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/socket.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/l2cap.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+
+#include <netinet/in.h>
+
+#include "cups.h"
+
+#define HCRP_PDU_CREDIT_GRANT		0x0001
+#define HCRP_PDU_CREDIT_REQUEST		0x0002
+#define HCRP_PDU_GET_LPT_STATUS		0x0005
+
+#define HCRP_STATUS_FEATURE_UNSUPPORTED	0x0000
+#define HCRP_STATUS_SUCCESS		0x0001
+#define HCRP_STATUS_CREDIT_SYNC_ERROR	0x0002
+#define HCRP_STATUS_GENERIC_FAILURE	0xffff
+
+struct hcrp_pdu_hdr {
+	uint16_t pid;
+	uint16_t tid;
+	uint16_t plen;
+} __attribute__ ((packed));
+#define HCRP_PDU_HDR_SIZE 6
+
+struct hcrp_credit_grant_cp {
+	uint32_t credit;
+} __attribute__ ((packed));
+#define HCRP_CREDIT_GRANT_CP_SIZE 4
+
+struct hcrp_credit_grant_rp {
+	uint16_t status;
+} __attribute__ ((packed));
+#define HCRP_CREDIT_GRANT_RP_SIZE 2
+
+struct hcrp_credit_request_rp {
+	uint16_t status;
+	uint32_t credit;
+} __attribute__ ((packed));
+#define HCRP_CREDIT_REQUEST_RP_SIZE 6
+
+struct hcrp_get_lpt_status_rp {
+	uint16_t status;
+	uint8_t  lpt_status;
+} __attribute__ ((packed));
+#define HCRP_GET_LPT_STATUS_RP_SIZE 3
+
+static int hcrp_credit_grant(int sk, uint16_t tid, uint32_t credit)
+{
+	struct hcrp_pdu_hdr hdr;
+	struct hcrp_credit_grant_cp cp;
+	struct hcrp_credit_grant_rp rp;
+	unsigned char buf[128];
+	int len;
+
+	hdr.pid = htons(HCRP_PDU_CREDIT_GRANT);
+	hdr.tid = htons(tid);
+	hdr.plen = htons(HCRP_CREDIT_GRANT_CP_SIZE);
+	cp.credit = credit;
+	memcpy(buf, &hdr, HCRP_PDU_HDR_SIZE);
+	memcpy(buf + HCRP_PDU_HDR_SIZE, &cp, HCRP_CREDIT_GRANT_CP_SIZE);
+	len = write(sk, buf, HCRP_PDU_HDR_SIZE + HCRP_CREDIT_GRANT_CP_SIZE);
+	if (len < 0)
+		return len;
+
+	len = read(sk, buf, sizeof(buf));
+	if (len < 0)
+		return len;
+
+	memcpy(&hdr, buf, HCRP_PDU_HDR_SIZE);
+	memcpy(&rp, buf + HCRP_PDU_HDR_SIZE, HCRP_CREDIT_GRANT_RP_SIZE);
+
+	if (ntohs(rp.status) != HCRP_STATUS_SUCCESS) {
+		errno = EIO;
+		return -1;
+	}
+
+	return 0;
+}
+
+static int hcrp_credit_request(int sk, uint16_t tid, uint32_t *credit)
+{
+	struct hcrp_pdu_hdr hdr;
+	struct hcrp_credit_request_rp rp;
+	unsigned char buf[128];
+	int len;
+
+	hdr.pid = htons(HCRP_PDU_CREDIT_REQUEST);
+	hdr.tid = htons(tid);
+	hdr.plen = htons(0);
+	memcpy(buf, &hdr, HCRP_PDU_HDR_SIZE);
+	len = write(sk, buf, HCRP_PDU_HDR_SIZE);
+	if (len < 0)
+		return len;
+
+	len = read(sk, buf, sizeof(buf));
+	if (len < 0)
+		return len;
+
+	memcpy(&hdr, buf, HCRP_PDU_HDR_SIZE);
+	memcpy(&rp, buf + HCRP_PDU_HDR_SIZE, HCRP_CREDIT_REQUEST_RP_SIZE);
+
+	if (ntohs(rp.status) != HCRP_STATUS_SUCCESS) {
+		errno = EIO;
+		return -1;
+	}
+
+	if (credit)
+		*credit = ntohl(rp.credit);
+
+	return 0;
+}
+
+static int hcrp_get_lpt_status(int sk, uint16_t tid, uint8_t *lpt_status)
+{
+	struct hcrp_pdu_hdr hdr;
+	struct hcrp_get_lpt_status_rp rp;
+	unsigned char buf[128];
+	int len;
+
+	hdr.pid = htons(HCRP_PDU_GET_LPT_STATUS);
+	hdr.tid = htons(tid);
+	hdr.plen = htons(0);
+	memcpy(buf, &hdr, HCRP_PDU_HDR_SIZE);
+	len = write(sk, buf, HCRP_PDU_HDR_SIZE);
+	if (len < 0)
+		return len;
+
+	len = read(sk, buf, sizeof(buf));
+	if (len < 0)
+		return len;
+
+	memcpy(&hdr, buf, HCRP_PDU_HDR_SIZE);
+	memcpy(&rp, buf + HCRP_PDU_HDR_SIZE, HCRP_GET_LPT_STATUS_RP_SIZE);
+
+	if (ntohs(rp.status) != HCRP_STATUS_SUCCESS) {
+		errno = EIO;
+		return -1;
+	}
+
+	if (lpt_status)
+		*lpt_status = rp.lpt_status;
+
+	return 0;
+}
+
+static inline int hcrp_get_next_tid(int tid)
+{
+	if (tid > 0xf000)
+		return 0;
+	else
+		return tid + 1;
+}
+
+int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned short data_psm, int fd, int copies, const char *cups_class)
+{
+	struct sockaddr_l2 addr;
+	struct l2cap_options opts;
+	socklen_t size;
+	unsigned char buf[2048];
+	int i, ctrl_sk, data_sk, count, len, timeout = 0;
+	unsigned int mtu;
+	uint8_t status;
+	uint16_t tid = 0;
+	uint32_t tmp, credit = 0;
+
+	if ((ctrl_sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) {
+		perror("ERROR: Can't create socket");
+		if (cups_class)
+			return CUPS_BACKEND_FAILED;
+		else
+			return CUPS_BACKEND_RETRY;
+	}
+
+	memset(&addr, 0, sizeof(addr));
+	addr.l2_family = AF_BLUETOOTH;
+	bacpy(&addr.l2_bdaddr, src);
+
+	if (bind(ctrl_sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+		perror("ERROR: Can't bind socket");
+		close(ctrl_sk);
+		if (cups_class)
+			return CUPS_BACKEND_FAILED;
+		else
+			return CUPS_BACKEND_RETRY;
+	}
+
+	memset(&addr, 0, sizeof(addr));
+	addr.l2_family = AF_BLUETOOTH;
+	bacpy(&addr.l2_bdaddr, dst);
+	addr.l2_psm = htobs(ctrl_psm);
+
+	if (connect(ctrl_sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+		perror("ERROR: Can't connect to device");
+		close(ctrl_sk);
+		if (cups_class)
+			return CUPS_BACKEND_FAILED;
+		else
+			return CUPS_BACKEND_RETRY;
+	}
+
+	if ((data_sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) {
+		perror("ERROR: Can't create socket");
+		close(ctrl_sk);
+		if (cups_class)
+			return CUPS_BACKEND_FAILED;
+		else
+			return CUPS_BACKEND_RETRY;
+	}
+
+	memset(&addr, 0, sizeof(addr));
+	addr.l2_family = AF_BLUETOOTH;
+	bacpy(&addr.l2_bdaddr, src);
+
+	if (bind(data_sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+		perror("ERROR: Can't bind socket");
+		close(data_sk);
+		close(ctrl_sk);
+		if (cups_class)
+			return CUPS_BACKEND_FAILED;
+		else
+			return CUPS_BACKEND_RETRY;
+	}
+
+	memset(&addr, 0, sizeof(addr));
+	addr.l2_family = AF_BLUETOOTH;
+	bacpy(&addr.l2_bdaddr, dst);
+	addr.l2_psm = htobs(data_psm);
+
+	if (connect(data_sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+		perror("ERROR: Can't connect to device");
+		close(data_sk);
+		close(ctrl_sk);
+		if (cups_class)
+			return CUPS_BACKEND_FAILED;
+		else
+			return CUPS_BACKEND_RETRY;
+	}
+
+	fputs("STATE: -connecting-to-device\n", stderr);
+
+	memset(&opts, 0, sizeof(opts));
+	size = sizeof(opts);
+
+	if (getsockopt(data_sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &size) < 0) {
+		perror("ERROR: Can't get socket options");
+		close(data_sk);
+		close(ctrl_sk);
+		if (cups_class)
+			return CUPS_BACKEND_FAILED;
+		else
+			return CUPS_BACKEND_RETRY;
+	}
+
+	mtu = opts.omtu;
+
+	/* Ignore SIGTERM signals if printing from stdin */
+	if (fd == 0) {
+#ifdef HAVE_SIGSET
+		sigset(SIGTERM, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+		memset(&action, 0, sizeof(action));
+		sigemptyset(&action.sa_mask);
+		action.sa_handler = SIG_IGN;
+		sigaction(SIGTERM, &action, NULL);
+#else
+		signal(SIGTERM, SIG_IGN);
+#endif /* HAVE_SIGSET */
+	}
+
+	tid = hcrp_get_next_tid(tid);
+	if (hcrp_credit_grant(ctrl_sk, tid, 0) < 0) {
+		fprintf(stderr, "ERROR: Can't grant initial credits\n");
+		close(data_sk);
+		close(ctrl_sk);
+		if (cups_class)
+			return CUPS_BACKEND_FAILED;
+		else
+			return CUPS_BACKEND_RETRY;
+	}
+
+	for (i = 0; i < copies; i++) {
+
+		if (fd != 0) {
+			fprintf(stderr, "PAGE: 1 1\n");
+			lseek(fd, 0, SEEK_SET);
+		}
+
+		while (1) {
+			if (credit < mtu) {
+				tid = hcrp_get_next_tid(tid);
+				if (!hcrp_credit_request(ctrl_sk, tid, &tmp)) {
+					credit += tmp;
+					timeout = 0;
+				}
+			}
+
+			if (!credit) {
+				if (timeout++ > 300) {
+					tid = hcrp_get_next_tid(tid);
+					if (!hcrp_get_lpt_status(ctrl_sk, tid, &status))
+						fprintf(stderr, "ERROR: LPT status 0x%02x\n", status);
+					break;
+				}
+
+				sleep(1);
+				continue;
+			}
+
+			count = read(fd, buf, (credit > mtu) ? mtu : credit);
+			if (count <= 0)
+				break;
+
+			len = write(data_sk, buf, count);
+			if (len < 0) {
+				perror("ERROR: Error writing to device");
+				close(data_sk);
+				close(ctrl_sk);
+				return CUPS_BACKEND_FAILED;
+			}
+
+			if (len != count)
+				fprintf(stderr, "ERROR: Can't send complete data\n");
+
+			credit -= len;
+		}
+
+	}
+
+	close(data_sk);
+	close(ctrl_sk);
+
+	return CUPS_BACKEND_OK;
+}
diff --git a/profiles/cups/main.c b/profiles/cups/main.c
new file mode 100644
index 0000000..a884c6e
--- /dev/null
+++ b/profiles/cups/main.c
@@ -0,0 +1,896 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2003-2010  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 <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/socket.h>
+#include <glib.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+
+#include <gdbus.h>
+
+#include "cups.h"
+
+struct cups_device {
+	char *bdaddr;
+	char *name;
+	char *id;
+};
+
+static GSList *device_list = NULL;
+static GMainLoop *loop = NULL;
+static DBusConnection *conn = NULL;
+static gboolean doing_disco = FALSE;
+
+#define ATTRID_1284ID 0x0300
+
+struct context_data {
+	gboolean found;
+	char *id;
+};
+
+static void element_start(GMarkupParseContext *context,
+				const gchar *element_name,
+				const gchar **attribute_names,
+				const gchar **attribute_values,
+				gpointer user_data, GError **err)
+{
+	struct context_data *ctx_data = user_data;
+
+	if (!strcmp(element_name, "record"))
+		return;
+
+	if (!strcmp(element_name, "attribute")) {
+		int i;
+		for (i = 0; attribute_names[i]; i++) {
+			if (strcmp(attribute_names[i], "id") != 0)
+				continue;
+			if (strtol(attribute_values[i], 0, 0) == ATTRID_1284ID)
+				ctx_data->found = TRUE;
+			break;
+		}
+		return;
+	}
+
+	if (ctx_data->found  && !strcmp(element_name, "text")) {
+		int i;
+		for (i = 0; attribute_names[i]; i++) {
+			if (!strcmp(attribute_names[i], "value")) {
+				ctx_data->id = g_strdup(attribute_values[i] + 2);
+				ctx_data->found = FALSE;
+			}
+		}
+	}
+}
+
+static GMarkupParser parser = {
+	element_start, NULL, NULL, NULL, NULL
+};
+
+static char *sdp_xml_parse_record(const char *data)
+{
+	GMarkupParseContext *ctx;
+	struct context_data ctx_data;
+	int size;
+
+	size = strlen(data);
+	ctx_data.found = FALSE;
+	ctx_data.id = NULL;
+	ctx = g_markup_parse_context_new(&parser, 0, &ctx_data, NULL);
+
+	if (g_markup_parse_context_parse(ctx, data, size, NULL) == FALSE) {
+		g_markup_parse_context_free(ctx);
+		g_free(ctx_data.id);
+		return NULL;
+	}
+
+	g_markup_parse_context_free(ctx);
+
+	return ctx_data.id;
+}
+
+static char *device_get_ieee1284_id(const char *adapter, const char *device)
+{
+	DBusMessage *message, *reply;
+	DBusMessageIter iter, reply_iter;
+	DBusMessageIter reply_iter_entry;
+	const char *hcr_print = "00001126-0000-1000-8000-00805f9b34fb";
+	const char *xml;
+	char *id = NULL;
+
+	/* Look for the service handle of the HCRP service */
+	message = dbus_message_new_method_call("org.bluez", device,
+						"org.bluez.Device",
+						"DiscoverServices");
+	dbus_message_iter_init_append(message, &iter);
+	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &hcr_print);
+
+	reply = dbus_connection_send_with_reply_and_block(conn,
+							message, -1, NULL);
+
+	dbus_message_unref(message);
+
+	if (!reply)
+		return NULL;
+
+	dbus_message_iter_init(reply, &reply_iter);
+
+	if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) {
+		dbus_message_unref(reply);
+		return NULL;
+	}
+
+	dbus_message_iter_recurse(&reply_iter, &reply_iter_entry);
+
+	/* Hopefully we only get one handle, or take a punt */
+	while (dbus_message_iter_get_arg_type(&reply_iter_entry) ==
+							DBUS_TYPE_DICT_ENTRY) {
+		guint32 key;
+		DBusMessageIter dict_entry;
+
+		dbus_message_iter_recurse(&reply_iter_entry, &dict_entry);
+
+		/* Key ? */
+		dbus_message_iter_get_basic(&dict_entry, &key);
+		if (!key) {
+			dbus_message_iter_next(&reply_iter_entry);
+			continue;
+		}
+
+		/* Try to get the value */
+		if (!dbus_message_iter_next(&dict_entry)) {
+			dbus_message_iter_next(&reply_iter_entry);
+			continue;
+		}
+
+		dbus_message_iter_get_basic(&dict_entry, &xml);
+
+		id = sdp_xml_parse_record(xml);
+		if (id != NULL)
+			break;
+		dbus_message_iter_next(&reply_iter_entry);
+	}
+
+	dbus_message_unref(reply);
+
+	return id;
+}
+
+static void print_printer_details(const char *name, const char *bdaddr,
+								const char *id)
+{
+	char *uri, *escaped;
+
+	escaped = g_strdelimit(g_strdup(name), "\"", '\'');
+	uri = g_strdup_printf("bluetooth://%c%c%c%c%c%c%c%c%c%c%c%c",
+				bdaddr[0], bdaddr[1],
+				bdaddr[3], bdaddr[4],
+				bdaddr[6], bdaddr[7],
+				bdaddr[9], bdaddr[10],
+				bdaddr[12], bdaddr[13],
+				bdaddr[15], bdaddr[16]);
+	printf("direct %s \"%s\" \"%s (Bluetooth)\"", uri, escaped, escaped);
+	if (id != NULL)
+		printf(" \"%s\"\n", id);
+	else
+		printf("\n");
+	g_free(escaped);
+	g_free(uri);
+}
+
+static void add_device_to_list(const char *name, const char *bdaddr,
+								const char *id)
+{
+	struct cups_device *device;
+	GSList *l;
+
+	/* Look for the device in the list */
+	for (l = device_list; l != NULL; l = l->next) {
+		device = (struct cups_device *) l->data;
+
+		if (strcmp(device->bdaddr, bdaddr) == 0) {
+			if (device->name != name) {
+				g_free(device->name);
+				device->name = g_strdup(name);
+			}
+			g_free(device->id);
+			device->id = g_strdup(id);
+			return;
+		}
+	}
+
+	/* Or add it to the list if it's not there */
+	device = g_new0(struct cups_device, 1);
+	device->bdaddr = g_strdup(bdaddr);
+	device->name = g_strdup(name);
+	device->id = g_strdup(id);
+
+	device_list = g_slist_prepend(device_list, device);
+	print_printer_details(device->name, device->bdaddr, device->id);
+}
+
+static gboolean parse_device_properties(DBusMessageIter *reply_iter,
+						char **name, char **bdaddr)
+{
+	guint32 class = 0;
+	DBusMessageIter reply_iter_entry;
+
+	if (dbus_message_iter_get_arg_type(reply_iter) != DBUS_TYPE_ARRAY)
+		return FALSE;
+
+	dbus_message_iter_recurse(reply_iter, &reply_iter_entry);
+
+	while (dbus_message_iter_get_arg_type(&reply_iter_entry) ==
+							DBUS_TYPE_DICT_ENTRY) {
+		const char *key;
+		DBusMessageIter dict_entry, iter_dict_val;
+
+		dbus_message_iter_recurse(&reply_iter_entry, &dict_entry);
+
+		/* Key == Class ? */
+		dbus_message_iter_get_basic(&dict_entry, &key);
+		if (!key) {
+			dbus_message_iter_next(&reply_iter_entry);
+			continue;
+		}
+
+		if (strcmp(key, "Class") != 0 &&
+				strcmp(key, "Alias") != 0 &&
+				strcmp(key, "Address") != 0) {
+			dbus_message_iter_next(&reply_iter_entry);
+			continue;
+		}
+
+		/* Try to get the value */
+		if (!dbus_message_iter_next(&dict_entry)) {
+			dbus_message_iter_next(&reply_iter_entry);
+			continue;
+		}
+		dbus_message_iter_recurse(&dict_entry, &iter_dict_val);
+		if (strcmp(key, "Class") == 0) {
+			dbus_message_iter_get_basic(&iter_dict_val, &class);
+		} else {
+			const char *value;
+			dbus_message_iter_get_basic(&iter_dict_val, &value);
+			if (strcmp(key, "Alias") == 0) {
+				*name = g_strdup(value);
+			} else if (bdaddr) {
+				*bdaddr = g_strdup(value);
+			}
+		}
+		dbus_message_iter_next(&reply_iter_entry);
+	}
+
+	if (class == 0)
+		return FALSE;
+	if (((class & 0x1f00) >> 8) == 0x06 && (class & 0x80))
+		return TRUE;
+
+	return FALSE;
+}
+
+static gboolean device_is_printer(const char *adapter, const char *device_path, char **name, char **bdaddr)
+{
+	DBusMessage *message, *reply;
+	DBusMessageIter reply_iter;
+	gboolean retval;
+
+	message = dbus_message_new_method_call("org.bluez", device_path,
+							"org.bluez.Device",
+							"GetProperties");
+
+	reply = dbus_connection_send_with_reply_and_block(conn,
+							message, -1, NULL);
+
+	dbus_message_unref(message);
+
+	if (!reply)
+		return FALSE;
+
+	dbus_message_iter_init(reply, &reply_iter);
+
+	retval = parse_device_properties(&reply_iter, name, bdaddr);
+
+	dbus_message_unref(reply);
+
+	return retval;
+}
+
+static void remote_device_found(const char *adapter, const char *bdaddr,
+							const char *name)
+{
+	DBusMessage *message, *reply, *adapter_reply;
+	DBusMessageIter iter;
+	char *object_path = NULL;
+	char *id;
+
+	adapter_reply = NULL;
+
+	if (adapter == NULL) {
+		message = dbus_message_new_method_call("org.bluez", "/",
+							"org.bluez.Manager",
+							"DefaultAdapter");
+
+		adapter_reply = dbus_connection_send_with_reply_and_block(conn,
+							message, -1, NULL);
+
+		dbus_message_unref(message);
+
+		if (!adapter_reply)
+			return;
+
+		if (dbus_message_get_args(adapter_reply, NULL,
+					DBUS_TYPE_OBJECT_PATH, &adapter,
+					DBUS_TYPE_INVALID) == FALSE) {
+			dbus_message_unref(adapter_reply);
+			return;
+		}
+	}
+
+	message = dbus_message_new_method_call("org.bluez", adapter,
+							"org.bluez.Adapter",
+							"FindDevice");
+	dbus_message_iter_init_append(message, &iter);
+	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);
+
+	if (adapter_reply != NULL)
+		dbus_message_unref(adapter_reply);
+
+	reply = dbus_connection_send_with_reply_and_block(conn,
+							message, -1, NULL);
+
+	dbus_message_unref(message);
+
+	if (!reply) {
+		message = dbus_message_new_method_call("org.bluez", adapter,
+							"org.bluez.Adapter",
+							"CreateDevice");
+		dbus_message_iter_init_append(message, &iter);
+		dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);
+
+		reply = dbus_connection_send_with_reply_and_block(conn,
+							message, -1, NULL);
+
+		dbus_message_unref(message);
+
+		if (!reply)
+			return;
+	}
+
+	if (dbus_message_get_args(reply, NULL,
+					DBUS_TYPE_OBJECT_PATH, &object_path,
+					DBUS_TYPE_INVALID) == FALSE) {
+		dbus_message_unref(reply);
+		return;
+	}
+
+	id = device_get_ieee1284_id(adapter, object_path);
+	add_device_to_list(name, bdaddr, id);
+	g_free(id);
+
+	dbus_message_unref(reply);
+}
+
+static void discovery_completed(void)
+{
+	g_slist_free(device_list);
+	device_list = NULL;
+
+	g_main_loop_quit(loop);
+}
+
+static void remote_device_disappeared(const char *bdaddr)
+{
+	GSList *l;
+
+	for (l = device_list; l != NULL; l = l->next) {
+		struct cups_device *device = l->data;
+
+		if (strcmp(device->bdaddr, bdaddr) == 0) {
+			g_free(device->name);
+			g_free(device->bdaddr);
+			g_free(device);
+			device_list = g_slist_delete_link(device_list, l);
+			return;
+		}
+	}
+}
+
+static gboolean list_known_printers(const char *adapter)
+{
+	DBusMessageIter reply_iter, iter_array;
+	DBusError error;
+	DBusMessage *message, *reply;
+
+	message = dbus_message_new_method_call("org.bluez", adapter,
+						"org.bluez.Adapter",
+						"ListDevices");
+	if (message == NULL)
+		return FALSE;
+
+	dbus_error_init(&error);
+	reply = dbus_connection_send_with_reply_and_block(conn, message,
+								-1, &error);
+
+	dbus_message_unref(message);
+
+	if (dbus_error_is_set(&error))
+		return FALSE;
+
+	dbus_message_iter_init(reply, &reply_iter);
+	if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) {
+		dbus_message_unref(reply);
+		return FALSE;
+	}
+
+	dbus_message_iter_recurse(&reply_iter, &iter_array);
+	while (dbus_message_iter_get_arg_type(&iter_array) ==
+						DBUS_TYPE_OBJECT_PATH) {
+		const char *object_path;
+		char *name = NULL;
+		char *bdaddr = NULL;
+
+		dbus_message_iter_get_basic(&iter_array, &object_path);
+		if (device_is_printer(adapter, object_path, &name, &bdaddr)) {
+			char *id;
+
+			id = device_get_ieee1284_id(adapter, object_path);
+			add_device_to_list(name, bdaddr, id);
+			g_free(id);
+		}
+		g_free(name);
+		g_free(bdaddr);
+		dbus_message_iter_next(&iter_array);
+	}
+
+	dbus_message_unref(reply);
+
+	return FALSE;
+}
+
+static DBusHandlerResult filter_func(DBusConnection *connection,
+					DBusMessage *message, void *user_data)
+{
+	if (dbus_message_is_signal(message, "org.bluez.Adapter",
+						"DeviceFound")) {
+		const char *adapter, *bdaddr;
+		char *name;
+		DBusMessageIter iter;
+
+		dbus_message_iter_init(message, &iter);
+		dbus_message_iter_get_basic(&iter, &bdaddr);
+		dbus_message_iter_next(&iter);
+
+		adapter = dbus_message_get_path(message);
+		if (parse_device_properties(&iter, &name, NULL))
+			remote_device_found(adapter, bdaddr, name);
+		g_free (name);
+	} else if (dbus_message_is_signal(message, "org.bluez.Adapter",
+						"DeviceDisappeared")) {
+		const char *bdaddr;
+
+		dbus_message_get_args(message, NULL,
+					DBUS_TYPE_STRING, &bdaddr,
+					DBUS_TYPE_INVALID);
+		remote_device_disappeared(bdaddr);
+	} else if (dbus_message_is_signal(message, "org.bluez.Adapter",
+						"PropertyChanged")) {
+		DBusMessageIter iter, value_iter;
+		const char *name;
+		gboolean discovering;
+
+		dbus_message_iter_init(message, &iter);
+		dbus_message_iter_get_basic(&iter, &name);
+		if (name == NULL || strcmp(name, "Discovering") != 0)
+			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+		dbus_message_iter_next(&iter);
+		dbus_message_iter_recurse(&iter, &value_iter);
+		dbus_message_iter_get_basic(&value_iter, &discovering);
+
+		if (discovering == FALSE && doing_disco) {
+			doing_disco = FALSE;
+			discovery_completed();
+		}
+	}
+
+	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static gboolean list_printers(void)
+{
+	/* 1. Connect to the bus
+	 * 2. Get the manager
+	 * 3. Get the default adapter
+	 * 4. Get a list of devices
+	 * 5. Get the class of each device
+	 * 6. Print the details from each printer device
+	 */
+	DBusError error;
+	dbus_bool_t hcid_exists;
+	DBusMessage *reply, *message;
+	DBusMessageIter reply_iter;
+	char *adapter, *match;
+
+	conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
+	if (conn == NULL)
+		return TRUE;
+
+	dbus_error_init(&error);
+	hcid_exists = dbus_bus_name_has_owner(conn, "org.bluez", &error);
+	if (dbus_error_is_set(&error))
+		return TRUE;
+
+	if (!hcid_exists)
+		return TRUE;
+
+	/* Get the default adapter */
+	message = dbus_message_new_method_call("org.bluez", "/",
+						"org.bluez.Manager",
+						"DefaultAdapter");
+	if (message == NULL) {
+		dbus_connection_unref(conn);
+		return FALSE;
+	}
+
+	reply = dbus_connection_send_with_reply_and_block(conn,
+							message, -1, &error);
+
+	dbus_message_unref(message);
+
+	if (dbus_error_is_set(&error)) {
+		dbus_connection_unref(conn);
+		/* No adapter */
+		return TRUE;
+	}
+
+	dbus_message_iter_init(reply, &reply_iter);
+	if (dbus_message_iter_get_arg_type(&reply_iter) !=
+						DBUS_TYPE_OBJECT_PATH) {
+		dbus_message_unref(reply);
+		dbus_connection_unref(conn);
+		return FALSE;
+	}
+
+	dbus_message_iter_get_basic(&reply_iter, &adapter);
+	adapter = g_strdup(adapter);
+	dbus_message_unref(reply);
+
+	if (!dbus_connection_add_filter(conn, filter_func, adapter, g_free)) {
+		g_free(adapter);
+		dbus_connection_unref(conn);
+		return FALSE;
+	}
+
+#define MATCH_FORMAT				\
+	"type='signal',"			\
+	"interface='org.bluez.Adapter',"	\
+	"sender='org.bluez',"			\
+	"path='%s'"
+
+	match = g_strdup_printf(MATCH_FORMAT, adapter);
+	dbus_bus_add_match(conn, match, &error);
+	g_free(match);
+
+	/* Add the the recent devices */
+	list_known_printers(adapter);
+
+	doing_disco = TRUE;
+	message = dbus_message_new_method_call("org.bluez", adapter,
+					"org.bluez.Adapter",
+					"StartDiscovery");
+
+	if (!dbus_connection_send_with_reply(conn, message, NULL, -1)) {
+		dbus_message_unref(message);
+		dbus_connection_unref(conn);
+		g_free(adapter);
+		return FALSE;
+	}
+	dbus_message_unref(message);
+
+	loop = g_main_loop_new(NULL, TRUE);
+	g_main_loop_run(loop);
+
+	g_free(adapter);
+	dbus_connection_unref(conn);
+
+	return TRUE;
+}
+
+static gboolean print_ieee1284(const char *bdaddr)
+{
+	DBusMessage *message, *reply, *adapter_reply;
+	DBusMessageIter iter;
+	char *object_path = NULL;
+	char *adapter;
+	char *id;
+
+	adapter_reply = NULL;
+
+	conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
+	if (conn == NULL)
+		return FALSE;
+
+	message = dbus_message_new_method_call("org.bluez", "/",
+			"org.bluez.Manager",
+			"DefaultAdapter");
+
+	adapter_reply = dbus_connection_send_with_reply_and_block(conn,
+			message, -1, NULL);
+
+	dbus_message_unref(message);
+
+	if (!adapter_reply)
+		return FALSE;
+
+	if (dbus_message_get_args(adapter_reply, NULL,
+			DBUS_TYPE_OBJECT_PATH, &adapter,
+			DBUS_TYPE_INVALID) == FALSE) {
+		dbus_message_unref(adapter_reply);
+		return FALSE;
+	}
+
+	message = dbus_message_new_method_call("org.bluez", adapter,
+			"org.bluez.Adapter",
+			"FindDevice");
+	dbus_message_iter_init_append(message, &iter);
+	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);
+
+	if (adapter_reply != NULL)
+		dbus_message_unref(adapter_reply);
+
+	reply = dbus_connection_send_with_reply_and_block(conn,
+			message, -1, NULL);
+
+	dbus_message_unref(message);
+
+	if (!reply) {
+		message = dbus_message_new_method_call("org.bluez", adapter,
+				"org.bluez.Adapter",
+				"CreateDevice");
+		dbus_message_iter_init_append(message, &iter);
+		dbus_message_iter_append_basic(&iter,
+				DBUS_TYPE_STRING, &bdaddr);
+
+		reply = dbus_connection_send_with_reply_and_block(conn,
+				message, -1, NULL);
+
+		dbus_message_unref(message);
+
+		if (!reply)
+			return FALSE;
+	}
+
+	if (dbus_message_get_args(reply, NULL,
+					DBUS_TYPE_OBJECT_PATH, &object_path,
+					DBUS_TYPE_INVALID) == FALSE) {
+		dbus_message_unref(reply);
+		return FALSE;
+	}
+
+	id = device_get_ieee1284_id(adapter, object_path);
+	if (id == NULL) {
+		dbus_message_unref(reply);
+		return FALSE;
+	}
+	printf("%s", id);
+	g_free(id);
+
+	dbus_message_unref(reply);
+
+	return TRUE;
+}
+
+/*
+ *  Usage: printer-uri job-id user title copies options [file]
+ *
+ */
+
+int main(int argc, char *argv[])
+{
+	sdp_session_t *sdp;
+	bdaddr_t bdaddr;
+	unsigned short ctrl_psm, data_psm;
+	uint8_t channel, b[6];
+	char *ptr, str[3], device[18], service[12];
+	const char *uri, *cups_class;
+	int i, err, fd, copies, proto;
+
+	/* Make sure status messages are not buffered */
+	setbuf(stderr, NULL);
+
+	/* Make sure output is not buffered */
+	setbuf(stdout, NULL);
+
+	/* Ignore SIGPIPE signals */
+#ifdef HAVE_SIGSET
+	sigset(SIGPIPE, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+	memset(&action, 0, sizeof(action));
+	action.sa_handler = SIG_IGN;
+	sigaction(SIGPIPE, &action, NULL);
+#else
+	signal(SIGPIPE, SIG_IGN);
+#endif /* HAVE_SIGSET */
+
+	if (argc == 1) {
+		if (list_printers() == TRUE)
+			return CUPS_BACKEND_OK;
+		else
+			return CUPS_BACKEND_FAILED;
+	} else if (argc == 3 && strcmp(argv[1], "--get-deviceid") == 0) {
+		if (bachk(argv[2]) < 0) {
+			fprintf(stderr, "Invalid Bluetooth address '%s'\n",
+					argv[2]);
+			return CUPS_BACKEND_FAILED;
+		}
+		if (print_ieee1284(argv[2]) == FALSE)
+			return CUPS_BACKEND_FAILED;
+		return CUPS_BACKEND_OK;
+	}
+
+	if (argc < 6 || argc > 7) {
+		fprintf(stderr, "Usage: bluetooth job-id user title copies"
+				" options [file]\n");
+		fprintf(stderr, "       bluetooth --get-deviceid [bdaddr]\n");
+		return CUPS_BACKEND_FAILED;
+	}
+
+	if (argc == 6) {
+		fd = 0;
+		copies = 1;
+	} else {
+		if ((fd = open(argv[6], O_RDONLY)) < 0) {
+			perror("ERROR: Unable to open print file");
+			return CUPS_BACKEND_FAILED;
+		}
+		copies = atoi(argv[4]);
+	}
+
+	uri = getenv("DEVICE_URI");
+	if (!uri)
+		uri = argv[0];
+
+	if (strncasecmp(uri, "bluetooth://", 12)) {
+		fprintf(stderr, "ERROR: No device URI found\n");
+		return CUPS_BACKEND_FAILED;
+	}
+
+	ptr = argv[0] + 12;
+	for (i = 0; i < 6; i++) {
+		strncpy(str, ptr, 2);
+		b[i] = (uint8_t) strtol(str, NULL, 16);
+		ptr += 2;
+	}
+	sprintf(device, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+			b[0], b[1], b[2], b[3], b[4], b[5]);
+
+	str2ba(device, &bdaddr);
+
+	ptr = strchr(ptr, '/');
+	if (ptr) {
+		strncpy(service, ptr + 1, 12);
+
+		if (!strncasecmp(ptr + 1, "spp", 3))
+			proto = 1;
+		else if (!strncasecmp(ptr + 1, "hcrp", 4))
+			proto = 2;
+		else
+			proto = 0;
+	} else {
+		strcpy(service, "auto");
+		proto = 0;
+	}
+
+	cups_class = getenv("CLASS");
+
+	fprintf(stderr,
+		"DEBUG: %s device %s service %s fd %d copies %d class %s\n",
+			argv[0], device, service, fd, copies,
+			cups_class ? cups_class : "(none)");
+
+	fputs("STATE: +connecting-to-device\n", stderr);
+
+service_search:
+	sdp = sdp_connect(BDADDR_ANY, &bdaddr, SDP_RETRY_IF_BUSY);
+	if (!sdp) {
+		fprintf(stderr, "ERROR: Can't open Bluetooth connection\n");
+		return CUPS_BACKEND_FAILED;
+	}
+
+	switch (proto) {
+	case 1:
+		err = sdp_search_spp(sdp, &channel);
+		break;
+	case 2:
+		err = sdp_search_hcrp(sdp, &ctrl_psm, &data_psm);
+		break;
+	default:
+		proto = 2;
+		err = sdp_search_hcrp(sdp, &ctrl_psm, &data_psm);
+		if (err) {
+			proto = 1;
+			err = sdp_search_spp(sdp, &channel);
+		}
+		break;
+	}
+
+	sdp_close(sdp);
+
+	if (err) {
+		if (cups_class) {
+			fputs("INFO: Unable to contact printer, queuing on "
+					"next printer in class...\n", stderr);
+			sleep(5);
+			return CUPS_BACKEND_FAILED;
+		}
+		sleep(20);
+		fprintf(stderr, "ERROR: Can't get service information\n");
+		goto service_search;
+	}
+
+connect:
+	switch (proto) {
+	case 1:
+		err = spp_print(BDADDR_ANY, &bdaddr, channel,
+						fd, copies, cups_class);
+		break;
+	case 2:
+		err = hcrp_print(BDADDR_ANY, &bdaddr, ctrl_psm, data_psm,
+						fd, copies, cups_class);
+		break;
+	default:
+		err = CUPS_BACKEND_FAILED;
+		fprintf(stderr, "ERROR: Unsupported protocol\n");
+		break;
+	}
+
+	if (err == CUPS_BACKEND_FAILED && cups_class) {
+		fputs("INFO: Unable to contact printer, queuing on "
+					"next printer in class...\n", stderr);
+		sleep(5);
+		return CUPS_BACKEND_FAILED;
+	} else if (err == CUPS_BACKEND_RETRY) {
+		sleep(20);
+		goto connect;
+	}
+
+	if (fd != 0)
+		close(fd);
+
+	if (!err)
+		fprintf(stderr, "INFO: Ready to print\n");
+
+	return err;
+}
diff --git a/profiles/cups/sdp.c b/profiles/cups/sdp.c
new file mode 100644
index 0000000..c7f17a4
--- /dev/null
+++ b/profiles/cups/sdp.c
@@ -0,0 +1,119 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2003-2010  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 <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/socket.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+
+#include "cups.h"
+
+int sdp_search_hcrp(sdp_session_t *sdp, unsigned short *ctrl_psm, unsigned short *data_psm)
+{
+	sdp_list_t *srch, *attrs, *rsp;
+	uuid_t svclass;
+	uint16_t attr1, attr2;
+	int err;
+
+	if (!sdp)
+		return -1;
+
+	sdp_uuid16_create(&svclass, HCR_PRINT_SVCLASS_ID);
+	srch = sdp_list_append(NULL, &svclass);
+
+	attr1 = SDP_ATTR_PROTO_DESC_LIST;
+	attrs = sdp_list_append(NULL, &attr1);
+	attr2 = SDP_ATTR_ADD_PROTO_DESC_LIST;
+	attrs = sdp_list_append(attrs, &attr2);
+
+	err = sdp_service_search_attr_req(sdp, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp);
+	if (err)
+		return -1;
+
+	for (; rsp; rsp = rsp->next) {
+		sdp_record_t *rec = (sdp_record_t *) rsp->data;
+		sdp_list_t *protos;
+
+		if (!sdp_get_access_protos(rec, &protos)) {
+			unsigned short psm = sdp_get_proto_port(protos, L2CAP_UUID);
+			if (psm > 0) {
+				*ctrl_psm = psm;
+			}
+		}
+
+		if (!sdp_get_add_access_protos(rec, &protos)) {
+			unsigned short psm = sdp_get_proto_port(protos, L2CAP_UUID);
+			if (psm > 0 && *ctrl_psm > 0) {
+				*data_psm = psm;
+				return 0;
+			}
+		}
+	}
+
+	return -1;
+}
+
+int sdp_search_spp(sdp_session_t *sdp, uint8_t *channel)
+{
+	sdp_list_t *srch, *attrs, *rsp;
+	uuid_t svclass;
+	uint16_t attr;
+	int err;
+
+	if (!sdp)
+		return -1;
+
+	sdp_uuid16_create(&svclass, SERIAL_PORT_SVCLASS_ID);
+	srch = sdp_list_append(NULL, &svclass);
+
+	attr = SDP_ATTR_PROTO_DESC_LIST;
+	attrs = sdp_list_append(NULL, &attr);
+
+	err = sdp_service_search_attr_req(sdp, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp);
+	if (err)
+		return -1;
+
+	for (; rsp; rsp = rsp->next) {
+		sdp_record_t *rec = (sdp_record_t *) rsp->data;
+		sdp_list_t *protos;
+
+		if (!sdp_get_access_protos(rec, &protos)) {
+			uint8_t ch = sdp_get_proto_port(protos, RFCOMM_UUID);
+			if (ch > 0) {
+				*channel = ch;
+				return 0;
+			}
+		}
+	}
+
+	return -1;
+}
diff --git a/profiles/cups/spp.c b/profiles/cups/spp.c
new file mode 100644
index 0000000..d906ed2
--- /dev/null
+++ b/profiles/cups/spp.c
@@ -0,0 +1,118 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2003-2010  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 <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/socket.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/rfcomm.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+
+#include "cups.h"
+
+int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies, const char *cups_class)
+{
+	struct sockaddr_rc addr;
+	unsigned char buf[2048];
+	int i, sk, err, len;
+
+	if ((sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) {
+		perror("ERROR: Can't create socket");
+		if (cups_class)
+			return CUPS_BACKEND_FAILED;
+		else
+			return CUPS_BACKEND_RETRY;
+	}
+
+	addr.rc_family = AF_BLUETOOTH;
+	bacpy(&addr.rc_bdaddr, src);
+	addr.rc_channel = 0;
+
+	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+		perror("ERROR: Can't bind socket");
+		close(sk);
+		if (cups_class)
+			return CUPS_BACKEND_FAILED;
+		else
+			return CUPS_BACKEND_RETRY;
+	}
+
+	addr.rc_family = AF_BLUETOOTH;
+	bacpy(&addr.rc_bdaddr, dst);
+	addr.rc_channel = channel;
+
+	if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+		perror("ERROR: Can't connect to device");
+		close(sk);
+		if (cups_class)
+			return CUPS_BACKEND_FAILED;
+		else
+			return CUPS_BACKEND_RETRY;
+	}
+
+	fputs("STATE: -connecting-to-device\n", stderr);
+
+	/* Ignore SIGTERM signals if printing from stdin */
+	if (fd == 0) {
+#ifdef HAVE_SIGSET
+		sigset(SIGTERM, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+		memset(&action, 0, sizeof(action));
+		sigemptyset(&action.sa_mask);
+		action.sa_handler = SIG_IGN;
+		sigaction(SIGTERM, &action, NULL);
+#else
+		signal(SIGTERM, SIG_IGN);
+#endif /* HAVE_SIGSET */
+	}
+
+	for (i = 0; i < copies; i++) {
+
+		if (fd != 0) {
+			fprintf(stderr, "PAGE: 1 1\n");
+			lseek(fd, 0, SEEK_SET);
+		}
+
+		while ((len = read(fd, buf, sizeof(buf))) > 0) {
+			err = write(sk, buf, len);
+			if (err < 0) {
+				perror("ERROR: Error writing to device");
+				close(sk);
+				return CUPS_BACKEND_FAILED;
+			}
+		}
+
+	}
+
+	close(sk);
+
+	return CUPS_BACKEND_OK;
+}
-- 
1.7.10.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 14/14] plugins: remove unmaintained plugins
  2012-07-09 21:10 [PATCH 01/14] input: remove unneeded header inclusions Gustavo Padovan
                   ` (6 preceding siblings ...)
  2012-07-09 21:10 ` [PATCH 12/14] cups: move it to " Gustavo Padovan
@ 2012-07-09 21:10 ` Gustavo Padovan
  7 siblings, 0 replies; 10+ messages in thread
From: Gustavo Padovan @ 2012-07-09 21:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

---
 Makefile.am         |   15 --
 acinclude.m4        |   18 --
 bootstrap-configure |    2 -
 plugins/hal.c       |  144 --------------
 plugins/maemo6.c    |  283 ---------------------------
 plugins/pnat.c      |  526 ---------------------------------------------------
 6 files changed, 988 deletions(-)
 delete mode 100644 plugins/hal.c
 delete mode 100644 plugins/maemo6.c
 delete mode 100644 plugins/pnat.c

diff --git a/Makefile.am b/Makefile.am
index a769228..65d2b78 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -132,11 +132,6 @@ mcap_sources += profiles/health/mcap_lib.h profiles/health/mcap_internal.h \
 		profiles/health/mcap_sync.c
 endif
 
-if PNATPLUGIN
-builtin_modules += pnat
-builtin_sources += plugins/pnat.c
-endif
-
 if AUDIOPLUGIN
 builtin_modules += audio
 builtin_sources += audio/main.c \
@@ -248,13 +243,8 @@ endif
 builtin_modules += mgmtops
 builtin_sources += plugins/mgmtops.c
 
-if HAL
-builtin_modules += hal
-builtin_sources += plugins/hal.c
-else
 builtin_modules += formfactor
 builtin_sources += plugins/formfactor.c
-endif
 
 EXTRA_DIST += plugins/hal.c plugins/formfactor.c
 
@@ -269,11 +259,6 @@ builtin_modules += wiimote
 builtin_sources += plugins/wiimote.c
 endif
 
-if MAEMO6PLUGIN
-builtin_modules += maemo6
-builtin_sources += plugins/maemo6.c
-endif
-
 if DBUSOOBPLUGIN
 builtin_modules += dbusoob
 builtin_sources += plugins/dbusoob.c
diff --git a/acinclude.m4 b/acinclude.m4
index 842eea3..39b0a18 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -167,7 +167,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	fortify_enable=yes
 	pie_enable=yes
 	sndfile_enable=${sndfile_found}
-	hal_enable=no
 	usb_enable=${usb_found}
 	gstreamer_enable=${gstreamer_found}
 	audio_enable=yes
@@ -176,7 +175,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	sap_enable=no
 	service_enable=yes
 	health_enable=no
-	pnat_enable=no
 	tools_enable=yes
 	cups_enable=no
 	test_enable=no
@@ -186,7 +184,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	dfutool_enable=no
 	datafiles_enable=yes
 	telephony_driver=dummy
-	maemo6_enable=no
 	sap_driver=dummy
 	dbusoob_enable=no
 	wiimote_enable=no
@@ -233,10 +230,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 		health_enable=${enableval}
 	])
 
-	AC_ARG_ENABLE(pnat, AC_HELP_STRING([--enable-pnat], [enable pnat plugin]), [
-		pnat_enable=${enableval}
-	])
-
 	AC_ARG_ENABLE(gstreamer, AC_HELP_STRING([--enable-gstreamer], [enable GStreamer support]), [
 		gstreamer_enable=${enableval}
 	])
@@ -287,10 +280,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 
 	AC_SUBST([TELEPHONY_DRIVER], [telephony-${telephony_driver}.c])
 
-	AC_ARG_ENABLE(maemo6, AC_HELP_STRING([--enable-maemo6], [compile with maemo6 plugin]), [
-		maemo6_enable=${enableval}
-	])
-
 	AC_ARG_ENABLE(dbusoob, AC_HELP_STRING([--enable-dbusoob], [compile with D-Bus OOB plugin]), [
 		dbusoob_enable=${enableval}
 	])
@@ -299,10 +288,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 		wiimote_enable=${enableval}
 	])
 
-	AC_ARG_ENABLE(hal, AC_HELP_STRING([--enable-hal], [Use HAL to determine adapter class]), [
-		hal_enable=${enableval}
-	])
-
 	AC_ARG_ENABLE(gatt, AC_HELP_STRING([--enable-gatt], [enable gatt module]), [
 		gatt_enable=${enableval}
 	])
@@ -345,9 +330,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	AM_CONDITIONAL(SERVICEPLUGIN, test "${service_enable}" = "yes")
 	AM_CONDITIONAL(HEALTHPLUGIN, test "${health_enable}" = "yes")
 	AM_CONDITIONAL(MCAP, test "${health_enable}" = "yes")
-	AM_CONDITIONAL(HAL, test "${hal_enable}" = "yes")
 	AM_CONDITIONAL(READLINE, test "${readline_found}" = "yes")
-	AM_CONDITIONAL(PNATPLUGIN, test "${pnat_enable}" = "yes")
 	AM_CONDITIONAL(CUPS, test "${cups_enable}" = "yes")
 	AM_CONDITIONAL(TEST, test "${test_enable}" = "yes" && test "${check_found}" = "yes")
 	AM_CONDITIONAL(TOOLS, test "${tools_enable}" = "yes")
@@ -356,7 +339,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	AM_CONDITIONAL(HID2HCI, test "${hid2hci_enable}" = "yes" && test "${usb_found}" = "yes" && test "${udev_found}" = "yes")
 	AM_CONDITIONAL(DFUTOOL, test "${dfutool_enable}" = "yes" && test "${usb_found}" = "yes")
 	AM_CONDITIONAL(DATAFILES, test "${datafiles_enable}" = "yes")
-	AM_CONDITIONAL(MAEMO6PLUGIN, test "${maemo6_enable}" = "yes")
 	AM_CONDITIONAL(DBUSOOBPLUGIN, test "${dbusoob_enable}" = "yes")
 	AM_CONDITIONAL(WIIMOTEPLUGIN, test "${wiimote_enable}" = "yes")
 	AM_CONDITIONAL(GATTMODULES, test "${gatt_enable}" = "yes")
diff --git a/bootstrap-configure b/bootstrap-configure
index ff63c58..7177c65 100755
--- a/bootstrap-configure
+++ b/bootstrap-configure
@@ -24,8 +24,6 @@ fi
 		--enable-test \
 		--enable-cups \
 		--enable-dbusoob \
-		--enable-maemo6 \
-		--enable-pnat \
 		--enable-sap \
 		--enable-wiimote \
 		--disable-pcmcia \
diff --git a/plugins/hal.c b/plugins/hal.c
deleted file mode 100644
index 21d7688..0000000
--- a/plugins/hal.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2004-2010  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 <errno.h>
-#include <dbus/dbus.h>
-
-#include <bluetooth/bluetooth.h>
-
-#include "plugin.h"
-#include "adapter.h"
-#include "log.h"
-
-static void formfactor_reply(DBusPendingCall *call, void *user_data)
-{
-	struct btd_adapter *adapter = user_data;
-	const char *formfactor = NULL;
-	DBusMessage *reply;
-	uint8_t minor = 0;
-
-	reply = dbus_pending_call_steal_reply(call);
-
-	if (dbus_set_error_from_message(NULL, reply) == TRUE) {
-		error("Failed to access HAL");
-		dbus_message_unref(reply);
-		return;
-	}
-
-	if (dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &formfactor,
-						DBUS_TYPE_INVALID) == FALSE) {
-		error("Wrong formfactor arguments");
-		dbus_message_unref(reply);
-		return;
-	}
-
-	DBG("Computer is classified as %s", formfactor);
-
-	if (formfactor != NULL) {
-		if (g_str_equal(formfactor, "laptop") == TRUE)
-			minor |= (1 << 2) | (1 << 3);
-		else if (g_str_equal(formfactor, "desktop") == TRUE)
-			minor |= 1 << 2;
-		else if (g_str_equal(formfactor, "server") == TRUE)
-			minor |= 1 << 3;
-		else if (g_str_equal(formfactor, "handheld") == TRUE)
-			minor += 1 << 4;
-	}
-
-	dbus_message_unref(reply);
-
-	/* Computer major class */
-	DBG("Setting 0x%06x for major/minor device class", (1 << 8) | minor);
-
-	btd_adapter_set_class(adapter, 0x01, minor);
-}
-
-static DBusConnection *connection;
-
-static int hal_probe(struct btd_adapter *adapter)
-{
-	const char *property = "system.formfactor";
-	DBusMessage *message;
-	DBusPendingCall *call;
-
-	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
-	if (connection == NULL)
-		return -ENOMEM;
-
-	message = dbus_message_new_method_call("org.freedesktop.Hal",
-				"/org/freedesktop/Hal/devices/computer",
-						"org.freedesktop.Hal.Device",
-							"GetPropertyString");
-	if (message == NULL) {
-		error("Failed to create formfactor request");
-		dbus_connection_unref(connection);
-		return -ENOMEM;
-	}
-
-	dbus_message_append_args(message, DBUS_TYPE_STRING, &property,
-							DBUS_TYPE_INVALID);
-
-	if (dbus_connection_send_with_reply(connection, message,
-						&call, -1) == FALSE) {
-		error("Failed to send formfactor request");
-		dbus_message_unref(message);
-		dbus_connection_unref(connection);
-		return -EIO;
-	}
-
-	dbus_pending_call_set_notify(call, formfactor_reply, adapter, NULL);
-
-	dbus_pending_call_unref(call);
-
-	dbus_message_unref(message);
-
-	return 0;
-}
-
-static void hal_remove(struct btd_adapter *adapter)
-{
-	dbus_connection_unref(connection);
-}
-
-static struct btd_adapter_driver hal_driver = {
-	.name	= "hal",
-	.probe	= hal_probe,
-	.remove	= hal_remove,
-};
-
-static int hal_init(void)
-{
-	return btd_register_adapter_driver(&hal_driver);
-}
-
-static void hal_exit(void)
-{
-	btd_unregister_adapter_driver(&hal_driver);
-}
-
-BLUETOOTH_PLUGIN_DEFINE(hal, VERSION,
-		BLUETOOTH_PLUGIN_PRIORITY_LOW, hal_init, hal_exit)
diff --git a/plugins/maemo6.c b/plugins/maemo6.c
deleted file mode 100644
index 4819af4..0000000
--- a/plugins/maemo6.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2006-2010  Nokia Corporation
- *  Copyright (C) 2004-2010  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 <glib.h>
-#include <dbus/dbus.h>
-
-#include "adapter.h"
-#include "plugin.h"
-#include "log.h"
-#include "gdbus.h"
-
-/* from mce/mode-names.h */
-#define MCE_RADIO_STATE_BLUETOOTH	(1 << 3)
-
-/* from mce/dbus-names.h */
-#define MCE_SERVICE			"com.nokia.mce"
-#define MCE_REQUEST_IF			"com.nokia.mce.request"
-#define MCE_SIGNAL_IF			"com.nokia.mce.signal"
-#define MCE_REQUEST_PATH		"/com/nokia/mce/request"
-#define MCE_SIGNAL_PATH			"/com/nokia/mce/signal"
-#define MCE_RADIO_STATES_CHANGE_REQ	"req_radio_states_change"
-#define MCE_RADIO_STATES_GET		"get_radio_states"
-#define MCE_RADIO_STATES_SIG		"radio_states_ind"
-#define MCE_TKLOCK_MODE_SIG		"tklock_mode_ind"
-
-static guint watch_id;
-static guint tklock_watch_id;
-static DBusConnection *conn = NULL;
-static gboolean mce_bt_set = FALSE;
-static gboolean mce_bt_on = FALSE;
-
-static gboolean mce_tklock_mode_cb(DBusConnection *connection,
-					DBusMessage *message, void *user_data)
-{
-	struct btd_adapter *adapter = user_data;
-	DBusMessageIter args;
-	const char *sigvalue;
-
-	if (!dbus_message_iter_init(message, &args)) {
-		error("message has no arguments");
-	} else if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_STRING) {
-		error("argument is not string");
-	} else {
-
-		dbus_message_iter_get_basic(&args, &sigvalue);
-		DBG("got signal with value %s", sigvalue);
-
-		if (g_strcmp0("unlocked", sigvalue) == 0 && mce_bt_on)
-			btd_adapter_enable_auto_connect(adapter);
-	}
-
-	return TRUE;
-}
-
-static gboolean mce_signal_callback(DBusConnection *connection,
-					DBusMessage *message, void *user_data)
-{
-	DBusMessageIter args;
-	uint32_t sigvalue;
-	struct btd_adapter *adapter = user_data;
-	int err;
-
-	DBG("received mce signal");
-
-	if (!dbus_message_iter_init(message, &args))
-		error("message has no arguments");
-	else if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&args))
-		error("argument is not uint32");
-	else {
-		dbus_message_iter_get_basic(&args, &sigvalue);
-		DBG("got signal with value %u", sigvalue);
-
-		/* set the adapter according to the mce signal
-		   and remember the value */
-		mce_bt_on = sigvalue & MCE_RADIO_STATE_BLUETOOTH ? TRUE : FALSE;
-
-		if (mce_bt_on)
-			err = btd_adapter_switch_online(adapter);
-		else
-			err = btd_adapter_switch_offline(adapter);
-
-		if (err == 0)
-			mce_bt_set = TRUE;
-
-	}
-
-	return TRUE;
-}
-
-static void read_radio_states_cb(DBusPendingCall *call, void *user_data)
-{
-	DBusError derr;
-	DBusMessage *reply;
-	dbus_uint32_t radio_states;
-	struct btd_adapter *adapter = user_data;
-	int err;
-
-	reply = dbus_pending_call_steal_reply(call);
-
-	dbus_error_init(&derr);
-	if (dbus_set_error_from_message(&derr, reply)) {
-		error("mce replied with an error: %s, %s",
-				derr.name, derr.message);
-		dbus_error_free(&derr);
-		goto done;
-	}
-
-	if (dbus_message_get_args(reply, &derr,
-				DBUS_TYPE_UINT32, &radio_states,
-				DBUS_TYPE_INVALID) == FALSE) {
-		error("unable to parse get_radio_states reply: %s, %s",
-							derr.name, derr.message);
-		dbus_error_free(&derr);
-		goto done;
-	}
-
-	DBG("radio_states: %d", radio_states);
-
-	mce_bt_on = radio_states & MCE_RADIO_STATE_BLUETOOTH ? TRUE : FALSE;
-
-	if (mce_bt_on)
-		err = btd_adapter_switch_online(adapter);
-	else
-		err = btd_adapter_switch_offline(adapter);
-
-	if (err == 0)
-		mce_bt_set = TRUE;
-
-done:
-	dbus_message_unref(reply);
-}
-
-static void adapter_powered(struct btd_adapter *adapter, gboolean powered)
-{
-	DBusMessage *msg;
-	static gboolean startup = TRUE;
-
-	DBG("adapter_powered called with %d", powered);
-
-	if (startup) {
-		DBusPendingCall *call;
-
-		/* Initialization: sync adapter state and MCE radio state */
-
-		DBG("Startup: reading MCE Bluetooth radio state...");
-		startup = FALSE;
-
-		msg = dbus_message_new_method_call(MCE_SERVICE,
-					MCE_REQUEST_PATH, MCE_REQUEST_IF,
-					MCE_RADIO_STATES_GET);
-
-		if (!dbus_connection_send_with_reply(conn, msg, &call, -1)) {
-			error("calling %s failed", MCE_RADIO_STATES_GET);
-			dbus_message_unref(msg);
-			return;
-		}
-
-		dbus_pending_call_set_notify(call, read_radio_states_cb,
-								adapter, NULL);
-		dbus_pending_call_unref(call);
-		dbus_message_unref(msg);
-		return;
-	}
-
-	/* MCE initiated operation */
-	if (mce_bt_set == TRUE) {
-		mce_bt_set = FALSE;
-		return;
-	}
-
-	/* Non MCE operation: set MCE according to adapter state */
-	if (mce_bt_on != powered) {
-		dbus_uint32_t radio_states;
-		dbus_uint32_t radio_mask = MCE_RADIO_STATE_BLUETOOTH;
-
-		msg = dbus_message_new_method_call(MCE_SERVICE,
-					MCE_REQUEST_PATH, MCE_REQUEST_IF,
-					MCE_RADIO_STATES_CHANGE_REQ);
-
-		radio_states = (powered ? MCE_RADIO_STATE_BLUETOOTH : 0);
-
-		DBG("Changing MCE Bluetooth radio state to: %d", radio_states);
-
-		dbus_message_append_args(msg, DBUS_TYPE_UINT32, &radio_states,
-					DBUS_TYPE_UINT32, &radio_mask,
-					DBUS_TYPE_INVALID);
-
-		if (dbus_connection_send(conn, msg, NULL))
-			mce_bt_on = powered;
-		else
-			error("calling %s failed", MCE_RADIO_STATES_CHANGE_REQ);
-
-		dbus_message_unref(msg);
-	}
-}
-
-static int mce_probe(struct btd_adapter *adapter)
-{
-
-	DBG("path %s", adapter_get_path(adapter));
-
-	watch_id = g_dbus_add_signal_watch(conn, NULL, MCE_SIGNAL_PATH,
-					MCE_SIGNAL_IF, MCE_RADIO_STATES_SIG,
-					mce_signal_callback, adapter, NULL);
-
-	tklock_watch_id = g_dbus_add_signal_watch(conn, NULL, MCE_SIGNAL_PATH,
-					MCE_SIGNAL_IF, MCE_TKLOCK_MODE_SIG,
-					mce_tklock_mode_cb, adapter, NULL);
-
-	btd_adapter_register_powered_callback(adapter, adapter_powered);
-
-	return 0;
-}
-
-static void mce_remove(struct btd_adapter *adapter)
-{
-	DBG("path %s", adapter_get_path(adapter));
-
-	if (watch_id > 0)
-		g_dbus_remove_watch(conn, watch_id);
-
-	if (tklock_watch_id > 0)
-		g_dbus_remove_watch(conn, tklock_watch_id);
-
-	btd_adapter_unregister_powered_callback(adapter, adapter_powered);
-}
-
-static struct btd_adapter_driver mce_driver = {
-	.name	= "mce",
-	.probe	= mce_probe,
-	.remove	= mce_remove,
-};
-
-static int maemo6_init(void)
-{
-	DBG("init maemo6 plugin");
-
-	conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
-	if (conn == NULL) {
-		error("Unable to connect to D-Bus");
-		return -1;
-	}
-
-	return btd_register_adapter_driver(&mce_driver);
-}
-
-static void maemo6_exit(void)
-{
-	DBG("exit maemo6 plugin");
-
-	if (conn != NULL)
-		dbus_connection_unref(conn);
-
-	btd_unregister_adapter_driver(&mce_driver);
-}
-
-BLUETOOTH_PLUGIN_DEFINE(maemo6, VERSION,
-		BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, maemo6_init, maemo6_exit)
diff --git a/plugins/pnat.c b/plugins/pnat.c
deleted file mode 100644
index 3c611a9..0000000
--- a/plugins/pnat.c
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2010  Nokia Corporation
- *  Copyright (C) 2010  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 <errno.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <fcntl.h>
-
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/rfcomm.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
-#include <bluetooth/uuid.h>
-
-#include <glib.h>
-
-#include <gdbus.h>
-
-#include "plugin.h"
-#include "sdpd.h"
-#include "btio.h"
-#include "adapter.h"
-#include "log.h"
-
-/* FIXME: This location should be build-time configurable */
-#define PNATD "/usr/bin/phonet-at"
-
-#define DUN_CHANNEL 1
-
-#define TTY_TIMEOUT 100
-#define TTY_TRIES 10
-
-struct dun_client {
-	bdaddr_t bda;
-
-	GIOChannel *io;	/* Client socket */
-	guint io_watch;	/* Client IO watch id */
-
-	guint tty_timer;
-	int tty_tries;
-	gboolean tty_open;
-	int tty_id;
-	char tty_name[PATH_MAX];
-
-	GPid pnatd_pid;
-};
-
-struct dun_server {
-	bdaddr_t bda;		/* Local adapter address */
-
-	uint32_t record_handle; /* Local SDP record handle */
-	GIOChannel *server;	/* Server socket */
-
-	int rfcomm_ctl;
-
-	struct dun_client client;
-};
-
-static GSList *servers = NULL;
-
-static void disconnect(struct dun_server *server)
-{
-	struct dun_client *client = &server->client;
-
-	if (!client->io)
-		return;
-
-	if (client->io_watch > 0) {
-		g_source_remove(client->io_watch);
-		client->io_watch = 0;
-	}
-
-	g_io_channel_shutdown(client->io, TRUE, NULL);
-	g_io_channel_unref(client->io);
-	client->io = NULL;
-
-	if (client->pnatd_pid > 0) {
-		kill(client->pnatd_pid, SIGTERM);
-		client->pnatd_pid = 0;
-	}
-
-	if (client->tty_timer > 0) {
-		g_source_remove(client->tty_timer);
-		client->tty_timer = 0;
-	}
-
-	if (client->tty_id >= 0) {
-		struct rfcomm_dev_req req;
-
-		memset(&req, 0, sizeof(req));
-		req.dev_id = client->tty_id;
-		req.flags = (1 << RFCOMM_HANGUP_NOW);
-		ioctl(server->rfcomm_ctl, RFCOMMRELEASEDEV, &req);
-
-		client->tty_name[0] = '\0';
-		client->tty_open = FALSE;
-		client->tty_id = -1;
-	}
-}
-
-static gboolean client_event(GIOChannel *chan,
-					GIOCondition cond, gpointer data)
-{
-	struct dun_server *server = data;
-	struct dun_client *client = &server->client;
-	char addr[18];
-
-	ba2str(&client->bda, addr);
-
-	DBG("Disconnected DUN from %s (%s)", addr, client->tty_name);
-
-	client->io_watch = 0;
-	disconnect(server);
-
-	return FALSE;
-}
-
-static void pnatd_exit(GPid pid, gint status, gpointer user_data)
-{
-	struct dun_server *server = user_data;
-	struct dun_client *client = &server->client;
-
-        if (WIFEXITED(status))
-                DBG("pnatd (%d) exited with status %d", pid,
-							WEXITSTATUS(status));
-        else
-                DBG("pnatd (%d) was killed by signal %d", pid,
-							WTERMSIG(status));
-	g_spawn_close_pid(pid);
-
-	if (pid != client->pnatd_pid)
-		return;
-
-	/* So disconnect() doesn't send SIGTERM to a non-existing process */
-	client->pnatd_pid = 0;
-
-	disconnect(server);
-}
-
-static gboolean start_pnatd(struct dun_server *server)
-{
-	struct dun_client *client = &server->client;
-	GSpawnFlags flags = G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH;
-	char *argv[] = { PNATD, client->tty_name, NULL };
-	GError *err = NULL;
-	GPid pid;
-
-	g_spawn_async(NULL, argv, NULL, flags, NULL, NULL, &pid, &err);
-	if (err != NULL) {
-		error("Unable to spawn pnatd: %s", err->message);
-		g_error_free(err);
-		return FALSE;
-	}
-
-	DBG("pnatd started for %s with pid %d", client->tty_name, pid);
-
-	client->pnatd_pid = pid;
-
-	/* We do not store the GSource id since g_remove_source doesn't
-	 * make sense for a child watch. If the callback gets removed
-	 * waitpid won't be called and the child remains as a zombie)
-	 */
-	g_child_watch_add(pid, pnatd_exit, server);
-
-	return TRUE;
-}
-
-static gboolean tty_try_open(gpointer user_data)
-{
-	struct dun_server *server = user_data;
-	struct dun_client *client = &server->client;
-	int tty_fd;
-
-	tty_fd = open(client->tty_name, O_RDONLY | O_NOCTTY);
-	if (tty_fd < 0) {
-		if (errno == EACCES)
-			goto disconnect;
-
-		client->tty_tries--;
-
-		if (client->tty_tries <= 0)
-			goto disconnect;
-
-		return TRUE;
-	}
-
-	DBG("%s created for DUN", client->tty_name);
-
-	client->tty_open = TRUE;
-	client->tty_timer = 0;
-
-	g_io_channel_unref(client->io);
-	g_source_remove(client->io_watch);
-
-	client->io = g_io_channel_unix_new(tty_fd);
-	client->io_watch = g_io_add_watch(client->io,
-					G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-					client_event, server);
-
-	if (!start_pnatd(server))
-		goto disconnect;
-
-	return FALSE;
-
-disconnect:
-	client->tty_timer = 0;
-	disconnect(server);
-	return FALSE;
-}
-
-static gboolean create_tty(struct dun_server *server)
-{
-	struct dun_client *client = &server->client;
-	struct rfcomm_dev_req req;
-	int sk = g_io_channel_unix_get_fd(client->io);
-
-	memset(&req, 0, sizeof(req));
-	req.dev_id = -1;
-	req.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP);
-
-	bacpy(&req.src, &server->bda);
-	bacpy(&req.dst, &client->bda);
-
-	bt_io_get(client->io, BT_IO_RFCOMM, NULL,
-			BT_IO_OPT_DEST_CHANNEL, &req.channel,
-			BT_IO_OPT_INVALID);
-
-	client->tty_id = ioctl(sk, RFCOMMCREATEDEV, &req);
-	if (client->tty_id < 0) {
-		error("Can't create RFCOMM TTY: %s", strerror(errno));
-		return FALSE;
-	}
-
-	snprintf(client->tty_name, PATH_MAX - 1, "/dev/rfcomm%d",
-							client->tty_id);
-
-	client->tty_tries = TTY_TRIES;
-
-	tty_try_open(server);
-	if (!client->tty_open && client->tty_tries > 0)
-		client->tty_timer = g_timeout_add(TTY_TIMEOUT,
-							tty_try_open, server);
-
-	return TRUE;
-}
-
-static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
-{
-	struct dun_server *server = user_data;
-
-	if (err) {
-		error("Accepting DUN connection failed: %s", err->message);
-		disconnect(server);
-		return;
-	}
-
-	if (!create_tty(server)) {
-		error("Device creation failed");
-		disconnect(server);
-	}
-}
-
-static void auth_cb(DBusError *derr, void *user_data)
-{
-	struct dun_server *server = user_data;
-	struct dun_client *client = &server->client;
-	GError *err = NULL;
-
-	if (derr && dbus_error_is_set(derr)) {
-		error("DUN access denied: %s", derr->message);
-		goto drop;
-	}
-
-	if (!bt_io_accept(client->io, connect_cb, server, NULL, &err)) {
-		error("bt_io_accept: %s", err->message);
-		g_error_free(err);
-		goto drop;
-	}
-
-	return;
-
-drop:
-	disconnect(server);
-}
-
-static gboolean auth_watch(GIOChannel *chan, GIOCondition cond, gpointer data)
-{
-	struct dun_server *server = data;
-	struct dun_client *client = &server->client;
-
-	error("DUN client disconnected while waiting for authorization");
-
-	btd_cancel_authorization(&server->bda, &client->bda);
-
-	disconnect(server);
-
-	return FALSE;
-}
-
-static void confirm_cb(GIOChannel *io, gpointer user_data)
-{
-	struct dun_server *server = user_data;
-	struct dun_client *client = &server->client;
-	GError *err = NULL;
-
-	if (client->io) {
-		error("Rejecting DUN connection since one already exists");
-		return;
-	}
-
-	bt_io_get(io, BT_IO_RFCOMM, &err,
-			BT_IO_OPT_DEST_BDADDR, &client->bda,
-			BT_IO_OPT_INVALID);
-	if (err != NULL) {
-		error("Unable to get DUN source and dest address: %s",
-								err->message);
-		g_error_free(err);
-		return;
-	}
-
-	if (btd_request_authorization(&server->bda, &client->bda, DUN_GW_UUID,
-						auth_cb, user_data) < 0) {
-		error("Requesting DUN authorization failed");
-		return;
-	}
-
-	client->io_watch = g_io_add_watch(io, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-						(GIOFunc) auth_watch, server);
-	client->io = g_io_channel_ref(io);
-}
-
-static sdp_record_t *dun_record(uint8_t ch)
-{
-	sdp_list_t *svclass_id, *pfseq, *apseq, *root, *aproto;
-	uuid_t root_uuid, dun, gn, l2cap, rfcomm;
-	sdp_profile_desc_t profile;
-	sdp_list_t *proto[2];
-	sdp_record_t *record;
-	sdp_data_t *channel;
-
-	record = sdp_record_alloc();
-	if (!record)
-		return NULL;
-
-	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
-	root = sdp_list_append(NULL, &root_uuid);
-	sdp_set_browse_groups(record, root);
-
-	sdp_uuid16_create(&dun, DIALUP_NET_SVCLASS_ID);
-	svclass_id = sdp_list_append(NULL, &dun);
-	sdp_uuid16_create(&gn,  GENERIC_NETWORKING_SVCLASS_ID);
-	svclass_id = sdp_list_append(svclass_id, &gn);
-	sdp_set_service_classes(record, svclass_id);
-
-	sdp_uuid16_create(&profile.uuid, DIALUP_NET_PROFILE_ID);
-	profile.version = 0x0100;
-	pfseq = sdp_list_append(NULL, &profile);
-	sdp_set_profile_descs(record, pfseq);
-
-	sdp_uuid16_create(&l2cap, L2CAP_UUID);
-	proto[0] = sdp_list_append(NULL, &l2cap);
-	apseq = sdp_list_append(NULL, proto[0]);
-
-	sdp_uuid16_create(&rfcomm, RFCOMM_UUID);
-	proto[1] = sdp_list_append(NULL, &rfcomm);
-	channel = sdp_data_alloc(SDP_UINT8, &ch);
-	proto[1] = sdp_list_append(proto[1], channel);
-	apseq = sdp_list_append(apseq, proto[1]);
-
-	aproto = sdp_list_append(0, apseq);
-	sdp_set_access_protos(record, aproto);
-
-	sdp_set_info_attr(record, "Dial-Up Networking", 0, 0);
-
-	sdp_data_free(channel);
-	sdp_list_free(root, NULL);
-	sdp_list_free(svclass_id, NULL);
-	sdp_list_free(proto[0], NULL);
-	sdp_list_free(proto[1], NULL);
-	sdp_list_free(pfseq, NULL);
-	sdp_list_free(apseq, NULL);
-	sdp_list_free(aproto, NULL);
-
-	return record;
-}
-
-static gint server_cmp(gconstpointer a, gconstpointer b)
-{
-	const struct dun_server *server = a;
-	const bdaddr_t *src = b;
-
-	return bacmp(src, &server->bda);
-}
-
-static int pnat_probe(struct btd_adapter *adapter)
-{
-	struct dun_server *server;
-	GIOChannel *io;
-	GError *err = NULL;
-	sdp_record_t *record;
-	bdaddr_t src;
-
-	adapter_get_address(adapter, &src);
-
-	server = g_new0(struct dun_server, 1);
-
-	io = bt_io_listen(BT_IO_RFCOMM, NULL, confirm_cb, server, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, &src,
-				BT_IO_OPT_CHANNEL, DUN_CHANNEL,
-				BT_IO_OPT_INVALID);
-	if (err != NULL) {
-		error("Failed to start DUN server: %s", err->message);
-		g_error_free(err);
-		goto fail;
-	}
-
-	record = dun_record(DUN_CHANNEL);
-	if (!record) {
-		error("Unable to allocate new service record");
-		goto fail;
-	}
-
-	if (add_record_to_server(&src, record) < 0) {
-		error("Unable to register DUN service record");
-		goto fail;
-	}
-
-	server->rfcomm_ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM);
-	if (server->rfcomm_ctl < 0) {
-		error("Unable to create RFCOMM control socket: %s (%d)",
-						strerror(errno), errno);
-		goto fail;
-	}
-
-	server->server = io;
-	server->record_handle = record->handle;
-	bacpy(&server->bda, &src);
-
-	servers = g_slist_append(servers, server);
-
-	return 0;
-
-fail:
-	if (io != NULL)
-		g_io_channel_unref(io);
-	g_free(server);
-	return -EIO;
-}
-
-static void pnat_remove(struct btd_adapter *adapter)
-{
-	struct dun_server *server;
-	GSList *match;
-	bdaddr_t src;
-
-	adapter_get_address(adapter, &src);
-
-	match = g_slist_find_custom(servers, &src, server_cmp);
-	if (match == NULL)
-		return;
-
-	server = match->data;
-
-	servers = g_slist_delete_link(servers, match);
-
-	disconnect(server);
-
-	remove_record_from_server(server->record_handle);
-	close(server->rfcomm_ctl);
-	g_io_channel_shutdown(server->server, TRUE, NULL);
-	g_io_channel_unref(server->server);
-	g_free(server);
-}
-
-static struct btd_adapter_driver pnat_server = {
-	.name	= "pnat-server",
-	.probe	= pnat_probe,
-	.remove	= pnat_remove,
-};
-
-static int pnat_init(void)
-{
-	DBG("Setup Phonet AT (DUN) plugin");
-
-	return btd_register_adapter_driver(&pnat_server);
-}
-
-static void pnat_exit(void)
-{
-	DBG("Cleanup Phonet AT (DUN) plugin");
-
-	btd_unregister_adapter_driver(&pnat_server);
-}
-
-BLUETOOTH_PLUGIN_DEFINE(pnat, VERSION,
-			BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
-			pnat_init, pnat_exit)
-- 
1.7.10.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 03/14] btmgmt: move to tools folder
  2012-07-09 21:10 ` [PATCH 03/14] btmgmt: move to tools folder Gustavo Padovan
@ 2012-07-10  2:36   ` Vinicius Costa Gomes
  0 siblings, 0 replies; 10+ messages in thread
From: Vinicius Costa Gomes @ 2012-07-10  2:36 UTC (permalink / raw)
  To: Gustavo Padovan; +Cc: linux-bluetooth, Gustavo Padovan

Hi Gustavo,

On 18:10 Mon 09 Jul, Gustavo Padovan wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> 
> ---
>  .gitignore     |    2 +-
>  Makefile.tools |    6 +-
>  mgmt/main.c    | 1933 --------------------------------------------------------
>  3 files changed, 4 insertions(+), 1937 deletions(-)
>  delete mode 100644 mgmt/main.c

It may be that I am missing something, but this doesn't look like a move.

> 
> diff --git a/.gitignore b/.gitignore
> index c7d079e..bc65dcf 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -86,7 +86,7 @@ compat/dund
>  compat/hidd
>  compat/pand
>  unit/test-eir
> -mgmt/btmgmt
> +tools/mgmt/btmgmt

Wouldn't it be just "tools/btmgmt"?

>  monitor/btmon
>  emulator/btvirt
>  
> diff --git a/Makefile.tools b/Makefile.tools
> index 3cb105c..56839b7 100644
> --- a/Makefile.tools
> +++ b/Makefile.tools
> @@ -50,10 +50,10 @@ tools_ppporc_LDADD = lib/libbluetooth-private.la
>  
>  tools_hcieventmask_LDADD = lib/libbluetooth-private.la
>  
> -noinst_PROGRAMS += mgmt/btmgmt monitor/btmon emulator/btvirt
> +noinst_PROGRAMS += tools/btmgmt monitor/btmon emulator/btvirt
>  
> -mgmt_btmgmt_SOURCES = mgmt/main.c src/glib-helper.c
> -mgmt_btmgmt_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@
> +tools_btmgmt_SOURCES = tools/btmgmt.c src/glib-helper.c
> +tools_btmgmt_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@
>  
>  monitor_btmon_SOURCES = monitor/main.c monitor/bt.h \
>  					monitor/mainloop.h monitor/mainloop.c \
> diff --git a/mgmt/main.c b/mgmt/main.c
> deleted file mode 100644
> index b2d6c3c..0000000
> --- a/mgmt/main.c
> +++ /dev/null
> @@ -1,1933 +0,0 @@
> -/*
> - *  BlueZ - Bluetooth protocol stack for Linux
> - *
> - *  Copyright (C) 2011  Intel Corporation. All rights reserved.
> - *
> - *  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 <stdlib.h>
> -#include <stdio.h>
> -#include <unistd.h>
> -#include <errno.h>
> -#include <string.h>
> -#include <sys/types.h>
> -#include <sys/socket.h>
> -#include <poll.h>
> -#include <getopt.h>
> -#include <stdbool.h>
> -
> -#include <bluetooth/bluetooth.h>
> -#include <bluetooth/hci.h>
> -#include <bluetooth/hci_lib.h>
> -#include <bluetooth/sdp.h>
> -#include <bluetooth/sdp_lib.h>
> -#include <bluetooth/mgmt.h>
> -
> -#include <glib.h>
> -#include "glib-helper.h"
> -
> -static bool monitor = false;
> -static bool discovery = false;
> -static bool resolve_names = true;
> -
> -typedef void (*cmd_cb)(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data);
> -
> -static struct pending_cmd {
> -	uint16_t op;
> -	uint16_t id;
> -	cmd_cb cb;
> -	void *user_data;
> -	struct pending_cmd *next;
> -} *pending = NULL;
> -
> -static int mgmt_send_cmd(int mgmt_sk, uint16_t op, uint16_t id, void *data,
> -				size_t len, cmd_cb func, void *user_data)
> -{
> -	char buf[1024];
> -	struct pending_cmd *cmd;
> -	struct mgmt_hdr *hdr = (void *) buf;
> -
> -	if (len + MGMT_HDR_SIZE > sizeof(buf))
> -		return -EINVAL;
> -
> -	cmd = calloc(1, sizeof(struct pending_cmd));
> -	if (cmd == NULL)
> -		return -errno;
> -
> -	cmd->op = op;
> -	cmd->id = id;
> -	cmd->cb = func;
> -	cmd->user_data = user_data;
> -
> -	memset(buf, 0, sizeof(buf));
> -	hdr->opcode = htobs(op);
> -	hdr->index = htobs(id);
> -	hdr->len = htobs(len);
> -	memcpy(buf + MGMT_HDR_SIZE, data, len);
> -
> -	if (write(mgmt_sk, buf, MGMT_HDR_SIZE + len) < 0) {
> -		fprintf(stderr, "Unable to write to socket: %s\n",
> -							strerror(errno));
> -		free(cmd);
> -		return -1;
> -	}
> -
> -	cmd->next = pending;
> -	pending = cmd;
> -
> -	return 0;
> -}
> -
> -static int mgmt_open(void)
> -{
> -	struct sockaddr_hci addr;
> -	int sk;
> -
> -	sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
> -	if (sk < 0) {
> -		fprintf(stderr, "socket: %s\n", strerror(errno));
> -		return sk;
> -	}
> -
> -	memset(&addr, 0, sizeof(addr));
> -	addr.hci_family = AF_BLUETOOTH;
> -	addr.hci_dev = HCI_DEV_NONE;
> -	addr.hci_channel = HCI_CHANNEL_CONTROL;
> -
> -	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
> -		fprintf(stderr, "bind: %s\n", strerror(errno));
> -		close(sk);
> -		return -1;
> -	}
> -
> -	return sk;
> -}
> -
> -static void mgmt_check_pending(int mgmt_sk, uint16_t op, uint16_t index,
> -				uint16_t status, void *data, uint16_t len)
> -{
> -	struct pending_cmd *c, *prev;
> -
> -	for (c = pending, prev = NULL; c != NULL; prev = c, c = c->next) {
> -		if (c->op != op)
> -			continue;
> -		if (c->id != index)
> -			continue;
> -
> -		if (c == pending)
> -			pending = c->next;
> -		else
> -			prev->next = c->next;
> -
> -		c->cb(mgmt_sk, op, index, status, data, len, c->user_data);
> -
> -		free(c);
> -		break;
> -	}
> -}
> -
> -static int mgmt_cmd_complete(int mgmt_sk, uint16_t index,
> -				struct mgmt_ev_cmd_complete *ev, uint16_t len)
> -{
> -	uint16_t op;
> -
> -	if (len < sizeof(*ev)) {
> -		fprintf(stderr, "Too short (%u bytes) cmd complete event\n",
> -									len);
> -		return -EINVAL;
> -	}
> -
> -	op = bt_get_le16(&ev->opcode);
> -
> -	len -= sizeof(*ev);
> -
> -	if (monitor)
> -		printf("%s complete, opcode 0x%04x len %u\n", mgmt_opstr(op),
> -								op, len);
> -
> -	mgmt_check_pending(mgmt_sk, op, index, ev->status, ev->data, len);
> -
> -	return 0;
> -}
> -
> -static int mgmt_cmd_status(int mgmt_sk, uint16_t index,
> -				struct mgmt_ev_cmd_status *ev, uint16_t len)
> -{
> -	uint16_t opcode;
> -
> -	if (len < sizeof(*ev)) {
> -		fprintf(stderr, "Too short (%u bytes) cmd status event\n",
> -									len);
> -		return -EINVAL;
> -	}
> -
> -	opcode = bt_get_le16(&ev->opcode);
> -
> -	if (monitor)
> -		printf("cmd status, opcode 0x%04x status 0x%02x (%s)\n",
> -				opcode, ev->status, mgmt_errstr(ev->status));
> -
> -	if (ev->status != 0)
> -		mgmt_check_pending(mgmt_sk, opcode, index, ev->status,
> -								NULL, 0);
> -
> -	return 0;
> -}
> -
> -static int mgmt_controller_error(uint16_t index,
> -					struct mgmt_ev_controller_error *ev,
> -					uint16_t len)
> -{
> -	if (len < sizeof(*ev)) {
> -		fprintf(stderr,
> -			"Too short (%u bytes) controller error event\n", len);
> -		return -EINVAL;
> -	}
> -
> -	if (monitor)
> -		printf("hci%u error 0x%02x\n", index, ev->error_code);
> -
> -	return 0;
> -}
> -
> -static int mgmt_index_added(int mgmt_sk, uint16_t index)
> -{
> -	if (monitor)
> -		printf("hci%u added\n", index);
> -	return 0;
> -}
> -
> -static int mgmt_index_removed(int mgmt_sk, uint16_t index)
> -{
> -	if (monitor)
> -		printf("hci%u removed\n", index);
> -	return 0;
> -}
> -
> -static const char *settings_str[] = {
> -				"powered",
> -				"connectable",
> -				"fast-connectable",
> -				"discoverable",
> -				"pairable",
> -				"link-security",
> -				"ssp",
> -				"br/edr",
> -				"hs",
> -				"le" ,
> -};
> -
> -static void print_settings(uint32_t settings)
> -{
> -	unsigned i;
> -
> -	for (i = 0; i < NELEM(settings_str); i++) {
> -		if ((settings & (1 << i)) != 0)
> -			printf("%s ", settings_str[i]);
> -	}
> -}
> -
> -static int mgmt_new_settings(int mgmt_sk, uint16_t index,
> -					uint32_t *ev, uint16_t len)
> -{
> -	if (len < sizeof(*ev)) {
> -		fprintf(stderr, "Too short new_settings event (%u)\n", len);
> -		return -EINVAL;
> -	}
> -
> -	if (monitor) {
> -		printf("hci%u new_settings: ", index);
> -		print_settings(bt_get_le32(ev));
> -		printf("\n");
> -	}
> -
> -	return 0;
> -}
> -
> -static int mgmt_discovering(int mgmt_sk, uint16_t index,
> -				struct mgmt_ev_discovering *ev, uint16_t len)
> -{
> -	if (len < sizeof(*ev)) {
> -		fprintf(stderr, "Too short (%u bytes) discovering event\n",
> -									len);
> -		return -EINVAL;
> -	}
> -
> -	if (ev->discovering == 0 && discovery)
> -		exit(EXIT_SUCCESS);
> -
> -	if (monitor)
> -		printf("hci%u type %u discovering %s\n", index,
> -				ev->type, ev->discovering ? "on" : "off");
> -
> -	return 0;
> -}
> -
> -static int mgmt_new_link_key(int mgmt_sk, uint16_t index,
> -				struct mgmt_ev_new_link_key *ev, uint16_t len)
> -{
> -
> -	if (len != sizeof(*ev)) {
> -		fprintf(stderr, "Invalid new_link_key length (%u bytes)\n",
> -									len);
> -		return -EINVAL;
> -	}
> -
> -	if (monitor) {
> -		char addr[18];
> -		ba2str(&ev->key.addr.bdaddr, addr);
> -		printf("hci%u new_link_key %s type 0x%02x pin_len %d "
> -				"store_hint %u\n", index, addr, ev->key.type,
> -				ev->key.pin_len, ev->store_hint);
> -	}
> -
> -	return 0;
> -}
> -
> -static const char *typestr(uint8_t type)
> -{
> -	const char *str[] = { "BR/EDR", "LE Public", "LE Random" };
> -
> -	if (type <= BDADDR_LE_RANDOM)
> -		return str[type];
> -
> -	return "(unknown)";
> -}
> -
> -static int mgmt_connected(int mgmt_sk, uint16_t index,
> -					struct mgmt_ev_device_connected *ev,
> -					uint16_t len)
> -{
> -	uint16_t eir_len;
> -
> -	if (len < sizeof(*ev)) {
> -		fprintf(stderr,
> -			"Invalid connected event length (%u bytes)\n", len);
> -		return -EINVAL;
> -	}
> -
> -	eir_len = bt_get_le16(&ev->eir_len);
> -	if (len != sizeof(*ev) + eir_len) {
> -		fprintf(stderr, "Invalid connected event length "
> -			"(%u bytes, eir_len %u bytes)\n", len, eir_len);
> -		return -EINVAL;
> -	}
> -
> -	if (monitor) {
> -		char addr[18];
> -		ba2str(&ev->addr.bdaddr, addr);
> -		printf("hci%u %s type %s connected eir_len %u\n", index, addr,
> -					typestr(ev->addr.type), eir_len);
> -	}
> -
> -	return 0;
> -}
> -
> -static int mgmt_disconnected(int mgmt_sk, uint16_t index,
> -				struct mgmt_addr_info *ev, uint16_t len)
> -{
> -	if (len != sizeof(*ev)) {
> -		fprintf(stderr,
> -			"Invalid disconnected event length (%u bytes)\n", len);
> -		return -EINVAL;
> -	}
> -
> -	if (monitor) {
> -		char addr[18];
> -		ba2str(&ev->bdaddr, addr);
> -		printf("hci%u %s type %s disconnected\n", index, addr,
> -							typestr(ev->type));
> -	}
> -
> -	return 0;
> -}
> -
> -static int mgmt_conn_failed(int mgmt_sk, uint16_t index,
> -				struct mgmt_ev_connect_failed *ev,
> -				uint16_t len)
> -{
> -	if (len != sizeof(*ev)) {
> -		fprintf(stderr,
> -			"Invalid connect_failed event length (%u bytes)\n", len);
> -		return -EINVAL;
> -	}
> -
> -	if (monitor) {
> -		char addr[18];
> -		ba2str(&ev->addr.bdaddr, addr);
> -		printf("hci%u %s type %s connect failed (status 0x%02x, %s)\n",
> -				index, addr, typestr(ev->addr.type), ev->status,
> -				mgmt_errstr(ev->status));
> -	}
> -
> -	return 0;
> -}
> -
> -static int mgmt_auth_failed(int mgmt_sk, uint16_t index,
> -				struct mgmt_ev_auth_failed *ev,
> -				uint16_t len)
> -{
> -	if (len != sizeof(*ev)) {
> -		fprintf(stderr,
> -			"Invalid auth_failed event length (%u bytes)\n", len);
> -		return -EINVAL;
> -	}
> -
> -	if (monitor) {
> -		char addr[18];
> -		ba2str(&ev->addr.bdaddr, addr);
> -		printf("hci%u %s auth failed with status 0x%02x (%s)\n",
> -			index, addr, ev->status, mgmt_errstr(ev->status));
> -	}
> -
> -	return 0;
> -}
> -
> -static int mgmt_name_changed(int mgmt_sk, uint16_t index,
> -				struct mgmt_ev_local_name_changed *ev,
> -				uint16_t len)
> -{
> -	if (len != sizeof(*ev)) {
> -		fprintf(stderr,
> -			"Invalid local_name_changed length (%u bytes)\n", len);
> -		return -EINVAL;
> -	}
> -
> -	if (monitor)
> -		printf("hci%u name changed: %s\n", index, ev->name);
> -
> -	return 0;
> -}
> -
> -static void confirm_name_rsp(int mgmt_sk, uint16_t op, uint16_t id,
> -				uint8_t status, void *rsp, uint16_t len,
> -				void *user_data)
> -{
> -	struct mgmt_rp_confirm_name *rp = rsp;
> -	char addr[18];
> -
> -	if (len == 0 && status != 0) {
> -		fprintf(stderr,
> -			"hci%u confirm_name failed with status 0x%02x (%s)\n",
> -					id, status, mgmt_errstr(status));
> -		return;
> -	}
> -
> -	if (len != sizeof(*rp)) {
> -		fprintf(stderr,
> -			"hci%u confirm_name rsp length %u instead of %zu\n",
> -			id, len, sizeof(*rp));
> -		return;
> -	}
> -
> -	ba2str(&rp->addr.bdaddr, addr);
> -
> -	if (status != 0)
> -		fprintf(stderr,
> -			"hci%u confirm_name for %s failed: 0x%02x (%s)\n",
> -			id, addr, status, mgmt_errstr(status));
> -	else
> -		printf("hci%u confirm_name succeeded for %s\n", id, addr);
> -}
> -
> -static int mgmt_device_found(int mgmt_sk, uint16_t index,
> -				struct mgmt_ev_device_found *ev, uint16_t len)
> -{
> -	uint32_t flags;
> -	uint16_t eir_len;
> -
> -	if (len < sizeof(*ev)) {
> -		fprintf(stderr,
> -			"Too short device_found length (%u bytes)\n", len);
> -		return -EINVAL;
> -	}
> -
> -	flags = btohs(ev->flags);
> -
> -	eir_len = bt_get_le16(&ev->eir_len);
> -	if (len != sizeof(*ev) + eir_len) {
> -		fprintf(stderr, "dev_found: expected %zu bytes, got %u bytes",
> -						sizeof(*ev) + eir_len, len);
> -		return -EINVAL;
> -	}
> -
> -	if (monitor || discovery) {
> -		char addr[18];
> -		ba2str(&ev->addr.bdaddr, addr);
> -		printf("hci%u dev_found: %s type %s rssi %d "
> -			"flags 0x%04x eir_len %u\n", index, addr,
> -			typestr(ev->addr.type), ev->rssi, flags, eir_len);
> -	}
> -
> -	if (discovery && (flags & MGMT_DEV_FOUND_CONFIRM_NAME)) {
> -		struct mgmt_cp_confirm_name cp;
> -
> -		memset(&cp, 0, sizeof(cp));
> -		memcpy(&cp.addr, &ev->addr, sizeof(cp.addr));
> -		if (resolve_names)
> -			cp.name_known = 0;
> -		else
> -			cp.name_known = 1;
> -
> -		mgmt_send_cmd(mgmt_sk, MGMT_OP_CONFIRM_NAME, index,
> -					&cp, sizeof(cp), confirm_name_rsp,
> -					NULL);
> -	}
> -
> -	return 0;
> -}
> -
> -static void pin_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data)
> -{
> -	if (status != 0) {
> -		fprintf(stderr,
> -			"hci%u PIN Code reply failed with status 0x%02x (%s)",
> -					id, status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	printf("hci%u PIN Reply successful\n", id);
> -}
> -
> -static int mgmt_pin_reply(int mgmt_sk, uint16_t index,
> -						struct mgmt_addr_info *addr,
> -						const char *pin, size_t len)
> -{
> -	struct mgmt_cp_pin_code_reply cp;
> -
> -	memset(&cp, 0, sizeof(cp));
> -	memcpy(&cp.addr, addr, sizeof(cp.addr));
> -	cp.pin_len = len;
> -	memcpy(cp.pin_code, pin, len);
> -
> -	return mgmt_send_cmd(mgmt_sk, MGMT_OP_PIN_CODE_REPLY, index,
> -					&cp, sizeof(cp), pin_rsp, NULL);
> -}
> -
> -static void pin_neg_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data)
> -{
> -	if (status != 0) {
> -		fprintf(stderr,
> -			"hci%u PIN Neg reply failed with status 0x%02x (%s)",
> -					id, status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	printf("hci%u PIN Negative Reply successful\n", id);
> -}
> -
> -static int mgmt_pin_neg_reply(int mgmt_sk, uint16_t index,
> -						struct mgmt_addr_info *addr)
> -{
> -	struct mgmt_cp_pin_code_neg_reply cp;
> -
> -	memset(&cp, 0, sizeof(cp));
> -	memcpy(&cp.addr, addr, sizeof(cp.addr));
> -
> -	return mgmt_send_cmd(mgmt_sk, MGMT_OP_PIN_CODE_NEG_REPLY, index,
> -					&cp, sizeof(cp), pin_neg_rsp, NULL);
> -}
> -
> -static int mgmt_request_pin(int mgmt_sk, uint16_t index,
> -				struct mgmt_ev_pin_code_request *ev,
> -				uint16_t len)
> -{
> -	char pin[18];
> -	size_t pin_len;
> -
> -	if (len != sizeof(*ev)) {
> -		fprintf(stderr,
> -			"Invalid pin_code request length (%u bytes)\n", len);
> -		return -EINVAL;
> -	}
> -
> -	if (monitor) {
> -		char addr[18];
> -		ba2str(&ev->addr.bdaddr, addr);
> -		printf("hci%u %s request PIN\n", index, addr);
> -	}
> -
> -	printf("PIN Request (press enter to reject) >> ");
> -	fflush(stdout);
> -
> -	memset(pin, 0, sizeof(pin));
> -
> -	if (fgets(pin, sizeof(pin), stdin) == NULL || pin[0] == '\n')
> -		return mgmt_pin_neg_reply(mgmt_sk, index, &ev->addr);
> -
> -	pin_len = strlen(pin);
> -	if (pin[pin_len - 1] == '\n') {
> -		pin[pin_len - 1] = '\0';
> -		pin_len--;
> -	}
> -
> -	return mgmt_pin_reply(mgmt_sk, index, &ev->addr, pin, pin_len);
> -}
> -
> -static void confirm_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data)
> -{
> -	if (status != 0) {
> -		fprintf(stderr,
> -			"hci%u User Confirm reply failed. status 0x%02x (%s)",
> -					id, status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	printf("hci%u User Confirm Reply successful\n", id);
> -}
> -
> -static int mgmt_confirm_reply(int mgmt_sk, uint16_t index, bdaddr_t *bdaddr)
> -{
> -	struct mgmt_cp_user_confirm_reply cp;
> -
> -	memset(&cp, 0, sizeof(cp));
> -	bacpy(&cp.addr.bdaddr, bdaddr);
> -
> -	return mgmt_send_cmd(mgmt_sk, MGMT_OP_USER_CONFIRM_REPLY, index,
> -					&cp, sizeof(cp), confirm_rsp, NULL);
> -}
> -
> -static void confirm_neg_rsp(int mgmt_sk, uint16_t op, uint16_t id,
> -				uint8_t status, void *rsp, uint16_t len,
> -				void *user_data)
> -{
> -	if (status != 0) {
> -		fprintf(stderr,
> -			"hci%u Confirm Neg reply failed. status 0x%02x (%s)",
> -					id, status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	printf("hci%u User Confirm Negative Reply successful\n", id);
> -}
> -
> -static int mgmt_confirm_neg_reply(int mgmt_sk, uint16_t index,
> -							bdaddr_t *bdaddr)
> -{
> -	struct mgmt_cp_user_confirm_reply cp;
> -
> -	memset(&cp, 0, sizeof(cp));
> -	bacpy(&cp.addr.bdaddr, bdaddr);
> -
> -	return mgmt_send_cmd(mgmt_sk, MGMT_OP_USER_CONFIRM_NEG_REPLY, index,
> -				&cp, sizeof(cp), confirm_neg_rsp, NULL);
> -}
> -
> -
> -static int mgmt_user_confirm(int mgmt_sk, uint16_t index,
> -				struct mgmt_ev_user_confirm_request *ev,
> -				uint16_t len)
> -{
> -	char rsp[5];
> -	size_t rsp_len;
> -	uint32_t val;
> -	char addr[18];
> -
> -	if (len != sizeof(*ev)) {
> -		fprintf(stderr,
> -			"Invalid user_confirm request length (%u)\n", len);
> -		return -EINVAL;
> -	}
> -
> -	ba2str(&ev->addr.bdaddr, addr);
> -	val = bt_get_le32(&ev->value);
> -
> -	if (monitor)
> -		printf("hci%u %s User Confirm %06u hint %u\n", index, addr,
> -							val, ev->confirm_hint);
> -
> -	if (ev->confirm_hint)
> -		printf("Accept pairing with %s (yes/no) >> ", addr);
> -	else
> -		printf("Confirm value %06u for %s (yes/no) >> ", val, addr);
> -
> -	fflush(stdout);
> -
> -	memset(rsp, 0, sizeof(rsp));
> -
> -	if (fgets(rsp, sizeof(rsp), stdin) == NULL || rsp[0] == '\n')
> -		return mgmt_confirm_neg_reply(mgmt_sk, index, &ev->addr.bdaddr);
> -
> -	rsp_len = strlen(rsp);
> -	if (rsp[rsp_len - 1] == '\n') {
> -		rsp[rsp_len - 1] = '\0';
> -		rsp_len--;
> -	}
> -
> -	if (rsp[0] == 'y' || rsp[0] == 'Y')
> -		return mgmt_confirm_reply(mgmt_sk, index, &ev->addr.bdaddr);
> -	else
> -		return mgmt_confirm_neg_reply(mgmt_sk, index, &ev->addr.bdaddr);
> -}
> -
> -static int mgmt_handle_event(int mgmt_sk, uint16_t ev, uint16_t index,
> -						void *data, uint16_t len)
> -{
> -	if (monitor)
> -		printf("event: %s\n", mgmt_evstr(ev));
> -
> -	switch (ev) {
> -	case MGMT_EV_CMD_COMPLETE:
> -		return mgmt_cmd_complete(mgmt_sk, index, data, len);
> -	case MGMT_EV_CMD_STATUS:
> -		return mgmt_cmd_status(mgmt_sk, index, data, len);
> -	case MGMT_EV_CONTROLLER_ERROR:
> -		return mgmt_controller_error(index, data, len);
> -	case MGMT_EV_INDEX_ADDED:
> -		return mgmt_index_added(mgmt_sk, index);
> -	case MGMT_EV_INDEX_REMOVED:
> -		return mgmt_index_removed(mgmt_sk, index);
> -	case MGMT_EV_NEW_SETTINGS:
> -		return mgmt_new_settings(mgmt_sk, index, data, len);
> -	case MGMT_EV_DISCOVERING:
> -		return mgmt_discovering(mgmt_sk, index, data, len);
> -	case MGMT_EV_NEW_LINK_KEY:
> -		return mgmt_new_link_key(mgmt_sk, index, data, len);
> -	case MGMT_EV_DEVICE_CONNECTED:
> -		return mgmt_connected(mgmt_sk, index, data, len);
> -	case MGMT_EV_DEVICE_DISCONNECTED:
> -		return mgmt_disconnected(mgmt_sk, index, data, len);
> -	case MGMT_EV_CONNECT_FAILED:
> -		return mgmt_conn_failed(mgmt_sk, index, data, len);
> -	case MGMT_EV_AUTH_FAILED:
> -		return mgmt_auth_failed(mgmt_sk, index, data, len);
> -	case MGMT_EV_LOCAL_NAME_CHANGED:
> -		return mgmt_name_changed(mgmt_sk, index, data, len);
> -	case MGMT_EV_DEVICE_FOUND:
> -		return mgmt_device_found(mgmt_sk, index, data, len);
> -	case MGMT_EV_PIN_CODE_REQUEST:
> -		return mgmt_request_pin(mgmt_sk, index, data, len);
> -	case MGMT_EV_USER_CONFIRM_REQUEST:
> -		return mgmt_user_confirm(mgmt_sk, index, data, len);
> -	default:
> -		if (monitor)
> -			printf("Unhandled event 0x%04x (%s)\n", ev, mgmt_evstr(ev));
> -		return 0;
> -	}
> -}
> -
> -static int mgmt_process_data(int mgmt_sk)
> -{
> -	char buf[1024];
> -	struct mgmt_hdr *hdr = (void *) buf;
> -	uint16_t len, ev, index;
> -	ssize_t ret;
> -
> -	ret = read(mgmt_sk, buf, sizeof(buf));
> -	if (ret < 0) {
> -		fprintf(stderr, "read: %s\n", strerror(errno));
> -		return ret;
> -	}
> -
> -	if (ret < MGMT_HDR_SIZE) {
> -		fprintf(stderr, "Too small mgmt packet (%zd bytes)\n", ret);
> -		return 0;
> -	}
> -
> -	ev = bt_get_le16(&hdr->opcode);
> -	index = bt_get_le16(&hdr->index);
> -	len = bt_get_le16(&hdr->len);
> -
> -	if (monitor)
> -		printf("event 0x%04x len 0x%04x index 0x%04x\n", ev, len, index);
> -
> -	if (ret != MGMT_HDR_SIZE + len) {
> -		fprintf(stderr, "Packet length mismatch. ret %zd len %u",
> -								ret, len);
> -		return 0;
> -	}
> -
> -	mgmt_handle_event(mgmt_sk, ev, index, buf + MGMT_HDR_SIZE, len);
> -
> -	return 0;
> -}
> -
> -static void cmd_monitor(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	printf("Monitoring mgmt events...\n");
> -	monitor = true;
> -}
> -
> -static void version_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data)
> -{
> -	struct mgmt_rp_read_version *rp = rsp;
> -
> -	if (status != 0) {
> -		fprintf(stderr, "Reading mgmt version failed with status"
> -			" 0x%02x (%s)\n", status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (len < sizeof(*rp)) {
> -		fprintf(stderr, "Too small version reply (%u bytes)\n", len);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	printf("MGMT Version %u, revision %u\n", rp->version,
> -						bt_get_le16(&rp->revision));
> -
> -	exit(EXIT_SUCCESS);
> -}
> -
> -static void cmd_version(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE,
> -					NULL, 0, version_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send read_version cmd\n");
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void commands_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data)
> -{
> -	struct mgmt_rp_read_commands *rp = rsp;
> -	uint16_t num_commands, num_events, *opcode;
> -	size_t expected_len;
> -	int i;
> -
> -	if (status != 0) {
> -		fprintf(stderr, "Reading supported commands failed with status"
> -			" 0x%02x (%s)\n", status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (len < sizeof(*rp)) {
> -		fprintf(stderr, "Too small commands reply (%u bytes)\n", len);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	num_commands = bt_get_le16(&rp->num_commands);
> -	num_events = bt_get_le16(&rp->num_events);
> -
> -	expected_len = sizeof(*rp) + num_commands * sizeof(uint16_t) +
> -						num_events * sizeof(uint16_t);
> -
> -	if (len < expected_len) {
> -		fprintf(stderr, "Too small commands reply (%u != %zu)\n",
> -							len, expected_len);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	opcode = rp->opcodes;
> -
> -	printf("%u commands:\n", num_commands);
> -	for (i = 0; i < num_commands; i++) {
> -		uint16_t op = bt_get_le16(opcode++);
> -		printf("\t%s (0x%04x)\n", mgmt_opstr(op), op);
> -	}
> -
> -	printf("%u events:\n", num_events);
> -	for (i = 0; i < num_events; i++) {
> -		uint16_t ev = bt_get_le16(opcode++);
> -		printf("\t%s (0x%04x)\n", mgmt_evstr(ev), ev);
> -	}
> -
> -	exit(EXIT_SUCCESS);
> -}
> -
> -static void cmd_commands(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE,
> -					NULL, 0, commands_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send read_commands cmd\n");
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void info_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data)
> -{
> -	struct mgmt_rp_read_info *rp = rsp;
> -	char addr[18];
> -
> -	if (status != 0) {
> -		fprintf(stderr,
> -			"Reading hci%u info failed with status 0x%02x (%s)\n",
> -					id, status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (len < sizeof(*rp)) {
> -		fprintf(stderr, "Too small info reply (%u bytes)\n", len);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	ba2str(&rp->bdaddr, addr);
> -	printf("hci%u:\taddr %s version %u manufacturer %u"
> -			" class 0x%02x%02x%02x\n",
> -			id, addr, rp->version, bt_get_le16(&rp->manufacturer),
> -			rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
> -
> -	printf("\tsupported settings: ");
> -	print_settings(bt_get_le32(&rp->supported_settings));
> -
> -	printf("\n\tcurrent settings: ");
> -	print_settings(bt_get_le32(&rp->current_settings));
> -
> -	printf("\n\tname %s\n", rp->name);
> -	printf("\tshort name %s\n", rp->short_name);
> -
> -	if (pending == NULL)
> -		exit(EXIT_SUCCESS);
> -}
> -
> -static void index_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data)
> -{
> -	struct mgmt_rp_read_index_list *rp = rsp;
> -	uint16_t count;
> -	unsigned int i;
> -
> -	if (status != 0) {
> -		fprintf(stderr,
> -			"Reading index list failed with status 0x%02x (%s)\n",
> -						status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (len < sizeof(*rp)) {
> -		fprintf(stderr, "Too small index list reply (%u bytes)\n",
> -									len);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	count = bt_get_le16(&rp->num_controllers);
> -
> -	if (len < sizeof(*rp) + count * sizeof(uint16_t)) {
> -		fprintf(stderr,
> -			"Index count (%u) doesn't match reply length (%u)\n",
> -								count, len);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (monitor)
> -		printf("Index list with %u item%s\n",
> -						count, count > 1 ? "s" : "");
> -
> -	if (count == 0)
> -		exit(EXIT_SUCCESS);
> -
> -	if (monitor && count > 0)
> -		printf("\t");
> -
> -	for (i = 0; i < count; i++) {
> -		uint16_t index;
> -
> -		index = bt_get_le16(&rp->index[i]);
> -
> -		if (monitor)
> -			printf("hci%u ", index);
> -
> -		if (mgmt_send_cmd(mgmt_sk, MGMT_OP_READ_INFO, index, NULL,
> -					0, info_rsp, NULL) < 0) {
> -			fprintf(stderr, "Unable to send read_info cmd\n");
> -			exit(EXIT_FAILURE);
> -		}
> -	}
> -
> -	if (monitor && count > 0)
> -		printf("\n");
> -}
> -
> -static void cmd_info(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	if (index == MGMT_INDEX_NONE) {
> -		if (mgmt_send_cmd(mgmt_sk, MGMT_OP_READ_INDEX_LIST,
> -					MGMT_INDEX_NONE, NULL, 0,
> -					index_rsp, NULL) < 0) {
> -			fprintf(stderr, "Unable to send index_list cmd\n");
> -			exit(EXIT_FAILURE);
> -		}
> -
> -		return;
> -	}
> -
> -	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_READ_INFO, index, NULL,
> -						0, info_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send read_info cmd\n");
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void setting_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data)
> -{
> -	uint32_t *rp = rsp;
> -
> -	if (status != 0) {
> -		fprintf(stderr,
> -			"%s for hci%u failed with status 0x%02x (%s)\n",
> -			mgmt_opstr(op), id, status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (len < sizeof(*rp)) {
> -		fprintf(stderr, "Too small %s response (%u bytes)\n",
> -							mgmt_opstr(op), len);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	printf("hci%u %s complete, settings: ", id, mgmt_opstr(op));
> -	print_settings(bt_get_le32(rp));
> -	printf("\n");
> -
> -	exit(EXIT_SUCCESS);
> -}
> -
> -static void cmd_setting(int mgmt_sk, uint16_t index, uint16_t op,
> -							int argc, char **argv)
> -{
> -	uint8_t val;
> -
> -	if (argc < 2) {
> -		printf("Specify \"on\" or \"off\"\n");
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
> -		val = 1;
> -	else if (strcasecmp(argv[1], "off") == 0)
> -		val = 0;
> -	else
> -		val = atoi(argv[1]);
> -
> -	if (index == MGMT_INDEX_NONE)
> -		index = 0;
> -
> -	if (mgmt_send_cmd(mgmt_sk, op, index, &val, sizeof(val),
> -						setting_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send %s cmd\n", mgmt_opstr(op));
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void cmd_power(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	cmd_setting(mgmt_sk, index, MGMT_OP_SET_POWERED, argc, argv);
> -}
> -
> -static void cmd_discov(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	struct mgmt_cp_set_discoverable cp;
> -
> -	if (argc < 2) {
> -		printf("Usage: btmgmt %s <yes/no> [timeout]\n", argv[0]);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	memset(&cp, 0, sizeof(cp));
> -
> -	if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
> -		cp.val = 1;
> -	else if (strcasecmp(argv[1], "off") == 0)
> -		cp.val = 0;
> -	else
> -		cp.val = atoi(argv[1]);
> -
> -	if (argc > 2)
> -		cp.timeout = htobs(atoi(argv[2]));
> -
> -	if (index == MGMT_INDEX_NONE)
> -		index = 0;
> -
> -	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_SET_DISCOVERABLE, index,
> -				&cp, sizeof(cp), setting_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send set_discoverable cmd\n");
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void cmd_connectable(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	cmd_setting(mgmt_sk, index, MGMT_OP_SET_CONNECTABLE, argc, argv);
> -}
> -
> -static void cmd_pairable(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	cmd_setting(mgmt_sk, index, MGMT_OP_SET_PAIRABLE, argc, argv);
> -}
> -
> -static void cmd_linksec(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	cmd_setting(mgmt_sk, index, MGMT_OP_SET_LINK_SECURITY, argc, argv);
> -}
> -
> -static void cmd_ssp(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	cmd_setting(mgmt_sk, index, MGMT_OP_SET_SSP, argc, argv);
> -}
> -
> -static void cmd_hs(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	cmd_setting(mgmt_sk, index, MGMT_OP_SET_HS, argc, argv);
> -}
> -
> -static void cmd_le(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	cmd_setting(mgmt_sk, index, MGMT_OP_SET_LE, argc, argv);
> -}
> -
> -static void class_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data)
> -{
> -	struct mgmt_ev_class_of_dev_changed *rp = rsp;
> -
> -	if (len == 0 && status != 0) {
> -		fprintf(stderr, "%s failed, status 0x%02x (%s)\n",
> -				mgmt_opstr(op), status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (len != sizeof(*rp)) {
> -		fprintf(stderr, "Unexpected %s len %u\n", mgmt_opstr(op), len);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	printf("%s succeeded. Class 0x%02x%02x%02x\n", mgmt_opstr(op),
> -		rp->class_of_dev[2], rp->class_of_dev[1], rp->class_of_dev[0]);
> -
> -	exit(EXIT_SUCCESS);
> -}
> -
> -static void cmd_class(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	uint8_t class[2];
> -
> -	if (argc < 3) {
> -		printf("Usage: btmgmt %s <major> <minor>\n", argv[0]);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	class[0] = atoi(argv[1]);
> -	class[1] = atoi(argv[2]);
> -
> -	if (index == MGMT_INDEX_NONE)
> -		index = 0;
> -
> -	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_SET_DEV_CLASS, index,
> -				class, sizeof(class), class_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send set_dev_class cmd\n");
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void disconnect_rsp(int mgmt_sk, uint16_t op, uint16_t id,
> -				uint8_t status, void *rsp, uint16_t len,
> -				void *user_data)
> -{
> -	struct mgmt_rp_disconnect *rp = rsp;
> -	char addr[18];
> -
> -	if (len == 0 && status != 0) {
> -		fprintf(stderr, "Disconnect failed with status 0x%02x (%s)\n",
> -						status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (len != sizeof(*rp)) {
> -		fprintf(stderr, "Invalid disconnect response length (%u)\n",
> -									len);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	ba2str(&rp->addr.bdaddr, addr);
> -
> -	if (status == 0) {
> -		printf("%s disconnected\n", addr);
> -		exit(EXIT_SUCCESS);
> -	} else {
> -		fprintf(stderr,
> -			"Disconnecting %s failed with status 0x%02x (%s)\n",
> -				addr, status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void cmd_disconnect(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	struct mgmt_cp_disconnect cp;
> -
> -	if (argc < 2) {
> -		printf("Usage: btmgmt %s <address>\n", argv[0]);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	str2ba(argv[1], &cp.addr.bdaddr);
> -
> -	if (index == MGMT_INDEX_NONE)
> -		index = 0;
> -
> -	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_DISCONNECT, index,
> -				&cp, sizeof(cp), disconnect_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send disconnect cmd\n");
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void con_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data)
> -{
> -	struct mgmt_rp_get_connections *rp = rsp;
> -	uint16_t count, i;
> -
> -	if (len < sizeof(*rp)) {
> -		fprintf(stderr, "Too small (%u bytes) get_connections rsp\n",
> -									len);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	count = bt_get_le16(&rp->conn_count);
> -	if (len != sizeof(*rp) + count * sizeof(struct mgmt_addr_info)) {
> -		fprintf(stderr, "Invalid get_connections length "
> -					" (count=%u, len=%u)\n", count, len);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	for (i = 0; i < count; i++) {
> -		char addr[18];
> -
> -		ba2str(&rp->addr[i].bdaddr, addr);
> -
> -		printf("%s type %s\n", addr, typestr(rp->addr[i].type));
> -	}
> -
> -	exit(EXIT_SUCCESS);
> -}
> -
> -static void cmd_con(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	if (index == MGMT_INDEX_NONE)
> -		index = 0;
> -
> -	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_GET_CONNECTIONS, index, NULL, 0,
> -							con_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send get_connections cmd\n");
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void find_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data)
> -{
> -	if (status != 0) {
> -		fprintf(stderr,
> -			"Unable to start discovery. status 0x%02x (%s)\n",
> -						status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	printf("Discovery started\n");
> -	discovery = true;
> -}
> -
> -static void find_usage(void)
> -{
> -	printf("Usage: btmgmt find [-l|-b]>\n");
> -}
> -
> -static struct option find_options[] = {
> -	{ "help",	0, 0, 'h' },
> -	{ "le-only",	1, 0, 'l' },
> -	{ "bredr-only",	1, 0, 'b' },
> -	{ 0, 0, 0, 0 }
> -};
> -
> -static void cmd_find(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	struct mgmt_cp_start_discovery cp;
> -	uint8_t type;
> -	int opt;
> -
> -	if (index == MGMT_INDEX_NONE)
> -		index = 0;
> -
> -	type = 0;
> -	hci_set_bit(BDADDR_BREDR, &type);
> -	hci_set_bit(BDADDR_LE_PUBLIC, &type);
> -	hci_set_bit(BDADDR_LE_RANDOM, &type);
> -
> -	while ((opt = getopt_long(argc, argv, "+lbh", find_options,
> -								NULL)) != -1) {
> -		switch (opt) {
> -		case 'l':
> -			hci_clear_bit(BDADDR_BREDR, &type);
> -			hci_set_bit(BDADDR_LE_PUBLIC, &type);
> -			hci_set_bit(BDADDR_LE_RANDOM, &type);
> -			break;
> -		case 'b':
> -			hci_set_bit(BDADDR_BREDR, &type);
> -			hci_clear_bit(BDADDR_LE_PUBLIC, &type);
> -			hci_clear_bit(BDADDR_LE_RANDOM, &type);
> -			break;
> -		case 'h':
> -		default:
> -			find_usage();
> -			exit(EXIT_SUCCESS);
> -		}
> -	}
> -
> -	argc -= optind;
> -	argv += optind;
> -	optind = 0;
> -
> -	memset(&cp, 0, sizeof(cp));
> -	cp.type = type;
> -
> -	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_START_DISCOVERY, index,
> -				&cp, sizeof(cp), find_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send start_discovery cmd\n");
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void name_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data)
> -{
> -	if (status != 0) {
> -		fprintf(stderr, "Unable to set local name. status 0x%02x (%s)",
> -						status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	exit(EXIT_SUCCESS);
> -}
> -
> -static void cmd_name(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	struct mgmt_cp_set_local_name cp;
> -
> -	if (argc < 2) {
> -		printf("Usage: btmgmt %s <name> [shortname]\n", argv[0]);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (index == MGMT_INDEX_NONE)
> -		index = 0;
> -
> -	memset(&cp, 0, sizeof(cp));
> -	strncpy((char *) cp.name, argv[1], HCI_MAX_NAME_LENGTH);
> -	if (argc > 2)
> -		strncpy((char *) cp.short_name, argv[2],
> -					MGMT_MAX_SHORT_NAME_LENGTH);
> -
> -	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_SET_LOCAL_NAME, index,
> -					&cp, sizeof(cp), name_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send set_name cmd\n");
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void pair_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data)
> -{
> -	struct mgmt_rp_pair_device *rp = rsp;
> -	char addr[18];
> -
> -	if (len == 0 && status != 0) {
> -		fprintf(stderr, "Pairing failed with status 0x%02x (%s)\n",
> -						status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (len != sizeof(*rp)) {
> -		fprintf(stderr, "Unexpected pair_rsp len %u\n", len);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	ba2str(&rp->addr.bdaddr, addr);
> -
> -	if (status != 0) {
> -		fprintf(stderr,
> -			"Pairing with %s (%s) failed. status 0x%02x (%s)\n",
> -			addr, typestr(rp->addr.type), status,
> -			mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	printf("Paired with %s\n", addr);
> -
> -	exit(EXIT_SUCCESS);
> -}
> -
> -static void pair_usage(void)
> -{
> -	printf("Usage: btmgmt pair [-c cap] [-t type] <remote address>\n");
> -}
> -
> -static struct option pair_options[] = {
> -	{ "help",	0, 0, 'h' },
> -	{ "capability",	1, 0, 'c' },
> -	{ "type",	1, 0, 't' },
> -	{ 0, 0, 0, 0 }
> -};
> -
> -static void cmd_pair(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	struct mgmt_cp_pair_device cp;
> -	uint8_t cap = 0x01;
> -	uint8_t type = BDADDR_BREDR;
> -	int opt;
> -
> -	while ((opt = getopt_long(argc, argv, "+c:t:h", pair_options,
> -								NULL)) != -1) {
> -		switch (opt) {
> -		case 'c':
> -			cap = strtol(optarg, NULL, 0);
> -			break;
> -		case 't':
> -			type = strtol(optarg, NULL, 0);
> -			break;
> -		case 'h':
> -		default:
> -			pair_usage();
> -			exit(EXIT_SUCCESS);
> -		}
> -	}
> -
> -	argc -= optind;
> -	argv += optind;
> -	optind = 0;
> -
> -	if (argc < 1) {
> -		pair_usage();
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (index == MGMT_INDEX_NONE)
> -		index = 0;
> -
> -	memset(&cp, 0, sizeof(cp));
> -	str2ba(argv[0], &cp.addr.bdaddr);
> -	cp.addr.type = type;
> -	cp.io_cap = cap;
> -
> -	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_PAIR_DEVICE, index, &cp, sizeof(cp),
> -							pair_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send pair_device cmd\n");
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void unpair_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data)
> -{
> -	struct mgmt_rp_unpair_device *rp = rsp;
> -	char addr[18];
> -
> -	if (len == 0 && status != 0) {
> -		fprintf(stderr, "Unpair device failed. status 0x%02x (%s)\n",
> -						status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (len != sizeof(*rp)) {
> -		fprintf(stderr, "Unexpected unpair_device_rsp len %u\n", len);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	ba2str(&rp->addr.bdaddr, addr);
> -
> -	if (status != 0) {
> -		fprintf(stderr,
> -			"Unpairing %s failed. status 0x%02x (%s)\n",
> -				addr, status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	printf("%s unpaired\n", addr);
> -
> -	exit(EXIT_SUCCESS);
> -}
> -
> -static void cmd_unpair(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	struct mgmt_cp_unpair_device cp;
> -
> -	if (argc < 2) {
> -		printf("Usage: btmgmt %s <remote address>\n", argv[0]);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (index == MGMT_INDEX_NONE)
> -		index = 0;
> -
> -	memset(&cp, 0, sizeof(cp));
> -	str2ba(argv[1], &cp.addr.bdaddr);
> -	cp.disconnect = 1;
> -
> -	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_UNPAIR_DEVICE, index, &cp,
> -					sizeof(cp), unpair_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send unpair_device cmd\n");
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void keys_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data)
> -{
> -	if (status != 0) {
> -		fprintf(stderr, "Load keys failed with status 0x%02x (%s)\n",
> -						status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	printf("Keys successfully loaded\n");
> -
> -	exit(EXIT_SUCCESS);
> -}
> -
> -static void cmd_keys(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	struct mgmt_cp_load_link_keys cp;
> -
> -	if (index == MGMT_INDEX_NONE)
> -		index = 0;
> -
> -	memset(&cp, 0, sizeof(cp));
> -
> -	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_LOAD_LINK_KEYS, index,
> -				&cp, sizeof(cp), keys_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send load_keys cmd\n");
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void block_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data)
> -{
> -	struct mgmt_addr_info *rp = rsp;
> -	char addr[18];
> -
> -	if (len == 0 && status != 0) {
> -		fprintf(stderr, "%s failed, status 0x%02x (%s)\n",
> -				mgmt_opstr(op), status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (len != sizeof(*rp)) {
> -		fprintf(stderr, "Unexpected %s len %u\n", mgmt_opstr(op), len);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	ba2str(&rp->bdaddr, addr);
> -
> -	if (status != 0) {
> -		fprintf(stderr, "%s %s (%s) failed. status 0x%02x (%s)\n",
> -				mgmt_opstr(op), addr, typestr(rp->type),
> -				status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	printf("%s %s succeeded\n", mgmt_opstr(op), addr);
> -
> -	exit(EXIT_SUCCESS);
> -}
> -
> -static void block_usage(void)
> -{
> -	printf("Usage: btmgmt block [-t type] <remote address>\n");
> -}
> -
> -static struct option block_options[] = {
> -	{ "help",	0, 0, 'h' },
> -	{ "type",	1, 0, 't' },
> -	{ 0, 0, 0, 0 }
> -};
> -
> -static void cmd_block(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	struct mgmt_cp_block_device cp;
> -	uint8_t type = BDADDR_BREDR;
> -	int opt;
> -
> -	while ((opt = getopt_long(argc, argv, "+t:h", block_options,
> -							NULL)) != -1) {
> -		switch (opt) {
> -		case 't':
> -			type = strtol(optarg, NULL, 0);
> -			break;
> -		case 'h':
> -		default:
> -			block_usage();
> -			exit(EXIT_SUCCESS);
> -		}
> -	}
> -
> -	argc -= optind;
> -	argv += optind;
> -	optind = 0;
> -
> -	if (argc < 1) {
> -		block_usage();
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (index == MGMT_INDEX_NONE)
> -		index = 0;
> -
> -	memset(&cp, 0, sizeof(cp));
> -	str2ba(argv[0], &cp.addr.bdaddr);
> -	cp.addr.type = type;
> -
> -	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_BLOCK_DEVICE, index,
> -				&cp, sizeof(cp), block_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send block_device cmd\n");
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void unblock_usage(void)
> -{
> -	printf("Usage: btmgmt unblock [-t type] <remote address>\n");
> -}
> -
> -static void cmd_unblock(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	struct mgmt_cp_unblock_device cp;
> -	uint8_t type = BDADDR_BREDR;
> -	int opt;
> -
> -	while ((opt = getopt_long(argc, argv, "+t:h", block_options,
> -							NULL)) != -1) {
> -		switch (opt) {
> -		case 't':
> -			type = strtol(optarg, NULL, 0);
> -			break;
> -		case 'h':
> -		default:
> -			unblock_usage();
> -			exit(EXIT_SUCCESS);
> -		}
> -	}
> -
> -	argc -= optind;
> -	argv += optind;
> -	optind = 0;
> -
> -	if (argc < 1) {
> -		unblock_usage();
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (index == MGMT_INDEX_NONE)
> -		index = 0;
> -
> -	memset(&cp, 0, sizeof(cp));
> -	str2ba(argv[0], &cp.addr.bdaddr);
> -	cp.addr.type = type;
> -
> -	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_UNBLOCK_DEVICE, index,
> -				&cp, sizeof(cp), block_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send unblock_device cmd\n");
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void uuid_to_uuid128(uuid_t *uuid128, const uuid_t *uuid)
> -{
> -	if (uuid->type == SDP_UUID16)
> -		sdp_uuid16_to_uuid128(uuid128, uuid);
> -	else if (uuid->type == SDP_UUID32)
> -		sdp_uuid32_to_uuid128(uuid128, uuid);
> -	else
> -		memcpy(uuid128, uuid, sizeof(*uuid));
> -}
> -
> -static void cmd_add_uuid(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	struct mgmt_cp_add_uuid cp;
> -	uint128_t uint128;
> -	uuid_t uuid, uuid128;
> -
> -	if (argc < 3) {
> -		printf("UUID and service hint needed\n");
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (index == MGMT_INDEX_NONE)
> -		index = 0;
> -
> -	if (bt_string2uuid(&uuid, argv[1]) < 0) {
> -		printf("Invalid UUID: %s\n", argv[1]);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	memset(&cp, 0, sizeof(cp));
> -
> -	uuid_to_uuid128(&uuid128, &uuid);
> -	ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
> -	htob128(&uint128, (uint128_t *) cp.uuid);
> -
> -	cp.svc_hint = atoi(argv[2]);
> -
> -	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_ADD_UUID, index,
> -				&cp, sizeof(cp), class_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send add_uuid cmd\n");
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void cmd_remove_uuid(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	struct mgmt_cp_remove_uuid cp;
> -	uint128_t uint128;
> -	uuid_t uuid, uuid128;
> -
> -	if (argc < 2) {
> -		printf("UUID needed\n");
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	if (index == MGMT_INDEX_NONE)
> -		index = 0;
> -
> -	if (bt_string2uuid(&uuid, argv[1]) < 0) {
> -		printf("Invalid UUID: %s\n", argv[1]);
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	memset(&cp, 0, sizeof(cp));
> -
> -	uuid_to_uuid128(&uuid128, &uuid);
> -	ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
> -	htob128(&uint128, (uint128_t *) cp.uuid);
> -
> -	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_REMOVE_UUID, index,
> -				&cp, sizeof(cp), class_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send remove_uuid cmd\n");
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static void cmd_clr_uuids(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	char *uuid_any = "00000000-0000-0000-0000-000000000000";
> -	char *rm_argv[] = { "rm-uuid", uuid_any, NULL };
> -
> -	cmd_remove_uuid(mgmt_sk, index, 2, rm_argv);
> -}
> -
> -static void did_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
> -				void *rsp, uint16_t len, void *user_data)
> -{
> -	if (status != 0) {
> -		fprintf(stderr, "Set Device ID failed with status 0x%02x (%s)\n",
> -						status, mgmt_errstr(status));
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	printf("Device ID successfully set\n");
> -
> -	exit(EXIT_SUCCESS);
> -}
> -
> -static void did_usage(void)
> -{
> -	printf("Usage: btmgmt did <source>:<vendor>:<product>:<version>\n");
> -	printf("       possible source values: bluetooth, usb\n");
> -}
> -
> -static void cmd_did(int mgmt_sk, uint16_t index, int argc, char **argv)
> -{
> -	struct mgmt_cp_set_device_id cp;
> -	uint16_t vendor, product, version , source;
> -	int result;
> -
> -	if (argc < 2) {
> -		did_usage();
> -		exit(EXIT_FAILURE);
> -	}
> -
> -	result = sscanf(argv[1], "bluetooth:%4hx:%4hx:%4hx", &vendor, &product,
> -								&version);
> -	if (result == 3) {
> -		source = 0x0001;
> -		goto done;
> -	}
> -
> -	result = sscanf(argv[1], "usb:%4hx:%4hx:%4hx", &vendor, &product,
> -								&version);
> -	if (result == 3) {
> -		source = 0x0002;
> -		goto done;
> -	}
> -
> -	did_usage();
> -	exit(EXIT_FAILURE);
> -
> -done:
> -	if (index == MGMT_INDEX_NONE)
> -		index = 0;
> -
> -	cp.source = htobs(source);
> -	cp.vendor = htobs(vendor);
> -	cp.product = htobs(product);
> -	cp.version = htobs(version);
> -
> -	if (mgmt_send_cmd(mgmt_sk, MGMT_OP_SET_DEVICE_ID, index,
> -				&cp, sizeof(cp), did_rsp, NULL) < 0) {
> -		fprintf(stderr, "Unable to send set_dev_class cmd\n");
> -		exit(EXIT_FAILURE);
> -	}
> -}
> -
> -static struct {
> -	char *cmd;
> -	void (*func)(int mgmt_sk, uint16_t index, int argc, char **argv);
> -	char *doc;
> -} command[] = {
> -	{ "monitor",	cmd_monitor,	"Monitor events"		},
> -	{ "version",	cmd_version,	"Get the MGMT Version"		},
> -	{ "commands",	cmd_commands,	"List supported commands"	},
> -	{ "info",	cmd_info,	"Show controller info"		},
> -	{ "power",	cmd_power,	"Toggle powered state"		},
> -	{ "discov",	cmd_discov,	"Toggle discoverable state"	},
> -	{ "connectable",cmd_connectable,"Toggle connectable state"	},
> -	{ "pairable",	cmd_pairable,	"Toggle pairable state"		},
> -	{ "linksec",	cmd_linksec,	"Toggle link level security"	},
> -	{ "ssp",	cmd_ssp,	"Toggle SSP mode"		},
> -	{ "hs",		cmd_hs,		"Toggle HS Support"		},
> -	{ "le",		cmd_le,		"Toggle LE Support"		},
> -	{ "class",	cmd_class,	"Set device major/minor class"	},
> -	{ "disconnect", cmd_disconnect, "Disconnect device"		},
> -	{ "con",	cmd_con,	"List connections"		},
> -	{ "find",	cmd_find,	"Discover nearby devices"	},
> -	{ "name",	cmd_name,	"Set local name"		},
> -	{ "pair",	cmd_pair,	"Pair with a remote device"	},
> -	{ "unpair",	cmd_unpair,	"Unpair device"			},
> -	{ "keys",	cmd_keys,	"Load Keys"			},
> -	{ "block",	cmd_block,	"Block Device"			},
> -	{ "unblock",	cmd_unblock,	"Unblock Device"		},
> -	{ "add-uuid",	cmd_add_uuid,	"Add UUID"			},
> -	{ "rm-uuid",	cmd_add_uuid,	"Remove UUID"			},
> -	{ "clr-uuids",	cmd_clr_uuids,	"Clear UUIDs",			},
> -	{ "did",	cmd_did,	"Set Device ID",		},
> -	{ NULL, NULL, 0 }
> -};
> -
> -static void usage(void)
> -{
> -	int i;
> -
> -	printf("btmgmt ver %s\n", VERSION);
> -	printf("Usage:\n"
> -		"\tbtmgmt [options] <command> [command parameters]\n");
> -
> -	printf("Options:\n"
> -		"\t--index <id>\tSpecify adapter index\n"
> -		"\t--verbose\tEnable extra logging\n"
> -		"\t--help\tDisplay help\n");
> -
> -	printf("Commands:\n");
> -	for (i = 0; command[i].cmd; i++)
> -		printf("\t%-15s\t%s\n", command[i].cmd, command[i].doc);
> -
> -	printf("\n"
> -		"For more information on the usage of each command use:\n"
> -		"\tbtmgmt <command> --help\n" );
> -}
> -
> -static struct option main_options[] = {
> -	{ "index",	1, 0, 'i' },
> -	{ "verbose",	0, 0, 'v' },
> -	{ "help",	0, 0, 'h' },
> -	{ 0, 0, 0, 0 }
> -};
> -
> -int main(int argc, char *argv[])
> -{
> -	int opt, i, mgmt_sk;
> -	uint16_t index = MGMT_INDEX_NONE;
> -	struct pollfd pollfd;
> -
> -	while ((opt = getopt_long(argc, argv, "+hvi:",
> -						main_options, NULL)) != -1) {
> -		switch (opt) {
> -		case 'i':
> -			if (strlen(optarg) > 3 &&
> -					strncasecmp(optarg, "hci", 3) == 0)
> -				index = atoi(&optarg[4]);
> -			else
> -				index = atoi(optarg);
> -			break;
> -		case 'v':
> -			monitor = true;
> -			break;
> -		case 'h':
> -		default:
> -			usage();
> -			return 0;
> -		}
> -	}
> -
> -	argc -= optind;
> -	argv += optind;
> -	optind = 0;
> -
> -	if (argc < 1) {
> -		usage();
> -		return 0;
> -	}
> -
> -	mgmt_sk = mgmt_open();
> -	if (mgmt_sk < 0) {
> -		fprintf(stderr, "Unable to open mgmt socket\n");
> -		return -1;
> -	}
> -
> -	for (i = 0; command[i].cmd; i++) {
> -		if (strcmp(command[i].cmd, argv[0]) != 0)
> -			continue;
> -
> -		command[i].func(mgmt_sk, index, argc, argv);
> -		break;
> -	}
> -
> -	if (command[i].cmd == NULL) {
> -		fprintf(stderr, "Unknown command: %s\n", argv[0]);
> -		close(mgmt_sk);
> -		return -1;
> -	}
> -
> -	pollfd.fd = mgmt_sk;
> -	pollfd.events = POLLIN;
> -	pollfd.revents = 0;
> -
> -	while (poll(&pollfd, 1, -1) >= 0) {
> -		if (pollfd.revents & (POLLHUP | POLLERR | POLLNVAL))
> -			break;
> -
> -		if (pollfd.revents & POLLIN)
> -			mgmt_process_data(mgmt_sk);
> -
> -		pollfd.revents = 0;
> -	}
> -
> -	close(mgmt_sk);
> -
> -	return 0;
> -}
> -- 
> 1.7.10.2
> 
> --
> 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


Cheers,
-- 
Vinicius

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2012-07-10  2:36 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-09 21:10 [PATCH 01/14] input: remove unneeded header inclusions Gustavo Padovan
2012-07-09 21:10 ` [PATCH 02/14] serial: remove the whole serial code Gustavo Padovan
2012-07-09 21:10 ` [PATCH 03/14] btmgmt: move to tools folder Gustavo Padovan
2012-07-10  2:36   ` Vinicius Costa Gomes
2012-07-09 21:10 ` [PATCH 04/14] alert: move alert to profiles dir Gustavo Padovan
2012-07-09 21:10 ` [PATCH 05/14] deviceinfo: move to profiles folder Gustavo Padovan
2012-07-09 21:10 ` [PATCH 07/14] thermometer: move to the " Gustavo Padovan
2012-07-09 21:10 ` [PATCH 08/14] time: " Gustavo Padovan
2012-07-09 21:10 ` [PATCH 12/14] cups: move it to " Gustavo Padovan
2012-07-09 21:10 ` [PATCH 14/14] plugins: remove unmaintained plugins Gustavo Padovan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.