Linux bluetooth development
 help / color / mirror / Atom feed
* pull request: bluetooth 2013-11-11
From: Gustavo Padovan @ 2013-11-11 18:27 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, linux-bluetooth, linux-kernel

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

Hi John,

A few fixes for 3.13. There is 3 fixes to the RFCOMM protocol. One crash fix to
L2CAP. A simple fix to a bad behaviour in the SMP protocol, and last, an
revert, that I sent in the last pull request but doesn't seem to be in your
tree.

Please pull or let me know of any issues. Thanks!


	Gustavo

---
The following changes since commit 8ce9beac4661f576ea0d518b9f086bb52a171a37:

  drivers: net: wireless: b43: Fix possible NULL ptr dereference (2013-10-18 13:41:11 -0400)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth master

for you to fetch changes up to 3244d4a55c95708b0fa6fd820a9009534ed08a5f:

  Bluetooth: Fix rejecting SMP security request in slave role (2013-11-11 15:48:36 -0200)

----------------------------------------------------------------
Hans de Goede (1):
      Bluetooth: revert: "Bluetooth: Add missing reset_resume dev_pm_ops"

Johan Hedberg (1):
      Bluetooth: Fix rejecting SMP security request in slave role

Marcel Holtmann (1):
      Bluetooth: Fix issue with RFCOMM getsockopt operation

Seung-Woo Kim (3):
      Bluetooth: Fix RFCOMM bind fail for L2CAP sock
      Bluetooth: Fix to set proper bdaddr_type for RFCOMM connect
      Bluetooth: Fix crash in l2cap_chan_send after l2cap_chan_del

 drivers/bluetooth/btusb.c   | 1 -
 net/bluetooth/l2cap_core.c  | 3 +++
 net/bluetooth/rfcomm/core.c | 3 +++
 net/bluetooth/rfcomm/sock.c | 6 +++++-
 net/bluetooth/smp.c         | 3 +++
 5 files changed, 14 insertions(+), 2 deletions(-)


[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH BlueZ v2] audio/AVDTP: Remove avdtp_init and avdtp_exit
From: Johan Hedberg @ 2013-11-11 16:50 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1384186675-14940-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Mon, Nov 11, 2013, Luiz Augusto von Dentz wrote:
> This is now done on demand by avdtp_register_sep and avdtp_unregister_sep
> so the server socket is only registered when there is an endpoint
> available and the record is properly registered.
> ---
> v2: Fix return of avdtp_server_init
> 
>  profiles/audio/a2dp.c  |  11 -----
>  profiles/audio/avdtp.c | 118 +++++++++++++++++++++++++------------------------
>  profiles/audio/avdtp.h |   3 --
>  3 files changed, 60 insertions(+), 72 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH BlueZ v2] audio/AVDTP: Remove avdtp_init and avdtp_exit
From: Luiz Augusto von Dentz @ 2013-11-11 16:17 UTC (permalink / raw)
  To: linux-bluetooth

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

This is now done on demand by avdtp_register_sep and avdtp_unregister_sep
so the server socket is only registered when there is an endpoint
available and the record is properly registered.
---
v2: Fix return of avdtp_server_init

 profiles/audio/a2dp.c  |  11 -----
 profiles/audio/avdtp.c | 118 +++++++++++++++++++++++++------------------------
 profiles/audio/avdtp.h |   3 --
 3 files changed, 60 insertions(+), 72 deletions(-)

diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index 8477b5d..6b3d6b2 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -1187,17 +1187,8 @@ static struct a2dp_server *find_server(GSList *list, struct btd_adapter *a)
 static struct a2dp_server *a2dp_server_register(struct btd_adapter *adapter)
 {
 	struct a2dp_server *server;
-	int av_err;
 
 	server = g_new0(struct a2dp_server, 1);
-
-	av_err = avdtp_init(adapter);
-	if (av_err < 0) {
-		DBG("AVDTP not registered");
-		g_free(server);
-		return NULL;
-	}
-
 	server->adapter = btd_adapter_ref(adapter);
 	servers = g_slist_append(servers, server);
 
@@ -1217,8 +1208,6 @@ static void a2dp_unregister_sep(struct a2dp_sep *sep)
 
 static void a2dp_server_unregister(struct a2dp_server *server)
 {
-	avdtp_exit(server->adapter);
-
 	servers = g_slist_remove(servers, server);
 	btd_adapter_unref(server->adapter);
 	g_free(server);
diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index dab8f1c..9378350 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -3683,6 +3683,45 @@ int avdtp_delay_report(struct avdtp *session, struct avdtp_stream *stream,
 							&req, sizeof(req));
 }
 
+static GIOChannel *avdtp_server_socket(const bdaddr_t *src, gboolean master)
+{
+	GError *err = NULL;
+	GIOChannel *io;
+
+	io = bt_io_listen(NULL, avdtp_confirm_cb,
+				NULL, NULL, &err,
+				BT_IO_OPT_SOURCE_BDADDR, src,
+				BT_IO_OPT_PSM, AVDTP_PSM,
+				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+				BT_IO_OPT_MASTER, master,
+				BT_IO_OPT_INVALID);
+	if (!io) {
+		error("%s", err->message);
+		g_error_free(err);
+	}
+
+	return io;
+}
+
+static struct avdtp_server *avdtp_server_init(struct btd_adapter *adapter)
+{
+	struct avdtp_server *server;
+
+	server = g_new0(struct avdtp_server, 1);
+
+	server->io = avdtp_server_socket(adapter_get_address(adapter), TRUE);
+	if (!server->io) {
+		g_free(server);
+		return NULL;
+	}
+
+	server->adapter = btd_adapter_ref(adapter);
+
+	servers = g_slist_append(servers, server);
+
+	return server;
+}
+
 struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
 						uint8_t type,
 						uint8_t media_type,
@@ -3696,8 +3735,11 @@ struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
 	struct avdtp_local_sep *sep;
 
 	server = find_server(servers, adapter);
-	if (!server)
-		return NULL;
+	if (!server) {
+		server = avdtp_server_init(adapter);
+		if (!server)
+			return NULL;
+	}
 
 	if (g_slist_length(server->seps) > MAX_SEID)
 		return NULL;
@@ -3722,6 +3764,18 @@ struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
 	return sep;
 }
 
+static void avdtp_server_destroy(struct avdtp_server *server)
+{
+	g_slist_free_full(server->sessions, avdtp_free);
+
+	servers = g_slist_remove(servers, server);
+
+	g_io_channel_shutdown(server->io, TRUE, NULL);
+	g_io_channel_unref(server->io);
+	btd_adapter_unref(server->adapter);
+	g_free(server);
+}
+
 int avdtp_unregister_sep(struct avdtp_local_sep *sep)
 {
 	struct avdtp_server *server;
@@ -3740,27 +3794,12 @@ int avdtp_unregister_sep(struct avdtp_local_sep *sep)
 
 	g_free(sep);
 
-	return 0;
-}
-
-static GIOChannel *avdtp_server_socket(const bdaddr_t *src, gboolean master)
-{
-	GError *err = NULL;
-	GIOChannel *io;
+	if (server->seps)
+		return 0;
 
-	io = bt_io_listen(NULL, avdtp_confirm_cb,
-				NULL, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, src,
-				BT_IO_OPT_PSM, AVDTP_PSM,
-				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-				BT_IO_OPT_MASTER, master,
-				BT_IO_OPT_INVALID);
-	if (!io) {
-		error("%s", err->message);
-		g_error_free(err);
-	}
+	avdtp_server_destroy(server);
 
-	return io;
+	return 0;
 }
 
 const char *avdtp_strerror(struct avdtp_error *err)
@@ -3823,43 +3862,6 @@ struct btd_device *avdtp_get_device(struct avdtp *session)
 	return session->device;
 }
 
-int avdtp_init(struct btd_adapter *adapter)
-{
-	struct avdtp_server *server;
-
-	server = g_new0(struct avdtp_server, 1);
-
-	server->io = avdtp_server_socket(adapter_get_address(adapter), TRUE);
-	if (!server->io) {
-		g_free(server);
-		return -1;
-	}
-
-	server->adapter = btd_adapter_ref(adapter);
-
-	servers = g_slist_append(servers, server);
-
-	return 0;
-}
-
-void avdtp_exit(struct btd_adapter *adapter)
-{
-	struct avdtp_server *server;
-
-	server = find_server(servers, adapter);
-	if (!server)
-		return;
-
-	g_slist_free_full(server->sessions, avdtp_free);
-
-	servers = g_slist_remove(servers, server);
-
-	g_io_channel_shutdown(server->io, TRUE, NULL);
-	g_io_channel_unref(server->io);
-	btd_adapter_unref(server->adapter);
-	g_free(server);
-}
-
 gboolean avdtp_has_stream(struct avdtp *session, struct avdtp_stream *stream)
 {
 	return g_slist_find(session->streams, stream) ? TRUE : FALSE;
diff --git a/profiles/audio/avdtp.h b/profiles/audio/avdtp.h
index 3bf7503..5606506 100644
--- a/profiles/audio/avdtp.h
+++ b/profiles/audio/avdtp.h
@@ -308,6 +308,3 @@ struct btd_adapter *avdtp_get_adapter(struct avdtp *session);
 struct btd_device *avdtp_get_device(struct avdtp *session);
 
 void avdtp_set_device_disconnect(struct avdtp *session, gboolean dev_dc);
-
-int avdtp_init(struct btd_adapter *adapter);
-void avdtp_exit(struct btd_adapter *adapter);
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH BlueZ] audio/AVDTP: Remove avdtp_init and avdtp_exit
From: Luiz Augusto von Dentz @ 2013-11-11 15:34 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org
In-Reply-To: <1384179100-11209-1-git-send-email-luiz.dentz@gmail.com>

Hi,

On Mon, Nov 11, 2013 at 4:11 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> This is now done on demand by avdtp_register_sep and avdtp_unregister_sep
> so the server socket is only registered when there is an endpoint
> available and the record is properly registered.
> ---
>  profiles/audio/a2dp.c  |  11 -----
>  profiles/audio/avdtp.c | 118 +++++++++++++++++++++++++------------------------
>  profiles/audio/avdtp.h |   3 --
>  3 files changed, 60 insertions(+), 72 deletions(-)
>
> diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
> index 8477b5d..6b3d6b2 100644
> --- a/profiles/audio/a2dp.c
> +++ b/profiles/audio/a2dp.c
> @@ -1187,17 +1187,8 @@ static struct a2dp_server *find_server(GSList *list, struct btd_adapter *a)
>  static struct a2dp_server *a2dp_server_register(struct btd_adapter *adapter)
>  {
>         struct a2dp_server *server;
> -       int av_err;
>
>         server = g_new0(struct a2dp_server, 1);
> -
> -       av_err = avdtp_init(adapter);
> -       if (av_err < 0) {
> -               DBG("AVDTP not registered");
> -               g_free(server);
> -               return NULL;
> -       }
> -
>         server->adapter = btd_adapter_ref(adapter);
>         servers = g_slist_append(servers, server);
>
> @@ -1217,8 +1208,6 @@ static void a2dp_unregister_sep(struct a2dp_sep *sep)
>
>  static void a2dp_server_unregister(struct a2dp_server *server)
>  {
> -       avdtp_exit(server->adapter);
> -
>         servers = g_slist_remove(servers, server);
>         btd_adapter_unref(server->adapter);
>         g_free(server);
> diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
> index dab8f1c..9a470f1 100644
> --- a/profiles/audio/avdtp.c
> +++ b/profiles/audio/avdtp.c
> @@ -3683,6 +3683,45 @@ int avdtp_delay_report(struct avdtp *session, struct avdtp_stream *stream,
>                                                         &req, sizeof(req));
>  }
>
> +static GIOChannel *avdtp_server_socket(const bdaddr_t *src, gboolean master)
> +{
> +       GError *err = NULL;
> +       GIOChannel *io;
> +
> +       io = bt_io_listen(NULL, avdtp_confirm_cb,
> +                               NULL, NULL, &err,
> +                               BT_IO_OPT_SOURCE_BDADDR, src,
> +                               BT_IO_OPT_PSM, AVDTP_PSM,
> +                               BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
> +                               BT_IO_OPT_MASTER, master,
> +                               BT_IO_OPT_INVALID);
> +       if (!io) {
> +               error("%s", err->message);
> +               g_error_free(err);
> +       }
> +
> +       return io;
> +}
> +
> +static struct avdtp_server *avdtp_server_init(struct btd_adapter *adapter)
> +{
> +       struct avdtp_server *server;
> +
> +       server = g_new0(struct avdtp_server, 1);
> +
> +       server->io = avdtp_server_socket(adapter_get_address(adapter), TRUE);
> +       if (!server->io) {
> +               g_free(server);
> +               return NULL;
> +       }
> +
> +       server->adapter = btd_adapter_ref(adapter);
> +
> +       servers = g_slist_append(servers, server);
> +
> +       return 0;
> +}
> +
>  struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
>                                                 uint8_t type,
>                                                 uint8_t media_type,
> @@ -3696,8 +3735,11 @@ struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
>         struct avdtp_local_sep *sep;
>
>         server = find_server(servers, adapter);
> -       if (!server)
> -               return NULL;
> +       if (!server) {
> +               server = avdtp_server_init(adapter);
> +               if (!server)
> +                       return NULL;
> +       }
>
>         if (g_slist_length(server->seps) > MAX_SEID)
>                 return NULL;
> @@ -3722,6 +3764,18 @@ struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
>         return sep;
>  }
>
> +static void avdtp_server_destroy(struct avdtp_server *server)
> +{
> +       g_slist_free_full(server->sessions, avdtp_free);
> +
> +       servers = g_slist_remove(servers, server);
> +
> +       g_io_channel_shutdown(server->io, TRUE, NULL);
> +       g_io_channel_unref(server->io);
> +       btd_adapter_unref(server->adapter);
> +       g_free(server);
> +}
> +
>  int avdtp_unregister_sep(struct avdtp_local_sep *sep)
>  {
>         struct avdtp_server *server;
> @@ -3740,27 +3794,12 @@ int avdtp_unregister_sep(struct avdtp_local_sep *sep)
>
>         g_free(sep);
>
> -       return 0;
> -}
> -
> -static GIOChannel *avdtp_server_socket(const bdaddr_t *src, gboolean master)
> -{
> -       GError *err = NULL;
> -       GIOChannel *io;
> +       if (server->seps)
> +               return 0;
>
> -       io = bt_io_listen(NULL, avdtp_confirm_cb,
> -                               NULL, NULL, &err,
> -                               BT_IO_OPT_SOURCE_BDADDR, src,
> -                               BT_IO_OPT_PSM, AVDTP_PSM,
> -                               BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
> -                               BT_IO_OPT_MASTER, master,
> -                               BT_IO_OPT_INVALID);
> -       if (!io) {
> -               error("%s", err->message);
> -               g_error_free(err);
> -       }
> +       avdtp_server_destroy(server);
>
> -       return io;
> +       return 0;
>  }
>
>  const char *avdtp_strerror(struct avdtp_error *err)
> @@ -3823,43 +3862,6 @@ struct btd_device *avdtp_get_device(struct avdtp *session)
>         return session->device;
>  }
>
> -int avdtp_init(struct btd_adapter *adapter)
> -{
> -       struct avdtp_server *server;
> -
> -       server = g_new0(struct avdtp_server, 1);
> -
> -       server->io = avdtp_server_socket(adapter_get_address(adapter), TRUE);
> -       if (!server->io) {
> -               g_free(server);
> -               return -1;
> -       }
> -
> -       server->adapter = btd_adapter_ref(adapter);
> -
> -       servers = g_slist_append(servers, server);
> -
> -       return 0;
> -}
> -
> -void avdtp_exit(struct btd_adapter *adapter)
> -{
> -       struct avdtp_server *server;
> -
> -       server = find_server(servers, adapter);
> -       if (!server)
> -               return;
> -
> -       g_slist_free_full(server->sessions, avdtp_free);
> -
> -       servers = g_slist_remove(servers, server);
> -
> -       g_io_channel_shutdown(server->io, TRUE, NULL);
> -       g_io_channel_unref(server->io);
> -       btd_adapter_unref(server->adapter);
> -       g_free(server);
> -}
> -
>  gboolean avdtp_has_stream(struct avdtp *session, struct avdtp_stream *stream)
>  {
>         return g_slist_find(session->streams, stream) ? TRUE : FALSE;
> diff --git a/profiles/audio/avdtp.h b/profiles/audio/avdtp.h
> index 3bf7503..5606506 100644
> --- a/profiles/audio/avdtp.h
> +++ b/profiles/audio/avdtp.h
> @@ -308,6 +308,3 @@ struct btd_adapter *avdtp_get_adapter(struct avdtp *session);
>  struct btd_device *avdtp_get_device(struct avdtp *session);
>
>  void avdtp_set_device_disconnect(struct avdtp *session, gboolean dev_dc);
> -
> -int avdtp_init(struct btd_adapter *adapter);
> -void avdtp_exit(struct btd_adapter *adapter);
> --
> 1.8.3.1

There is apparently a bug in this one, well send a v2 shortly.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH 4/4] android/pan: Handle connection and control state notifications
From: Ravi kumar Veeramally @ 2013-11-11 14:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1384181621-8070-1-git-send-email-ravikumar.veeramally@linux.intel.com>

---
 android/hal-pan.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/android/hal-pan.c b/android/hal-pan.c
index 76f5159..4173925 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -31,10 +31,41 @@ static bool interface_ready(void)
 	return cbs != NULL;
 }
 
+static void handle_conn_state(void *buf)
+{
+	struct hal_ev_pan_conn_state *ev = buf;
+
+	if (cbs->connection_state_cb)
+		cbs->connection_state_cb(ev->state, ev->status,
+					(bt_bdaddr_t *) ev->bdaddr,
+					ev->local_role, ev->remote_role);
+}
+
+static void handle_ctrl_state(void *buf)
+{
+	struct hal_ev_pan_ctrl_state *ev = buf;
+
+	if (cbs->control_state_cb)
+		cbs->control_state_cb(ev->state, ev->status,
+					ev->local_role, (char *)ev->name);
+}
+
 void bt_notify_pan(uint16_t opcode, void *buf, uint16_t len)
 {
 	if (!interface_ready())
 		return;
+
+	switch (opcode) {
+	case HAL_EV_PAN_CONN_STATE:
+		handle_conn_state(buf);
+		break;
+	case HAL_EV_PAN_CTRL_STATE:
+		handle_ctrl_state(buf);
+		break;
+	default:
+		DBG("Unhandled callback opcode=0x%x", opcode);
+		break;
+	}
 }
 
 static bt_status_t pan_enable(int local_role)
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 3/4] android/pan: Add notify method to PAN notifications
From: Ravi kumar Veeramally @ 2013-11-11 14:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1384181621-8070-1-git-send-email-ravikumar.veeramally@linux.intel.com>

---
 android/hal-pan.c | 6 ++++++
 android/hal.h     | 1 +
 2 files changed, 7 insertions(+)

diff --git a/android/hal-pan.c b/android/hal-pan.c
index a560055..76f5159 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -31,6 +31,12 @@ static bool interface_ready(void)
 	return cbs != NULL;
 }
 
+void bt_notify_pan(uint16_t opcode, void *buf, uint16_t len)
+{
+	if (!interface_ready())
+		return;
+}
+
 static bt_status_t pan_enable(int local_role)
 {
 	struct hal_cmd_pan_enable cmd;
diff --git a/android/hal.h b/android/hal.h
index 2ce7932..be5d491 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -31,3 +31,4 @@ void bt_thread_associate(void);
 void bt_thread_disassociate(void);
 void bt_notify_hidhost(uint16_t opcode, void *buf, uint16_t len);
 void bt_notify_a2dp(uint16_t opcode, void *buf, uint16_t len);
+void bt_notify_pan(uint16_t opcode, void *buf, uint16_t len);
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 2/4] android/pan: Add PAN cleanup interface implementation
From: Ravi kumar Veeramally @ 2013-11-11 14:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1384181621-8070-1-git-send-email-ravikumar.veeramally@linux.intel.com>

---
 android/hal-pan.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/android/hal-pan.c b/android/hal-pan.c
index cacc6c0..a560055 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -114,16 +114,18 @@ static bt_status_t pan_init(const btpan_callbacks_t *callbacks)
 
 static void pan_cleanup()
 {
+	struct hal_cmd_register_module cmd;
+
 	DBG("");
 
 	if (!interface_ready())
 		return;
 
-	/* TODO: disable service */
-
-	/* TODO: stop PAN thread */
-
 	cbs = NULL;
+	cmd.service_id = HAL_SERVICE_ID_PAN;
+
+	hal_ipc_cmd(HAL_SERVICE_ID_PAN, HAL_OP_UNREGISTER_MODULE,
+					sizeof(cmd), &cmd, 0, NULL, NULL);
 }
 
 static btpan_interface_t pan_if = {
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 1/4] android/pan: Add PAN related defines and event struct to hsl-msg header
From: Ravi kumar Veeramally @ 2013-11-11 14:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1384181621-8070-1-git-send-email-ravikumar.veeramally@linux.intel.com>

---
 android/hal-msg.h | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index 569c8ea..00d6e39 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -317,6 +317,33 @@ struct hal_cmd_a2dp_disconnect {
 
 /* PAN HAL API */
 
+/* PAN Roles */
+#define HAL_PAN_ROLE_NONE	0x00
+#define HAL_PAN_ROLE_NAP	0x01
+#define HAL_PAN_ROLE_PANU	0x02
+
+/* PAN Control states */
+#define HAL_PAN_CTRL_ENABLED	0x00
+#define HAL_PAN_CTRL_DISABLED	0x01
+
+/* PAN Connection states */
+#define HAL_PAN_STATE_CONNECTED		0x00
+#define HAL_PAN_STATE_CONNECTING	0x01
+#define HAL_PAN_STATE_DISCONNECTED	0x02
+#define HAL_PAN_STATE_DISCONNECTING	0x03
+
+/* PAN status values */
+#define HAL_PAN_STATUS_FAIL		0x01
+#define HAL_PAN_STATUS_NOT_READY	0x02
+#define HAL_PAN_STATUS_NO_MEMORY	0x03
+#define HAL_PAN_STATUS_BUSY		0x04
+#define HAL_PAN_STATUS_DONE		0x05
+#define HAL_PAN_STATUS_UNSUPORTED	0x06
+#define HAL_PAN_STATUS_INVAL		0x07
+#define HAL_PAN_STATUS_UNHANDLED	0x08
+#define HAL_PAN_STATUS_AUTH_FAILED	0x09
+#define HAL_PAN_STATUS_DEVICE_DOWN	0x0A
+
 #define HAL_OP_PAN_ENABLE	0x01
 struct hal_cmd_pan_enable {
 	uint8_t local_role;
@@ -486,6 +513,23 @@ struct hal_ev_hidhost_virtual_unplug {
 	uint8_t  status;
 } __attribute__((packed));
 
+#define HAL_EV_PAN_CONN_STATE			0x81
+struct hal_ev_pan_conn_state {
+	uint8_t  state;
+	uint8_t  status;
+	uint8_t  bdaddr[6];
+	uint8_t  local_role;
+	uint8_t  remote_role;
+} __attribute__((packed));
+
+#define HAL_EV_PAN_CTRL_STATE			0x82
+struct hal_ev_pan_ctrl_state {
+	uint8_t  state;
+	uint8_t  status;
+	uint8_t  local_role;
+	uint8_t  name[17];
+} __attribute__((packed));
+
 #define HAL_EV_A2DP_CONNECTION_STATE	0x81
 struct hal_ev_a2dp_connection_state {
 	uint8_t state;
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 0/4] Implement missing PAN interface and notifications
From: Ravi kumar Veeramally @ 2013-11-11 14:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

Patch set implements missing cleanup interface and adds event structs
to hal-msg.h and implements connection and control state notifications.

Ravi kumar Veeramally (4):
  android/pan: Add PAN related defines and event struct to hsl-msg
    header
  android/pan: Add PAN cleanup interface implementation
  android/pan: Add notify method to PAN notifications
  android/pan: Handle connection and control state notifications

 android/hal-msg.h | 44 ++++++++++++++++++++++++++++++++++++++++++++
 android/hal-pan.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
 android/hal.h     |  1 +
 3 files changed, 88 insertions(+), 4 deletions(-)

-- 
1.8.3.2


^ permalink raw reply

* [PATCH BlueZ] audio/AVDTP: Remove avdtp_init and avdtp_exit
From: Luiz Augusto von Dentz @ 2013-11-11 14:11 UTC (permalink / raw)
  To: linux-bluetooth

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

This is now done on demand by avdtp_register_sep and avdtp_unregister_sep
so the server socket is only registered when there is an endpoint
available and the record is properly registered.
---
 profiles/audio/a2dp.c  |  11 -----
 profiles/audio/avdtp.c | 118 +++++++++++++++++++++++++------------------------
 profiles/audio/avdtp.h |   3 --
 3 files changed, 60 insertions(+), 72 deletions(-)

diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index 8477b5d..6b3d6b2 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -1187,17 +1187,8 @@ static struct a2dp_server *find_server(GSList *list, struct btd_adapter *a)
 static struct a2dp_server *a2dp_server_register(struct btd_adapter *adapter)
 {
 	struct a2dp_server *server;
-	int av_err;
 
 	server = g_new0(struct a2dp_server, 1);
-
-	av_err = avdtp_init(adapter);
-	if (av_err < 0) {
-		DBG("AVDTP not registered");
-		g_free(server);
-		return NULL;
-	}
-
 	server->adapter = btd_adapter_ref(adapter);
 	servers = g_slist_append(servers, server);
 
@@ -1217,8 +1208,6 @@ static void a2dp_unregister_sep(struct a2dp_sep *sep)
 
 static void a2dp_server_unregister(struct a2dp_server *server)
 {
-	avdtp_exit(server->adapter);
-
 	servers = g_slist_remove(servers, server);
 	btd_adapter_unref(server->adapter);
 	g_free(server);
diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index dab8f1c..9a470f1 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -3683,6 +3683,45 @@ int avdtp_delay_report(struct avdtp *session, struct avdtp_stream *stream,
 							&req, sizeof(req));
 }
 
+static GIOChannel *avdtp_server_socket(const bdaddr_t *src, gboolean master)
+{
+	GError *err = NULL;
+	GIOChannel *io;
+
+	io = bt_io_listen(NULL, avdtp_confirm_cb,
+				NULL, NULL, &err,
+				BT_IO_OPT_SOURCE_BDADDR, src,
+				BT_IO_OPT_PSM, AVDTP_PSM,
+				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+				BT_IO_OPT_MASTER, master,
+				BT_IO_OPT_INVALID);
+	if (!io) {
+		error("%s", err->message);
+		g_error_free(err);
+	}
+
+	return io;
+}
+
+static struct avdtp_server *avdtp_server_init(struct btd_adapter *adapter)
+{
+	struct avdtp_server *server;
+
+	server = g_new0(struct avdtp_server, 1);
+
+	server->io = avdtp_server_socket(adapter_get_address(adapter), TRUE);
+	if (!server->io) {
+		g_free(server);
+		return NULL;
+	}
+
+	server->adapter = btd_adapter_ref(adapter);
+
+	servers = g_slist_append(servers, server);
+
+	return 0;
+}
+
 struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
 						uint8_t type,
 						uint8_t media_type,
@@ -3696,8 +3735,11 @@ struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
 	struct avdtp_local_sep *sep;
 
 	server = find_server(servers, adapter);
-	if (!server)
-		return NULL;
+	if (!server) {
+		server = avdtp_server_init(adapter);
+		if (!server)
+			return NULL;
+	}
 
 	if (g_slist_length(server->seps) > MAX_SEID)
 		return NULL;
@@ -3722,6 +3764,18 @@ struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
 	return sep;
 }
 
+static void avdtp_server_destroy(struct avdtp_server *server)
+{
+	g_slist_free_full(server->sessions, avdtp_free);
+
+	servers = g_slist_remove(servers, server);
+
+	g_io_channel_shutdown(server->io, TRUE, NULL);
+	g_io_channel_unref(server->io);
+	btd_adapter_unref(server->adapter);
+	g_free(server);
+}
+
 int avdtp_unregister_sep(struct avdtp_local_sep *sep)
 {
 	struct avdtp_server *server;
@@ -3740,27 +3794,12 @@ int avdtp_unregister_sep(struct avdtp_local_sep *sep)
 
 	g_free(sep);
 
-	return 0;
-}
-
-static GIOChannel *avdtp_server_socket(const bdaddr_t *src, gboolean master)
-{
-	GError *err = NULL;
-	GIOChannel *io;
+	if (server->seps)
+		return 0;
 
-	io = bt_io_listen(NULL, avdtp_confirm_cb,
-				NULL, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, src,
-				BT_IO_OPT_PSM, AVDTP_PSM,
-				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-				BT_IO_OPT_MASTER, master,
-				BT_IO_OPT_INVALID);
-	if (!io) {
-		error("%s", err->message);
-		g_error_free(err);
-	}
+	avdtp_server_destroy(server);
 
-	return io;
+	return 0;
 }
 
 const char *avdtp_strerror(struct avdtp_error *err)
@@ -3823,43 +3862,6 @@ struct btd_device *avdtp_get_device(struct avdtp *session)
 	return session->device;
 }
 
-int avdtp_init(struct btd_adapter *adapter)
-{
-	struct avdtp_server *server;
-
-	server = g_new0(struct avdtp_server, 1);
-
-	server->io = avdtp_server_socket(adapter_get_address(adapter), TRUE);
-	if (!server->io) {
-		g_free(server);
-		return -1;
-	}
-
-	server->adapter = btd_adapter_ref(adapter);
-
-	servers = g_slist_append(servers, server);
-
-	return 0;
-}
-
-void avdtp_exit(struct btd_adapter *adapter)
-{
-	struct avdtp_server *server;
-
-	server = find_server(servers, adapter);
-	if (!server)
-		return;
-
-	g_slist_free_full(server->sessions, avdtp_free);
-
-	servers = g_slist_remove(servers, server);
-
-	g_io_channel_shutdown(server->io, TRUE, NULL);
-	g_io_channel_unref(server->io);
-	btd_adapter_unref(server->adapter);
-	g_free(server);
-}
-
 gboolean avdtp_has_stream(struct avdtp *session, struct avdtp_stream *stream)
 {
 	return g_slist_find(session->streams, stream) ? TRUE : FALSE;
diff --git a/profiles/audio/avdtp.h b/profiles/audio/avdtp.h
index 3bf7503..5606506 100644
--- a/profiles/audio/avdtp.h
+++ b/profiles/audio/avdtp.h
@@ -308,6 +308,3 @@ struct btd_adapter *avdtp_get_adapter(struct avdtp *session);
 struct btd_device *avdtp_get_device(struct avdtp *session);
 
 void avdtp_set_device_disconnect(struct avdtp *session, gboolean dev_dc);
-
-int avdtp_init(struct btd_adapter *adapter);
-void avdtp_exit(struct btd_adapter *adapter);
-- 
1.8.3.1


^ permalink raw reply related

* [RFCv1 9/9] android/hal-sock: Write channel to Android fd
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

---
 android/socket.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 20f4e38..0188646 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -27,6 +27,7 @@
 
 #include <glib.h>
 #include <stdbool.h>
+#include <unistd.h>
 #include <errno.h>
 
 #include "lib/bluetooth.h"
@@ -292,6 +293,10 @@ static int handle_listen(void *buf)
 	rfslot->real_sock = g_io_channel_unix_get_fd(io);
 	rfcomm_srv_list = g_list_append(rfcomm_srv_list, rfslot);
 
+	/* TODO: Check this */
+	if (write(rfslot->fd, &ch, sizeof(ch)) < 0)
+		return -1;
+
 	DBG("real_sock %d fd %d hal_fd %d",
 				rfslot->real_sock, rfslot->fd, rfslot->hal_fd);
 
-- 
1.7.10.4


^ permalink raw reply related

* [RFCv1 8/9] android/hal-sock: Implement accept signal over Android fd
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Android expects to get accept signal over file descriptor which was
set during listen HAL call.
---
 android/socket.c |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index a962cdc..20f4e38 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -36,6 +36,7 @@
 #include "hal-ipc.h"
 #include "ipc.h"
 #include "adapter.h"
+#include "utils.h"
 #include "socket.h"
 
 /* Simple list of RFCOMM server sockets */
@@ -68,6 +69,45 @@ static struct rfcomm_slot *create_rfslot(int sock)
 	return rfslot;
 }
 
+static int bt_sock_send_fd(int sock_fd, const void *buf, int len, int send_fd)
+{
+	ssize_t ret;
+	struct msghdr msg;
+	struct cmsghdr *cmsg;
+	struct iovec iv;
+	char msgbuf[CMSG_SPACE(1)];
+
+	DBG("len %d sock_fd %d send_fd %d", len, sock_fd, send_fd);
+
+	if (sock_fd == -1 || send_fd == -1)
+		return -1;
+
+	memset(&msg, 0, sizeof(msg));
+
+	msg.msg_control = msgbuf;
+	msg.msg_controllen = sizeof(msgbuf);
+	cmsg = CMSG_FIRSTHDR(&msg);
+	cmsg->cmsg_level = SOL_SOCKET;
+	cmsg->cmsg_type = SCM_RIGHTS;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(send_fd));
+	memcpy(CMSG_DATA(cmsg), &send_fd, sizeof(send_fd));
+
+	iv.iov_base = (unsigned char *) buf;
+	iv.iov_len = len;
+
+	msg.msg_iov = &iv;
+	msg.msg_iovlen = 1;
+
+	ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL);
+	if (ret < 0) {
+		error("sendmsg(): sock_fd %d send_fd %d: %s",
+					sock_fd, send_fd, strerror(errno));
+		return ret;
+	}
+
+	return ret;
+}
+
 static const uint8_t UUID_PBAP[] = {
 	0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
 	0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
@@ -161,6 +201,21 @@ static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
 	return TRUE;
 }
 
+static void socket_send_accept(struct rfcomm_slot *rfslot, bdaddr_t *bdaddr,
+							int fd_accepted)
+{
+	struct hal_sock_connect_signal cmd;
+
+	DBG("");
+
+	cmd.size = sizeof(cmd);
+	bdaddr2android(bdaddr, cmd.bdaddr);
+	cmd.channel = rfslot->channel;
+	cmd.status = 0;
+
+	bt_sock_send_fd(rfslot->fd, &cmd, sizeof(cmd), fd_accepted);
+}
+
 static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
 {
 	struct rfcomm_slot *rfslot = user_data;
@@ -190,6 +245,8 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
 	rfslot_acc = create_rfslot(sock_acc);
 	rfcomm_accepted_list = g_list_append(rfcomm_accepted_list, rfslot_acc);
 
+	socket_send_accept(rfslot, &dst, rfslot_acc->hal_fd);
+
 	/* Handle events from Android */
 	io_stack = g_io_channel_unix_new(rfslot_acc->fd);
 	g_io_add_watch(io_stack, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-- 
1.7.10.4


^ permalink raw reply related

* [RFCv1 7/9] android/hal-sock: Implement RFCOMM events
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Copy data from RFCOMM socket to Android framework.
---
 android/socket.c |   29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index dfad9da..a962cdc 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -129,6 +129,35 @@ static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
 static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
 								gpointer data)
 {
+	struct rfcomm_slot *rfslot = data;
+	unsigned char buf[1024] = { 0 };
+	int len;
+
+	DBG("rfslot: fd %d hal_fd %d real_sock %d chan %u sock %d",
+		rfslot->fd, rfslot->hal_fd, rfslot->real_sock, rfslot->channel,
+		g_io_channel_unix_get_fd(io));
+
+	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);
+		g_io_channel_shutdown(io, TRUE, NULL);
+		return FALSE;
+	}
+
+	/* FIXME check real_sock vs sock(io) */
+	len = recv(rfslot->real_sock, buf, sizeof(buf), 0);
+	if (len <= 0) {
+		error("recv(): %s sock %d", strerror(errno), rfslot->real_sock);
+		return FALSE;
+	}
+
+	DBG("read %d bytes, write to fd %d", len, rfslot->fd);
+
+	if (send(rfslot->fd, buf, len, MSG_DONTWAIT) < 0) {
+		error("send(): %s sock %d", strerror(errno), rfslot->fd);
+		return FALSE;
+	}
+
 	return TRUE;
 }
 
-- 
1.7.10.4


^ permalink raw reply related

* [RFCv1 6/9] android/hal-sock: Implement Android RFCOMM stack events
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Handle events from Android framework. Write everything to real RFCOMM
socket.
---
 android/socket.c |   29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 0ee53ba..dfad9da 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -94,6 +94,35 @@ static int get_rfcomm_chan(const uint8_t *uuid)
 static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
 								gpointer data)
 {
+	struct rfcomm_slot *rfslot = data;
+	unsigned char buf[1024] = { 0 };
+	int len;
+
+	DBG("rfslot: fd %d hal_fd %d real_sock %d chan %u sock %d",
+		rfslot->fd, rfslot->hal_fd, rfslot->real_sock, rfslot->channel,
+		g_io_channel_unix_get_fd(io));
+
+	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);
+		g_io_channel_shutdown(io, TRUE, NULL);
+		return FALSE;
+	}
+
+	/* FIXME check fd vs sock(io) */
+	len = recv(rfslot->fd, buf, sizeof(buf), 0);
+	if (len <= 0) {
+		error("recv(): %s", strerror(errno));
+		return FALSE;
+	}
+
+	DBG("read %d bytes write to %d", len, rfslot->real_sock);
+
+	if (send(rfslot->real_sock, buf, len, 0) < 0) {
+		error("send(): %s", strerror(errno));
+		return FALSE;
+	}
+
 	return TRUE;
 }
 
-- 
1.7.10.4


^ permalink raw reply related

* [RFCv1 5/9] android/hal-sock: Implement socket accepted event
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

When we get accepted event we create rfcomm slot and start listening
for events from Android framework and from RFCOMM real socket.
---
 android/socket.c |   50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 80cb39e..0ee53ba 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -91,8 +91,58 @@ static int get_rfcomm_chan(const uint8_t *uuid)
 	return -1;
 }
 
+static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
+								gpointer data)
+{
+	return TRUE;
+}
+
+static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
+								gpointer data)
+{
+	return TRUE;
+}
+
 static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
 {
+	struct rfcomm_slot *rfslot = user_data;
+	struct rfcomm_slot *rfslot_acc;
+	GIOChannel *io_stack;
+	bdaddr_t dst;
+	char address[18];
+	int sock_acc;
+
+	bt_io_get(io, &err,
+			BT_IO_OPT_DEST_BDADDR, &dst,
+			BT_IO_OPT_INVALID);
+	if (err) {
+		error("%s", err->message);
+		g_io_channel_shutdown(io, TRUE, NULL);
+		return;
+	}
+
+	ba2str(&dst, address);
+	DBG("Incoming connection from %s rfslot %p", address, rfslot);
+
+	DBG("rfslot: fd %d hal_fd %d real_sock %d chan %u sock %d",
+		rfslot->fd, rfslot->hal_fd, rfslot->real_sock, rfslot->channel,
+		g_io_channel_unix_get_fd(io));
+
+	sock_acc = g_io_channel_unix_get_fd(io);
+	rfslot_acc = create_rfslot(sock_acc);
+	rfcomm_accepted_list = g_list_append(rfcomm_accepted_list, rfslot_acc);
+
+	/* Handle events from Android */
+	io_stack = g_io_channel_unix_new(rfslot_acc->fd);
+	g_io_add_watch(io_stack, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+					sock_stack_event_cb, rfslot_acc);
+	g_io_channel_unref(io_stack);
+
+	/* Handle rfcomm events */
+	g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+				sock_rfcomm_event_cb, rfslot_acc);
+
+	DBG("rfslot %p rfslot_acc %p", rfslot, rfslot_acc);
 }
 
 static int handle_listen(void *buf)
-- 
1.7.10.4


^ permalink raw reply related

* [RFCv1 4/9] android/hal-sock: Initial listen handle
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Handle HAL socket listen call. Create RFCOMM socket and wait for events.
---
 android/socket.c |   94 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 92 insertions(+), 2 deletions(-)

diff --git a/android/socket.c b/android/socket.c
index c283c5f..80cb39e 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -27,22 +27,112 @@
 
 #include <glib.h>
 #include <stdbool.h>
+#include <errno.h>
 
 #include "lib/bluetooth.h"
+#include "btio/btio.h"
 #include "log.h"
 #include "hal-msg.h"
 #include "hal-ipc.h"
 #include "ipc.h"
+#include "adapter.h"
 #include "socket.h"
 
+/* Simple list of RFCOMM server sockets */
+GList *rfcomm_srv_list = NULL;
+/* Simple list of RFCOMM accepted sockets */
+GList *rfcomm_accepted_list = NULL;
 
-static int handle_listen(void *buf)
+struct rfcomm_slot {
+	int fd;
+	int hal_fd;
+	int real_sock;
+	uint32_t channel;
+};
+
+static struct rfcomm_slot *create_rfslot(int sock)
 {
-	DBG("Not implemented");
+	int fds[2] = {-1, -1};
+	struct rfcomm_slot *rfslot;
+
+	if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) < 0) {
+		error("socketpair(): %s", strerror(errno));
+		return NULL;
+	}
+
+	rfslot = g_malloc0(sizeof(*rfslot));
+	rfslot->fd = fds[0];
+	rfslot->hal_fd = fds[1];
+	rfslot->real_sock = sock;
+
+	return rfslot;
+}
+
+static const uint8_t UUID_PBAP[] = {
+	0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
+	0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
+};
+#define RFCOMM_CHAN_PBAP 19
+
+static const uint8_t UUID_OPP[] = {
+	0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
+	0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
+};
+#define RFCOMM_CHAN_OPP 12
+
+static int get_rfcomm_chan(const uint8_t *uuid)
+{
+	if (!memcmp(UUID_PBAP, uuid, sizeof(UUID_PBAP)))
+		return RFCOMM_CHAN_PBAP;
+
+	if (!memcmp(UUID_OPP, uuid, sizeof(UUID_OPP)))
+		return RFCOMM_CHAN_OPP;
 
 	return -1;
 }
 
+static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
+{
+}
+
+static int handle_listen(void *buf)
+{
+	struct hal_cmd_sock_listen *cmd = buf;
+	const bdaddr_t *src = bt_adapter_get_address();
+	struct rfcomm_slot *rfslot;
+	GIOChannel *io;
+	GError *err = NULL;
+	int ch;
+
+	DBG("");
+
+	ch = get_rfcomm_chan(cmd->uuid);
+	if (ch < 0)
+		return -1;
+
+	DBG("rfcomm channel %u", ch);
+
+	rfslot = create_rfslot(-1);
+
+	io = bt_io_listen(connect_cb, NULL, rfslot, NULL, &err,
+				BT_IO_OPT_SOURCE_BDADDR, src,
+				BT_IO_OPT_CHANNEL, ch,
+				BT_IO_OPT_INVALID);
+	if (!io) {
+		error("Failed listen: %s", err->message);
+		g_error_free(err);
+		return -1;
+	}
+
+	rfslot->real_sock = g_io_channel_unix_get_fd(io);
+	rfcomm_srv_list = g_list_append(rfcomm_srv_list, rfslot);
+
+	DBG("real_sock %d fd %d hal_fd %d",
+				rfslot->real_sock, rfslot->fd, rfslot->hal_fd);
+
+	return rfslot->hal_fd;
+}
+
 static int handle_connect(void *buf)
 {
 	DBG("Not implemented");
-- 
1.7.10.4


^ permalink raw reply related

* [RFCv1 3/9] android/ahl-sock: Add connect signal to socket
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Connect signal is used to pass information to framework that socket
is accepted.
---
 android/hal-msg.h |    2 ++
 android/socket.h  |    7 +++++++
 2 files changed, 9 insertions(+)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index 569c8ea..68cc8ed 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -232,6 +232,8 @@ struct hal_cmd_sock_connect {
 	uint8_t  flags;
 } __attribute__((packed));
 
+/* Bluetooth Hidhost HAL api */
+
 #define HAL_OP_HIDHOST_CONNECT		0x01
 struct hal_cmd_hidhost_connect {
 	uint8_t bdaddr[6];
diff --git a/android/socket.h b/android/socket.h
index 7aa5574..ba56c9b 100644
--- a/android/socket.h
+++ b/android/socket.h
@@ -21,6 +21,13 @@
  *
  */
 
+struct hal_sock_connect_signal {
+	short   size;
+	uint8_t bdaddr[6];
+	int     channel;
+	int     status;
+} __attribute__((packed));
+
 void bt_sock_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len);
 
 bool bt_socket_register(int sk, const bdaddr_t *addr);
-- 
1.7.10.4


^ permalink raw reply related

* [RFCv1 2/9] android: Avoid unneeded includes
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Declare struct mgmt in adapter.h. This avoids including mgmt.h in
every file using adapter functions like socket and hid.
---
 android/adapter.h |    2 ++
 android/hidhost.c |    1 -
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/android/adapter.h b/android/adapter.h
index c62b859..3bda9d9 100644
--- a/android/adapter.h
+++ b/android/adapter.h
@@ -23,6 +23,8 @@
 
 typedef void (*bt_adapter_ready)(int err);
 
+struct mgmt;
+
 void bt_adapter_init(uint16_t index, struct mgmt *mgmt_if,
 							bt_adapter_ready cb);
 
diff --git a/android/hidhost.c b/android/hidhost.c
index 683938f..8c3e9f6 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -38,7 +38,6 @@
 #include "lib/sdp.h"
 #include "lib/sdp_lib.h"
 #include "lib/uuid.h"
-#include "src/shared/mgmt.h"
 #include "src/sdp-client.h"
 #include "src/glib-helper.h"
 #include "profiles/input/uhid_copy.h"
-- 
1.7.10.4


^ permalink raw reply related

* [RFCv1 1/9] android/hal-sock: Add debug flag printing
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

---
 android/hal-sock.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/android/hal-sock.c b/android/hal-sock.c
index b7bc88e..eafa451 100644
--- a/android/hal-sock.c
+++ b/android/hal-sock.c
@@ -55,8 +55,8 @@ static bt_status_t sock_listen(btsock_type_t type, const char *service_name,
 		return BT_STATUS_PARM_INVALID;
 	}
 
-	DBG("uuid %s chan %d sock %p type %d service_name %s",
-			btuuid2str(uuid), chan, sock, type, service_name);
+	DBG("uuid %s chan %d sock %p type %d service_name %s flags 0x%02x",
+		btuuid2str(uuid), chan, sock, type, service_name, flags);
 
 	switch (type) {
 	case BTSOCK_RFCOMM:
@@ -82,8 +82,8 @@ static bt_status_t sock_connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
 		return BT_STATUS_PARM_INVALID;
 	}
 
-	DBG("uuid %s chan %d sock %p type %d", btuuid2str(uuid), chan, sock,
-									type);
+	DBG("uuid %s chan %d sock %p type %d flags 0x%02x",
+		btuuid2str(uuid), chan, sock, type, flags);
 
 	if (type != BTSOCK_RFCOMM) {
 		error("Socket type %u not supported", type);
-- 
1.7.10.4


^ permalink raw reply related

* [RFCv1 0/9] Socket HAL
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
  To: linux-bluetooth

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

This is initial code implementing socket HAL. Receiving files
through OPP currently working somehow.

For tracking rfcomm sockets I use structure rfslot which has following
fields:
 - real_sock - real RFCOMM socket
 - fd - fd to communicate with Android framework
 - hal_fd - fd passed to Android framework with CMSG

Andrei Emeltchenko (9):
  android/hal-sock: Add debug flag printing
  android: Avoid unneeded includes
  android/ahl-sock: Add connect signal to socket
  android/hal-sock: Initial listen handle
  android/hal-sock: Implement socket accepted event
  android/hal-sock: Implement Android RFCOMM stack events
  android/hal-sock: Implement RFCOMM events
  android/hal-sock: Implement accept signal over Android fd
  android/hal-sock: Write channel to Android fd

 android/adapter.h  |    2 +
 android/hal-msg.h  |    2 +
 android/hal-sock.c |    8 +-
 android/hidhost.c  |    1 -
 android/socket.c   |  264 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 android/socket.h   |    7 ++
 6 files changed, 277 insertions(+), 7 deletions(-)

-- 
1.7.10.4


^ permalink raw reply

* Re: [RFCv1 2/9] android: Avoid unneeded includes
From: Szymon Janc @ 2013-11-11 13:31 UTC (permalink / raw)
  To: Luiz Augusto von Dentz
  Cc: Andrei Emeltchenko, linux-bluetooth@vger.kernel.org
In-Reply-To: <CABBYNZJMGQHVog9cPDqqLfe7ocdBy4UTrW+T9a6SjWWE=qd6=w@mail.gmail.com>

Hi Luiz,

On Monday 11 November 2013 15:20:21 Luiz Augusto von Dentz wrote:
> Hi Andrei,
> 
> On Mon, Nov 11, 2013 at 2:37 PM, Andrei Emeltchenko
> 
> <Andrei.Emeltchenko.news@gmail.com> wrote:
> > From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> > 
> > Declare struct mgmt in adapter.h. This avoids including mgmt.h in
> > every file using adapter functions like socket and hid.
> > ---
> > 
> >  android/adapter.h |    2 ++
> >  android/hidhost.c |    1 -
> >  2 files changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/android/adapter.h b/android/adapter.h
> > index c62b859..3bda9d9 100644
> > --- a/android/adapter.h
> > +++ b/android/adapter.h
> > @@ -23,6 +23,8 @@
> > 
> >  typedef void (*bt_adapter_ready)(int err);
> > 
> > +struct mgmt;
> > +
> > 
> >  void bt_adapter_init(uint16_t index, struct mgmt *mgmt_if,
> >  
> >                                                         bt_adapter_ready
> >                                                         cb);
> > 
> > diff --git a/android/hidhost.c b/android/hidhost.c
> > index 683938f..8c3e9f6 100644
> > --- a/android/hidhost.c
> > +++ b/android/hidhost.c
> > @@ -38,7 +38,6 @@
> > 
> >  #include "lib/sdp.h"
> >  #include "lib/sdp_lib.h"
> >  #include "lib/uuid.h"
> > 
> > -#include "src/shared/mgmt.h"
> > 
> >  #include "src/sdp-client.h"
> >  #include "src/glib-helper.h"
> >  #include "profiles/input/uhid_copy.h"
> > 
> > --
> > 1.7.10.4
> 
> Well it looks like we need to find a proper place for the mgmt
> interaction, or then perhaps pass the fd and use mgmt_new on adapter
> but that seems to require some work as it does create a different mgmt
> objects with different queues which I don't think is safe to use.

I've some patches that try to address this issue. Should be able to send them
soon.

-- 
Szymon K. Janc
szymon.janc@gmail.com

^ permalink raw reply

* Re: [RFCv1 2/9] android: Avoid unneeded includes
From: Luiz Augusto von Dentz @ 2013-11-11 13:20 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1384173438-21708-3-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Mon, Nov 11, 2013 at 2:37 PM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Declare struct mgmt in adapter.h. This avoids including mgmt.h in
> every file using adapter functions like socket and hid.
> ---
>  android/adapter.h |    2 ++
>  android/hidhost.c |    1 -
>  2 files changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/android/adapter.h b/android/adapter.h
> index c62b859..3bda9d9 100644
> --- a/android/adapter.h
> +++ b/android/adapter.h
> @@ -23,6 +23,8 @@
>
>  typedef void (*bt_adapter_ready)(int err);
>
> +struct mgmt;
> +
>  void bt_adapter_init(uint16_t index, struct mgmt *mgmt_if,
>                                                         bt_adapter_ready cb);
>
> diff --git a/android/hidhost.c b/android/hidhost.c
> index 683938f..8c3e9f6 100644
> --- a/android/hidhost.c
> +++ b/android/hidhost.c
> @@ -38,7 +38,6 @@
>  #include "lib/sdp.h"
>  #include "lib/sdp_lib.h"
>  #include "lib/uuid.h"
> -#include "src/shared/mgmt.h"
>  #include "src/sdp-client.h"
>  #include "src/glib-helper.h"
>  #include "profiles/input/uhid_copy.h"
> --
> 1.7.10.4

Well it looks like we need to find a proper place for the mgmt
interaction, or then perhaps pass the fd and use mgmt_new on adapter
but that seems to require some work as it does create a different mgmt
objects with different queues which I don't think is safe to use.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH 3/3] obex: Use XDG_RUNTIME_DIR as a default root
From: Luiz Augusto von Dentz @ 2013-11-11 13:01 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1384173342.1898.8.camel@nuvo>

Hi Bastien,

On Mon, Nov 11, 2013 at 2:35 PM, Bastien Nocera <hadess@hadess.net> wrote:
> On Mon, 2013-11-11 at 11:00 +0200, Luiz Augusto von Dentz wrote:
>> Hi Bastien,
>>
>> On Sun, Nov 10, 2013 at 3:46 PM, Bastien Nocera <hadess@hadess.net> wrote:
>> > On Sat, 2013-11-09 at 18:03 +0100, Bastien Nocera wrote:
>> >> It's per-user, so we won't try to overwrite somebody else's
>> >> files in /tmp when that happens.
>> >
>> > There might be another useful directory instead. We could use
>> > g_get_user_cache_dir() instead of the run-time dir. This would save
>> > cross-partition moves by default, making the move to the Downloads dir
>> > atomic (a single rename, which can fail, iterate until we find a "free"
>> > filename).
>> >
>> > Is that better for you?
>>
>> Yep, it sounds better. Regarding renaming that is up the agent, if you
>> really want to do that its probably fine but Im still not convinced
>> this is absolutely necessary if obexd is running with the same user as
>> the agent can just create the file while authorizing so you wouldn't
>> need to move after completed, but again this is completely up to the
>> agent to decide where the files should go.
>
> You seem to think that all the application/services running under one
> user would have the same rights. That's currently the case, but won't be
> in the future.

Interesting that would cause some problems for sure...

>> Btw, what about fd passing? In theory we can create a different
>> version of the agent interface to enable passing fd directly, and in
>> fact we were thinking about this already as for some services you
>> wanted them to be dynamic so we were thinking on having this set by
>> the agent when it registers.
>
> I'm fine with a file descriptor as well, but obex push server is
> currently broken in GNOME 3.10. I'm happy doing the changes in GNOME
> 3.12 (due in 6 months).
>
> Can we get the cache dir change in, and make the API change later on?

Yep, lets use the cache dir and then think about the API change.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* [RFCv1 9/9] android/hal-sock: Write channel to Android fd
From: Andrei Emeltchenko @ 2013-11-11 12:37 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384173438-21708-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

---
 android/socket.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 20f4e38..0188646 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -27,6 +27,7 @@
 
 #include <glib.h>
 #include <stdbool.h>
+#include <unistd.h>
 #include <errno.h>
 
 #include "lib/bluetooth.h"
@@ -292,6 +293,10 @@ static int handle_listen(void *buf)
 	rfslot->real_sock = g_io_channel_unix_get_fd(io);
 	rfcomm_srv_list = g_list_append(rfcomm_srv_list, rfslot);
 
+	/* TODO: Check this */
+	if (write(rfslot->fd, &ch, sizeof(ch)) < 0)
+		return -1;
+
 	DBG("real_sock %d fd %d hal_fd %d",
 				rfslot->real_sock, rfslot->fd, rfslot->hal_fd);
 
-- 
1.7.10.4


^ permalink raw reply related

* [RFCv1 8/9] android/hal-sock: Implement accept signal over Android fd
From: Andrei Emeltchenko @ 2013-11-11 12:37 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1384173438-21708-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Android expects to get accept signal over file descriptor which was
set during listen HAL call.
---
 android/socket.c |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index a962cdc..20f4e38 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -36,6 +36,7 @@
 #include "hal-ipc.h"
 #include "ipc.h"
 #include "adapter.h"
+#include "utils.h"
 #include "socket.h"
 
 /* Simple list of RFCOMM server sockets */
@@ -68,6 +69,45 @@ static struct rfcomm_slot *create_rfslot(int sock)
 	return rfslot;
 }
 
+static int bt_sock_send_fd(int sock_fd, const void *buf, int len, int send_fd)
+{
+	ssize_t ret;
+	struct msghdr msg;
+	struct cmsghdr *cmsg;
+	struct iovec iv;
+	char msgbuf[CMSG_SPACE(1)];
+
+	DBG("len %d sock_fd %d send_fd %d", len, sock_fd, send_fd);
+
+	if (sock_fd == -1 || send_fd == -1)
+		return -1;
+
+	memset(&msg, 0, sizeof(msg));
+
+	msg.msg_control = msgbuf;
+	msg.msg_controllen = sizeof(msgbuf);
+	cmsg = CMSG_FIRSTHDR(&msg);
+	cmsg->cmsg_level = SOL_SOCKET;
+	cmsg->cmsg_type = SCM_RIGHTS;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(send_fd));
+	memcpy(CMSG_DATA(cmsg), &send_fd, sizeof(send_fd));
+
+	iv.iov_base = (unsigned char *) buf;
+	iv.iov_len = len;
+
+	msg.msg_iov = &iv;
+	msg.msg_iovlen = 1;
+
+	ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL);
+	if (ret < 0) {
+		error("sendmsg(): sock_fd %d send_fd %d: %s",
+					sock_fd, send_fd, strerror(errno));
+		return ret;
+	}
+
+	return ret;
+}
+
 static const uint8_t UUID_PBAP[] = {
 	0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
 	0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
@@ -161,6 +201,21 @@ static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
 	return TRUE;
 }
 
+static void socket_send_accept(struct rfcomm_slot *rfslot, bdaddr_t *bdaddr,
+							int fd_accepted)
+{
+	struct hal_sock_connect_signal cmd;
+
+	DBG("");
+
+	cmd.size = sizeof(cmd);
+	bdaddr2android(bdaddr, cmd.bdaddr);
+	cmd.channel = rfslot->channel;
+	cmd.status = 0;
+
+	bt_sock_send_fd(rfslot->fd, &cmd, sizeof(cmd), fd_accepted);
+}
+
 static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
 {
 	struct rfcomm_slot *rfslot = user_data;
@@ -190,6 +245,8 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
 	rfslot_acc = create_rfslot(sock_acc);
 	rfcomm_accepted_list = g_list_append(rfcomm_accepted_list, rfslot_acc);
 
+	socket_send_accept(rfslot, &dst, rfslot_acc->hal_fd);
+
 	/* Handle events from Android */
 	io_stack = g_io_channel_unix_new(rfslot_acc->fd);
 	g_io_add_watch(io_stack, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-- 
1.7.10.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