Linux bluetooth development
 help / color / mirror / Atom feed
* BT Handover Issue
From: Bruno Bruzzano @ 2013-11-26 22:26 UTC (permalink / raw)
  To: sameo, linux-bluetooth@vger.kernel.org, linux-nfc

Hi Samuel,

When I try to send the BT Handover Message to pair my smartphone
(Nexus5), I encounter an issue.
My background is bluez upstream, neard upstream.
I did the following steps:
-run bluetooth -ndE
-run neard -nd '*'
-run ./simple-agent (with NoInputNoOutput capability)
-set power and poll the NFC Adapter
-put my device on top of the adapter ( -> neard recognizes the device,
creating the right deviceX interface)
-./test-device push /org/neard/nfc0/device0 Handover bluetooth

The procedure starts, but it stopped itself before to send the message
to the device.
Here, I made a pastebin of neard.
http://pastebin.com/XEqeucER
In addiction, here you can find other 2 pastbins about the messages I
receive when I do the push (typing './test-device push
/org/neard/nfc0/device0 .....')
http://pastebin.com/faai51ed
http://pastebin.com/N0jWnyXG

Another question: do you think it is possibile send the Handover
Message using the MIME type? I mean, typing: ./test-device push
/org/neard/nfc0/device3 MIME raw application/vnd.bluetooth.ep.oob
'lenghtOOB + device mac_address'

Please give me a feedback.
Thanks!

Bruno aka br1_21

^ permalink raw reply

* Re: [PATCH 3/6] android/socket: Handle Android events for server socket
From: Johan Hedberg @ 2013-11-26 15:46 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1385474750-18331-3-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Tue, Nov 26, 2013, Andrei Emeltchenko wrote:
> Add watch for tracking events from Android framework for server socket.
> ---
>  android/socket.c | 27 ++++++++++++++++++++++++++-
>  1 file changed, 26 insertions(+), 1 deletion(-)

I've applied the first two patches, but wanted to ask about this one:

> +static gboolean sock_server_stack_event_cb(GIOChannel *io, GIOCondition cond,
> +								gpointer data)
> +{
> +	struct rfcomm_sock *rfsock = data;
> +
> +	DBG("");
> +
> +	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
> +		error("Socket error: sock %d cond %d",
> +					g_io_channel_unix_get_fd(io), cond);
> +		cleanup_rfsock(rfsock);
> +
> +		return FALSE;
> +	}
> +
> +	return TRUE;
> +}

I don't see where (in which patch) you'd add code to handle G_IO_IN on
this socket. Aren't you supposed to read data from this socket and write
it to the RFCOMM one?

Johan

^ permalink raw reply

* Re: [PATCH 1/2] android/haltest: trivial: Fix typo channle -> channel
From: Johan Hedberg @ 2013-11-26 15:43 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1385473625-14266-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Tue, Nov 26, 2013, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> 
> ---
>  android/client/if-sock.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Both patches have been applied. Thanks.

Johan

^ permalink raw reply

* [PATCH BlueZ 3/3] core/agent: Set first agent as default
From: Luiz Augusto von Dentz @ 2013-11-26 15:05 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385478310-22520-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This sets the first agent automatically as default so systems with a
single agent should never have to bother with RequestDefaultAgent.
---
 src/agent.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/agent.c b/src/agent.c
index 7880ba6..aa8ba33 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -930,6 +930,9 @@ static DBusMessage *register_agent(DBusConnection *conn,
 
 	DBG("agent %s", agent->owner);
 
+	if (g_hash_table_size(agent_list) == 0)
+		set_default_agent(agent);
+
 	g_hash_table_replace(agent_list, agent->owner, agent);
 
 	return dbus_message_new_method_return(msg);
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ 2/3] client: Fix not releasing agent if bluetoothd exit without calling Release
From: Luiz Augusto von Dentz @ 2013-11-26 15:05 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385478310-22520-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

If AgentManager1 disappear the agent should auto release itself
otherwise next time AgentManager1 appears bluetoothctl wont register
the agent again.
---
 client/agent.c | 26 ++++++++++++++++----------
 client/main.c  |  5 ++++-
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/client/agent.c b/client/agent.c
index 81526a1..f074d82 100644
--- a/client/agent.c
+++ b/client/agent.c
@@ -156,14 +156,11 @@ dbus_bool_t agent_input(DBusConnection *conn, const char *input)
 	return TRUE;
 }
 
-static DBusMessage *release_agent(DBusConnection *conn,
-					DBusMessage *msg, void *user_data)
+static void agent_release(DBusConnection *conn)
 {
 	agent_registered = FALSE;
 	agent_capability = NULL;
 
-	rl_printf("Agent released\n");
-
 	if (pending_message) {
 		dbus_message_unref(pending_message);
 		pending_message = NULL;
@@ -172,6 +169,14 @@ static DBusMessage *release_agent(DBusConnection *conn,
 	agent_release_prompt();
 
 	g_dbus_unregister_interface(conn, AGENT_PATH, AGENT_INTERFACE);
+}
+
+static DBusMessage *release_agent(DBusConnection *conn,
+					DBusMessage *msg, void *user_data)
+{
+	rl_printf("Agent released\n");
+
+	agent_release(conn);
 
 	return dbus_message_new_method_return(msg);
 }
@@ -430,13 +435,8 @@ static void unregister_agent_reply(DBusMessage *message, void *user_data)
 	dbus_error_init(&error);
 
 	if (dbus_set_error_from_message(&error, message) == FALSE) {
-		agent_registered = FALSE;
-		agent_capability = NULL;
 		rl_printf("Agent unregistered\n");
-
-		if (g_dbus_unregister_interface(conn, AGENT_PATH,
-						AGENT_INTERFACE) == FALSE)
-			rl_printf("Failed to unregister agent object\n");
+		agent_release(conn);
 	} else {
 		rl_printf("Failed to unregister agent: %s\n", error.name);
 		dbus_error_free(&error);
@@ -450,6 +450,12 @@ void agent_unregister(DBusConnection *conn, GDBusProxy *manager)
 		return;
 	}
 
+	if (!manager) {
+		rl_printf("Agent unregistered\n");
+		agent_release(conn);
+		return;
+	}
+
 	if (g_dbus_proxy_method_call(manager, "UnregisterAgent",
 						unregister_agent_setup,
 						unregister_agent_reply,
diff --git a/client/main.c b/client/main.c
index 5639f0e..fe5f290 100644
--- a/client/main.c
+++ b/client/main.c
@@ -319,8 +319,11 @@ static void proxy_removed(GDBusProxy *proxy, void *user_data)
 			dev_list = NULL;
 		}
 	} else if (!strcmp(interface, "org.bluez.AgentManager1")) {
-		if (agent_manager == proxy)
+		if (agent_manager == proxy) {
 			agent_manager = NULL;
+			if (agent_capability)
+				agent_unregister(dbus_conn, NULL);
+		}
 	}
 }
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ 1/3] client: Add 'auto' parameter to agent command
From: Luiz Augusto von Dentz @ 2013-11-26 15:05 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds 'auto' parameter to agent command which auto accepts requests
whenever possible.
---
 client/agent.c | 14 +++++++++++++-
 client/agent.h |  2 +-
 client/main.c  | 30 ++++++++++++++++++------------
 3 files changed, 32 insertions(+), 14 deletions(-)

diff --git a/client/agent.c b/client/agent.c
index 2d9dffd..81526a1 100644
--- a/client/agent.c
+++ b/client/agent.c
@@ -27,6 +27,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdbool.h>
 #include <readline/readline.h>
 #include <gdbus.h>
 
@@ -40,6 +41,7 @@
 
 static gboolean agent_registered = FALSE;
 static const char *agent_capability = NULL;
+static bool agent_auto_accept = false;
 static DBusMessage *pending_message = NULL;
 static char *agent_saved_prompt = NULL;
 static int agent_saved_point = 0;
@@ -259,6 +261,9 @@ static DBusMessage *request_confirmation(DBusConnection *conn,
 	dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device,
 				DBUS_TYPE_UINT32, &passkey, DBUS_TYPE_INVALID);
 
+	if (agent_auto_accept)
+		return dbus_message_new_method_return(msg);
+
 	str = g_strdup_printf("Confirm passkey %06u (yes/no): ", passkey);
 	agent_prompt(str);
 	g_free(str);
@@ -278,6 +283,9 @@ static DBusMessage *request_authorization(DBusConnection *conn,
 	dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device,
 							DBUS_TYPE_INVALID);
 
+	if (agent_auto_accept)
+		return dbus_message_new_method_return(msg);
+
 	agent_prompt("Accept pairing (yes/no): ");
 
 	pending_message = dbus_message_ref(msg);
@@ -296,6 +304,9 @@ static DBusMessage *authorize_service(DBusConnection *conn,
 	dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device,
 				DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID);
 
+	if (agent_auto_accept)
+		return dbus_message_new_method_return(msg);
+
 	str = g_strdup_printf("Authorize service %s (yes/no): ", uuid);
 	agent_prompt(str);
 	g_free(str);
@@ -375,7 +386,7 @@ static void register_agent_reply(DBusMessage *message, void *user_data)
 }
 
 void agent_register(DBusConnection *conn, GDBusProxy *manager,
-						const char *capability)
+				const char *capability, bool auto_accept)
 
 {
 	if (agent_registered == TRUE) {
@@ -401,6 +412,7 @@ void agent_register(DBusConnection *conn, GDBusProxy *manager,
 	}
 
 	agent_capability = NULL;
+	agent_auto_accept = auto_accept;
 }
 
 static void unregister_agent_setup(DBusMessageIter *iter, void *user_data)
diff --git a/client/agent.h b/client/agent.h
index 0fbe8e5..467afb0 100644
--- a/client/agent.h
+++ b/client/agent.h
@@ -22,7 +22,7 @@
  */
 
 void agent_register(DBusConnection *conn, GDBusProxy *manager,
-						const char *capability);
+				const char *capability, bool auto_accept);
 void agent_unregister(DBusConnection *conn, GDBusProxy *manager);
 void agent_default(DBusConnection *conn, GDBusProxy *manager);
 
diff --git a/client/main.c b/client/main.c
index ebc85c6..5639f0e 100644
--- a/client/main.c
+++ b/client/main.c
@@ -29,6 +29,7 @@
 #include <errno.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <stdbool.h>
 #include <signal.h>
 #include <sys/signalfd.h>
 
@@ -53,13 +54,15 @@ static GMainLoop *main_loop;
 static DBusConnection *dbus_conn;
 
 static GDBusProxy *agent_manager;
-static char *auto_register_agent = NULL;
+static char *agent_capability = NULL;
+static bool agent_auto_accept = false;
 
 static GDBusProxy *default_ctrl;
 static GList *ctrl_list;
 static GList *dev_list;
 
 static const char * const agent_arguments[] = {
+	"auto",
 	"on",
 	"off",
 	"DisplayOnly",
@@ -284,9 +287,10 @@ static void proxy_added(GDBusProxy *proxy, void *user_data)
 		if (!agent_manager) {
 			agent_manager = proxy;
 
-			if (auto_register_agent)
+			if (agent_capability)
 				agent_register(dbus_conn, agent_manager,
-							auto_register_agent);
+							agent_capability,
+							agent_auto_accept);
 		}
 	}
 }
@@ -434,7 +438,8 @@ static gboolean parse_argument_agent(const char *arg, dbus_bool_t *value,
 		return FALSE;
 	}
 
-	if (strcmp(arg, "on") == 0 || strcmp(arg, "yes") == 0) {
+	if (strcmp(arg, "on") == 0 || strcmp(arg, "yes") == 0 ||
+						strcmp(arg, "auto") == 0) {
 		*value = TRUE;
 		*capability = "";
 		return TRUE;
@@ -680,17 +685,18 @@ static void cmd_agent(const char *arg)
 		return;
 
 	if (enable == TRUE) {
-		g_free(auto_register_agent);
-		auto_register_agent = g_strdup(capability);
+		g_free(agent_capability);
+		agent_capability = g_strdup(capability);
+		agent_auto_accept = strcmp(arg, "auto") == 0 ? true : false;
 
 		if (agent_manager)
 			agent_register(dbus_conn, agent_manager,
-						auto_register_agent);
+					agent_capability, agent_auto_accept);
 		else
 			rl_printf("Agent registration enabled\n");
 	} else {
-		g_free(auto_register_agent);
-		auto_register_agent = NULL;
+		g_free(agent_capability);
+		agent_capability = NULL;
 
 		if (agent_manager)
 			agent_unregister(dbus_conn, agent_manager);
@@ -1331,9 +1337,9 @@ static gboolean parse_agent(const char *key, const char *value,
 					gpointer user_data, GError **error)
 {
 	if (value)
-		auto_register_agent = g_strdup(value);
+		agent_capability = g_strdup(value);
 	else
-		auto_register_agent = g_strdup("");
+		agent_capability = g_strdup("");
 
 	return TRUE;
 }
@@ -1410,7 +1416,7 @@ int main(int argc, char *argv[])
 	g_list_free_full(ctrl_list, proxy_leak);
 	g_list_free_full(dev_list, proxy_leak);
 
-	g_free(auto_register_agent);
+	g_free(agent_capability);
 
 	return 0;
 }
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 6/6] android: Do not dereference possible NULL pointer
From: Andrei Emeltchenko @ 2013-11-26 14:05 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385474750-18331-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

eir might be NULL, do not derefernce it in debug and print instead
pointer.
---
 android/bluetooth.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index aa684bd..77ce519 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -916,8 +916,8 @@ static void mgmt_device_found_event(uint16_t index, uint16_t length,
 	flags = btohl(ev->flags);
 
 	ba2str(&ev->addr.bdaddr, addr);
-	DBG("hci%u addr %s, rssi %d flags 0x%04x eir_len %u eir %u",
-				index, addr, ev->rssi, flags, eir_len, *eir);
+	DBG("hci%u addr %s, rssi %d flags 0x%04x eir_len %u eir %p",
+				index, addr, ev->rssi, flags, eir_len, eir);
 
 	confirm_name = flags & MGMT_DEV_FOUND_CONFIRM_NAME;
 
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 5/6] android/hal-sock: Check uuid before dereference
From: Andrei Emeltchenko @ 2013-11-26 14:05 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385474750-18331-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

uuid might be NULL and channel might be specified which makes it
valid case for Android. This adds check for uuid and service name.
---
 android/hal-sock.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/android/hal-sock.c b/android/hal-sock.c
index e02a49a..f45be30 100644
--- a/android/hal-sock.c
+++ b/android/hal-sock.c
@@ -34,12 +34,17 @@ static bt_status_t sock_listen_rfcomm(const char *service_name,
 
 	DBG("");
 
+	memset(&cmd, 0, sizeof(cmd));
+
 	cmd.flags = flags;
 	cmd.type = BTSOCK_RFCOMM;
 	cmd.channel = chan;
-	memcpy(cmd.uuid, uuid, sizeof(cmd.uuid));
-	memset(cmd.name, 0, sizeof(cmd.name));
-	memcpy(cmd.name, service_name, strlen(service_name));
+
+	if (uuid)
+		memcpy(cmd.uuid, uuid, sizeof(cmd.uuid));
+
+	if (service_name)
+		memcpy(cmd.name, service_name, strlen(service_name));
 
 	return hal_ipc_cmd(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_LISTEN,
 				sizeof(cmd), &cmd, NULL, NULL, sock);
@@ -90,10 +95,15 @@ static bt_status_t sock_connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
 		return BT_STATUS_UNSUPPORTED;
 	}
 
+	memset(&cmd, 0, sizeof(cmd));
+
 	cmd.flags = flags;
 	cmd.type = type;
 	cmd.channel = chan;
-	memcpy(cmd.uuid, uuid, sizeof(cmd.uuid));
+
+	if (uuid)
+		memcpy(cmd.uuid, uuid, sizeof(cmd.uuid));
+
 	memcpy(cmd.bdaddr, bdaddr, sizeof(cmd.bdaddr));
 
 	return hal_ipc_cmd(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_CONNECT,
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 4/6] android/socket: Check create_rfsock returns valid structure
From: Andrei Emeltchenko @ 2013-11-26 14:05 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385474750-18331-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

---
 android/socket.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/android/socket.c b/android/socket.c
index c4f14ab..772afaa 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -638,6 +638,11 @@ static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
 
 	sock_acc = g_io_channel_unix_get_fd(io);
 	rfsock_acc = create_rfsock(sock_acc, &hal_fd);
+	if (!rfsock_acc) {
+		g_io_channel_shutdown(io, TRUE, NULL);
+		return;
+	}
+
 	connections = g_list_append(connections, rfsock_acc);
 
 	DBG("rfsock: fd %d real_sock %d chan %u sock %d",
@@ -898,8 +903,11 @@ static int handle_connect(void *buf)
 
 	DBG("");
 
-	android2bdaddr(cmd->bdaddr, &dst);
 	rfsock = create_rfsock(-1, &hal_fd);
+	if (!rfsock)
+		return -1;
+
+	android2bdaddr(cmd->bdaddr, &dst);
 	bacpy(&rfsock->dst, &dst);
 
 	memset(&uuid, 0, sizeof(uuid));
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 3/6] android/socket: Handle Android events for server socket
From: Andrei Emeltchenko @ 2013-11-26 14:05 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385474750-18331-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Add watch for tracking events from Android framework for server socket.
---
 android/socket.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/android/socket.c b/android/socket.c
index 20dbc5e..c4f14ab 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -587,6 +587,24 @@ static bool sock_send_accept(struct rfcomm_sock *rfsock, bdaddr_t *bdaddr,
 	return true;
 }
 
+static gboolean sock_server_stack_event_cb(GIOChannel *io, GIOCondition cond,
+								gpointer data)
+{
+	struct rfcomm_sock *rfsock = data;
+
+	DBG("");
+
+	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
+		error("Socket error: sock %d cond %d",
+					g_io_channel_unix_get_fd(io), cond);
+		cleanup_rfsock(rfsock);
+
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
 static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
 {
 	struct rfcomm_sock *rfsock = user_data;
@@ -656,7 +674,8 @@ static int handle_listen(void *buf)
 	const struct profile_info *profile;
 	struct rfcomm_sock *rfsock;
 	BtIOSecLevel sec_level;
-	GIOChannel *io;
+	GIOChannel *io, *io_stack;
+	GIOCondition cond;
 	GError *err = NULL;
 	int hal_fd;
 	int chan;
@@ -701,6 +720,12 @@ static int handle_listen(void *buf)
 	g_io_channel_set_close_on_unref(io, TRUE);
 	g_io_channel_unref(io);
 
+	/* Handle events from Android */
+	cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
+	io_stack = g_io_channel_unix_new(rfsock->fd);
+	g_io_add_watch(io_stack, cond, sock_server_stack_event_cb, rfsock);
+	g_io_channel_unref(io_stack);
+
 	DBG("real_sock %d fd %d hal_fd %d", rfsock->real_sock, rfsock->fd,
 								hal_fd);
 
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 2/6] android/socket: Use security level for connect / listen
From: Andrei Emeltchenko @ 2013-11-26 14:05 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385474750-18331-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Use MEDIUM security level for connections without profile and default
sec_level for others. rfsock now has pointer to profile info.
---
 android/socket.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/android/socket.c b/android/socket.c
index 184deae..20dbc5e 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -70,6 +70,8 @@ struct rfcomm_sock {
 
 	bdaddr_t dst;
 	uint32_t service_handle;
+
+	const struct profile_info *profile;
 };
 
 static struct rfcomm_sock *create_rfsock(int sock, int *hal_fd)
@@ -667,7 +669,7 @@ static int handle_listen(void *buf)
 			return -1;
 		else {
 			chan = cmd->channel;
-			sec_level = BT_IO_SEC_LOW;
+			sec_level = BT_IO_SEC_MEDIUM;
 		}
 	} else {
 		chan = profile->channel;
@@ -786,6 +788,7 @@ fail:
 static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 {
 	struct rfcomm_sock *rfsock = data;
+	BtIOSecLevel sec_level = BT_IO_SEC_MEDIUM;
 	GError *gerr = NULL;
 	sdp_list_t *list;
 	GIOChannel *io;
@@ -829,11 +832,14 @@ static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 
 	DBG("Got RFCOMM channel %d", chan);
 
+	if (rfsock->profile)
+		sec_level = rfsock->profile->sec_level;
+
 	io = bt_io_connect(connect_cb, rfsock, NULL, &gerr,
 				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
 				BT_IO_OPT_DEST_BDADDR, &rfsock->dst,
 				BT_IO_OPT_CHANNEL, chan,
-				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+				BT_IO_OPT_SEC_LEVEL, sec_level,
 				BT_IO_OPT_INVALID);
 	if (!io) {
 		error("Failed connect: %s", gerr->message);
@@ -875,6 +881,8 @@ static int handle_connect(void *buf)
 	uuid.type = SDP_UUID128;
 	memcpy(&uuid.value.uuid128, cmd->uuid, sizeof(uint128_t));
 
+	rfsock->profile = get_profile_by_uuid(cmd->uuid);
+
 	if (bt_search_service(&adapter_addr, &dst, &uuid, sdp_search_cb, rfsock,
 								NULL) < 0) {
 		error("Failed to search SDP records");
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 1/6] android/socket: Make profile struct const
From: Andrei Emeltchenko @ 2013-11-26 14:05 UTC (permalink / raw)
  To: linux-bluetooth

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

We are not supposed to change profile structure, make it const.
---
 android/socket.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/android/socket.c b/android/socket.c
index 83e6996..184deae 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -335,7 +335,7 @@ static sdp_record_t *create_spp_record(uint8_t chan, const char *svc_name)
 	return record;
 }
 
-static struct profile_info {
+static const struct profile_info {
 	uint8_t		uuid[16];
 	uint8_t		channel;
 	uint8_t		svc_hint;
@@ -381,7 +381,7 @@ static struct profile_info {
 	},
 };
 
-static uint32_t sdp_service_register(struct profile_info *profile,
+static uint32_t sdp_service_register(const struct profile_info *profile,
 							const void *svc_name)
 {
 	sdp_record_t *record;
@@ -444,7 +444,7 @@ static int bt_sock_send_fd(int sock_fd, const void *buf, int len, int send_fd)
 	return ret;
 }
 
-static struct profile_info *get_profile_by_uuid(const uint8_t *uuid)
+static const struct profile_info *get_profile_by_uuid(const uint8_t *uuid)
 {
 	unsigned int i;
 
@@ -651,7 +651,7 @@ static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
 static int handle_listen(void *buf)
 {
 	struct hal_cmd_sock_listen *cmd = buf;
-	struct profile_info *profile;
+	const struct profile_info *profile;
 	struct rfcomm_sock *rfsock;
 	BtIOSecLevel sec_level;
 	GIOChannel *io;
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 2/2] android/haltest: Add uuid autocompletions
From: Andrei Emeltchenko @ 2013-11-26 13:47 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385473625-14266-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

---
 android/client/if-sock.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/android/client/if-sock.c b/android/client/if-sock.c
index 12ac755..5394a5d 100644
--- a/android/client/if-sock.c
+++ b/android/client/if-sock.c
@@ -35,6 +35,10 @@ ENDMAP
 static int listen_fd[MAX_LISTEN_FD];
 static int listen_fd_count;
 
+static const char * const uuids[] = {
+	"00001101", "00001105", "0000112f", NULL
+};
+
 /*
  * This function reads data from file descriptor and
  * prints it to the user
@@ -193,6 +197,9 @@ static void listen_c(int argc, const char **argv, enum_func *enum_func,
 	if (argc == 3) {
 		*user = TYPE_ENUM(btsock_type_t);
 		*enum_func = enum_defines;
+	} else if (argc == 5) {
+		*user = (void *) uuids;
+		*enum_func = enum_strings;
 	}
 }
 
@@ -264,6 +271,9 @@ static void connect_c(int argc, const char **argv, enum_func *enum_func,
 	} else if (argc == 4) {
 		*user = TYPE_ENUM(btsock_type_t);
 		*enum_func = enum_defines;
+	} else if (argc == 5) {
+		*user = (void *) uuids;
+		*enum_func = enum_strings;
 	}
 }
 
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 1/2] android/haltest: trivial: Fix typo channle -> channel
From: Andrei Emeltchenko @ 2013-11-26 13:47 UTC (permalink / raw)
  To: linux-bluetooth

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

---
 android/client/if-sock.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/android/client/if-sock.c b/android/client/if-sock.c
index eef9a76..12ac755 100644
--- a/android/client/if-sock.c
+++ b/android/client/if-sock.c
@@ -328,9 +328,9 @@ static void connect_p(int argc, const char **argv)
 /* Methods available in btsock_interface_t */
 static struct method methods[] = {
 	STD_METHODCH(listen,
-			"<sock_type> <srvc_name> <uuid> [<channle>] [<flags>]"),
+			"<sock_type> <srvc_name> <uuid> [<channel>] [<flags>]"),
 	STD_METHODCH(connect,
-			"<addr> <sock_type> <uuid> <channle> [<flags>]"),
+			"<addr> <sock_type> <uuid> <channel> [<flags>]"),
 	END_METHOD
 };
 
-- 
1.8.3.2


^ permalink raw reply related

* Re: [PATCH v2 00/20] Initial AVDTP for Android
From: Luiz Augusto von Dentz @ 2013-11-26 13:46 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org
In-Reply-To: <1385391283-10962-1-git-send-email-luiz.dentz@gmail.com>

Hi,

On Mon, Nov 25, 2013 at 4:54 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> The code is based on the current implementation available in
> profiles/audio/avdtp.{c,h} but it is transport agnostic and does not
> contain any external dependency except glib for IO handling.
>
> Both the signaling and the transport connection has to be handled by
> the upper layer, that is why it is not modified in place to avoid
> breaking current implemention until this work is considered stable.
>
> Two new function are added:
>
>   - avdtp_new: Creates AVDTP session and attach signaling transport
>   - avdtp_stream_set_transport: Set stream transport
>
> Both receives a fd as parameter so in future it should be possible to
> replace the IO handling.
>
> This set also includes a initial test set based on the current AVDTP
> test specification, once merged more tests will be added as well,
> then the intent is to make this used by audio plugin.
>
> Note: It is possible to track back to the original code by doing:
> git log --follow or git blame -C -C.
>
> v2: Add a separate commit to copy existing AVDTP files
>
> Luiz Augusto von Dentz (20):
>   android: Add copy of current AVDTP implemention
>   android/AVDTP: Strip dependencies
>   unit/AVDTP: Add /TP/SIG/SMG/BV-05-C test
>   unit/AVDTP: Add /TP/SIG/SMG/BV-06-C test
>   unit/AVDTP: Add /TP/SIG/SMG/BV-07-C test
>   unit/AVDTP: Add /TP/SIG/SMG/BV-08-C test
>   unit/AVDTP: Add /TP/SIG/SMG/BV-09-C test
>   unit/AVDTP: Add /TP/SIG/SMG/BV-10-C test
>   unit/AVDTP: Add /TP/SIG/SMG/BV-11-C test
>   unit/AVDTP: Add /TP/SIG/SMG/BV-12-C test
>   unit/AVDTP: Add /TP/SIG/SMG/BV-15-C test
>   unit/AVDTP: Add /TP/SIG/SMG/BV-16-C test
>   unit/AVDTP: Add /TP/SIG/SMG/BV-17-C test
>   unit/AVDTP: Add /TP/SIG/SMG/BV-18-C test
>   unit/AVDTP: Add /TP/SIG/SMG/BV-19-C test
>   unit/AVDTP: Add /TP/SIG/SMG/BV-20-C test
>   unit/AVDTP: Add /TP/SIG/SMG/BV-21-C test
>   unit/AVDTP: Add /TP/SIG/SMG/BV-22-C test
>   unit/AVDTP: Add /TP/SIG/SMG/BV-23-C test
>   unit/AVDTP: Add /TP/SIG/SMG/BV-24-C test
>
>  Makefile.am         |    8 +
>  android/Makefile.am |    1 +
>  android/a2dp.c      |   23 +
>  android/avdtp.c     | 3256 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  android/avdtp.h     |  275 +++++
>  unit/test-avdtp.c   |  612 ++++++++++
>  6 files changed, 4175 insertions(+)
>  create mode 100644 android/avdtp.c
>  create mode 100644 android/avdtp.h
>  create mode 100644 unit/test-avdtp.c
>
> --
> 1.8.3.1

This set is now upstream.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: Crasher during remote initiated pairing
From: Johan Hedberg @ 2013-11-26 13:43 UTC (permalink / raw)
  To: Bastien Nocera, linux-bluetooth
In-Reply-To: <20131126133427.GA19614@x220.p-661hnu-f1>

Hi Bastien,

On Tue, Nov 26, 2013, Johan Hedberg wrote:
> On Mon, Nov 25, 2013, Bastien Nocera wrote:
> > Heya,
> > 
> > I have a particularly stubborn device, the TomTom Go Remote that tries
> > to connect to my computer as soon as it's turned on, even when I've
> > removed the pairing on the computer side.
> > 
> > With GNOME's Bluetooth wizard open, I receive an out of the blue request
> > for pairing, I pass it the expected PIN code (0000), I then find that
> > the wizard doesn't work as I expected and turn it off. bluetoothd
> > promptly crashes:
> > 
> > Program received signal SIGSEGV, Segmentation fault.
> > 0x00007f0cf9ffde24 in agent_auth_cb (agent=<optimized out>, derr=0x7fffab655920, user_data=0x7f0cfb2e0020) at src/adapter.c:4370
> > 4370		struct service_auth *auth = adapter->auths->head->data;
> > (gdb) p adapter
> > $1 = (struct btd_adapter *) 0x7f0cfb2e0020
> > (gdb) p adapter->auths
> > $2 = (GQueue *) 0x7f0cfb2d1240
> > (gdb) p adapter->auths->head
> > $3 = 0x0
> > 
> > Some missing NULL checks?
> 
> Not sure. The GQueue internals should not be of our concern, meaning if
> we have a non-NULL GQueue pointer I'd expect it to be safe to call
> g_queue_is_empty on that pointer. I wonder if this is some kind of
> freed memory access or similar. valgrind might show this.

Just ignore the above, I was following the exact line number in the
trace (4370) which landed me in process_auth_queue() instead of
agent_auth_cb(), i.e. I was looking at the wrong piece of code and
making the wrong conclusions.

Johan

^ permalink raw reply

* Re: Crasher during remote initiated pairing
From: Johan Hedberg @ 2013-11-26 13:34 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: linux-bluetooth
In-Reply-To: <1385398409.3423.25.camel@nuvo>

Hi Bastien,

On Mon, Nov 25, 2013, Bastien Nocera wrote:
> Heya,
> 
> I have a particularly stubborn device, the TomTom Go Remote that tries
> to connect to my computer as soon as it's turned on, even when I've
> removed the pairing on the computer side.
> 
> With GNOME's Bluetooth wizard open, I receive an out of the blue request
> for pairing, I pass it the expected PIN code (0000), I then find that
> the wizard doesn't work as I expected and turn it off. bluetoothd
> promptly crashes:
> 
> Program received signal SIGSEGV, Segmentation fault.
> 0x00007f0cf9ffde24 in agent_auth_cb (agent=<optimized out>, derr=0x7fffab655920, user_data=0x7f0cfb2e0020) at src/adapter.c:4370
> 4370		struct service_auth *auth = adapter->auths->head->data;
> (gdb) p adapter
> $1 = (struct btd_adapter *) 0x7f0cfb2e0020
> (gdb) p adapter->auths
> $2 = (GQueue *) 0x7f0cfb2d1240
> (gdb) p adapter->auths->head
> $3 = 0x0
> 
> Some missing NULL checks?

Not sure. The GQueue internals should not be of our concern, meaning if
we have a non-NULL GQueue pointer I'd expect it to be safe to call
g_queue_is_empty on that pointer. I wonder if this is some kind of
freed memory access or similar. valgrind might show this.

Johan

^ permalink raw reply

* Re: [PATCH 1/4] android: Add CAP_NET_RAW capability
From: Ravi kumar Veeramally @ 2013-11-26 13:14 UTC (permalink / raw)
  To: linux-bluetooth, johan.hedberg
In-Reply-To: <20131125142532.GA26309@x220.p-661hnu-f1>

Hi Johan,

On 25.11.2013 16:25, Johan Hedberg wrote:
> Hi Ravi,
>
> On Mon, Nov 25, 2013, Ravi kumar Veeramally wrote:
>> On 25.11.2013 16:01, Johan Hedberg wrote:
>>> Hi Ravi,
>>>
>>> On Mon, Nov 25, 2013, Ravi kumar Veeramally wrote:
>>>> CAP_NET_RAW capability is required to up the bnep interfaces
>>>> in android environment.
>>>> ---
>>>>   android/main.c | 1 +
>>>>   1 file changed, 1 insertion(+)
>>>>
>>>> diff --git a/android/main.c b/android/main.c
>>>> index c9733f3..bfd2a87 100644
>>>> --- a/android/main.c
>>>> +++ b/android/main.c
>>>> @@ -506,6 +506,7 @@ static bool set_capabilities(void)
>>>>   	header.pid = 0;
>>>>   	cap.effective = cap.permitted =
>>>> +		CAP_TO_MASK(CAP_NET_RAW) |
>>>>   		CAP_TO_MASK(CAP_NET_ADMIN) |
>>>>   		CAP_TO_MASK(CAP_NET_BIND_SERVICE);
>>>>   	cap.inheritable = 0;
>>> Would you then say that commit 9bda7e8c2130de9a3340ebd0e6cc1dedc2eae338
>>> is incorrect? A quick grep doesn't show any instances of checking this
>>> capability in the BNEP code of the kernel. Exactly which system call is
>>> it that needs it?
>>     bnep_if_up from profiles/network/common.c
>>   ---
>>          ifr.ifr_flags |= IFF_UP;
>>          ifr.ifr_flags |= IFF_MULTICAST;
>>
>>          err = ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr);
>> ---
>>   requires this capability in android environment only.
>>   this code is under android macro.
> So you've verified that under "normal" Linux this ioctl does not require
> the NET_RAW capability?
>
>>> If you answered positively to my first question, please send a patch for
>>> that as well.
>>   I didn't understand this, sorry.
> My first question was: "Would you then say that
> commit 9bda7e8c2130de9a3340ebd0e6cc1dedc2eae338 is incorrect?". Do you
> not understand that question or what I asked you to do in case the
> answer is "yes"?

   I tried on host with systemd configure options and limiting 
capabilities to
  only CAP_NET_ADMIN and CAP_NET_BIND_SERVICE. ioctl call for 
interface(bnepX)
  up works well. Android throws an error("Permission denied"). 
CAP_NET_RAW is required
for android.

Thanks,
Ravi.

^ permalink raw reply

* [PATCH] android/bluetooth: Change discoverable mode only if connectable
From: Szymon Janc @ 2013-11-26 12:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

There is no need to sending set_discoverable command if new settings
are not connectable as clearing connectable also clear discoverable.
Sending set_discoverable when not connectable result in 'rejected'
mgmt response.
---
 android/bluetooth.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index aa684bd..ffca084 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -1907,7 +1907,7 @@ static uint8_t set_scan_mode(void *buf, uint16_t len)
 			return HAL_STATUS_FAILED;
 	}
 
-	if (cur_disc != disc) {
+	if (cur_disc != disc && conn) {
 		if (!set_discoverable(disc ? 0x01 : 0x00, 0))
 			return HAL_STATUS_FAILED;
 	}
-- 
1.8.3.2


^ permalink raw reply related

* Re: Intel 7260 bluetooth malfunction when it is connected to EHCI bus
From: Michal Labedzki @ 2013-11-26  9:11 UTC (permalink / raw)
  To: Hui Wang
  Cc: Stevie Trujillo, Marcel Holtmann, tedd.an,
	linux-bluetooth@vger.kernel.org development
In-Reply-To: <CALkxMhEzw+mL5UtF=gZ8MQrWRM_2WEQQeq6jR1hvYiSZ=Mfi3g@mail.gmail.com>

Bug is now fixed in "svn path=3D/trunk/; revision=3D53525". You can wait
for next development (1.11.3) or stable (1.12), however you can build
Wireshark from sources (should be easy - like BlueZ: git clone
http://code.wireshark.org/git/wireshark; ./autogen; ./configure; make;
./wireshark) or via "private" sources like:
$ sudo add-apt-repository ppa:dreibh/ppa
$ sudo apt-get update
$ sudo apt-get install wireshark

On 8 November 2013 12:17, Michal Labedzki <michal.labedzki@tieto.com> wrote=
:
> Hello,
>
> Could you create a bug for Wireshark? (capture log are welcome)
> https://bugs.wireshark.org/bugzilla/buglist.cgi?resolution=3D---&query_fo=
rmat=3Dadvanced&list_id=3D11313
>
> I check and that is right. There are two commands shares the same
> code. "Setup Synchronous Connection" and "Accept Synchronous
> Connection Request". But second one should be different. I can fix
> that.
> Also I recommend to try latest development Wireshark - it is generally st=
able.
>
> On 8 November 2013 02:43, Hui Wang <hui.wang@canonical.com> wrote:
>> On 11/07/2013 06:07 PM, Stevie Trujillo wrote:
>>>
>>> On Thu, 07 Nov 2013 11:45:53 +0800
>>> Hui Wang <hui.wang@canonical.com> wrote:
>>>
>>>> Do you know any tools can decode the log generated by usbmon?
>>>
>>> Hmm, I never actually used the usbmon program. I did "modprobe usbmon",
>>> then Wireshark shows usbmon{1..4} (one for each bus) as an interface
>>> like eth0 for ethernet. http://wiki.wireshark.org/CaptureSetup/USB
>>>
>>> If it's difficult to compare two captures in Wireshark (I don't know an=
y
>>> other method than visual inspection), tshark (Wireshark's "command-line
>>> counter-part") is able to decode to stdout. Maybe one can run the diff
>>> program on that. The output seems a bit terse however.
>>>
>>> Please be aware: in my Wireshark (1.10.2) one of the of the SCO setup
>>> packets are decoded slightly wrong. It looks like Wireshark is missing
>>> a BDADDR in the beginning, so all the other fields get shifted.
>>>
>>>
>> Thanks for sharing this knowledge, i will have a try according to your
>> instructions.
>>
>> Regards,
>> Hui.
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-bluetoot=
h"
>> in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
>
> --
>
> Pozdrawiam / Best regards
> -------------------------------------------------------------------------=
------------------------------------
> Micha=C5=82 =C5=81ab=C4=99dzki, Software Engineer
> Tieto Corporation
>
> Product Development Services
>
> http://www.tieto.com / http://www.tieto.pl
> ---
> ASCII: Michal Labedzki
> location: Swobodna 1 Street, 50-088 Wroc=C5=82aw, Poland
> room: 5.01 (desk next to 5.08)
> ---
> Please note: The information contained in this message may be legally
> privileged and confidential and protected from disclosure. If the
> reader of this message is not the intended recipient, you are hereby
> notified that any unauthorised use, distribution or copying of this
> communication is strictly prohibited. If you have received this
> communication in error, please notify us immediately by replying to
> the message and deleting it from your computer. Thank You.
> ---
> Please consider the environment before printing this e-mail.
> ---
> Tieto Poland sp=C3=B3=C5=82ka z ograniczon=C4=85 odpowiedzialno=C5=9Bci=
=C4=85 z siedzib=C4=85 w
> Szczecinie, ul. Malczewskiego 26. Zarejestrowana w S=C4=85dzie Rejonowym
> Szczecin-Centrum w Szczecinie, XIII Wydzia=C5=82 Gospodarczy Krajowego
> Rejestru S=C4=85dowego pod numerem 0000124858. NIP: 8542085557. REGON:
> 812023656. Kapita=C5=82 zak=C5=82adowy: 4 271500 PLN



--=20

Pozdrawiam / Best regards
---------------------------------------------------------------------------=
----------------------------------
Micha=C5=82 =C5=81ab=C4=99dzki, Software Engineer
Tieto Corporation

Product Development Services

http://www.tieto.com / http://www.tieto.pl
---
ASCII: Michal Labedzki
location: Swobodna 1 Street, 50-088 Wroc=C5=82aw, Poland
room: 5.01 (desk next to 5.08)
---
Please note: The information contained in this message may be legally
privileged and confidential and protected from disclosure. If the
reader of this message is not the intended recipient, you are hereby
notified that any unauthorised use, distribution or copying of this
communication is strictly prohibited. If you have received this
communication in error, please notify us immediately by replying to
the message and deleting it from your computer. Thank You.
---
Please consider the environment before printing this e-mail.
---
Tieto Poland sp=C3=B3=C5=82ka z ograniczon=C4=85 odpowiedzialno=C5=9Bci=C4=
=85 z siedzib=C4=85 w
Szczecinie, ul. Malczewskiego 26. Zarejestrowana w S=C4=85dzie Rejonowym
Szczecin-Centrum w Szczecinie, XIII Wydzia=C5=82 Gospodarczy Krajowego
Rejestru S=C4=85dowego pod numerem 0000124858. NIP: 8542085557. REGON:
812023656. Kapita=C5=82 zak=C5=82adowy: 4 271500 PLN

^ permalink raw reply

* [PATCH 13/13] input: Add support for handling sixaxis devices
From: Szymon Janc @ 2013-11-25 22:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1385417752-25664-1-git-send-email-szymon.janc@gmail.com>

This allows to handle incoming connection from unknown devices.
If device happens to be sixaxis input device is created after
SDP was queried and then connection is authorized.
---
 profiles/input/server.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 103 insertions(+), 1 deletion(-)

diff --git a/profiles/input/server.c b/profiles/input/server.c
index 21d4562..8a50d23 100644
--- a/profiles/input/server.c
+++ b/profiles/input/server.c
@@ -63,6 +63,100 @@ static int server_cmp(gconstpointer s, gconstpointer user_data)
 	return bacmp(&server->src, src);
 }
 
+struct sixaxis_data {
+	GIOChannel *chan;
+	uint16_t psm;
+};
+
+static void connect_event_cb(GIOChannel *chan, GError *err, gpointer data);
+
+static void sixaxis_sdp_cb(struct btd_device *dev, int err, void *user_data)
+{
+	struct sixaxis_data *data = user_data;
+	struct input_server *server;
+	GError *gerr = NULL;
+	const bdaddr_t *src;
+	GSList *l;
+
+	DBG("err %d (%s)", err, strerror(-err));
+
+	if (err < 0)
+		goto fail;
+
+	src = btd_adapter_get_address(device_get_adapter(dev));
+
+	l = g_slist_find_custom(servers, src, server_cmp);
+	if (!l)
+		goto fail;
+
+	server = l->data;
+
+	err = input_device_set_channel(src, device_get_address(dev),
+							data->psm, data->chan);
+	if (err < 0)
+		goto fail;
+
+	if (server->confirm) {
+		if (!bt_io_accept(server->confirm, connect_event_cb, server,
+								NULL, &gerr)) {
+			error("bt_io_accept: %s", gerr->message);
+			g_error_free(gerr);
+			goto fail;
+		}
+
+		g_io_channel_unref(server->confirm);
+		server->confirm = NULL;
+	}
+
+	g_io_channel_unref(data->chan);
+	g_free(data);
+
+	return;
+
+fail:
+	g_io_channel_shutdown(data->chan, TRUE, NULL);
+	g_io_channel_unref(data->chan);
+	g_free(data);
+}
+
+static void sixaxis_browse_sdp(const bdaddr_t *src, const bdaddr_t *dst,
+						GIOChannel *chan, uint16_t psm)
+{
+	struct btd_device *device;
+	struct sixaxis_data *data;
+
+	if (psm != L2CAP_PSM_HIDP_CTRL)
+		return;
+
+	device = btd_adapter_find_device(adapter_find(src), dst);
+	if (!device)
+		return;
+
+	data = g_new0(struct sixaxis_data, 1);
+	data->chan = g_io_channel_ref(chan);
+	data->psm = psm;
+
+	device_discover_services(device);
+	device_wait_for_svc_complete(device, sixaxis_sdp_cb, data);
+}
+
+static bool check_sixaxis(const bdaddr_t *src, const bdaddr_t *dst)
+{
+	struct btd_device *device;
+
+	device = btd_adapter_find_device(adapter_find(src), dst);
+	if (!device)
+		return false;
+
+	if (btd_device_get_vendor(device) != 0x054c)
+		return false;
+
+	if (btd_device_get_product(device) != 0x0268)
+		return false;
+
+	return true;
+}
+
 static void connect_event_cb(GIOChannel *chan, GError *err, gpointer data)
 {
 	uint16_t psm;
@@ -95,6 +189,11 @@ static void connect_event_cb(GIOChannel *chan, GError *err, gpointer data)
 	if (ret == 0)
 		return;
 
+	if (ret == -ENOENT && check_sixaxis(&src, &dst)) {
+		sixaxis_browse_sdp(&src, &dst, chan, psm);
+		return;
+	}
+
 	error("Refusing input device connect: %s (%d)", strerror(-ret), -ret);
 
 	/* Send unplug virtual cable to unknown devices */
@@ -129,6 +228,9 @@ static void auth_callback(DBusError *derr, void *user_data)
 		goto reject;
 	}
 
+	if (!input_device_exists(&src, &dst) && check_sixaxis(&src, &dst))
+		return;
+
 	if (!bt_io_accept(server->confirm, connect_event_cb, server,
 				NULL, &err)) {
 		error("bt_io_accept: %s", err->message);
@@ -175,7 +277,7 @@ static void confirm_event_cb(GIOChannel *chan, gpointer user_data)
 		goto drop;
 	}
 
-	if (!input_device_exists(&src, &dst)) {
+	if (!input_device_exists(&src, &dst) && !check_sixaxis(&src, &dst)) {
 		error("Refusing connection from %s: unknown device", addr);
 		goto drop;
 	}
-- 
1.8.4.4


^ permalink raw reply related

* [PATCH 12/13] device: Add device_discover_services function
From: Szymon Janc @ 2013-11-25 22:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1385417752-25664-1-git-send-email-szymon.janc@gmail.com>

This will allow to query remote services from plugins for not yet
discovered devices.
---
 src/device.c | 17 +++++++++++++++++
 src/device.h |  2 ++
 2 files changed, 19 insertions(+)

diff --git a/src/device.c b/src/device.c
index 4e952c5..847ffad 100644
--- a/src/device.c
+++ b/src/device.c
@@ -3524,6 +3524,23 @@ static int device_browse_sdp(struct btd_device *device, DBusMessage *msg)
 	return err;
 }
 
+int device_discover_services(struct btd_device *device)
+{
+	int err;
+
+	if (device_is_bredr(device))
+		err = device_browse_sdp(device, NULL);
+	else
+		err = device_browse_primary(device, NULL);
+
+	if (err == 0 && device->discov_timer) {
+		g_source_remove(device->discov_timer);
+		device->discov_timer = 0;
+	}
+
+	return err;
+}
+
 struct btd_adapter *device_get_adapter(struct btd_device *device)
 {
 	if (!device)
diff --git a/src/device.h b/src/device.h
index a0d25fe..c3fea4a 100644
--- a/src/device.h
+++ b/src/device.h
@@ -131,5 +131,7 @@ bool device_remove_svc_complete_callback(struct btd_device *dev,
 struct btd_service *btd_device_get_service(struct btd_device *dev,
 						const char *remote_uuid);
 
+int device_discover_services(struct btd_device *device);
+
 void btd_device_init(void);
 void btd_device_cleanup(void);
-- 
1.8.4.4


^ permalink raw reply related

* [PATCH 11/13] plugins/sixaxis: Add support for configuring new controllers
From: Szymon Janc @ 2013-11-25 22:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1385417752-25664-1-git-send-email-szymon.janc@gmail.com>

When new PS3 controller is detected provide it with default adapter
address. Also create new btd_device with proper PNP info if it wasn't
existing yet.
---
 plugins/sixaxis.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 178 insertions(+), 1 deletion(-)

diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
index 7a5c6c2..86cfe82 100644
--- a/plugins/sixaxis.c
+++ b/plugins/sixaxis.c
@@ -29,19 +29,196 @@
 
 #include <stddef.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/hidraw.h>
+#include <linux/input.h>
 #include <glib.h>
 #include <libudev.h>
 
+#include "lib/bluetooth.h"
+#include "uuid.h"
+#include "adapter.h"
+#include "device.h"
 #include "plugin.h"
 #include "log.h"
 
+static const struct {
+	const char *name;
+	uint16_t source;
+	uint16_t vid;
+	uint16_t pid;
+	uint16_t version;
+} devices[] = {
+	{
+		.name = "PLAYSTATION(R)3 Controller",
+		.source = 0x0002,
+		.vid = 0x054c,
+		.pid = 0x0268,
+		.version = 0x0000,
+	},
+};
+
 static struct udev *ctx = NULL;
 static struct udev_monitor *monitor = NULL;
 static guint watch_id = 0;
 
+static int get_device_bdaddr(int fd, bdaddr_t *bdaddr)
+{
+	uint8_t buf[18];
+	int ret;
+
+	memset(buf, 0, sizeof(buf));
+
+	buf[0] = 0xf2;
+
+	ret = ioctl(fd, HIDIOCGFEATURE(sizeof(buf)), buf);
+	if (ret < 0) {
+		error("sixaxis: failed to read device address (%s)",
+							strerror(errno));
+		return ret;
+	}
+
+	baswap(bdaddr, (bdaddr_t *) (buf + 4));
+
+	return 0;
+}
+
+static int get_master_bdaddr(int fd, bdaddr_t *bdaddr)
+{
+	uint8_t buf[8];
+	int ret;
+
+	memset(buf, 0, sizeof(buf));
+
+	buf[0] = 0xf5;
+
+	ret = ioctl(fd, HIDIOCGFEATURE(sizeof(buf)), buf);
+	if (ret < 0) {
+		error("sixaxis: failed to read master address (%s)",
+							strerror(errno));
+		return ret;
+	}
+
+	baswap(bdaddr, (bdaddr_t *) (buf + 2));
+
+	return 0;
+}
+
+static int set_master_bdaddr(int fd, const bdaddr_t *bdaddr)
+{
+	uint8_t buf[8];
+	int ret;
+
+	buf[0] = 0xf5;
+	buf[1] = 0x01;
+
+	baswap((bdaddr_t *) (buf + 2), bdaddr);
+
+	ret = ioctl(fd, HIDIOCSFEATURE(sizeof(buf)), buf);
+	if (ret < 0)
+		error("sixaxis: failed to write master address (%s)",
+							strerror(errno));
+
+	return ret;
+}
+
+static void setup_device(int fd, int index, struct btd_adapter *adapter)
+{
+	char device_addr[18], master_addr[18], adapter_addr[18];
+	bdaddr_t device_bdaddr, master_bdaddr;
+	const bdaddr_t *adapter_bdaddr;
+	struct btd_device *device;
+
+	if (get_device_bdaddr(fd, &device_bdaddr) < 0)
+		return;
+
+	if (get_master_bdaddr(fd, &master_bdaddr) < 0)
+		return;
+
+	adapter_bdaddr = btd_adapter_get_address(adapter);
+
+	if (bacmp(adapter_bdaddr, &master_bdaddr)) {
+		if (set_master_bdaddr(fd, adapter_bdaddr) < 0)
+			return;
+	}
+
+	ba2str(&device_bdaddr, device_addr);
+	ba2str(&master_bdaddr, master_addr);
+	ba2str(adapter_bdaddr, adapter_addr);
+	DBG("remote %s old_master %s new_master %s",
+				device_addr, master_addr, adapter_addr);
+
+	device = btd_adapter_get_device(adapter, &device_bdaddr, BDADDR_BREDR);
+
+	if (g_slist_find_custom(btd_device_get_uuids(device), HID_UUID,
+						(GCompareFunc)strcasecmp)) {
+		DBG("device %s already known, skipping", device_addr);
+		return;
+	}
+
+	info("sixaxis: setting up new device");
+
+	btd_device_device_set_name(device, devices[index].name);
+	btd_device_set_pnpid(device, devices[index].source, devices[index].vid,
+				devices[index].pid, devices[index].version);
+	btd_device_set_temporary(device, FALSE);
+	btd_device_set_trusted(device, TRUE);
+}
+
+static int get_supported_device(struct udev_device *udevice, uint16_t *bus)
+{
+	struct udev_device *hid_parent;
+	uint16_t vid, pid;
+	const char *hid_id;
+	int i;
+
+	hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice,
+								"hid", NULL);
+	if (!hid_parent)
+		return -1;
+
+	hid_id = udev_device_get_property_value(hid_parent, "HID_ID");
+
+	if (sscanf(hid_id, "%hx:%hx:%hx", bus, &vid, &pid) != 3)
+		return -1;
+
+	for (i = 0; G_N_ELEMENTS(devices); i++) {
+		if (devices[i].vid == vid && devices[i].pid == pid)
+			return i;
+	}
+
+	return -1;
+}
+
 static void device_added(struct udev_device *udevice)
 {
-	DBG("");
+	struct btd_adapter *adapter;
+	uint16_t bus;
+	int index;
+	int fd;
+
+	adapter = btd_adapter_get_default();
+	if (!adapter)
+		return;
+
+	index = get_supported_device(udevice, &bus);
+	if (index < 0)
+		return;
+
+	info("sixaxis: compatible device connected: %s (%04X:%04X)",
+				devices[index].name, devices[index].vid,
+				devices[index].pid);
+
+	fd = open(udev_device_get_devnode(udevice), O_RDWR);
+	if (fd < 0)
+		return;
+
+	if (bus == BUS_USB)
+		setup_device(fd, index, adapter);
+
+	close(fd);
 }
 
 static gboolean monitor_watch(GIOChannel *source, GIOCondition condition,
-- 
1.8.4.4


^ permalink raw reply related

* [PATCH 10/13] plugins/sixaxis: Add initial code for udev handling
From: Szymon Janc @ 2013-11-25 22:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1385417752-25664-1-git-send-email-szymon.janc@gmail.com>

When new device is added plugin will be notified about it.
---
 plugins/sixaxis.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
index bf66bef..7a5c6c2 100644
--- a/plugins/sixaxis.c
+++ b/plugins/sixaxis.c
@@ -27,19 +27,82 @@
 #include <config.h>
 #endif
 
+#include <stddef.h>
+#include <errno.h>
+#include <glib.h>
+#include <libudev.h>
+
 #include "plugin.h"
 #include "log.h"
 
+static struct udev *ctx = NULL;
+static struct udev_monitor *monitor = NULL;
+static guint watch_id = 0;
+
+static void device_added(struct udev_device *udevice)
+{
+	DBG("");
+}
+
+static gboolean monitor_watch(GIOChannel *source, GIOCondition condition,
+							gpointer data)
+{
+	struct udev_device *udevice;
+
+	udevice = udev_monitor_receive_device(monitor);
+	if (!udevice)
+		return TRUE;
+
+	if (!g_strcmp0(udev_device_get_action(udevice), "add"))
+		device_added(udevice);
+
+	udev_device_unref(udevice);
+
+	return TRUE;
+}
+
 static int sixaxis_init(void)
 {
+	GIOChannel *channel;
+
 	DBG("");
 
+	ctx = udev_new();
+	if (!ctx)
+		return -EIO;
+
+	monitor = udev_monitor_new_from_netlink(ctx, "udev");
+	if (!monitor) {
+		udev_unref(ctx);
+		ctx = NULL;
+
+		return -EIO;
+	}
+
+	/* Listen for newly connected hidraw interfaces */
+	udev_monitor_filter_add_match_subsystem_devtype(monitor, "hidraw",
+									NULL);
+	udev_monitor_enable_receiving(monitor);
+
+	channel = g_io_channel_unix_new(udev_monitor_get_fd(monitor));
+	watch_id = g_io_add_watch(channel, G_IO_IN, monitor_watch, NULL);
+	g_io_channel_unref(channel);
+
 	return 0;
 }
 
 static void sixaxis_exit(void)
 {
 	DBG("");
+
+	g_source_remove(watch_id);
+	watch_id = 0;
+
+	udev_monitor_unref(monitor);
+	monitor = NULL;
+
+	udev_unref(ctx);
+	ctx = NULL;
 }
 
 BLUETOOTH_PLUGIN_DEFINE(sixaxis, VERSION, BLUETOOTH_PLUGIN_PRIORITY_LOW,
-- 
1.8.4.4


^ permalink raw reply related

* [PATCH 09/13] plugins: Add initial code for sixaxis plugin
From: Szymon Janc @ 2013-11-25 22:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1385417752-25664-1-git-send-email-szymon.janc@gmail.com>

This plugin will be used to associate PS3 controllers.
---
 Makefile.plugins    |  8 ++++++++
 bootstrap-configure |  1 +
 configure.ac        |  5 +++++
 plugins/sixaxis.c   | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 60 insertions(+)
 create mode 100644 plugins/sixaxis.c

diff --git a/Makefile.plugins b/Makefile.plugins
index 7c5f71d..f5025e9 100644
--- a/Makefile.plugins
+++ b/Makefile.plugins
@@ -110,3 +110,11 @@ builtin_sources += profiles/heartrate/heartrate.c
 builtin_modules += cyclingspeed
 builtin_sources += profiles/cyclingspeed/cyclingspeed.c
 endif
+
+if SIXAXIS
+plugin_LTLIBRARIES += plugins/sixaxis.la
+plugins_sixaxis_la_SOURCES = plugins/sixaxis.c
+plugins_sixaxis_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version \
+						-no-undefined @UDEV_LIBS@
+plugins_sixaxis_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden @UDEV_CFLAGS@
+endif
diff --git a/bootstrap-configure b/bootstrap-configure
index dc36311..c7f08ed 100755
--- a/bootstrap-configure
+++ b/bootstrap-configure
@@ -13,4 +13,5 @@ fi
 		--localstatedir=/var \
 		--enable-experimental \
 		--enable-android \
+		--enable-sixaxis \
 		--disable-datafiles $*
diff --git a/configure.ac b/configure.ac
index 949846e..ca226bb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -216,6 +216,11 @@ AC_ARG_ENABLE(experimental, AC_HELP_STRING([--enable-experimental],
 					[enable_experimental=${enableval}])
 AM_CONDITIONAL(EXPERIMENTAL, test "${enable_experimental}" = "yes")
 
+AC_ARG_ENABLE(sixaxis, AC_HELP_STRING([--enable-sixaxis],
+		[enable sixaxis plugin]), [enable_sixaxis=${enableval}])
+AM_CONDITIONAL(SIXAXIS, test "${enable_sixaxis}" = "yes" &&
+					 test "${enable_udev}" != "no")
+
 if (test "${prefix}" = "NONE"); then
 	dnl no prefix and no localstatedir, so default to /var
 	if (test "$localstatedir" = '${prefix}/var'); then
diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
new file mode 100644
index 0000000..bf66bef
--- /dev/null
+++ b/plugins/sixaxis.c
@@ -0,0 +1,46 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2009  Bastien Nocera <hadess@hadess.net>
+ *  Copyright (C) 2011  Antonio Ospite <ospite@studenti.unina.it>
+ *  Copyright (C) 2013  Szymon Janc <szymon.janc@gmail.com>
+ *
+ *
+ *  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 "plugin.h"
+#include "log.h"
+
+static int sixaxis_init(void)
+{
+	DBG("");
+
+	return 0;
+}
+
+static void sixaxis_exit(void)
+{
+	DBG("");
+}
+
+BLUETOOTH_PLUGIN_DEFINE(sixaxis, VERSION, BLUETOOTH_PLUGIN_PRIORITY_LOW,
+						sixaxis_init, sixaxis_exit)
-- 
1.8.4.4


^ permalink raw reply related


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