Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH 2/3] android/hidhost: Remove deprecated idle opcode from ipc document
From: Marcel Holtmann @ 2013-11-11 23:05 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <1384172130-29837-2-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

> Idle time is deprecated in HID 1_1. So remove it from ipc document
> and update GET_REPORT and VIRTUAL_UNPLUG opcode values.
> ---
> android/hal-ipc-api.txt | 10 ++--------
> android/hal-msg.h       |  4 ++--
> 2 files changed, 4 insertions(+), 10 deletions(-)
> 
> diff --git a/android/hal-ipc-api.txt b/android/hal-ipc-api.txt
> index 91ea280..57f4c13 100644
> --- a/android/hal-ipc-api.txt
> +++ b/android/hal-ipc-api.txt
> @@ -614,20 +614,14 @@ Notifications:
> 		                      0x01 = Boot
> 		                      0xff = Unsupported
> 
> -	Opcode 0x84 - Idle Time notification
> -
> -		Notification parameters: Remote address (6 octets)
> -		                         Status (1 octet)
> -		                         Idle time (2 octets)

so what does HID_1.1 actually mean? I still see this notification in bt_hh.h.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH 1/3] android: Update bond state on incoming bonding
From: Lukasz Rymanowski @ 2013-11-11 22:23 UTC (permalink / raw)
  To: Lukasz Rymanowski, linux-bluetooth, Szymon Janc
In-Reply-To: <20131111083735.GA4541@x220.p-661hnu-f1>

Hi Johan,

On Mon, Nov 11, 2013 at 9:37 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Lukasz,
>
> On Fri, Nov 08, 2013, Lukasz Rymanowski wrote:
>> Before sending any ssp request or pin code request up to HAL library we
>> need to send bond state change with bonding state. Otherwise incoming
>> bonding is impossible.
>> ---
>>  android/adapter.c | 21 ++++++++++++++++++---
>>  1 file changed, 18 insertions(+), 3 deletions(-)
>
> Wont this cause HAL_BOND_STATE_BONDING to be sent twice if the pairing
> was locally initiated through create_bond()?

Well, of course we could try to keep track our local bond state and
send HAL_BOND_STATE_BONDING in smarter way, but we don't need to. It
is not a problem for Android to handle HAL_BOND_STATE_BONDING twice.
Actually It works like this even now with current BT stack.
And of course we need to send this event up as soon as we start
bonding procedure, so it should stay in create_bond().

>
> Johan
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

\Łukasz

^ permalink raw reply

* Re: pull request: bluetooth 2013-11-11
From: John W. Linville @ 2013-11-11 19:05 UTC (permalink / raw)
  To: Gustavo Padovan, linux-wireless, linux-bluetooth, linux-kernel
In-Reply-To: <20131111182738.GB5648@joana>

On Mon, Nov 11, 2013 at 04:27:38PM -0200, Gustavo Padovan wrote:
> 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.

Are you looking in the wireless-next tree?  It seems to be there, no?

John

> 
> 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(-)
> 



-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* Re: [RFC BlueZ v1] doc: Add GATT API
From: Scott James Remnant @ 2013-11-11 18:56 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1381862383-9866-1-git-send-email-claudio.takahasi@openbossa.org>

On Tue, Oct 15, 2013 at 11:39 AM, Claudio Takahasi
<claudio.takahasi@openbossa.org> wrote:

> +GATT local and remote services share the same high-level D-Bus API. Local
> +refers to local GATT based service exported by a BlueZ plugin or an external
> +application. Remote refers to GATT services exported by the peer.

If this object format also be used to describe the services and
characteristics of a remote device, how will those be handled? I
assume that we don't want to get the value of every single
characteristic on connection - that seems wasteful, and would quite
rapidly drain the batteries of smaller devices.


How will service changed be handled? How will BlueZ track the set of
applications, and the set of services etc. defined by those
applications in a manner that keeps handles consistent? How will it
handle generating the Services Changed notification in the cases where
the set of applications and/or services change, or the handles change?


> +Characteristic hierarchy
> +========================
  :
> +Service                org.bluez
> +Interface      org.bluez.Characteristic1 [Experimental]
> +Object path    [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY

This would also need a "Permissions" property akin to the one you have
for Descriptors - characteristics can be "not accessible", read-only,
write-only, read/write - and can also require authorization,
authentication, encryption and minimum encryption key sizes - as with
descriptors.

> +               array{byte} Value [read-write]
> +
> +                       Cached Value of the characteristic. If present, the
> +                       value will be cached by bluetoothd and updated when the
> +                       PropertiesChanged signal is emitted.
> +
> +                       External services must emit this signal when the
> +                       characteristic supports notification/indication, so
> +                       that clients can be notified of the new value.

The PropertiesChanged signal explains how Notification will be handled
- but how will Indication? How will a service receive the Indication
Confirmation from the remote devices?


> +Application Manager hierarchy
> +=============================
  :
> +Service                org.bluez
> +Interface      org.bluez.ApplicationManager1 [Experimental]
> +Object path    /org/bluez
> +
> +Methods                RegisterAgent(object application, dict options)

Shouldn't this be "RegisterApplication" ?

I assume that the object path is the one to which D-Bus Object Manager
queries are sent, allowing a single process to implement multiple
"applications"?

> +               UnregisterAgent(object application)

Likewise, "UnregisterApplication" ?

> +Application Agent hierarchy
> +===========================
> +
> +Service                unique name
> +Interface      org.bluez.ApplicationAgent1 [Experimental]
> +Object path    freely definable
> +

"Agent" seems unnnecessary here - if the object is an Application,
then org.bluez.Application1 would be a decent enough name. Thus an
"Application" consists of multiple Services, each of which consists of
multiple Characteristics, each of which has multiple Descriptors

Scott
-- 
Scott James Remnant | Chrome OS Systems | keybuk@google.com | Google

^ permalink raw reply

* 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


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