Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH 10/18] eir: Rename eir_create to eir_create_oob
From: Szymon Janc @ 2012-09-21 10:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1348221750-15345-1-git-send-email-szymon.janc@tieto.com>

With mgmt interface EIR is created by kernel. Renaming this function
makes it clear what is a purpose of it in userspace. It also contains
support for EIR data types that shall be transmitted only over OOB
channel.

---
 src/eir.c |    2 +-
 src/eir.h |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/eir.c b/src/eir.c
index 46dde5a..a3c99e8 100644
--- a/src/eir.c
+++ b/src/eir.c
@@ -280,7 +280,7 @@ static void eir_generate_uuid128(GSList *list, uint8_t *ptr, uint16_t *eir_len)
 	}
 }
 
-void eir_create(const char *name, int8_t tx_power, uint32_t cod,
+void eir_create_oob(const char *name, int8_t tx_power, uint32_t cod,
 			uint8_t *hash, uint8_t *randomizer,
 			uint16_t did_vendor, uint16_t did_product,
 			uint16_t did_version, uint16_t did_source,
diff --git a/src/eir.h b/src/eir.h
index 1c7a603..55289f9 100644
--- a/src/eir.h
+++ b/src/eir.h
@@ -58,7 +58,7 @@ struct eir_data {
 void eir_data_free(struct eir_data *eir);
 int eir_parse(struct eir_data *eir, uint8_t *eir_data, uint8_t eir_len);
 int eir_parse_oob(struct eir_data *eir, uint8_t *eir_data, uint16_t eir_len);
-void eir_create(const char *name, int8_t tx_power, uint32_t cod,
+void eir_create_oob(const char *name, int8_t tx_power, uint32_t cod,
 			uint8_t *hash, uint8_t *randomizer,
 			uint16_t did_vendor, uint16_t did_product,
 			uint16_t did_version, uint16_t did_source,
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 09/18] eir: Add support for creating EIR with CoD field
From: Szymon Janc @ 2012-09-21 10:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1348221750-15345-1-git-send-email-szymon.janc@tieto.com>

This will be used to create EIR to be send over OOB channel.

---
 src/eir.c |   18 +++++++++++++++++-
 src/eir.h |    2 +-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/src/eir.c b/src/eir.c
index 0ef18e2..46dde5a 100644
--- a/src/eir.c
+++ b/src/eir.c
@@ -280,7 +280,7 @@ static void eir_generate_uuid128(GSList *list, uint8_t *ptr, uint16_t *eir_len)
 	}
 }
 
-void eir_create(const char *name, int8_t tx_power,
+void eir_create(const char *name, int8_t tx_power, uint32_t cod,
 			uint8_t *hash, uint8_t *randomizer,
 			uint16_t did_vendor, uint16_t did_product,
 			uint16_t did_version, uint16_t did_source,
@@ -294,6 +294,22 @@ void eir_create(const char *name, int8_t tx_power,
 	gboolean truncated = FALSE;
 	size_t name_len;
 
+	if (cod > 0) {
+		uint8_t class[3];
+
+		class[0] = (uint8_t) cod;
+		class[1] = (uint8_t) (cod >> 8);
+		class[2] = (uint8_t) (cod >> 16);
+
+		*ptr++ = 4;
+		*ptr++ = EIR_CLASS_OF_DEV;
+
+		memcpy(ptr, class, sizeof(class));
+		ptr += sizeof(class);
+
+		eir_len += sizeof(class) + 2;
+	}
+
 	if (hash) {
 		*ptr++ = 17;
 		*ptr++ = EIR_SSP_HASH;
diff --git a/src/eir.h b/src/eir.h
index 844c162..1c7a603 100644
--- a/src/eir.h
+++ b/src/eir.h
@@ -58,7 +58,7 @@ struct eir_data {
 void eir_data_free(struct eir_data *eir);
 int eir_parse(struct eir_data *eir, uint8_t *eir_data, uint8_t eir_len);
 int eir_parse_oob(struct eir_data *eir, uint8_t *eir_data, uint16_t eir_len);
-void eir_create(const char *name, int8_t tx_power,
+void eir_create(const char *name, int8_t tx_power, uint32_t cod,
 			uint8_t *hash, uint8_t *randomizer,
 			uint16_t did_vendor, uint16_t did_product,
 			uint16_t did_version, uint16_t did_source,
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 08/18] eir: Add support creating EIR with hash and randomizer fields
From: Szymon Janc @ 2012-09-21 10:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1348221750-15345-1-git-send-email-szymon.janc@tieto.com>

This will be used to create EIR to be send over OOB channel.

---
 src/eir.c |   28 +++++++++++++++++++++++++---
 src/eir.h |    8 +++++---
 2 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/src/eir.c b/src/eir.c
index 144f65c..0ef18e2 100644
--- a/src/eir.c
+++ b/src/eir.c
@@ -280,9 +280,11 @@ static void eir_generate_uuid128(GSList *list, uint8_t *ptr, uint16_t *eir_len)
 	}
 }
 
-void eir_create(const char *name, int8_t tx_power, uint16_t did_vendor,
-			uint16_t did_product, uint16_t did_version,
-			uint16_t did_source, GSList *uuids, uint8_t *data)
+void eir_create(const char *name, int8_t tx_power,
+			uint8_t *hash, uint8_t *randomizer,
+			uint16_t did_vendor, uint16_t did_product,
+			uint16_t did_version, uint16_t did_source,
+			GSList *uuids, uint8_t *data)
 {
 	GSList *l;
 	uint8_t *ptr = data;
@@ -292,6 +294,26 @@ void eir_create(const char *name, int8_t tx_power, uint16_t did_vendor,
 	gboolean truncated = FALSE;
 	size_t name_len;
 
+	if (hash) {
+		*ptr++ = 17;
+		*ptr++ = EIR_SSP_HASH;
+
+		memcpy(ptr, hash, 16);
+		ptr += 16;
+
+		eir_len += 16 + 2;
+	}
+
+	if (randomizer) {
+		*ptr++ = 17;
+		*ptr++ = EIR_SSP_RANDOMIZER;
+
+		memcpy(ptr, randomizer, 16);
+		ptr += 16;
+
+		eir_len += 16 + 2;
+	}
+
 	name_len = strlen(name);
 
 	if (name_len > 0) {
diff --git a/src/eir.h b/src/eir.h
index d2d6dc7..844c162 100644
--- a/src/eir.h
+++ b/src/eir.h
@@ -58,9 +58,11 @@ struct eir_data {
 void eir_data_free(struct eir_data *eir);
 int eir_parse(struct eir_data *eir, uint8_t *eir_data, uint8_t eir_len);
 int eir_parse_oob(struct eir_data *eir, uint8_t *eir_data, uint16_t eir_len);
-void eir_create(const char *name, int8_t tx_power, uint16_t did_vendor,
-			uint16_t did_product, uint16_t did_version,
-			uint16_t did_source, GSList *uuids, uint8_t *data);
+void eir_create(const char *name, int8_t tx_power,
+			uint8_t *hash, uint8_t *randomizer,
+			uint16_t did_vendor, uint16_t did_product,
+			uint16_t did_version, uint16_t did_source,
+			GSList *uuids, uint8_t *data);
 
 gboolean eir_has_data_type(uint8_t *data, size_t len, uint8_t type);
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 07/18] neard: Implement PushOOB function
From: Szymon Janc @ 2012-09-21 10:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1348221750-15345-1-git-send-email-szymon.janc@tieto.com>

This implements PushOOB function which allows neard to pass data used
for discovery and pairing. Only EIR data type is supported.

---
 plugins/neard.c |  241 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 235 insertions(+), 6 deletions(-)

diff --git a/plugins/neard.c b/plugins/neard.c
index 5f467b3..630a79b 100644
--- a/plugins/neard.c
+++ b/plugins/neard.c
@@ -36,6 +36,12 @@
 #include "log.h"
 #include "dbus-common.h"
 #include "adapter.h"
+#include "manager.h"
+#include "device.h"
+#include "eir.h"
+#include "storage.h"
+#include "agent.h"
+#include "oob.h"
 
 #define NEARD_NAME "org.neard"
 #define NEARD_PATH "/"
@@ -50,10 +56,32 @@ static DBusPendingCall *pending = NULL;
 static guint watcher_id = 0;
 static gboolean agent_registered = FALSE;
 
-static DBusMessage *error_failed(DBusMessage *msg, int error)
+static struct btd_adapter *pending_adapter = NULL;
+static DBusMessage *pending_msg = NULL;
+
+static DBusMessage *error_reply(DBusMessage *msg, int error)
 {
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
+	switch (error) {
+	case ENOTSUP:
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".NotSupported",
+						"Operation is not supported");
+
+	case ENOENT:
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".NoSuchDevice",
+							"No such device");
+
+	case EINPROGRESS:
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
+						"Operation already in progress");
+
+	case ENONET:
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".Disabled",
+							"Device disabled");
+
+	default:
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
 							"%s", strerror(error));
+	}
 }
 
 static void register_agent_cb(DBusPendingCall *call, void *user_data)
@@ -128,12 +156,199 @@ unregister:
 	g_dbus_unregister_interface(conn, AGENT_PATH, AGENT_INTERFACE);
 }
 
-static DBusMessage *push_oob(DBusConnection *conn, DBusMessage *msg,
-							void *user_data)
+static void pairing_complete(struct btd_adapter *adapter, bdaddr_t *bdaddr,
+							uint8_t status)
+{
+	DBusMessage *reply;
+	char address[18];
+
+	ba2str(bdaddr, address);
+	DBG("hci%u remote:%s", adapter_get_dev_id(adapter), address);
+
+	if (!pending_adapter || pending_adapter != adapter)
+		return;
+
+	if (status)
+		reply = error_reply(pending_msg, EIO);
+	else
+		reply = g_dbus_create_reply(pending_msg, DBUS_TYPE_INVALID);
+
+	dbus_message_unref(pending_msg);
+	pending_msg = NULL;
+	pending_adapter = NULL;
+
+	if (!g_dbus_send_message(conn, reply))
+		error("D-Bus send failed");
+}
+
+static int process_eir(struct btd_adapter *adapter, uint8_t *eir, size_t size,
+								gboolean pair)
+{
+	struct btd_device *device;
+	struct agent *agent;
+	struct eir_data eir_data;
+	bdaddr_t local;
+	char remote_address[18];
+
+	DBG("size %zu", size);
+
+	memset(&eir_data, 0, sizeof(eir_data));
+
+	if (eir_parse_oob(&eir_data, eir, size) < 0)
+		return -EINVAL;
+
+	ba2str(&eir_data.addr, remote_address);
+
+	DBG("hci%u remote:%s", adapter_get_dev_id(adapter), remote_address);
+
+	device = adapter_find_device(adapter, remote_address);
+
+	/* If already paired do nothing */
+	if (device && device_is_paired(device)) {
+		DBG("already paired");
+		eir_data_free(&eir_data);
+		return 1;
+	}
+
+	/* Pairing in progress... */
+	if (device && device_is_bonding(device, NULL)) {
+		DBG("pairing in progress");
+		eir_data_free(&eir_data);
+		return -EINPROGRESS;
+	}
+
+	/* If we have unpaired device hanging around, purge it */
+	if (device)
+		adapter_remove_device(conn, adapter, device, TRUE);
+
+	adapter_get_address(adapter, &local);
+
+	/* store OOB data */
+	if (eir_data.class != 0)
+		write_remote_class(&local, &eir_data.addr, eir_data.class);
+
+	/* TODO handle incomplete name? */
+	if (eir_data.name)
+		write_device_name(&local, &eir_data.addr, BDADDR_BREDR,
+								eir_data.name);
+
+	if (eir_data.hash)
+		btd_adapter_add_remote_oob_data(adapter, &eir_data.addr,
+					eir_data.hash, eir_data.randomizer);
+
+	/* TODO handle UUIDs? */
+
+	eir_data_free(&eir_data);
+
+	if (!pair)
+		return 1;
+
+	agent = adapter_get_agent(adapter);
+
+	return adapter_create_bonding(adapter, &eir_data.addr, BDADDR_BREDR,
+					agent_get_io_capability(agent));
+}
+
+static int process_params(DBusMessageIter *iter, struct btd_adapter *adapter,
+								gboolean pair)
 {
+	DBusMessageIter dict;
+	DBusMessageIter value;
+	DBusMessageIter entry;
+	const char *key;
+	int type;
+
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+		return -EINVAL;
+
+	dbus_message_iter_recurse(iter, &dict);
+
+	type = dbus_message_iter_get_arg_type(&dict);
+	if (type != DBUS_TYPE_DICT_ENTRY) {
+		if (!pair && type == DBUS_TYPE_INVALID)
+			return 1;
+
+		return -EINVAL;
+	}
+
+	dbus_message_iter_recurse(&dict, &entry);
+
+	if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
+		return -EINVAL;
+
+	dbus_message_iter_get_basic(&entry, &key);
+	dbus_message_iter_next(&entry);
+
+	dbus_message_iter_recurse(&entry, &value);
+
+	/* All keys have byte array type values */
+	if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_ARRAY)
+		return -EINVAL;
+
+	if (strcasecmp(key, "EIR") == 0) {
+		DBusMessageIter array;
+		uint8_t *eir;
+		int size;
+
+		dbus_message_iter_recurse(&value, &array);
+		dbus_message_iter_get_fixed_array(&array, &eir, &size);
+
+		return process_eir(adapter, eir, size, TRUE);
+	} else if (strcasecmp(key, "nokia.com:bt") == 0) {
+		/* TODO add support for Nokia BT 2.0 proprietary stuff */
+		return -ENOTSUP;
+	}
+
+	return -EINVAL;
+}
+
+static int check_adapter(struct btd_adapter *adapter)
+{
+	gboolean pairable;
+
+	if (pending_adapter)
+		return -EINPROGRESS;
+
+	if (!adapter)
+		return -ENOENT;
+
+	btd_adapter_get_mode(adapter, NULL, NULL, NULL, &pairable);
+
+	if (!pairable || !adapter_get_agent(adapter))
+		return -ENOENT;
+
+	if (!btd_adapter_ssp_enabled(adapter))
+		return -ENOTSUP;
+
+	return 0;
+}
+
+static DBusMessage *push_oob(DBusConnection *conn, DBusMessage *msg, void *data)
+{
+	struct btd_adapter *adapter;
+	DBusMessageIter iter;
+	int ret;
+
 	DBG("");
 
-	return error_failed(msg, ENOTSUP);
+	adapter = manager_get_default_adapter();
+	ret = check_adapter(adapter);
+	if (ret < 0)
+		return error_reply(msg, -ret);
+
+	dbus_message_iter_init(msg, &iter);
+
+	ret = process_params(&iter, adapter, TRUE);
+	if (ret < 0)
+		return error_reply(msg, -ret);
+
+	/* already paired, reply immediately */
+	if (ret > 0)
+		return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+
+	pending_adapter = adapter;
+	pending_msg = dbus_message_ref(msg);
+	return NULL;
 }
 
 static DBusMessage *request_oob(DBusConnection *conn, DBusMessage *msg,
@@ -141,7 +356,7 @@ static DBusMessage *request_oob(DBusConnection *conn, DBusMessage *msg,
 {
 	DBG("");
 
-	return error_failed(msg, ENOTSUP);
+	return error_reply(msg, ENOTSUP);
 }
 
 static DBusMessage *release(DBusConnection *conn, DBusMessage *msg,
@@ -194,8 +409,20 @@ static void neard_vanished(DBusConnection *conn, void *user_data)
 		g_dbus_unregister_interface(conn, AGENT_PATH, AGENT_INTERFACE);
 		agent_registered = FALSE;
 	}
+
+	if (pending_msg) {
+		dbus_message_unref(pending_msg);
+		pending_msg = NULL;
+	}
+
+	pending_adapter = NULL;
 }
 
+static struct oob_handler neard_handler = {
+	.read_local_cb = NULL,
+	.pairing_cb = pairing_complete,
+};
+
 static int neard_init(void)
 {
 	DBG("Setup neard plugin");
@@ -208,6 +435,8 @@ static int neard_init(void)
 	if (watcher_id == 0)
 		return -ENOMEM;
 
+	oob_register_cb(&neard_handler);
+
 	return 0;
 }
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 06/18] adapter: Handle missing randomizer in btd_adapter_add_remote_oob_data
From: Szymon Janc @ 2012-09-21 10:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1348221750-15345-1-git-send-email-szymon.janc@tieto.com>

Randomizer is optional. Handling missing randomizer in
btd_adapter_add_remote_oob_data is easy and will simplify caller code.

---
 plugins/dbusoob.c |    7 -------
 src/adapter.c     |    7 +++++++
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/plugins/dbusoob.c b/plugins/dbusoob.c
index a66c21d..ce9e5d4 100644
--- a/plugins/dbusoob.c
+++ b/plugins/dbusoob.c
@@ -233,13 +233,6 @@ static gboolean store_data(struct btd_adapter *adapter, struct oob_data *data)
 	adapter_get_address(adapter, &local);
 
 	if (data->hash) {
-		uint8_t empty_randomizer[16];
-
-		if (!data->randomizer) {
-			memset(empty_randomizer, 0, sizeof(empty_randomizer));
-			data->randomizer = empty_randomizer;
-		}
-
 		if (btd_adapter_add_remote_oob_data(adapter, &bdaddr,
 					data->hash, data->randomizer) < 0)
 			return FALSE;
diff --git a/src/adapter.c b/src/adapter.c
index d34e966..a00522a 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3574,6 +3574,13 @@ int btd_adapter_read_local_oob_data(struct btd_adapter *adapter)
 int btd_adapter_add_remote_oob_data(struct btd_adapter *adapter,
 			bdaddr_t *bdaddr, uint8_t *hash, uint8_t *randomizer)
 {
+	uint8_t empty_randomizer[16];
+
+	if (!randomizer) {
+		memset(empty_randomizer, 0, sizeof(empty_randomizer));
+		randomizer = empty_randomizer;
+	}
+
 	return mgmt_add_remote_oob_data(adapter->dev_id, bdaddr, hash,
 								randomizer);
 }
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 05/18] oob: Allow to register pairing complete callback
From: Szymon Janc @ 2012-09-21 10:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1348221750-15345-1-git-send-email-szymon.janc@tieto.com>

This will allow to register callback to be called when pairing is
finished.

---
 plugins/dbusoob.c |    7 ++++++-
 src/mgmt.c        |    1 +
 src/oob.c         |   22 +++++++++++++++++-----
 src/oob.h         |   15 ++++++++++++---
 4 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/plugins/dbusoob.c b/plugins/dbusoob.c
index a7259ba..a66c21d 100644
--- a/plugins/dbusoob.c
+++ b/plugins/dbusoob.c
@@ -354,13 +354,18 @@ static struct btd_adapter_driver oob_driver = {
 	.remove	= oob_remove,
 };
 
+static struct oob_handler dbusoob_handler = {
+	.read_local_cb = read_local_data_complete,
+	.pairing_cb = NULL,
+};
+
 static int dbusoob_init(void)
 {
 	DBG("Setup dbusoob plugin");
 
 	connection = get_dbus_connection();
 
-	oob_register_cb(read_local_data_complete);
+	oob_register_cb(&dbusoob_handler);
 
 	return btd_register_adapter_driver(&oob_driver);
 }
diff --git a/src/mgmt.c b/src/mgmt.c
index ee4cbbe..1dec839 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
@@ -1181,6 +1181,7 @@ static void pair_device_complete(int sk, uint16_t index, uint8_t status,
 	info = &controllers[index];
 
 	bonding_complete(info, &rp->addr.bdaddr, status);
+	oob_pairing_complete(&info->bdaddr, &rp->addr.bdaddr, status);
 }
 
 static void get_connections_complete(int sk, uint16_t index, void *buf,
diff --git a/src/oob.c b/src/oob.c
index 75798fb..73a15db 100644
--- a/src/oob.c
+++ b/src/oob.c
@@ -24,18 +24,30 @@
  */
 
 #include "adapter.h"
+#include "manager.h"
 #include "oob.h"
 
-static oob_read_cb_t local_oob_read_cb = NULL;
+static struct oob_handler *oob_handler = NULL;
 
-void oob_register_cb(oob_read_cb_t cb)
+
+void oob_register_cb(struct oob_handler *handler)
 {
-	local_oob_read_cb = cb;
+	oob_handler = handler;
 }
 
 void oob_read_local_data_complete(struct btd_adapter *adapter, uint8_t *hash,
 							uint8_t *randomizer)
 {
-	if (local_oob_read_cb)
-		local_oob_read_cb(adapter, hash, randomizer);
+	if (oob_handler && oob_handler->read_local_cb)
+		oob_handler->read_local_cb(adapter, hash, randomizer);
+}
+
+void oob_pairing_complete(bdaddr_t *local, bdaddr_t *remote, uint8_t status)
+{
+	struct btd_adapter *adapter;
+
+	adapter = manager_find_adapter(local);
+
+	if (adapter && oob_handler && oob_handler->pairing_cb)
+		oob_handler->pairing_cb(adapter, remote, status);
 }
diff --git a/src/oob.h b/src/oob.h
index 5805082..843ffdf 100644
--- a/src/oob.h
+++ b/src/oob.h
@@ -23,10 +23,19 @@
  *
  */
 
-typedef void (*oob_read_cb_t) (struct btd_adapter *adapter, uint8_t *hash,
-							uint8_t *randomizer);
+typedef void (*oob_read_local_cb_t) (struct btd_adapter *adapter,
+					uint8_t *hash, uint8_t *randomizer);
+typedef void (*oob_pairing_cb_t) (struct btd_adapter *adapter,
+					bdaddr_t *bdaddr, uint8_t status);
+
+struct oob_handler {
+	oob_read_local_cb_t read_local_cb;
+	oob_pairing_cb_t pairing_cb;
+};
 
-void oob_register_cb(oob_read_cb_t cb);
+void oob_register_cb(struct oob_handler *handler);
 
 void oob_read_local_data_complete(struct btd_adapter *adapter, uint8_t *hash,
 							uint8_t *randomizer);
+
+void oob_pairing_complete(bdaddr_t *local, bdaddr_t *remote, uint8_t status);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 04/18] eir: Add eir_parse_oob function
From: Szymon Janc @ 2012-09-21 10:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1348221750-15345-1-git-send-email-szymon.janc@tieto.com>

This will parse EIR received over OOB. Such EIR contains mandatory
and optional part.

---
 src/eir.c |   25 +++++++++++++++++++++++++
 src/eir.h |    2 ++
 2 files changed, 27 insertions(+)

diff --git a/src/eir.c b/src/eir.c
index 4b054ea..144f65c 100644
--- a/src/eir.c
+++ b/src/eir.c
@@ -38,6 +38,8 @@
 #include "glib-helper.h"
 #include "eir.h"
 
+#define EIR_OOB_MIN (2 + 6)
+
 void eir_data_free(struct eir_data *eir)
 {
 	g_slist_free_full(eir->services, g_free);
@@ -197,6 +199,29 @@ int eir_parse(struct eir_data *eir, uint8_t *eir_data, uint8_t eir_len)
 	return 0;
 }
 
+int eir_parse_oob(struct eir_data *eir, uint8_t *eir_data, uint16_t eir_len)
+{
+
+	if (eir_len < EIR_OOB_MIN)
+		return -1;
+
+	if (eir_len != bt_get_le16(eir_data))
+		return -1;
+
+	eir_data += sizeof(uint16_t);
+	eir_len -= sizeof(uint16_t);
+
+	memcpy(&eir->addr, eir_data, sizeof(bdaddr_t));
+	eir_data += sizeof(bdaddr_t);
+	eir_len -= sizeof(bdaddr_t);
+
+	/* optional OOB EIR data */
+	if (eir_len > 0)
+		return eir_parse(eir, eir_data, eir_len);
+
+	return 0;
+}
+
 #define SIZEOF_UUID128 16
 
 static void eir_generate_uuid128(GSList *list, uint8_t *ptr, uint16_t *eir_len)
diff --git a/src/eir.h b/src/eir.h
index 3a52563..d2d6dc7 100644
--- a/src/eir.h
+++ b/src/eir.h
@@ -52,10 +52,12 @@ struct eir_data {
 	gboolean name_complete;
 	uint8_t *hash;
 	uint8_t *randomizer;
+	bdaddr_t addr;
 };
 
 void eir_data_free(struct eir_data *eir);
 int eir_parse(struct eir_data *eir, uint8_t *eir_data, uint8_t eir_len);
+int eir_parse_oob(struct eir_data *eir, uint8_t *eir_data, uint16_t eir_len);
 void eir_create(const char *name, int8_t tx_power, uint16_t did_vendor,
 			uint16_t did_product, uint16_t did_version,
 			uint16_t did_source, GSList *uuids, uint8_t *data);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 03/18] eir: Store class in struct eir_data as uint32_t
From: Szymon Janc @ 2012-09-21 10:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1348221750-15345-1-git-send-email-szymon.janc@tieto.com>

This simplify code as class is stored on storage as uint32_t and
had to be converted to it in few places.

---
 src/adapter.c |   11 ++++-------
 src/eir.c     |    3 ++-
 src/eir.h     |    2 +-
 src/event.c   |   11 +++--------
 src/event.h   |    2 +-
 src/mgmt.c    |    2 +-
 6 files changed, 12 insertions(+), 19 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 06ba78c..d34e966 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2929,7 +2929,6 @@ void adapter_update_found_devices(struct btd_adapter *adapter,
 	struct eir_data eir_data;
 	char *alias, *name;
 	gboolean legacy, name_known;
-	uint32_t dev_class;
 	int err;
 	GSList *l;
 
@@ -2940,10 +2939,8 @@ void adapter_update_found_devices(struct btd_adapter *adapter,
 		return;
 	}
 
-	dev_class = eir_data.dev_class[0] | (eir_data.dev_class[1] << 8) |
-						(eir_data.dev_class[2] << 16);
-	if (dev_class != 0)
-		write_remote_class(&adapter->bdaddr, bdaddr, dev_class);
+	if (eir_data.class != 0)
+		write_remote_class(&adapter->bdaddr, bdaddr, eir_data.class);
 
 	if (eir_data.appearance != 0)
 		write_remote_appearance(&adapter->bdaddr, bdaddr, bdaddr_type,
@@ -2999,8 +2996,8 @@ void adapter_update_found_devices(struct btd_adapter *adapter,
 	alias = read_stored_data(&adapter->bdaddr, bdaddr, bdaddr_type,
 								"aliases");
 
-	dev = found_device_new(bdaddr, bdaddr_type, name, alias, dev_class,
-						legacy, eir_data.flags);
+	dev = found_device_new(bdaddr, bdaddr_type, name, alias,
+				eir_data.class, legacy, eir_data.flags);
 	free(name);
 	free(alias);
 
diff --git a/src/eir.c b/src/eir.c
index c29be40..4b054ea 100644
--- a/src/eir.c
+++ b/src/eir.c
@@ -166,7 +166,8 @@ int eir_parse(struct eir_data *eir, uint8_t *eir_data, uint8_t eir_len)
 		case EIR_CLASS_OF_DEV:
 			if (data_len < 3)
 				break;
-			memcpy(eir->dev_class, data, 3);
+			eir->class = data[0] | (data[1] << 8) |
+							(data[2] << 16);
 			break;
 
 		case EIR_GAP_APPEARANCE:
diff --git a/src/eir.h b/src/eir.h
index e6e870a..3a52563 100644
--- a/src/eir.h
+++ b/src/eir.h
@@ -47,7 +47,7 @@ struct eir_data {
 	GSList *services;
 	int flags;
 	char *name;
-	uint8_t dev_class[3];
+	uint32_t class;
 	uint16_t appearance;
 	gboolean name_complete;
 	uint8_t *hash;
diff --git a/src/event.c b/src/event.c
index 3b85961..670b79a 100644
--- a/src/event.c
+++ b/src/event.c
@@ -453,7 +453,7 @@ int btd_event_ltk_notify(bdaddr_t *local, bdaddr_t *peer, uint8_t bdaddr_type,
 }
 
 void btd_event_conn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t bdaddr_type,
-						char *name, uint8_t *dev_class)
+						char *name, uint32_t class)
 {
 	struct btd_adapter *adapter;
 	struct btd_device *device;
@@ -463,13 +463,8 @@ void btd_event_conn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t bdaddr_typ
 
 	update_lastused(local, peer, bdaddr_type);
 
-	if (dev_class != NULL) {
-		uint32_t class = dev_class[0] | (dev_class[1] << 8) |
-							(dev_class[2] << 16);
-
-		if (class != 0)
-			write_remote_class(local, peer, class);
-	}
+	if (class != 0)
+		write_remote_class(local, peer, class);
 
 	device_set_addr_type(device, bdaddr_type);
 
diff --git a/src/event.h b/src/event.h
index 7031cc9..6d001dd 100644
--- a/src/event.h
+++ b/src/event.h
@@ -30,7 +30,7 @@ void btd_event_set_legacy_pairing(bdaddr_t *local, bdaddr_t *peer, gboolean lega
 void btd_event_remote_class(bdaddr_t *local, bdaddr_t *peer, uint32_t class);
 void btd_event_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name);
 void btd_event_conn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t bdaddr_type,
-					char *name, uint8_t *dev_class);
+						char *name, uint32_t class);
 void btd_event_conn_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t status);
 void btd_event_disconn_complete(bdaddr_t *local, bdaddr_t *peer);
 void btd_event_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t status);
diff --git a/src/mgmt.c b/src/mgmt.c
index 3f83fdf..ee4cbbe 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
@@ -503,7 +503,7 @@ static void mgmt_device_connected(int sk, uint16_t index, void *buf, size_t len)
 	btd_event_conn_complete(&info->bdaddr, &ev->addr.bdaddr,
 						ev->addr.type,
 						eir_data.name,
-						eir_data.dev_class);
+						eir_data.class);
 
 	eir_data_free(&eir_data);
 }
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 02/18] eir: Add support for parsing SSP hash and randomizer
From: Szymon Janc @ 2012-09-21 10:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1348221750-15345-1-git-send-email-szymon.janc@tieto.com>

This will be used over OOB mechanism.

---
 src/eir.c |   18 ++++++++++++++++++
 src/eir.h |    4 ++++
 2 files changed, 22 insertions(+)

diff --git a/src/eir.c b/src/eir.c
index 50912a0..c29be40 100644
--- a/src/eir.c
+++ b/src/eir.c
@@ -44,6 +44,10 @@ void eir_data_free(struct eir_data *eir)
 	eir->services = NULL;
 	g_free(eir->name);
 	eir->name = NULL;
+	g_free(eir->hash);
+	eir->hash = NULL;
+	g_free(eir->randomizer);
+	eir->randomizer = NULL;
 }
 
 static void eir_parse_uuid16(struct eir_data *eir, void *data, uint8_t len)
@@ -170,6 +174,20 @@ int eir_parse(struct eir_data *eir, uint8_t *eir_data, uint8_t eir_len)
 				break;
 			eir->appearance = bt_get_le16(data);
 			break;
+
+		case EIR_SSP_HASH:
+			if (data_len < 16)
+				break;
+			eir->hash = g_malloc(16);
+			memcpy(eir->hash, data, 16);
+			break;
+
+		case EIR_SSP_RANDOMIZER:
+			if (data_len < 16)
+				break;
+			eir->randomizer = g_malloc(16);
+			memcpy(eir->randomizer, data, 16);
+			break;
 		}
 
 		eir_data += field_len + 1;
diff --git a/src/eir.h b/src/eir.h
index 3c81024..e6e870a 100644
--- a/src/eir.h
+++ b/src/eir.h
@@ -33,6 +33,8 @@
 #define EIR_NAME_COMPLETE           0x09  /* complete local name */
 #define EIR_TX_POWER                0x0A  /* transmit power level */
 #define EIR_CLASS_OF_DEV            0x0D  /* Class of Device */
+#define EIR_SSP_HASH                0x0E  /* SSP Hash */
+#define EIR_SSP_RANDOMIZER          0x0F  /* SSP Randomizer */
 #define EIR_DEVICE_ID               0x10  /* device ID */
 #define EIR_GAP_APPEARANCE          0x19  /* GAP appearance */
 
@@ -48,6 +50,8 @@ struct eir_data {
 	uint8_t dev_class[3];
 	uint16_t appearance;
 	gboolean name_complete;
+	uint8_t *hash;
+	uint8_t *randomizer;
 };
 
 void eir_data_free(struct eir_data *eir);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 01/18] Add initial neard plugin implementation
From: Szymon Janc @ 2012-09-21 10:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1348221750-15345-1-git-send-email-szymon.janc@tieto.com>

Initial implementation. Only register and unregister support.

---
 Makefile.am         |   11 ++-
 acinclude.m4        |   19 +++--
 bootstrap-configure |    3 +-
 plugins/neard.c     |  226 +++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 249 insertions(+), 10 deletions(-)
 create mode 100644 plugins/neard.c

diff --git a/Makefile.am b/Makefile.am
index 372111a..1d6b235 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -259,9 +259,14 @@ builtin_modules += wiimote
 builtin_sources += plugins/wiimote.c
 endif
 
-if DBUSOOBPLUGIN
-builtin_modules += dbusoob
-builtin_sources += plugins/dbusoob.c
+if OOB
+builtin_modules += @OOB_PLUGIN@
+builtin_sources += plugins/@OOB_PLUGIN@.c
+
+noinst_LIBRARIES += plugins/liboob.a
+
+plugins_liboob_a_SOURCES = plugins/dbusoob.c plugins/neard.c
+
 endif
 
 if MAINTAINER_MODE
diff --git a/acinclude.m4 b/acinclude.m4
index 39b0a18..69ab88f 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -185,9 +185,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	datafiles_enable=yes
 	telephony_driver=dummy
 	sap_driver=dummy
-	dbusoob_enable=no
 	wiimote_enable=no
 	gatt_enable=no
+	oob_enable=no
+	oob=dbusoob
 
 	AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization], [disable code optimization]), [
 		optimization_enable=${enableval}
@@ -280,10 +281,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 
 	AC_SUBST([TELEPHONY_DRIVER], [telephony-${telephony_driver}.c])
 
-	AC_ARG_ENABLE(dbusoob, AC_HELP_STRING([--enable-dbusoob], [compile with D-Bus OOB plugin]), [
-		dbusoob_enable=${enableval}
-	])
-
 	AC_ARG_ENABLE(wiimote, AC_HELP_STRING([--enable-wiimote], [compile with Wii Remote plugin]), [
 		wiimote_enable=${enableval}
 	])
@@ -292,6 +289,16 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 		gatt_enable=${enableval}
 	])
 
+	AC_ARG_ENABLE(oob, AC_HELP_STRING([--enable-oob], [enable OOB plugin]), [
+		oob_enable=${enableval}
+	])
+
+	AC_ARG_WITH(oob, AC_HELP_STRING([--with-oob=PLUGIN], [select OOB plugin (dbusoob, neard)]), [
+		oob=${withval}
+	])
+
+	AC_SUBST([OOB_PLUGIN], [${oob}])
+
 	misc_cflags=""
 	misc_ldflags=""
 
@@ -339,7 +346,7 @@ 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(DBUSOOBPLUGIN, test "${dbusoob_enable}" = "yes")
+	AM_CONDITIONAL(OOB, test "${oob_enable}" = "yes")
 	AM_CONDITIONAL(WIIMOTEPLUGIN, test "${wiimote_enable}" = "yes")
 	AM_CONDITIONAL(GATTMODULES, test "${gatt_enable}" = "yes")
 	AM_CONDITIONAL(HOGPLUGIN, test "${gatt_enable}" = "yes" && test "${input_enable}" = "yes")
diff --git a/bootstrap-configure b/bootstrap-configure
index 7177c65..37f1a7d 100755
--- a/bootstrap-configure
+++ b/bootstrap-configure
@@ -23,7 +23,8 @@ fi
 		--enable-hid2hci \
 		--enable-test \
 		--enable-cups \
-		--enable-dbusoob \
+		--enable-oob \
+		--with-oob=neard\
 		--enable-sap \
 		--enable-wiimote \
 		--disable-pcmcia \
diff --git a/plugins/neard.c b/plugins/neard.c
new file mode 100644
index 0000000..5f467b3
--- /dev/null
+++ b/plugins/neard.c
@@ -0,0 +1,226 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2012  Tieto Poland
+ *
+ *
+ *  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 <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/sdp.h>
+
+#include "plugin.h"
+#include "log.h"
+#include "dbus-common.h"
+#include "adapter.h"
+
+#define NEARD_NAME "org.neard"
+#define NEARD_PATH "/"
+#define NEARD_MANAGER_INTERFACE "org.neard.Manager"
+#define AGENT_INTERFACE "org.neard.HandoverAgent"
+#define AGENT_PATH "/org/bluez/neard_handover_agent"
+#define ERROR_INTERFACE "org.neard.HandoverAgent.Error"
+
+static DBusConnection *conn = NULL;
+static DBusPendingCall *pending = NULL;
+
+static guint watcher_id = 0;
+static gboolean agent_registered = FALSE;
+
+static DBusMessage *error_failed(DBusMessage *msg, int error)
+{
+	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
+							"%s", strerror(error));
+}
+
+static void register_agent_cb(DBusPendingCall *call, void *user_data)
+{
+	DBusMessage *message;
+	DBusError err;
+
+	message = dbus_pending_call_steal_reply(call);
+
+	dbus_error_init(&err);
+	if (dbus_set_error_from_message(&err, message)) {
+		error("neard manager replied with an error: %s, %s",
+						err.name, err.message);
+		dbus_error_free(&err);
+		dbus_message_unref(message);
+
+		g_dbus_unregister_interface(conn, AGENT_PATH, AGENT_INTERFACE);
+		return;
+	}
+
+	dbus_message_unref(message);
+	dbus_pending_call_cancel(pending);
+	pending = NULL;
+	agent_registered = TRUE;
+}
+
+static void register_agent(void)
+{
+	DBusMessage *message;
+	const gchar *path = AGENT_PATH;
+
+	message = dbus_message_new_method_call(NEARD_NAME, NEARD_PATH,
+			NEARD_MANAGER_INTERFACE, "RegisterHandoverAgent");
+	if (!message) {
+		error("Couldn't allocate D-Bus message");
+		return;
+	}
+
+	dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &path,
+						DBUS_TYPE_INVALID);
+
+	if (!dbus_connection_send_with_reply(conn, message, &pending, -1)) {
+		error("D-Bus send failed");
+		return;
+	}
+
+	dbus_pending_call_set_notify(pending, register_agent_cb, NULL, NULL);
+}
+
+static void unregister_agent(void)
+{
+	DBusMessage *message;
+	const gchar *path = AGENT_PATH;
+
+	agent_registered = FALSE;
+
+	message = dbus_message_new_method_call(NEARD_NAME, NEARD_PATH,
+			NEARD_MANAGER_INTERFACE, "UnregisterHandoverAgent");
+
+	if (!message) {
+		error("Couldn't allocate D-Bus message");
+		goto unregister;
+	}
+
+	dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &path,
+						DBUS_TYPE_INVALID);
+
+	if (!g_dbus_send_message(conn, message))
+		error("D-Bus send failed");
+
+unregister:
+	g_dbus_unregister_interface(conn, AGENT_PATH, AGENT_INTERFACE);
+}
+
+static DBusMessage *push_oob(DBusConnection *conn, DBusMessage *msg,
+							void *user_data)
+{
+	DBG("");
+
+	return error_failed(msg, ENOTSUP);
+}
+
+static DBusMessage *request_oob(DBusConnection *conn, DBusMessage *msg,
+								void *data)
+{
+	DBG("");
+
+	return error_failed(msg, ENOTSUP);
+}
+
+static DBusMessage *release(DBusConnection *conn, DBusMessage *msg,
+							void *user_data)
+{
+	DBG("");
+
+	agent_registered = FALSE;
+
+	g_dbus_unregister_interface(conn, AGENT_PATH, AGENT_INTERFACE);
+
+	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
+static const GDBusMethodTable neard_methods[] = {
+	{ GDBUS_ASYNC_METHOD("RequestOOB",
+			GDBUS_ARGS({ "data", "a{sv}" }),
+			GDBUS_ARGS({ "data", "a{sv}" }), request_oob) },
+	{ GDBUS_ASYNC_METHOD("PushOOB",
+			GDBUS_ARGS({ "data", "a{sv}"}), NULL, push_oob) },
+	{ GDBUS_METHOD("Release", NULL, NULL, release) },
+	{ }
+};
+
+static void neard_appeared(DBusConnection *conn, void *user_data)
+{
+	DBG("");
+
+	if (!g_dbus_register_interface(conn, AGENT_PATH, AGENT_INTERFACE,
+						neard_methods,
+						NULL, NULL, NULL, NULL)) {
+		error("neard interface init failed on path " AGENT_PATH);
+		return;
+	}
+
+	register_agent();
+}
+
+static void neard_vanished(DBusConnection *conn, void *user_data)
+{
+	DBG("");
+
+	if (pending) {
+		dbus_pending_call_cancel(pending);
+		pending = NULL;
+	}
+
+	/* neard existed without unregistering agent */
+	if (agent_registered) {
+		g_dbus_unregister_interface(conn, AGENT_PATH, AGENT_INTERFACE);
+		agent_registered = FALSE;
+	}
+}
+
+static int neard_init(void)
+{
+	DBG("Setup neard plugin");
+
+	conn = get_dbus_connection();
+
+	watcher_id = g_dbus_add_service_watch(conn, NEARD_NAME, neard_appeared,
+								neard_vanished,
+								NULL, NULL);
+	if (watcher_id == 0)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void neard_exit(void)
+{
+	DBG("Cleanup neard plugin");
+
+	g_dbus_remove_watch(conn, watcher_id);
+	watcher_id = 0;
+
+	if (agent_registered)
+		unregister_agent();
+}
+
+BLUETOOTH_PLUGIN_DEFINE(neard, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
+						neard_init, neard_exit)
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 00/18] neard plugin
From: Szymon Janc @ 2012-09-21 10:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Hi,

This implements initial support for bluez to be able to act as handover
agent for neard NFC daemon.

Neard Handover Agent API is still experimental and under development. It is
subject to change so this plugin should be considered experimental as well.

Currently only pairing is handled - no profile connection or any other action
is taken as this still needs to be clarified on API level.

Also I'm not sure if selecting oob plugin during configure is correct way.
Those are separate plugins, not backends like e.g. sap. Bute nabling both will
result in conflicts in runtime so they need to be mutually excluded (yet both
should be compiled with bootstrap-configure).

Comments are welcome.

-- 
BR
Szymon Janc


Szymon Janc (18):
  Add initial neard plugin implementation
  eir: Add support for parsing SSP hash and randomizer
  eir: Store class in struct eir_data as uint32_t
  eir: Add eir_parse_oob function
  oob: Allow to register pairing complete callback
  adapter: Handle missing randomizer in btd_adapter_add_remote_oob_data
  neard: Implement PushOOB function
  eir: Add support creating EIR with hash and randomizer fields
  eir: Add support for creating EIR with CoD field
  eir: Rename eir_create to eir_create_oob
  eir: Remove support for creating EIR with tx_power fields
  eir: Return number of bytes written by eir_create_oob
  eir: Remove struct uuid_info
  eir: Add support for creating proper OOB EIR
  adapter: Add btd_adapter_get_services function
  adapter: Rename btd_adapter_get_class to btd_adapter_read_class
  adapter: Add btd_adapter_get_class function
  neard: Implement RequestOOB function

 Makefile.am         |   11 +-
 acinclude.m4        |   19 +-
 bootstrap-configure |    3 +-
 plugins/dbusoob.c   |   14 +-
 plugins/neard.c     |  534 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/adapter.c       |   30 ++-
 src/adapter.h       |    5 +-
 src/eir.c           |  154 ++++++++++++---
 src/eir.h           |   21 +-
 src/event.c         |   11 +-
 src/event.h         |    2 +-
 src/mgmt.c          |    5 +-
 src/oob.c           |   22 ++-
 src/oob.h           |   15 +-
 14 files changed, 760 insertions(+), 86 deletions(-)
 create mode 100644 plugins/neard.c

-- 
1.7.9.5


^ permalink raw reply

* [PATCH 2/2] Bluetooth: Factor out Create Configuration Response
From: Andrei Emeltchenko @ 2012-09-21  9:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: gustavo, johan.hedberg
In-Reply-To: <1348219805-19406-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Use function to factor out similar code. For BR/EDR send EFS
Configuration Response immediately, for HS response will be sent
after receiving HCI Logical Link Complete event in the following
patches.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
 net/bluetooth/l2cap_core.c |   32 +++++++++++++++++++-------------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 9732f03..d43128f 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3557,6 +3557,22 @@ static inline void set_default_fcs(struct l2cap_chan *chan)
 		chan->fcs = L2CAP_FCS_CRC16;
 }
 
+static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
+				    u8 ident, u16 flags)
+{
+	struct l2cap_conn *conn = chan->conn;
+
+	BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
+	       flags);
+
+	clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
+	set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
+
+	l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
+		       l2cap_build_conf_rsp(chan, data,
+					    L2CAP_CONF_SUCCESS, flags), data);
+}
+
 static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
 {
 	struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
@@ -3648,16 +3664,11 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 	/* Got Conf Rsp PENDING from remote side and asume we sent
 	   Conf Rsp PENDING in the code above */
 	if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
-			test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
+	    test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
 
 		/* check compatibility */
 
-		clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
-		set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
-
-		l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
-					l2cap_build_conf_rsp(chan, rsp,
-					L2CAP_CONF_SUCCESS, flags), rsp);
+		l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
 	}
 
 unlock:
@@ -3705,12 +3716,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 
 			/* check compatibility */
 
-			clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
-			set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
-
-			l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
-						l2cap_build_conf_rsp(chan, buf,
-						L2CAP_CONF_SUCCESS, 0x0000), buf);
+			l2cap_send_efs_conf_rsp(chan, buf, cmd->ident, 0);
 		}
 		goto done;
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 1/2] Bluetooth: Factor out hci_queue_acl
From: Andrei Emeltchenko @ 2012-09-21  9:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: gustavo, johan.hedberg

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Use hci_chan as parameter instead of hci_conn as we need logical
handle from hci_chan for AMP link.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
 net/bluetooth/hci_core.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e407051..3588f31 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2151,9 +2151,10 @@ static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
 	hdr->dlen   = cpu_to_le16(len);
 }
 
-static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue,
+static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
 			  struct sk_buff *skb, __u16 flags)
 {
+	struct hci_conn *conn = chan->conn;
 	struct hci_dev *hdev = conn->hdev;
 	struct sk_buff *list;
 
@@ -2200,14 +2201,13 @@ static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue,
 
 void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
 {
-	struct hci_conn *conn = chan->conn;
-	struct hci_dev *hdev = conn->hdev;
+	struct hci_dev *hdev = chan->conn->hdev;
 
 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
 
 	skb->dev = (void *) hdev;
 
-	hci_queue_acl(conn, &chan->data_q, skb, flags);
+	hci_queue_acl(chan, &chan->data_q, skb, flags);
 
 	queue_work(hdev->workqueue, &hdev->tx_work);
 }
-- 
1.7.9.5


^ permalink raw reply related

* Re: [PATCH BlueZ V7 1/5] AVRCP: Add TG Record to support AVRCP Browsing
From: Luiz Augusto von Dentz @ 2012-09-21  9:23 UTC (permalink / raw)
  To: Joohi RASTOGI; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <3176460F0F455A44B2E93431E34FC86C228F881F31@EXDCVYMBSTM005.EQ1STM.local>

Hi Joohi,

On Fri, Sep 21, 2012 at 8:22 AM, Joohi RASTOGI
<joohi.rastogi@stericsson.com> wrote:
> From 7348afc3401746a1890763ac5b689fca164fd934 Mon Sep 17 00:00:00 2001
> From: Joohi Rastogi <joohi.rastogi@stericsson.com>
> Date: Thu, 20 Sep 2012 14:21:37 +0530
> Subject: [PATCH BlueZ V7 1/5] Adds SDP record to support browsing
>
> ---
>  audio/avctp.c |    4 ++--
>  audio/avctp.h |    3 ++-
>  audio/avrcp.c |   30 +++++++++++++++++++++++++-----
>  3 files changed, 29 insertions(+), 8 deletions(-)
>
> diff --git a/audio/avctp.c b/audio/avctp.c
> index 4e0e8dc..20aed66 100644
> --- a/audio/avctp.c
> +++ b/audio/avctp.c
> @@ -803,7 +803,7 @@ static GIOChannel *avctp_server_socket(const bdaddr_t *src, gboolean master)
>         io = bt_io_listen(NULL, avctp_confirm_cb, NULL,
>                                 NULL, &err,
>                                 BT_IO_OPT_SOURCE_BDADDR, src,
> -                               BT_IO_OPT_PSM, AVCTP_PSM,
> +                               BT_IO_OPT_PSM, AVCTP_CONTROL_PSM,
>                                 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
>                                 BT_IO_OPT_MASTER, master,
>                                 BT_IO_OPT_INVALID);
> @@ -1091,7 +1091,7 @@ struct avctp *avctp_connect(const bdaddr_t *src, const bdaddr_t *dst)
>         io = bt_io_connect(avctp_connect_cb, session, NULL, &err,
>                                 BT_IO_OPT_SOURCE_BDADDR, &session->server->src,
>                                 BT_IO_OPT_DEST_BDADDR, &session->dst,
> -                               BT_IO_OPT_PSM, AVCTP_PSM,
> +                               BT_IO_OPT_PSM, AVCTP_CONTROL_PSM,
>                                 BT_IO_OPT_INVALID);
>         if (err) {
>                 avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
> diff --git a/audio/avctp.h b/audio/avctp.h
> index d0cbd97..9d19b5d 100644
> --- a/audio/avctp.h
> +++ b/audio/avctp.h
> @@ -22,7 +22,8 @@
>   *
>   */
>
> -#define AVCTP_PSM 23
> +#define AVCTP_CONTROL_PSM              23
> +#define AVCTP_BROWSING_PSM             27
>
>  #define AVC_MTU 512
>  #define AVC_HEADER_LENGTH 3
> diff --git a/audio/avrcp.c b/audio/avrcp.c
> index 27be7e8..206d8fa 100644
> --- a/audio/avrcp.c
> +++ b/audio/avrcp.c
> @@ -106,6 +106,7 @@
>  #define AVRCP_FEATURE_CATEGORY_3       0x0004
>  #define AVRCP_FEATURE_CATEGORY_4       0x0008
>  #define AVRCP_FEATURE_PLAYER_SETTINGS  0x0010
> +#define AVRCP_FEATURE_BROWSING                 0x0040
>
>  #define AVRCP_BATTERY_STATUS_NORMAL            0
>  #define AVRCP_BATTERY_STATUS_WARNING           1
> @@ -191,7 +192,7 @@ static sdp_record_t *avrcp_ct_record(void)
>         sdp_list_t *aproto, *proto[2];
>         sdp_record_t *record;
>         sdp_data_t *psm, *version, *features;
> -       uint16_t lp = AVCTP_PSM;
> +       uint16_t lp = AVCTP_CONTROL_PSM;
>         uint16_t avrcp_ver = 0x0100, avctp_ver = 0x0103;
>         uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 |
>                                                 AVRCP_FEATURE_CATEGORY_2 |
> @@ -253,18 +254,20 @@ static sdp_record_t *avrcp_ct_record(void)
>
>  static sdp_record_t *avrcp_tg_record(void)
>  {
> -       sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> +       sdp_list_t *svclass_id, *pfseq, *apseq, *root, *apseq_browsing;
>         uuid_t root_uuid, l2cap, avctp, avrtg;
>         sdp_profile_desc_t profile[1];
>         sdp_list_t *aproto, *proto[2];
> -       sdp_record_t *record;
> -       sdp_data_t *psm, *version, *features;
> -       uint16_t lp = AVCTP_PSM;
> +       sdp_record_t *record;sdp_data_t *psm, *version, *features, *psm_browsing;
> +       sdp_list_t *aproto_browsing, *proto_browsing[2] = {0};
> +       uint16_t lp = AVCTP_CONTROL_PSM;
> +       uint16_t lp_browsing = AVCTP_BROWSING_PSM;
>         uint16_t avrcp_ver = 0x0104, avctp_ver = 0x0103;
>         uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 |
>                                         AVRCP_FEATURE_CATEGORY_2 |
>                                         AVRCP_FEATURE_CATEGORY_3 |
>                                         AVRCP_FEATURE_CATEGORY_4 |
> +                                       AVRCP_FEATURE_BROWSING |
>                                         AVRCP_FEATURE_PLAYER_SETTINGS );
>
>         record = sdp_record_alloc();
> @@ -295,6 +298,17 @@ static sdp_record_t *avrcp_tg_record(void)
>
>         aproto = sdp_list_append(0, apseq);
>         sdp_set_access_protos(record, aproto);
> +       proto_browsing[0] = sdp_list_append(0, &l2cap);
> +       psm_browsing = sdp_data_alloc(SDP_UINT16, &lp_browsing);
> +       proto_browsing[0] = sdp_list_append(proto_browsing[0], psm_browsing);
> +       apseq_browsing = sdp_list_append(0, proto_browsing[0]);
> +
> +       proto_browsing[1] = sdp_list_append(0, &avctp);
> +       proto_browsing[1] = sdp_list_append(proto_browsing[1], version);
> +       apseq_browsing = sdp_list_append(apseq_browsing, proto_browsing[1]);
> +
> +       aproto_browsing = sdp_list_append(0, apseq_browsing);
> +       sdp_set_add_access_protos(record, aproto_browsing);
>
>         /* Bluetooth Profile Descriptor List */
>         sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID);
> @@ -307,6 +321,12 @@ static sdp_record_t *avrcp_tg_record(void)
>
>         sdp_set_info_attr(record, "AVRCP TG", 0, 0);
>
> +       free(psm_browsing);
> +       sdp_list_free(proto_browsing[0], 0);
> +       sdp_list_free(proto_browsing[1], 0);
> +       sdp_list_free(apseq_browsing, 0);
> +       sdp_list_free(aproto_browsing, 0);
> +
>         free(psm);
>         free(version);
>         sdp_list_free(proto[0], 0);
> --
> 1.7.5.4

Please fix the coding style:

Applying: Adds SDP record to support browsing
WARNING:LONG_LINE: line over 80 characters
#70: FILE: audio/avrcp.c:261:
+	sdp_record_t *record;sdp_data_t *psm, *version, *features, *psm_browsing;

ERROR:SPACING: space required after that ';' (ctx:VxV)
#70: FILE: audio/avrcp.c:261:
+	sdp_record_t *record;sdp_data_t *psm, *version, *features, *psm_browsing;


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH] Cycling Speed and Cadence profile (CSCP) API
From: Andrzej Kaczmarek @ 2012-09-21  9:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1348218561-24509-1-git-send-email-andrzej.kaczmarek@tieto.com>

---
 doc/cycling-api.txt | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)
 create mode 100644 doc/cycling-api.txt

diff --git a/doc/cycling-api.txt b/doc/cycling-api.txt
new file mode 100644
index 0000000..5988cac
--- /dev/null
+++ b/doc/cycling-api.txt
@@ -0,0 +1,112 @@
+Cycling Speed and Cadence API description
+****************************************
+
+Copyright (C) 2012	Tieto Poland
+
+Cycling Manager hierarchy
+============================
+
+Service		org.bluez
+Interface	org.bluez.CyclingManager
+Object path	[variable prefix]/{hci0,hci1,...}
+
+Methods		RegisterWatcher(object agent)
+
+			Registers a watcher to monitor cycling speed and cadence
+			measurements.
+
+			Possible Errors: org.bluez.Error.InvalidArguments
+
+		UnregisterWatcher(object agent)
+
+			Unregisters a watcher.
+
+Cycling Speed and Cadence Profile hierarchy
+============================
+
+Service		org.bluez
+Interface	org.bluez.Cycling
+Object path	[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX
+
+Methods		void SetProperty(string name, variant value)
+
+			Changes the value of the specified property. Only
+			read-write properties can be changed. On success
+			this will emit a PropertyChanged signal.
+
+			Possible Errors: org.bluez.Error.InvalidArguments
+
+		dict GetProperties()
+
+			Returns all properties for the interface. See the
+			Properties section for the available properties.
+
+		SetCumulativeWheelRevolutions(uint32 value)
+
+			Sets cumulative wheel revolutions value if
+			Cumulative Wheel Revolutions feature is supported.
+
+			Possible Errors: org.bluez.Error.NotSupported
+
+Signals		PropertyChanged(string name, variant value)
+
+			This signal indicates a changed value of the given
+			property.
+
+Properties	String Location (optional) [readwrite]
+
+			Current sensor location, if supported.
+			If Multiple Sensor Locations feature is supported,
+			this property can be set to one of values read from
+			SupportedLocations property.
+
+			Possible values: "Other", "Top of shoe", "In shoe",
+					"Hip", "Front Wheel", "Left Crank",
+					"Right Crank", "Left Pedal",
+					"Right Pedal", "Front Hub",
+					"Rear Dropout", "Chainstay",
+					"Rear Wheel", "Rear Hub"
+
+		array{string} SupportedLocations (optional) [readonly]
+
+			List of locations supported by sensor, only present
+			if Multiple Sensor Locations feature is supported.
+
+		boolean WheelRevolutionDataSupported [readonly]
+
+			true if sensor can read and set Cumulative Wheel
+			Revolutions value, false otherwise.
+
+		boolean MultipleSensorLocationsSupported [readonly]
+
+			true if sensor supports Multiple Sensor Locations
+			feature and can set Location, false otherwise.
+
+Cycling Speed and Cadence Watcher hierarchy
+============================
+Service		unique name
+Interface	org.bluez.CyclingWatcher
+Object path	freely definable
+
+Methods		void MeasurementReceived(object device, dict measurement)
+
+			This callback is called whenever a cycling speed and
+			cadence measurement is received from sensor.
+
+			Measurement:
+
+				uint32 WheelRevolutions (optional):
+
+					Cumulative number of wheel revolutions
+
+				uint16 LastWheelEventTime (optional):
+
+					Value of Last Wheel Event time
+
+				uint16 CrankRevolutions (optional):
+
+					Cumulative number of crank revolutions
+
+				uint16 LastCrankEventTime (optional):
+
+					Value of Last Crank Event time
-- 
1.7.11.3


^ permalink raw reply related

* [RFC] Cycling Speed and Cadence profile (CSCP) API
From: Andrzej Kaczmarek @ 2012-09-21  9:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

Hi,

Here's proposal for CSCP API. This is of course for Collector role.
Not sure if 'Cycling' prefix for interface names (and probably also for plugin
name) is good enough, but couldn't think of anything better.

Comments are welcome.


Andrzej Kaczmarek (1):
  Cycling Speed and Cadence profile (CSCP) API

 doc/cycling-api.txt | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)
 create mode 100644 doc/cycling-api.txt

-- 
1.7.11.3


^ permalink raw reply

* [PATCH BlueZ V7 5/5] AVRCP: Add handler for browsing pdu
From: Joohi RASTOGI @ 2012-09-21  5:22 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org; +Cc: Luiz Augusto von Dentz, Joohi RASTOGI

>From e6ee4cec1e2eac5f343cad4fdcd05c2462b76282 Mon Sep 17 00:00:00 2001
From: Joohi Rastogi <joohi.rastogi@stericsson.com>
Date: Fri, 21 Sep 2012 10:40:35 +0530
Subject: [PATCH BlueZ V7 5/5] Implement generic handling of browsing PDU IDs

---
 audio/avctp.c |   24 ++++++++++++++++++-
 audio/avrcp.c |   70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 91 insertions(+), 3 deletions(-)
 mode change 100755 => 100644 audio/avrcp.c

diff --git a/audio/avctp.c b/audio/avctp.c
index fb5689e..146a0ce 100644
--- a/audio/avctp.c
+++ b/audio/avctp.c
@@ -481,9 +481,9 @@ static gboolean session_browsing_cb(GIOChannel *chan, GIOCondition cond,
 				gpointer data)
 {
 	struct avctp *session = data;
-	uint8_t  *buf;
+	uint8_t  *buf, *operands;
 	struct avctp_header *avctp;
-	int ret;
+	int ret, packet_size, operand_count, sock;
 
 	buf = avctp_read_data(&ret, session->browsing_mtu,
 						session->browsing_io);
@@ -495,9 +495,29 @@ static gboolean session_browsing_cb(GIOChannel *chan, GIOCondition cond,
 		goto failed;
 
 	avctp = (struct avctp_header *) buf;
+	DBG("AVCTP transaction %u, packet type %u, C/R %u, IPID %u, "
+				"PID 0x%04X",
+				avctp->transaction, avctp->packet_type,
+				avctp->cr, avctp->ipid, ntohs(avctp->pid));
 
 	if (avctp->packet_type != AVCTP_PACKET_SINGLE)
 		goto failed;
+	operands = buf + AVCTP_HEADER_LENGTH;
+	ret -= AVCTP_HEADER_LENGTH;
+	operand_count = ret;
+
+	packet_size = AVCTP_HEADER_LENGTH;
+	avctp->cr = AVCTP_RESPONSE;
+	if (browsing_handler)
+		packet_size += browsing_handler->cb(session, avctp->transaction,
+						operands, operand_count, browsing_handler->user_data);
+
+	if (packet_size != 0) {
+		sock = g_io_channel_unix_get_fd(session->browsing_io);
+		ret = write(sock, buf, packet_size);
+		if (ret != packet_size)
+			goto failed;
+	}
 
 	g_free(buf);
 	return TRUE;
diff --git a/audio/avrcp.c b/audio/avrcp.c
old mode 100755
new mode 100644
index 8259183..8c88d5d
--- a/audio/avrcp.c
+++ b/audio/avrcp.c
@@ -95,6 +95,9 @@
 #define AVRCP_ABORT_CONTINUING		0x41
 #define AVRCP_SET_ABSOLUTE_VOLUME	0x50
 
+#define AVRCP_INVALID_BROWSING_PDU		0x00
+#define AVRCP_GENERAL_REJECT 			0xA0
+
 /* Capabilities for AVRCP_GET_CAPABILITIES pdu */
 #define CAP_COMPANY_ID		0x02
 #define CAP_EVENTS_SUPPORTED	0x03
@@ -145,6 +148,12 @@ struct avrcp_header {
 #define AVRCP_MTU	(AVC_MTU - AVC_HEADER_LENGTH)
 #define AVRCP_PDU_MTU	(AVRCP_MTU - AVRCP_HEADER_LENGTH)
 
+struct avrcp_browsing_header {
+	uint8_t browsing_pdu;
+	uint16_t param_len;
+} __attribute__ ((packed));
+#define AVRCP_BROWSING_HEADER_LENGTH 3
+
 struct avrcp_server {
 	bdaddr_t src;
 	uint32_t tg_record_id;
@@ -165,7 +174,9 @@ struct avrcp_player {
 	struct audio_device *dev;
 
 	unsigned int control_handler;
+	unsigned int browsing_handler;
 	uint16_t registered_events;
+	uint8_t transaction;
 	uint8_t transaction_events[AVRCP_EVENT_LAST + 1];
 	struct pending_pdu *pending_pdu;
 
@@ -1080,6 +1091,14 @@ static struct control_pdu_handler {
 		{ },
 };
 
+static struct pdu_browsing_handler {
+	uint8_t browsing_pdu;
+	void (*func) (struct avrcp_player *player,
+						struct avrcp_browsing_header *pdu);
+	} browsing_handlers[] = {
+					{ AVRCP_INVALID_BROWSING_PDU, NULL },
+};
+
 /* handle vendordep pdu inside an avctp packet */
 static size_t handle_vendordep_pdu(struct avctp *session, uint8_t transaction,
 					uint8_t *code, uint8_t *subunit,
@@ -1139,6 +1158,47 @@ err_metadata:
 	return AVRCP_HEADER_LENGTH + 1;
 }
 
+static size_t handle_browsing_pdu(struct avctp *session,
+					uint8_t transaction, uint8_t *operands,
+					size_t operand_count, void *user_data)
+{
+	struct avrcp_player *player = user_data;
+	struct pdu_browsing_handler *b_handler;
+	struct avrcp_browsing_header *avrcp_browsing = (void *) operands;
+	uint8_t status;
+
+	operand_count += AVRCP_BROWSING_HEADER_LENGTH;
+
+	for (b_handler = browsing_handlers; b_handler; b_handler++) {
+		if (b_handler->browsing_pdu == AVRCP_INVALID_BROWSING_PDU) {
+			b_handler = NULL;
+			break;
+		}
+		if (b_handler->browsing_pdu == avrcp_browsing->browsing_pdu)
+			break;
+	}
+	if (!b_handler) {
+		avrcp_browsing->browsing_pdu = AVRCP_GENERAL_REJECT;
+		status = AVRCP_STATUS_INVALID_COMMAND;
+		goto err;
+	}
+	if (!b_handler->func) {
+		status = AVRCP_STATUS_INVALID_PARAM;
+		avrcp_browsing->param_len = htons(sizeof(status));
+		goto err;
+	}
+
+	player->transaction = transaction;
+	b_handler->func(player, avrcp_browsing);
+	return AVRCP_BROWSING_HEADER_LENGTH + ntohs(avrcp_browsing->param_len);
+
+	err:
+	avrcp_browsing->param_len = htons(sizeof(status));
+	memcpy(&operands[AVRCP_BROWSING_HEADER_LENGTH], &status,
+							(sizeof(status)));
+	return AVRCP_BROWSING_HEADER_LENGTH + sizeof(status);
+}
+
 size_t avrcp_handle_vendor_reject(uint8_t *code, uint8_t *operands)
 {
 	struct avrcp_header *pdu = (void *) operands;
@@ -1238,7 +1298,10 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,
 			avctp_unregister_pdu_handler(player->control_handler);
 			player->control_handler = 0;
 		}
-
+		if (player->browsing_handler) {
+			avctp_unregister_browsing_pdu_handler();
+			player->browsing_handler = 0;
+		}
 		break;
 	case AVCTP_STATE_CONNECTING:
 		player->session = avctp_connect(&dev->src, &dev->dst);
@@ -1249,6 +1312,11 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,
 							AVC_OP_VENDORDEP,
 							handle_vendordep_pdu,
 							player);
+		if (!player->browsing_handler)
+			player->browsing_handler =
+							avctp_register_browsing_pdu_handler(
+							handle_browsing_pdu,
+							player);
 		break;
 	case AVCTP_STATE_CONNECTED:
 		rec = btd_device_get_record(dev->btd_dev, AVRCP_TARGET_UUID);
-- 
1.7.5.4

Regards
Joohi

^ permalink raw reply related

* [PATCH BlueZ V7 4/5] AVRCP: Register/Unregister Browsing handler
From: Joohi RASTOGI @ 2012-09-21  5:22 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org; +Cc: Luiz Augusto von Dentz, Joohi RASTOGI

>From 0c8f6e695ce76d3660ae890f04b1c03529fce108 Mon Sep 17 00:00:00 2001
From: Joohi Rastogi <joohi.rastogi@stericsson.com>
Date: Fri, 21 Sep 2012 10:26:42 +0530
Subject: [PATCH] Add functions to register and unregister Browsing handler

---
 audio/avctp.c |   24 ++++++++++++++++++++++++
 audio/avctp.h |    8 +++++++-
 2 files changed, 31 insertions(+), 1 deletions(-)
 mode change 100755 => 100644 audio/avctp.h

diff --git a/audio/avctp.c b/audio/avctp.c
index 5a95d8d..fb5689e 100644
--- a/audio/avctp.c
+++ b/audio/avctp.c
@@ -158,6 +158,11 @@ struct avctp_pdu_handler {
 	unsigned int id;
 };
 
+struct avctp_browsing_pdu_handler {
+	avctp_browsing_pdu_cb cb;
+	void *user_data;
+};
+
 static struct {
 	const char *name;
 	uint8_t avc;
@@ -177,6 +182,7 @@ static GSList *callbacks = NULL;
 static GSList *servers = NULL;
 static GSList *control_handlers = NULL;
 static uint8_t id = 0;
+static struct avctp_browsing_pdu_handler *browsing_handler = NULL;
 
 static void auth_cb(DBusError *derr, void *user_data);
 
@@ -1261,6 +1267,18 @@ unsigned int avctp_register_pdu_handler(uint8_t opcode, avctp_control_pdu_cb cb,
 	return handler->id;
 }
 
+unsigned int avctp_register_browsing_pdu_handler(avctp_browsing_pdu_cb cb,
+					void *user_data)
+{
+	unsigned int id = 0;
+
+	browsing_handler = g_new(struct avctp_browsing_pdu_handler, 1);
+	browsing_handler->cb = cb;
+	browsing_handler->user_data = user_data;
+
+	return ++id;
+}
+
 gboolean avctp_unregister_pdu_handler(unsigned int id)
 {
 	GSList *l;
@@ -1278,6 +1296,12 @@ gboolean avctp_unregister_pdu_handler(unsigned int id)
 	return FALSE;
 }
 
+gboolean avctp_unregister_browsing_pdu_handler()
+{
+	g_free(browsing_handler);
+	return TRUE;
+}
+
 struct avctp *avctp_connect(const bdaddr_t *src, const bdaddr_t *dst)
 {
 	struct avctp *session;
diff --git a/audio/avctp.h b/audio/avctp.h
old mode 100755
new mode 100644
index 53919de..ae5c556
--- a/audio/avctp.h
+++ b/audio/avctp.h
@@ -82,6 +82,10 @@ typedef size_t (*avctp_control_pdu_cb) (struct avctp *session, uint8_t transacti
 typedef gboolean (*avctp_rsp_cb) (struct avctp *session, uint8_t code,
 					uint8_t subunit, uint8_t *operands,
 					size_t operand_count, void *user_data);
+typedef size_t (*avctp_browsing_pdu_cb) (struct avctp *session,
+					uint8_t transaction,
+					uint8_t *operands, size_t operand_count,
+					void *user_data);
 
 unsigned int avctp_add_state_cb(avctp_state_cb cb, void *user_data);
 gboolean avctp_remove_state_cb(unsigned int id);
@@ -96,7 +100,9 @@ void avctp_disconnect(struct avctp *session);
 unsigned int avctp_register_pdu_handler(uint8_t opcode, avctp_control_pdu_cb cb,
 							void *user_data);
 gboolean avctp_unregister_pdu_handler(unsigned int id);
-
+unsigned int avctp_register_browsing_pdu_handler(avctp_browsing_pdu_cb cb,
+							void *user_data);
+gboolean avctp_unregister_browsing_pdu_handler();
 int avctp_send_passthrough(struct avctp *session, uint8_t op);
 int avctp_send_vendordep(struct avctp *session, uint8_t transaction,
 				uint8_t code, uint8_t subunit,
-- 
1.7.5.4

Regards
Joohi

^ permalink raw reply related

* [PATCH BlueZ V8 3/5] AVRCP: Add browsing channel support
From: Joohi RASTOGI @ 2012-09-21  5:22 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org; +Cc: Luiz Augusto von Dentz, Joohi RASTOGI

>From 2439be8dc6289ad4e6461471c3cb0861d25c91e6 Mon Sep 17 00:00:00 2001
From: Joohi Rastogi <joohi.rastogi@stericsson.com>
Date: Fri, 21 Sep 2012 10:16:51 +0530
Subject: [PATCH BlueZ V8 3/5] Implements browsing channel creation and release

---
 audio/avctp.c |  265 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 235 insertions(+), 30 deletions(-)
 mode change 100755 => 100644 audio/avctp.c

diff --git a/audio/avctp.c b/audio/avctp.c
old mode 100755
new mode 100644
index 36133b3..daeb016
--- a/audio/avctp.c
+++ b/audio/avctp.c
@@ -42,6 +42,7 @@
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/sdp.h>
 #include <bluetooth/uuid.h>
+#include <bluetooth/l2cap.h>
 
 #include <glib.h>
 
@@ -120,6 +121,7 @@ struct avctp_state_callback {
 struct avctp_server {
 	bdaddr_t src;
 	GIOChannel *control_io;
+	GIOChannel *browsing_io;
 	GSList *sessions;
 };
 
@@ -138,9 +140,12 @@ struct avctp {
 	int uinput;
 
 	GIOChannel *control_io;
+	GIOChannel *browsing_io;
 	guint control_io_id;
+	guint browsing_io_id;
 
 	uint16_t control_mtu;
+	uint16_t browsing_mtu;
 
 	uint8_t key_quirks[256];
 	GSList *handlers;
@@ -327,6 +332,17 @@ static void avctp_disconnected(struct avctp *session)
 	if (!session)
 		return;
 
+	if (session->browsing_io) {
+		g_io_channel_shutdown(session->browsing_io, TRUE, NULL);
+		g_io_channel_unref(session->browsing_io);
+		session->browsing_io = NULL;
+	}
+
+	if (session->browsing_io_id) {
+		g_source_remove(session->browsing_io_id);
+		session->browsing_io_id = 0;
+	}
+
 	if (session->control_io) {
 		g_io_channel_shutdown(session->control_io, TRUE, NULL);
 		g_io_channel_unref(session->control_io);
@@ -433,31 +449,76 @@ static void handle_response(struct avctp *session, struct avctp_header *avctp,
 	}
 }
 
+static uint8_t *avctp_read_data(int *data_read, int length, GIOChannel
+				*chan) {
+	uint8_t *buffer;
+	int sock;
+
+	buffer = g_new0(uint8_t, length);
+	sock = g_io_channel_unix_get_fd(chan);
+
+	*data_read = read(sock, buffer, length);
+	if (*data_read <= 0)
+		goto failed;
+
+	if (*data_read < AVCTP_HEADER_LENGTH) {
+		error("Too small AVCTP packet");
+		goto failed;
+	}
+	return buffer;
+
+failed:
+	return NULL;
+}
+
+static gboolean session_browsing_cb(GIOChannel *chan, GIOCondition cond,
+				gpointer data)
+{
+	struct avctp *session = data;
+	uint8_t  *buf;
+	struct avctp_header *avctp;
+	int ret;
+
+	buf = avctp_read_data(&ret, session->browsing_mtu,
+						session->browsing_io);
+
+	if (buf == NULL)
+		goto failed;
+
+	if (!(cond & G_IO_IN))
+		goto failed;
+
+	avctp = (struct avctp_header *) buf;
+
+	if (avctp->packet_type != AVCTP_PACKET_SINGLE)
+		goto failed;
+
+	g_free(buf);
+	return TRUE;
+
+failed:
+	g_free(buf);
+	return FALSE;
+}
+
 static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
 				gpointer data)
 {
 	struct avctp *session = data;
-	uint8_t buf[1024], *operands, code, subunit;
+	uint8_t *buf, *operands, code, subunit;
 	struct avctp_header *avctp;
 	struct avc_header *avc;
 	int ret, packet_size, operand_count, sock;
 	struct avctp_pdu_handler *handler;
 
-	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
+	buf = avctp_read_data(&ret, session->control_mtu, session->control_io);
+	if (buf == NULL)
 		goto failed;
 
-	sock = g_io_channel_unix_get_fd(session->control_io);
-
-	ret = read(sock, buf, sizeof(buf));
-	if (ret <= 0)
+	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
 		goto failed;
 
-	DBG("Got %d bytes of data for AVCTP session %p", ret, session);
-
-	if ((unsigned int) ret < sizeof(struct avctp_header)) {
-		error("Too small AVCTP packet");
-		goto failed;
-	}
+	sock = g_io_channel_unix_get_fd(session->control_io);
 
 	avctp = (struct avctp_header *) buf;
 
@@ -487,6 +548,7 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
 
 	if (avctp->cr == AVCTP_RESPONSE) {
 		handle_response(session, avctp, avc, operands, operand_count);
+		g_free(buf);
 		return TRUE;
 	}
 
@@ -526,11 +588,13 @@ done:
 	ret = write(sock, buf, packet_size);
 	if (ret != packet_size)
 		goto failed;
+	g_free(buf);
 
 	return TRUE;
 
 failed:
 	DBG("AVCTP session %p got disconnected", session);
+	g_free(buf);
 	avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
 	return FALSE;
 }
@@ -614,6 +678,46 @@ static void init_uinput(struct avctp *session)
 		DBG("AVRCP: uinput initialized for %s", address);
 }
 
+static void avctp_connect_browsing_cb(GIOChannel *chan,
+					GError *err,
+					gpointer data)
+{
+	struct avctp *session = data;
+	char address[18];
+	uint16_t imtu;
+	GError *gerr = NULL;
+
+	if (err) {
+		error("Browsing: %s", err->message);
+		g_io_channel_shutdown(chan, TRUE, NULL);
+		g_io_channel_unref(chan);
+		session->browsing_io = NULL;
+		return;
+	}
+
+	bt_io_get(chan, &gerr,
+			BT_IO_OPT_DEST, &address,
+			BT_IO_OPT_IMTU, &imtu,
+			BT_IO_OPT_INVALID);
+	if (gerr) {
+		error("%s", gerr->message);
+		g_io_channel_shutdown(chan, TRUE, NULL);
+		g_io_channel_unref(chan);
+		session->browsing_io = NULL;
+		error("%s", gerr->message);
+		g_error_free(gerr);
+		return;
+	}
+
+	if (!session->browsing_io)
+		session->browsing_io = g_io_channel_ref(chan);
+
+	session->browsing_mtu = imtu;
+
+	session->browsing_io_id = g_io_add_watch(chan,
+				G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+				(GIOFunc) session_browsing_cb, session); }
+
 static void avctp_connect_cb(GIOChannel *chan, GError *err, gpointer data)
 {
 	struct avctp *session = data;
@@ -652,6 +756,31 @@ static void avctp_connect_cb(GIOChannel *chan, GError *err, gpointer data)
 				(GIOFunc) session_cb, session);
 }
 
+static void auth_browsing_cb(DBusError *derr, void *user_data) {
+	struct avctp *session = user_data;
+	GError *err = NULL;
+
+	if (session->browsing_io_id) {
+		g_source_remove(session->browsing_io_id);
+		session->browsing_io_id = 0;
+	}
+
+	if (derr && dbus_error_is_set(derr)) {
+		error("Browsing Access denied: %s", derr->message);
+		return;
+	}
+
+	if (!bt_io_accept(session->browsing_io, avctp_connect_browsing_cb,
+						session, NULL, &err)) {
+		error("Browsing bt_io_accept: %s", err->message);
+		if (session && session->browsing_io) {
+			g_io_channel_unref(session->browsing_io);
+			session->browsing_io = NULL;
+		}
+		g_error_free(err);
+	}
+}
+
 static void auth_cb(DBusError *derr, void *user_data)
 {
 	struct avctp *session = user_data;
@@ -730,6 +859,64 @@ static struct avctp *avctp_get_internal(const bdaddr_t *src,
 	return session;
 }
 
+static void avctp_control_confirm(struct avctp *session, GIOChannel *chan,
+						struct audio_device *dev)
+{
+	if (session->control_io) {
+		error("Refusing unexpected connect from");
+		goto drop;
+	}
+
+	avctp_set_state(session, AVCTP_STATE_CONNECTING);
+	session->control_io = g_io_channel_ref(chan);
+
+	if (audio_device_request_authorization(dev, AVRCP_TARGET_UUID,
+						auth_cb, session) < 0)
+		goto drop;
+
+	session->control_io_id = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP |
+						G_IO_NVAL, session_cb, session);
+	return;
+
+drop:
+	if (!session || !session->control_io)
+		g_io_channel_shutdown(chan, TRUE, NULL);
+
+	if (session && session->control_io)
+		g_io_channel_unref(session->control_io);
+
+	if (session)
+		avctp_set_state(session, AVCTP_STATE_DISCONNECTED); }
+
+static void avctp_browsing_confirm(struct avctp *session, GIOChannel *chan,
+						struct audio_device *dev)
+{
+
+	if (!session->control_io) {
+		error("Browsing: Refusing unexpected connect from");
+		goto drop;
+	}
+
+	if (session->browsing_io) {
+		error("Browsing channel already exists");
+		goto drop;
+	}
+
+	session->browsing_io = g_io_channel_ref(chan);
+
+	if (audio_device_request_authorization(dev, AVRCP_TARGET_UUID,
+						auth_browsing_cb, session) < 0)
+		goto drop;
+	return;
+
+drop:
+	if (!session || !session->control_io || !session->browsing_io)
+		g_io_channel_shutdown(chan, TRUE, NULL);
+
+	if (session && session->browsing_io)
+		g_io_channel_unref(session->browsing_io);
+}
+
 static void avctp_confirm_cb(GIOChannel *chan, gpointer data)
 {
 	struct avctp *session;
@@ -737,11 +924,13 @@ static void avctp_confirm_cb(GIOChannel *chan, gpointer data)
 	char address[18];
 	bdaddr_t src, dst;
 	GError *err = NULL;
+	uint16_t psm;
 
 	bt_io_get(chan, &err,
 			BT_IO_OPT_SOURCE_BDADDR, &src,
 			BT_IO_OPT_DEST_BDADDR, &dst,
 			BT_IO_OPT_DEST, address,
+			BT_IO_OPT_PSM, &psm,
 			BT_IO_OPT_INVALID);
 	if (err) {
 		error("%s", err->message);
@@ -772,30 +961,29 @@ static void avctp_confirm_cb(GIOChannel *chan, gpointer data)
 			goto drop;
 	}
 
-	if (session->control_io) {
-		error("Refusing unexpected connect from %s", address);
-		goto drop;
+	switch (psm) {
+	case AVCTP_CONTROL_PSM:
+		avctp_control_confirm(session, chan, dev);
+		break;
+	case AVCTP_BROWSING_PSM:
+		avctp_browsing_confirm(session, chan, dev);
+		break;
 	}
 
-	avctp_set_state(session, AVCTP_STATE_CONNECTING);
-	session->control_io = g_io_channel_ref(chan);
-
-	if (audio_device_request_authorization(dev, AVRCP_TARGET_UUID,
-						auth_cb, session) < 0)
-		goto drop;
-
-	session->control_io_id = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-							session_cb, session);
 	return;
 
 drop:
-	if (!session || !session->control_io)
-		g_io_channel_shutdown(chan, TRUE, NULL);
-	if (session)
+	if (session && session->browsing_io)
+		g_io_channel_unref(session->browsing_io);
+
+	if (session && session->control_io)
+		g_io_channel_unref(session->control_io);
+
+	if (session && psm == AVCTP_CONTROL_PSM)
 		avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
 }
 
-static GIOChannel *avctp_server_socket(const bdaddr_t *src, gboolean master)
+static GIOChannel *avctp_server_socket(const bdaddr_t *src, gboolean master, uint8_t mode, uint16_t psm)
 {
 	GError *err = NULL;
 	GIOChannel *io;
@@ -803,9 +991,10 @@ static GIOChannel *avctp_server_socket(const bdaddr_t *src, gboolean master)
 	io = bt_io_listen(NULL, avctp_confirm_cb, NULL,
 				NULL, &err,
 				BT_IO_OPT_SOURCE_BDADDR, src,
-				BT_IO_OPT_PSM, AVCTP_CONTROL_PSM,
+				BT_IO_OPT_PSM, psm,
 				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
 				BT_IO_OPT_MASTER, master,
+				BT_IO_OPT_MODE, mode,
 				BT_IO_OPT_INVALID);
 	if (!io) {
 		error("%s", err->message);
@@ -825,11 +1014,23 @@ int avctp_register(const bdaddr_t *src, gboolean master)
 
 	server = g_new0(struct avctp_server, 1);
 
-	server->control_io = avctp_server_socket(src, master);
+	server->control_io = avctp_server_socket(src, master, L2CAP_MODE_BASIC,
+							AVCTP_CONTROL_PSM);
 	if (!server->control_io) {
 		g_free(server);
 		return -1;
 	}
+	server->browsing_io = avctp_server_socket(src, master, L2CAP_MODE_ERTM,
+							AVCTP_BROWSING_PSM);
+	if (!server->browsing_io) {
+		if (server->control_io) {
+			g_io_channel_shutdown(server->control_io, TRUE, NULL);
+			g_io_channel_unref(server->control_io);
+			server->control_io = NULL;
+		}
+		g_free(server);
+		return -1;
+	}
 
 	bacpy(&server->src, src);
 
@@ -863,6 +1064,10 @@ void avctp_unregister(const bdaddr_t *src)
 
 	servers = g_slist_remove(servers, server);
 
+	g_io_channel_shutdown(server->browsing_io, TRUE, NULL);
+	g_io_channel_unref(server->browsing_io);
+	server->browsing_io = NULL;
+
 	g_io_channel_shutdown(server->control_io, TRUE, NULL);
 	g_io_channel_unref(server->control_io);
 	g_free(server);
-- 
1.7.5.4

Regards
Joohi

^ permalink raw reply related

* [PATCH BlueZ V7 2/5] AVRCP: Rename variables used for control channel
From: Joohi RASTOGI @ 2012-09-21  5:22 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org; +Cc: Luiz Augusto von Dentz, Joohi RASTOGI

>From 130000e4095a4db119ec760542b2c7be4aed7c1c Mon Sep 17 00:00:00 2001
From: Joohi Rastogi <joohi.rastogi@stericsson.com>
Date: Thu, 20 Sep 2012 15:30:01 +0530
Subject: [PATCH BlueZ V7 2/5] Prefix "control" is added to variables used for control
 channel. This will improve redability when Browsing channel
 is implemented

---
 audio/avctp.c |   80 ++++++++++++++++++++++++++++----------------------------
 audio/avctp.h |    4 +-
 audio/avrcp.c |   55 ++++++++++++++++++++-------------------
 3 files changed, 70 insertions(+), 69 deletions(-)

diff --git a/audio/avctp.c b/audio/avctp.c
index 20aed66..36133b3 100644
--- a/audio/avctp.c
+++ b/audio/avctp.c
@@ -119,7 +119,7 @@ struct avctp_state_callback {
 
 struct avctp_server {
 	bdaddr_t src;
-	GIOChannel *io;
+	GIOChannel *control_io;
 	GSList *sessions;
 };
 
@@ -137,10 +137,10 @@ struct avctp {
 
 	int uinput;
 
-	GIOChannel *io;
-	guint io_id;
+	GIOChannel *control_io;
+	guint control_io_id;
 
-	uint16_t mtu;
+	uint16_t control_mtu;
 
 	uint8_t key_quirks[256];
 	GSList *handlers;
@@ -148,7 +148,7 @@ struct avctp {
 
 struct avctp_pdu_handler {
 	uint8_t opcode;
-	avctp_pdu_cb cb;
+	avctp_control_pdu_cb cb;
 	void *user_data;
 	unsigned int id;
 };
@@ -170,7 +170,7 @@ static struct {
 
 static GSList *callbacks = NULL;
 static GSList *servers = NULL;
-static GSList *handlers = NULL;
+static GSList *control_handlers = NULL;
 static uint8_t id = 0;
 
 static void auth_cb(DBusError *derr, void *user_data);
@@ -327,15 +327,15 @@ static void avctp_disconnected(struct avctp *session)
 	if (!session)
 		return;
 
-	if (session->io) {
-		g_io_channel_shutdown(session->io, TRUE, NULL);
-		g_io_channel_unref(session->io);
-		session->io = NULL;
+	if (session->control_io) {
+		g_io_channel_shutdown(session->control_io, TRUE, NULL);
+		g_io_channel_unref(session->control_io);
+		session->control_io = NULL;
 	}
 
-	if (session->io_id) {
-		g_source_remove(session->io_id);
-		session->io_id = 0;
+	if (session->control_io_id) {
+		g_source_remove(session->control_io_id);
+		session->control_io_id = 0;
 
 		if (session->state == AVCTP_STATE_CONNECTING) {
 			struct audio_device *dev;
@@ -446,7 +446,7 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
 	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
 		goto failed;
 
-	sock = g_io_channel_unix_get_fd(session->io);
+	sock = g_io_channel_unix_get_fd(session->control_io);
 
 	ret = read(sock, buf, sizeof(buf));
 	if (ret <= 0)
@@ -504,7 +504,7 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
 		goto done;
 	}
 
-	handler = find_handler(handlers, avc->opcode);
+	handler = find_handler(control_handlers, avc->opcode);
 	if (!handler) {
 		DBG("handler not found for 0x%02x", avc->opcode);
 		packet_size += avrcp_handle_vendor_reject(&code, operands);
@@ -640,14 +640,14 @@ static void avctp_connect_cb(GIOChannel *chan, GError *err, gpointer data)
 
 	DBG("AVCTP: connected to %s", address);
 
-	if (!session->io)
-		session->io = g_io_channel_ref(chan);
+	if (!session->control_io)
+		session->control_io = g_io_channel_ref(chan);
 
 	init_uinput(session);
 
 	avctp_set_state(session, AVCTP_STATE_CONNECTED);
-	session->mtu = imtu;
-	session->io_id = g_io_add_watch(chan,
+	session->control_mtu = imtu;
+	 session->control_io_id = g_io_add_watch(chan,
 				G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
 				(GIOFunc) session_cb, session);
 }
@@ -657,9 +657,9 @@ static void auth_cb(DBusError *derr, void *user_data)
 	struct avctp *session = user_data;
 	GError *err = NULL;
 
-	if (session->io_id) {
-		g_source_remove(session->io_id);
-		session->io_id = 0;
+	if (session->control_io_id) {
+		g_source_remove(session->control_io_id);
+		session->control_io_id = 0;
 	}
 
 	if (derr && dbus_error_is_set(derr)) {
@@ -668,7 +668,7 @@ static void auth_cb(DBusError *derr, void *user_data)
 		return;
 	}
 
-	if (!bt_io_accept(session->io, avctp_connect_cb, session,
+	if (!bt_io_accept(session->control_io, avctp_connect_cb, session,
 								NULL, &err)) {
 		error("bt_io_accept: %s", err->message);
 		g_error_free(err);
@@ -772,24 +772,24 @@ static void avctp_confirm_cb(GIOChannel *chan, gpointer data)
 			goto drop;
 	}
 
-	if (session->io) {
+	if (session->control_io) {
 		error("Refusing unexpected connect from %s", address);
 		goto drop;
 	}
 
 	avctp_set_state(session, AVCTP_STATE_CONNECTING);
-	session->io = g_io_channel_ref(chan);
+	session->control_io = g_io_channel_ref(chan);
 
 	if (audio_device_request_authorization(dev, AVRCP_TARGET_UUID,
 						auth_cb, session) < 0)
 		goto drop;
 
-	session->io_id = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+	session->control_io_id = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
 							session_cb, session);
 	return;
 
 drop:
-	if (!session || !session->io)
+	if (!session || !session->control_io)
 		g_io_channel_shutdown(chan, TRUE, NULL);
 	if (session)
 		avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
@@ -825,8 +825,8 @@ int avctp_register(const bdaddr_t *src, gboolean master)
 
 	server = g_new0(struct avctp_server, 1);
 
-	server->io = avctp_server_socket(src, master);
-	if (!server->io) {
+	server->control_io = avctp_server_socket(src, master);
+	if (!server->control_io) {
 		g_free(server);
 		return -1;
 	}
@@ -863,8 +863,8 @@ void avctp_unregister(const bdaddr_t *src)
 
 	servers = g_slist_remove(servers, server);
 
-	g_io_channel_shutdown(server->io, TRUE, NULL);
-	g_io_channel_unref(server->io);
+	g_io_channel_shutdown(server->control_io, TRUE, NULL);
+	g_io_channel_unref(server->control_io);
 	g_free(server);
 
 	if (servers)
@@ -911,7 +911,7 @@ int avctp_send_passthrough(struct avctp *session, uint8_t op)
 	operands[0] = op & 0x7f;
 	operands[1] = 0;
 
-	sk = g_io_channel_unix_get_fd(session->io);
+	sk = g_io_channel_unix_get_fd(session->control_io);
 
 	if (write(sk, buf, sizeof(buf)) < 0)
 		return -errno;
@@ -940,7 +940,7 @@ static int avctp_send(struct avctp *session, uint8_t transaction, uint8_t cr,
 	if (session->state != AVCTP_STATE_CONNECTED)
 		return -ENOTCONN;
 
-	sk = g_io_channel_unix_get_fd(session->io);
+	sk = g_io_channel_unix_get_fd(session->control_io);
 
 	memset(buf, 0, sizeof(buf));
 
@@ -1035,13 +1035,13 @@ gboolean avctp_remove_state_cb(unsigned int id)
 	return FALSE;
 }
 
-unsigned int avctp_register_pdu_handler(uint8_t opcode, avctp_pdu_cb cb,
+unsigned int avctp_register_pdu_handler(uint8_t opcode, avctp_control_pdu_cb cb,
 							void *user_data)
 {
 	struct avctp_pdu_handler *handler;
 	static unsigned int id = 0;
 
-	handler = find_handler(handlers, opcode);
+	handler = find_handler(control_handlers, opcode);
 	if (handler)
 		return 0;
 
@@ -1051,7 +1051,7 @@ unsigned int avctp_register_pdu_handler(uint8_t opcode, avctp_pdu_cb cb,
 	handler->user_data = user_data;
 	handler->id = ++id;
 
-	handlers = g_slist_append(handlers, handler);
+	control_handlers = g_slist_append(control_handlers, handler);
 
 	return handler->id;
 }
@@ -1060,11 +1060,11 @@ gboolean avctp_unregister_pdu_handler(unsigned int id)
 {
 	GSList *l;
 
-	for (l = handlers; l != NULL; l = l->next) {
+	for (l = control_handlers; l != NULL; l = l->next) {
 		struct avctp_pdu_handler *handler = l->data;
 
 		if (handler->id == id) {
-			handlers = g_slist_remove(handlers, handler);
+			control_handlers = g_slist_remove(control_handlers, handler);
 			g_free(handler);
 			return TRUE;
 		}
@@ -1100,14 +1100,14 @@ struct avctp *avctp_connect(const bdaddr_t *src, const bdaddr_t *dst)
 		return NULL;
 	}
 
-	session->io = io;
+	session->control_io = io;
 
 	return session;
 }
 
 void avctp_disconnect(struct avctp *session)
 {
-	if (!session->io)
+	if (!session->control_io)
 		return;
 
 	avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
diff --git a/audio/avctp.h b/audio/avctp.h
index 9d19b5d..53919de 100755
--- a/audio/avctp.h
+++ b/audio/avctp.h
@@ -75,7 +75,7 @@ typedef void (*avctp_state_cb) (struct audio_device *dev,
 				avctp_state_t new_state,
 				void *user_data);
 
-typedef size_t (*avctp_pdu_cb) (struct avctp *session, uint8_t transaction,
+typedef size_t (*avctp_control_pdu_cb) (struct avctp *session, uint8_t transaction,
 					uint8_t *code, uint8_t *subunit,
 					uint8_t *operands, size_t operand_count,
 					void *user_data);
@@ -93,7 +93,7 @@ struct avctp *avctp_connect(const bdaddr_t *src, const bdaddr_t *dst);
 struct avctp *avctp_get(const bdaddr_t *src, const bdaddr_t *dst);
 void avctp_disconnect(struct avctp *session);
 
-unsigned int avctp_register_pdu_handler(uint8_t opcode, avctp_pdu_cb cb,
+unsigned int avctp_register_pdu_handler(uint8_t opcode, avctp_control_pdu_cb cb,
 							void *user_data);
 gboolean avctp_unregister_pdu_handler(unsigned int id);
 
diff --git a/audio/avrcp.c b/audio/avrcp.c
index 206d8fa..8259183 100755
--- a/audio/avrcp.c
+++ b/audio/avrcp.c
@@ -164,7 +164,7 @@ struct avrcp_player {
 	struct avctp *session;
 	struct audio_device *dev;
 
-	unsigned int handler;
+	unsigned int control_handler;
 	uint16_t registered_events;
 	uint8_t transaction_events[AVRCP_EVENT_LAST + 1];
 	struct pending_pdu *pending_pdu;
@@ -257,8 +257,9 @@ static sdp_record_t *avrcp_tg_record(void)
 	sdp_list_t *svclass_id, *pfseq, *apseq, *root, *apseq_browsing;
 	uuid_t root_uuid, l2cap, avctp, avrtg;
 	sdp_profile_desc_t profile[1];
-	sdp_list_t *aproto, *proto[2];
-	sdp_record_t *record;sdp_data_t *psm, *version, *features, *psm_browsing;
+	sdp_list_t *aproto_control, *proto_control[2];
+	sdp_record_t *record;
+	sdp_data_t *psm_control, *version, *features, *psm_browsing;
 	sdp_list_t *aproto_browsing, *proto_browsing[2] = {0};
 	uint16_t lp = AVCTP_CONTROL_PSM;
 	uint16_t lp_browsing = AVCTP_BROWSING_PSM;
@@ -285,19 +286,19 @@ static sdp_record_t *avrcp_tg_record(void)
 
 	/* Protocol Descriptor List */
 	sdp_uuid16_create(&l2cap, L2CAP_UUID);
-	proto[0] = sdp_list_append(0, &l2cap);
-	psm = sdp_data_alloc(SDP_UINT16, &lp);
-	proto[0] = sdp_list_append(proto[0], psm);
-	apseq = sdp_list_append(0, proto[0]);
+	proto_control[0] = sdp_list_append(0, &l2cap);
+	psm_control = sdp_data_alloc(SDP_UINT16, &lp);
+	proto_control[0] = sdp_list_append(proto_control[0], psm_control);
+	apseq = sdp_list_append(apseq, proto_control[1]);
 
 	sdp_uuid16_create(&avctp, AVCTP_UUID);
-	proto[1] = sdp_list_append(0, &avctp);
+	proto_control[1] = sdp_list_append(0, &avctp);
 	version = sdp_data_alloc(SDP_UINT16, &avctp_ver);
-	proto[1] = sdp_list_append(proto[1], version);
-	apseq = sdp_list_append(apseq, proto[1]);
+	proto_control[1] = sdp_list_append(proto_control[1], version);
+	apseq = sdp_list_append(apseq, proto_control[1]);
 
-	aproto = sdp_list_append(0, apseq);
-	sdp_set_access_protos(record, aproto);
+	aproto_control = sdp_list_append(0, apseq);
+	sdp_set_access_protos(record, aproto_control);
 	proto_browsing[0] = sdp_list_append(0, &l2cap);
 	psm_browsing = sdp_data_alloc(SDP_UINT16, &lp_browsing);
 	proto_browsing[0] = sdp_list_append(proto_browsing[0], psm_browsing);
@@ -327,12 +328,12 @@ static sdp_record_t *avrcp_tg_record(void)
 	sdp_list_free(apseq_browsing, 0);
 	sdp_list_free(aproto_browsing, 0);
 
-	free(psm);
+	free(psm_control);
 	free(version);
-	sdp_list_free(proto[0], 0);
-	sdp_list_free(proto[1], 0);
+	sdp_list_free(proto_control[0], 0);
+	sdp_list_free(proto_control[1], 0);
 	sdp_list_free(apseq, 0);
-	sdp_list_free(aproto, 0);
+	sdp_list_free(aproto_control, 0);
 	sdp_list_free(pfseq, 0);
 	sdp_list_free(root, 0);
 	sdp_list_free(svclass_id, 0);
@@ -1041,13 +1042,13 @@ err:
 	return AVC_CTYPE_REJECTED;
 }
 
-static struct pdu_handler {
+static struct control_pdu_handler {
 	uint8_t pdu_id;
 	uint8_t code;
 	uint8_t (*func) (struct avrcp_player *player,
 					struct avrcp_header *pdu,
 					uint8_t transaction);
-} handlers[] = {
+} control_handlers[] = {
 		{ AVRCP_GET_CAPABILITIES, AVC_CTYPE_STATUS,
 					avrcp_handle_get_capabilities },
 		{ AVRCP_LIST_PLAYER_ATTRIBUTES, AVC_CTYPE_STATUS,
@@ -1086,7 +1087,7 @@ static size_t handle_vendordep_pdu(struct avctp *session, uint8_t transaction,
 					void *user_data)
 {
 	struct avrcp_player *player = user_data;
-	struct pdu_handler *handler;
+	struct control_pdu_handler *handler;
 	struct avrcp_header *pdu = (void *) operands;
 	uint32_t company_id = get_company_id(pdu->company_id);
 
@@ -1106,7 +1107,7 @@ static size_t handle_vendordep_pdu(struct avctp *session, uint8_t transaction,
 		goto err_metadata;
 	}
 
-	for (handler = handlers; handler; handler++) {
+	for (handler = control_handlers; handler; handler++) {
 		if (handler->pdu_id == pdu->pdu_id)
 			break;
 	}
@@ -1233,9 +1234,9 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,
 		player->dev = NULL;
 		player->registered_events = 0;
 
-		if (player->handler) {
-			avctp_unregister_pdu_handler(player->handler);
-			player->handler = 0;
+		if (player->control_handler) {
+			avctp_unregister_pdu_handler(player->control_handler);
+			player->control_handler = 0;
 		}
 
 		break;
@@ -1243,8 +1244,8 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,
 		player->session = avctp_connect(&dev->src, &dev->dst);
 		player->dev = dev;
 
-		if (!player->handler)
-			player->handler = avctp_register_pdu_handler(
+		if (!player->control_handler)
+			player->control_handler = avctp_register_pdu_handler(
 							AVC_OP_VENDORDEP,
 							handle_vendordep_pdu,
 							player);
@@ -1362,8 +1363,8 @@ static void player_destroy(gpointer data)
 
 	player_abort_pending_pdu(player);
 
-	if (player->handler)
-		avctp_unregister_pdu_handler(player->handler);
+	if (player->control_handler)
+		avctp_unregister_pdu_handler(player->control_handler);
 
 	g_free(player);
 }
-- 
1.7.5.4

Regards
Joohi

^ permalink raw reply related

* [PATCH BlueZ V7 1/5] AVRCP: Add TG Record to support AVRCP Browsing
From: Joohi RASTOGI @ 2012-09-21  5:22 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org; +Cc: Luiz Augusto von Dentz, Joohi RASTOGI

>From 7348afc3401746a1890763ac5b689fca164fd934 Mon Sep 17 00:00:00 2001
From: Joohi Rastogi <joohi.rastogi@stericsson.com>
Date: Thu, 20 Sep 2012 14:21:37 +0530
Subject: [PATCH BlueZ V7 1/5] Adds SDP record to support browsing

---
 audio/avctp.c |    4 ++--
 audio/avctp.h |    3 ++-
 audio/avrcp.c |   30 +++++++++++++++++++++++++-----
 3 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/audio/avctp.c b/audio/avctp.c
index 4e0e8dc..20aed66 100644
--- a/audio/avctp.c
+++ b/audio/avctp.c
@@ -803,7 +803,7 @@ static GIOChannel *avctp_server_socket(const bdaddr_t *src, gboolean master)
 	io = bt_io_listen(NULL, avctp_confirm_cb, NULL,
 				NULL, &err,
 				BT_IO_OPT_SOURCE_BDADDR, src,
-				BT_IO_OPT_PSM, AVCTP_PSM,
+				BT_IO_OPT_PSM, AVCTP_CONTROL_PSM,
 				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
 				BT_IO_OPT_MASTER, master,
 				BT_IO_OPT_INVALID);
@@ -1091,7 +1091,7 @@ struct avctp *avctp_connect(const bdaddr_t *src, const bdaddr_t *dst)
 	io = bt_io_connect(avctp_connect_cb, session, NULL, &err,
 				BT_IO_OPT_SOURCE_BDADDR, &session->server->src,
 				BT_IO_OPT_DEST_BDADDR, &session->dst,
-				BT_IO_OPT_PSM, AVCTP_PSM,
+				BT_IO_OPT_PSM, AVCTP_CONTROL_PSM,
 				BT_IO_OPT_INVALID);
 	if (err) {
 		avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
diff --git a/audio/avctp.h b/audio/avctp.h
index d0cbd97..9d19b5d 100644
--- a/audio/avctp.h
+++ b/audio/avctp.h
@@ -22,7 +22,8 @@
  *
  */
 
-#define AVCTP_PSM 23
+#define AVCTP_CONTROL_PSM		23
+#define AVCTP_BROWSING_PSM		27
 
 #define AVC_MTU 512
 #define AVC_HEADER_LENGTH 3
diff --git a/audio/avrcp.c b/audio/avrcp.c
index 27be7e8..206d8fa 100644
--- a/audio/avrcp.c
+++ b/audio/avrcp.c
@@ -106,6 +106,7 @@
 #define AVRCP_FEATURE_CATEGORY_3	0x0004
 #define AVRCP_FEATURE_CATEGORY_4	0x0008
 #define AVRCP_FEATURE_PLAYER_SETTINGS	0x0010
+#define AVRCP_FEATURE_BROWSING			0x0040
 
 #define AVRCP_BATTERY_STATUS_NORMAL		0
 #define AVRCP_BATTERY_STATUS_WARNING		1
@@ -191,7 +192,7 @@ static sdp_record_t *avrcp_ct_record(void)
 	sdp_list_t *aproto, *proto[2];
 	sdp_record_t *record;
 	sdp_data_t *psm, *version, *features;
-	uint16_t lp = AVCTP_PSM;
+	uint16_t lp = AVCTP_CONTROL_PSM;
 	uint16_t avrcp_ver = 0x0100, avctp_ver = 0x0103;
 	uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 |
 						AVRCP_FEATURE_CATEGORY_2 |
@@ -253,18 +254,20 @@ static sdp_record_t *avrcp_ct_record(void)
 
 static sdp_record_t *avrcp_tg_record(void)
 {
-	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
+	sdp_list_t *svclass_id, *pfseq, *apseq, *root, *apseq_browsing;
 	uuid_t root_uuid, l2cap, avctp, avrtg;
 	sdp_profile_desc_t profile[1];
 	sdp_list_t *aproto, *proto[2];
-	sdp_record_t *record;
-	sdp_data_t *psm, *version, *features;
-	uint16_t lp = AVCTP_PSM;
+	sdp_record_t *record;sdp_data_t *psm, *version, *features, *psm_browsing;
+	sdp_list_t *aproto_browsing, *proto_browsing[2] = {0};
+	uint16_t lp = AVCTP_CONTROL_PSM;
+	uint16_t lp_browsing = AVCTP_BROWSING_PSM;
 	uint16_t avrcp_ver = 0x0104, avctp_ver = 0x0103;
 	uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 |
 					AVRCP_FEATURE_CATEGORY_2 |
 					AVRCP_FEATURE_CATEGORY_3 |
 					AVRCP_FEATURE_CATEGORY_4 |
+					AVRCP_FEATURE_BROWSING |
 					AVRCP_FEATURE_PLAYER_SETTINGS );
 
 	record = sdp_record_alloc();
@@ -295,6 +298,17 @@ static sdp_record_t *avrcp_tg_record(void)
 
 	aproto = sdp_list_append(0, apseq);
 	sdp_set_access_protos(record, aproto);
+	proto_browsing[0] = sdp_list_append(0, &l2cap);
+	psm_browsing = sdp_data_alloc(SDP_UINT16, &lp_browsing);
+	proto_browsing[0] = sdp_list_append(proto_browsing[0], psm_browsing);
+	apseq_browsing = sdp_list_append(0, proto_browsing[0]);
+
+	proto_browsing[1] = sdp_list_append(0, &avctp);
+	proto_browsing[1] = sdp_list_append(proto_browsing[1], version);
+	apseq_browsing = sdp_list_append(apseq_browsing, proto_browsing[1]);
+
+	aproto_browsing = sdp_list_append(0, apseq_browsing);
+	sdp_set_add_access_protos(record, aproto_browsing);
 
 	/* Bluetooth Profile Descriptor List */
 	sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID);
@@ -307,6 +321,12 @@ static sdp_record_t *avrcp_tg_record(void)
 
 	sdp_set_info_attr(record, "AVRCP TG", 0, 0);
 
+	free(psm_browsing);
+	sdp_list_free(proto_browsing[0], 0);
+	sdp_list_free(proto_browsing[1], 0);
+	sdp_list_free(apseq_browsing, 0);
+	sdp_list_free(aproto_browsing, 0);
+
 	free(psm);
 	free(version);
 	sdp_list_free(proto[0], 0);
-- 
1.7.5.4

Regards
Joohi

^ permalink raw reply related

* Re: [PATCH] Update rampatch file for AR9462.
From: Ben Hutchings @ 2012-09-20 22:26 UTC (permalink / raw)
  To: Peng Chen; +Cc: dwmw2, linux-bluetooth
In-Reply-To: <1347277502-32231-1-git-send-email-pengchen@qca.qualcomm.com>

[-- Attachment #1: Type: text/plain, Size: 332 bytes --]

On Mon, 2012-09-10 at 19:45 +0800, Peng Chen wrote:
> Signed-off-by: Peng Chen <pengchen@qca.qualcomm.com>
> ---
>  ar3k/AthrBT_0x11020000.dfu |  Bin 33820 -> 36828 bytes
>  1 file changed, 0 insertions(+), 0 deletions(-)
[...]

Applied, thanks.

Ben.

-- 
Ben Hutchings
The world is coming to an end.	Please log off.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply

* Re: Rebase against recent wireless-next
From: Gustavo Padovan @ 2012-09-20 18:10 UTC (permalink / raw)
  To: Andrei Emeltchenko, linux-bluetooth
In-Reply-To: <20120920110543.GE13291@aemeltch-MOBL1>

Hi Andrei,

* Andrei Emeltchenko <andrei.emeltchenko.news@gmail.com> [2012-09-20 14:05:45 +0300]:

> Hi Gustavo,
> 
> When we get rebased against wireless-next?

That will happen as soon as John pulls my latest pull request.

	Gustavo

^ permalink raw reply

* Re: Agenda (v2) for Linux Wireless (802.11/Bluetooth/NFC) Mini-Summit 2012 (Barcelona!)
From: Marcel Holtmann @ 2012-09-20 13:30 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, linux-bluetooth, alexander.smirnov
In-Reply-To: <20120911201729.GJ7015@tuxdriver.com>

Hi John,

> OK, making progress...still, we need some more discussion topics...
> 
> We have one room on the first day, and three rooms on the second day.
> I figure that the Bluetooth and 802.11 groups should each get a
> break-out room for their own in-depth discussons on the second day and
> the third room can be used for more general topics and presentations.
> 
> Below is my strawman agenda proposal.  Please make suggestions for
> improvements!

I think this looks pretty good. Lets see if we can find some volunteers
for the empty slots. Should be make sure that this schedule so far gets
published on the LinuxCon website?

Regards

Marcel



^ permalink raw reply

* Re: [PATCH v0 1/4] adapter: Replace device authorizing flag
From: Luiz Augusto von Dentz @ 2012-09-20 12:20 UTC (permalink / raw)
  To: Mikel Astiz; +Cc: linux-bluetooth, Mikel Astiz
In-Reply-To: <1347371730-14933-2-git-send-email-mikel.astiz.oss@gmail.com>

Hi Mikel,

On Tue, Sep 11, 2012 at 4:55 PM, Mikel Astiz <mikel.astiz.oss@gmail.com> wrote:
> From: Mikel Astiz <mikel.astiz@bmw-carit.de>
>
> Refactor code to drop the device authorizing flag by replacing it with a
> private authorization pointer in btd_adapter. After all, no more than
> one authorization can be ongoing, so the code is easier to follow if
> this is made explicit.
> ---
>  src/adapter.c |   48 ++++++++++++++++++++++++++++++++----------------
>  src/device.c  |   11 -----------
>  src/device.h  |    2 --
>  3 files changed, 32 insertions(+), 29 deletions(-)
>
> diff --git a/src/adapter.c b/src/adapter.c
> index 4b675e8..14c5322 100644
> --- a/src/adapter.c
> +++ b/src/adapter.c
> @@ -128,7 +128,8 @@ struct btd_adapter {
>         GSList *found_devices;
>         GSList *oor_devices;            /* out of range device list */
>         struct agent *agent;            /* For the new API */
> -       guint auth_idle_id;             /* Ongoing authorization */
> +       guint auth_idle_id;             /* Ongoing authorization (trusted) */
> +       struct service_auth *auth;      /* Ongoing authorization */

You should probably store the id directly inside struct service_auth
as they depend on each other then when you free auth you also remove
the id if not set to 0.

-- 
Luiz Augusto von Dentz

^ permalink raw reply


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