* [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 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
* 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: [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
* 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: [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: [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: [RFCv1 7/9] android/hal-sock: Implement RFCOMM events
From: Marcel Holtmann @ 2013-11-11 23:11 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <1384173438-21708-8-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
> 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;
> + }
> +
since both sockets are SOCK_STREAM there is no guarantee that write() will write exactly the same amount of data that you just got via read(). Especially when using MSG_DONTWAIT. The kernel can decide to interrupt you here any time it wants to.
So you need proper error handling for the send() part in case you get truncated transfers.
Regards
Marcel
^ permalink raw reply
* Re: pull request: bluetooth 2013-11-11
From: Marcel Holtmann @ 2013-11-11 23:17 UTC (permalink / raw)
To: Gustavo F. Padovan
Cc: John W. Linville, linux-wireless@vger.kernel.org Wireless,
linux-bluetooth@vger.kernel.org development,
linux-kernel@vger.kernel.org list
In-Reply-To: <20131111182738.GB5648@joana>
Hi Gustavo,
> 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”
this one is already in net-next actually. John pushed bluetooth and bluetooth-next to Dave at the same time.
> 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
These 5 fixes are still needed.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH 1/3] android: Update bond state on incoming bonding
From: Marcel Holtmann @ 2013-11-11 23:19 UTC (permalink / raw)
To: Lukasz Rymanowski
Cc: Lukasz Rymanowski, linux-bluetooth@vger.kernel.org development,
Szymon Janc
In-Reply-To: <CAN_7+Yb9smK8U+UeK8P-3YcBR0pC8spgsnVkw4f86jMO67A+FA@mail.gmail.com>
Hi Lukasz,
>>> 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().
I think we should keep track of our bond state internally. I get the feeling we will need that eventually anyway. For example we already know that we need to keep a mapping of BD_ADDR to address types to make LE work.
Regards
Marcel
^ permalink raw reply
* [PATCH 0/7] android: Some adapter and mgmt handling code cleanup
From: Szymon Janc @ 2013-11-12 0:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
Hi,
This patchset moves mgmt initalization handling from main.c to adapter.c so
now all mgmt handling is done from adaper.c. Adapter.c is also renamed to
bluetooth.c to match service name implemented by it.
Startup and shutdown timeouts are still handled in main.c (mostly due to
both resulting in mainloop shutdown so extra callback are avoided).
IO handling and commands dispatch is still done in main.c
--
BR
Szymon Janc
Szymon Janc (7):
android: Remove bt_adapter structure
android: Move adapter initialization to adapter.c
android/hidhost: Use adapter address provided on register
android: Report adapter address in adapter_ready callback
android: Remove not needed bt_adapter_get_address function
android: Rename adapter.c to bluetooth.c
android: Rename bluetooth service functions to match service name
android/Android.mk | 2 +-
android/Makefile.am | 4 +-
android/adapter.c | 1833 -----------------------------------------------
android/adapter.h | 34 -
android/bluetooth.c | 1985 +++++++++++++++++++++++++++++++++++++++++++++++++++
android/bluetooth.h | 35 +
android/hidhost.c | 21 +-
android/main.c | 314 ++------
8 files changed, 2092 insertions(+), 2136 deletions(-)
delete mode 100644 android/adapter.c
delete mode 100644 android/adapter.h
create mode 100644 android/bluetooth.c
create mode 100644 android/bluetooth.h
--
1.8.4.2
^ permalink raw reply
* [PATCH 1/7] android: Remove bt_adapter structure
From: Szymon Janc @ 2013-11-12 0:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384215857-19679-1-git-send-email-szymon.janc@tieto.com>
Only one controller is used so there is no need to keep extra
abstraction for it.
---
android/adapter.c | 271 +++++++++++++++++++++++++-----------------------------
1 file changed, 123 insertions(+), 148 deletions(-)
diff --git a/android/adapter.c b/android/adapter.c
index 65b3170..e161f9d 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -58,23 +58,17 @@ static int notification_sk = -1;
/* This list contains addresses which are asked for records */
static GSList *browse_reqs;
-struct bt_adapter {
- uint16_t index;
- struct mgmt *mgmt;
+static uint16_t adapter_index = MGMT_INDEX_NONE;
+static struct mgmt *mgmt_if = NULL;
+static bt_adapter_ready adapter_ready = NULL;
+static bdaddr_t adapter_bdaddr;
+static uint32_t adapter_dev_class = 0;
+static char *adapter_name = NULL;
+static uint32_t current_settings = 0;
- bt_adapter_ready ready;
+static bool adapter_discovering = false;
- bdaddr_t bdaddr;
- uint32_t dev_class;
-
- char *name;
-
- uint32_t supported_settings;
- uint32_t current_settings;
-
- bool discovering;
- uint32_t discoverable_timeout;
-};
+uint32_t adapter_discoverable_timeout = DEFAULT_DISCOVERABLE_TIMEOUT;
struct browse_req {
bdaddr_t bdaddr;
@@ -90,7 +84,6 @@ static const uint16_t uuid_list[] = {
0
};
-static struct bt_adapter *adapter;
static GSList *found_devices = NULL;
static void adapter_name_changed(const uint8_t *name)
@@ -115,13 +108,13 @@ static void adapter_name_changed(const uint8_t *name)
static void adapter_set_name(const uint8_t *name)
{
- if (!g_strcmp0(adapter->name, (const char *) name))
+ if (!g_strcmp0(adapter_name, (const char *) name))
return;
DBG("%s", name);
- g_free(adapter->name);
- adapter->name = g_strdup((const char *) name);
+ g_free(adapter_name);
+ adapter_name = g_strdup((const char *) name);
adapter_name_changed(name);
}
@@ -145,7 +138,7 @@ static void powered_changed(void)
{
struct hal_ev_adapter_state_changed ev;
- ev.state = (adapter->current_settings & MGMT_SETTING_POWERED) ?
+ ev.state = (current_settings & MGMT_SETTING_POWERED) ?
HAL_POWER_ON : HAL_POWER_OFF;
DBG("%u", ev.state);
@@ -158,8 +151,8 @@ static uint8_t settings2scan_mode(void)
{
bool connectable, discoverable;
- connectable = adapter->current_settings & MGMT_SETTING_CONNECTABLE;
- discoverable = adapter->current_settings & MGMT_SETTING_DISCOVERABLE;
+ connectable = current_settings & MGMT_SETTING_CONNECTABLE;
+ discoverable = current_settings & MGMT_SETTING_DISCOVERABLE;
if (connectable && discoverable)
return HAL_ADAPTER_SCAN_MODE_CONN_DISC;
@@ -201,7 +194,7 @@ static void adapter_class_changed(void)
ev->props[0].type = HAL_PROP_ADAPTER_CLASS;
ev->props[0].len = sizeof(uint32_t);
- memcpy(ev->props->val, &adapter->dev_class, sizeof(uint32_t));
+ memcpy(ev->props->val, &adapter_dev_class, sizeof(uint32_t));
ipc_send(notification_sk, HAL_SERVICE_ID_BLUETOOTH,
HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), buf, -1);
@@ -212,9 +205,9 @@ static void settings_changed(uint32_t settings)
uint32_t changed_mask;
uint32_t scan_mode_mask;
- changed_mask = adapter->current_settings ^ settings;
+ changed_mask = current_settings ^ settings;
- adapter->current_settings = settings;
+ current_settings = settings;
DBG("0x%08x", changed_mask);
@@ -229,7 +222,7 @@ static void settings_changed(uint32_t settings)
* Only when powered, the connectable and discoverable
* state changes should be communicated.
*/
- if (adapter->current_settings & MGMT_SETTING_POWERED)
+ if (current_settings & MGMT_SETTING_POWERED)
if (changed_mask & scan_mode_mask)
scan_mode_changed();
}
@@ -246,10 +239,9 @@ static void new_settings_callback(uint16_t index, uint16_t length,
settings = bt_get_le32(param);
- DBG("settings: 0x%8.8x -> 0x%8.8x", adapter->current_settings,
- settings);
+ DBG("settings: 0x%8.8x -> 0x%8.8x", current_settings, settings);
- if (settings == adapter->current_settings)
+ if (settings == current_settings)
return;
settings_changed(settings);
@@ -268,12 +260,12 @@ static void mgmt_dev_class_changed_event(uint16_t index, uint16_t length,
dev_class = rp->val[0] | (rp->val[1] << 8) | (rp->val[2] << 16);
- if (dev_class == adapter->dev_class)
+ if (dev_class == adapter_dev_class)
return;
DBG("Class: 0x%06x", dev_class);
- adapter->dev_class = dev_class;
+ adapter_dev_class = dev_class;
adapter_class_changed();
@@ -410,7 +402,7 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
/* Search for mandatory uuids */
if (uuid_list[req->search_uuid]) {
sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
- bt_search_service(&adapter->bdaddr, &req->bdaddr, &uuid,
+ bt_search_service(&adapter_bdaddr, &req->bdaddr, &uuid,
browse_cb, user_data, NULL);
return;
}
@@ -442,7 +434,7 @@ static uint8_t browse_remote_sdp(const bdaddr_t *addr)
bacpy(&req->bdaddr, addr);
sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
- if (bt_search_service(&adapter->bdaddr,
+ if (bt_search_service(&adapter_bdaddr,
&req->bdaddr, &uuid, browse_cb, req, NULL) < 0) {
browse_req_free(req);
return false;
@@ -597,17 +589,17 @@ static void mgmt_discovering_event(uint16_t index, uint16_t length,
return;
}
- DBG("hci%u type %u discovering %u", adapter->index, ev->type,
+ DBG("hci%u type %u discovering %u", adapter_index, ev->type,
ev->discovering);
- if (adapter->discovering == !!ev->discovering)
+ if (adapter_discovering == !!ev->discovering)
return;
- adapter->discovering = !!ev->discovering;
+ adapter_discovering = !!ev->discovering;
DBG("new discovering state %u", ev->discovering);
- if (adapter->discovering) {
+ if (adapter_discovering) {
cp.state = HAL_DISCOVERY_STATE_STARTED;
} else {
g_slist_free_full(found_devices, g_free);
@@ -628,7 +620,7 @@ static void confirm_device_name(const bdaddr_t *addr, uint8_t addr_type)
bacpy(&cp.addr.bdaddr, addr);
cp.addr.type = addr_type;
- if (mgmt_reply(adapter->mgmt, MGMT_OP_CONFIRM_NAME, adapter->index,
+ if (mgmt_reply(mgmt_if, MGMT_OP_CONFIRM_NAME, adapter_index,
sizeof(cp), &cp, NULL, NULL, NULL) == 0)
error("Failed to send confirm name request");
}
@@ -876,56 +868,49 @@ static void mgmt_device_unpaired_event(uint16_t index, uint16_t length,
static void register_mgmt_handlers(void)
{
- mgmt_register(adapter->mgmt, MGMT_EV_NEW_SETTINGS, adapter->index,
+ mgmt_register(mgmt_if, MGMT_EV_NEW_SETTINGS, adapter_index,
new_settings_callback, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_CLASS_OF_DEV_CHANGED,
- adapter->index, mgmt_dev_class_changed_event,
- NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_CLASS_OF_DEV_CHANGED, adapter_index,
+ mgmt_dev_class_changed_event, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_LOCAL_NAME_CHANGED,
- adapter->index, mgmt_local_name_changed_event,
- NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_LOCAL_NAME_CHANGED, adapter_index,
+ mgmt_local_name_changed_event, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_NEW_LINK_KEY, adapter->index,
+ mgmt_register(mgmt_if, MGMT_EV_NEW_LINK_KEY, adapter_index,
new_link_key_callback, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_PIN_CODE_REQUEST, adapter->index,
+ mgmt_register(mgmt_if, MGMT_EV_PIN_CODE_REQUEST, adapter_index,
pin_code_request_callback, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_USER_CONFIRM_REQUEST,
- adapter->index, user_confirm_request_callback,
- NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_USER_CONFIRM_REQUEST, adapter_index,
+ user_confirm_request_callback, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_USER_PASSKEY_REQUEST,
- adapter->index, user_passkey_request_callback,
- NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_USER_PASSKEY_REQUEST, adapter_index,
+ user_passkey_request_callback, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_PASSKEY_NOTIFY, adapter->index,
+ mgmt_register(mgmt_if, MGMT_EV_PASSKEY_NOTIFY, adapter_index,
user_passkey_notify_callback, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_DISCOVERING, adapter->index,
- mgmt_discovering_event,
- NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_DISCOVERING, adapter_index,
+ mgmt_discovering_event, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_FOUND,
- adapter->index, mgmt_device_found_event,
- NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_DEVICE_FOUND, adapter_index,
+ mgmt_device_found_event, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_CONNECTED, adapter->index,
+ mgmt_register(mgmt_if, MGMT_EV_DEVICE_CONNECTED, adapter_index,
mgmt_device_connected_event, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_DISCONNECTED,
- adapter->index, mgmt_device_disconnected_event,
- NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_DEVICE_DISCONNECTED, adapter_index,
+ mgmt_device_disconnected_event, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_CONNECT_FAILED, adapter->index,
+ mgmt_register(mgmt_if, MGMT_EV_CONNECT_FAILED, adapter_index,
mgmt_connect_failed_event, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_AUTH_FAILED, adapter->index,
+ mgmt_register(mgmt_if, MGMT_EV_AUTH_FAILED, adapter_index,
mgmt_auth_failed_event, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_UNPAIRED, adapter->index,
+ mgmt_register(mgmt_if, MGMT_EV_DEVICE_UNPAIRED, adapter_index,
mgmt_device_unpaired_event, NULL, NULL);
}
@@ -936,18 +921,18 @@ static void load_link_keys_complete(uint8_t status, uint16_t length,
if (status) {
error("Failed to load link keys for index %u: %s (0x%02x)",
- adapter->index, mgmt_errstr(status), status);
+ adapter_index, mgmt_errstr(status), status);
err = -EIO;
goto failed;
}
DBG("status %u", status);
- adapter->ready(0);
+ adapter_ready(0);
return;
failed:
- adapter->ready(err);
+ adapter_ready(err);
}
static void load_link_keys(GSList *keys)
@@ -975,14 +960,14 @@ static void load_link_keys(GSList *keys)
for (key = cp->keys; keys != NULL; keys = g_slist_next(keys), key++)
memcpy(key, keys->data, sizeof(*key));
- id = mgmt_send(adapter->mgmt, MGMT_OP_LOAD_LINK_KEYS, adapter->index,
+ id = mgmt_send(mgmt_if, MGMT_OP_LOAD_LINK_KEYS, adapter_index,
cp_size, cp, load_link_keys_complete, NULL, NULL);
g_free(cp);
if (id == 0) {
error("Failed to load link keys");
- adapter->ready(-EIO);
+ adapter_ready(-EIO);
}
}
@@ -1000,7 +985,7 @@ static void set_mode_complete(uint8_t status, uint16_t length,
* required in both cases. So it is safe to just call the
* event handling functions here.
*/
- new_settings_callback(adapter->index, length, param, NULL);
+ new_settings_callback(adapter_index, length, param, NULL);
}
static bool set_mode(uint16_t opcode, uint8_t mode)
@@ -1012,7 +997,7 @@ static bool set_mode(uint16_t opcode, uint8_t mode)
DBG("opcode=0x%x mode=0x%x", opcode, mode);
- if (mgmt_send(adapter->mgmt, opcode, adapter->index, sizeof(cp), &cp,
+ if (mgmt_send(mgmt_if, opcode, adapter_index, sizeof(cp), &cp,
set_mode_complete, NULL, NULL) > 0)
return true;
@@ -1028,9 +1013,8 @@ static void set_io_capability(void)
memset(&cp, 0, sizeof(cp));
cp.io_capability = DEFAULT_IO_CAPABILITY;
- if (mgmt_send(adapter->mgmt, MGMT_OP_SET_IO_CAPABILITY,
- adapter->index, sizeof(cp), &cp,
- NULL, NULL, NULL) == 0)
+ if (mgmt_send(mgmt_if, MGMT_OP_SET_IO_CAPABILITY, adapter_index,
+ sizeof(cp), &cp, NULL, NULL, NULL) == 0)
error("Failed to set IO capability");
}
@@ -1048,9 +1032,8 @@ static void set_device_id(void)
cp.product = htobs(0x0247); /* BlueZ for Android */
cp.version = htobs(major << 8 | minor);
- if (mgmt_send(adapter->mgmt, MGMT_OP_SET_DEVICE_ID,
- adapter->index, sizeof(cp), &cp,
- NULL, NULL, NULL) == 0)
+ if (mgmt_send(mgmt_if, MGMT_OP_SET_DEVICE_ID, adapter_index,
+ sizeof(cp), &cp, NULL, NULL, NULL) == 0)
error("Failed to set device id");
}
@@ -1075,9 +1058,9 @@ static uint8_t set_adapter_name(uint8_t *name, uint16_t len)
memset(&cp, 0, sizeof(cp));
memcpy(cp.name, name, len);
- if (mgmt_send(adapter->mgmt, MGMT_OP_SET_LOCAL_NAME, adapter->index,
- sizeof(cp), &cp, set_adapter_name_complete, NULL,
- NULL) > 0)
+ if (mgmt_send(mgmt_if, MGMT_OP_SET_LOCAL_NAME, adapter_index,
+ sizeof(cp), &cp, set_adapter_name_complete,
+ NULL, NULL) > 0)
return HAL_STATUS_SUCCESS;
error("Failed to set name");
@@ -1092,7 +1075,7 @@ static uint8_t set_discoverable_timeout(uint8_t *timeout)
* Just need to store this value here */
/* TODO: This should be in some storage */
- memcpy(&adapter->discoverable_timeout, timeout, sizeof(uint32_t));
+ memcpy(&adapter_discoverable_timeout, timeout, sizeof(uint32_t));
return HAL_STATUS_SUCCESS;
}
@@ -1100,14 +1083,14 @@ static void read_info_complete(uint8_t status, uint16_t length, const void *para
void *user_data)
{
const struct mgmt_rp_read_info *rp = param;
- uint32_t missing_settings;
+ uint32_t missing_settings, supported_settings;
int err;
DBG("");
if (status) {
error("Failed to read info for index %u: %s (0x%02x)",
- adapter->index, mgmt_errstr(status), status);
+ adapter_index, mgmt_errstr(status), status);
err = -EIO;
goto failed;
}
@@ -1125,13 +1108,15 @@ static void read_info_complete(uint8_t status, uint16_t length, const void *para
}
/* Store adapter information */
- bacpy(&adapter->bdaddr, &rp->bdaddr);
- adapter->dev_class = rp->dev_class[0] | (rp->dev_class[1] << 8) |
+ bacpy(&adapter_bdaddr, &rp->bdaddr);
+ adapter_dev_class = rp->dev_class[0] | (rp->dev_class[1] << 8) |
(rp->dev_class[2] << 16);
- adapter->name = g_strdup((const char *) rp->name);
+ adapter_name = g_strdup((const char *) rp->name);
- adapter->supported_settings = btohs(rp->supported_settings);
- adapter->current_settings = btohs(rp->current_settings);
+ supported_settings = btohs(rp->supported_settings);
+ current_settings = btohs(rp->current_settings);
+
+ /* TODO: Read discoverable timeout from storage here */
/* TODO: Register all event notification handlers */
register_mgmt_handlers();
@@ -1141,8 +1126,7 @@ static void read_info_complete(uint8_t status, uint16_t length, const void *para
set_io_capability();
set_device_id();
- missing_settings = adapter->current_settings ^
- adapter->supported_settings;
+ missing_settings = current_settings ^ supported_settings;
if (missing_settings & MGMT_SETTING_SSP)
set_mode(MGMT_OP_SET_SSP, 0x01);
@@ -1153,26 +1137,21 @@ static void read_info_complete(uint8_t status, uint16_t length, const void *para
return;
failed:
- adapter->ready(err);
+ adapter_ready(err);
}
void bt_adapter_init(uint16_t index, struct mgmt *mgmt, bt_adapter_ready cb)
{
- adapter = g_new0(struct bt_adapter, 1);
-
- adapter->mgmt = mgmt_ref(mgmt);
- adapter->index = index;
- adapter->discovering = false;
- adapter->ready = cb;
- /* TODO: Read it from some storage */
- adapter->discoverable_timeout = DEFAULT_DISCOVERABLE_TIMEOUT;
+ mgmt_if = mgmt_ref(mgmt);
+ adapter_index = index;
+ adapter_ready = cb;
if (mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL,
read_info_complete, NULL, NULL) > 0)
return;
- mgmt_unref(adapter->mgmt);
- adapter->ready(-EIO);
+ mgmt_unref(mgmt_if);
+ adapter_ready(-EIO);
}
static bool set_discoverable(uint8_t mode, uint16_t timeout)
@@ -1185,9 +1164,8 @@ static bool set_discoverable(uint8_t mode, uint16_t timeout)
DBG("mode %u timeout %u", mode, timeout);
- if (mgmt_send(adapter->mgmt, MGMT_OP_SET_DISCOVERABLE,
- adapter->index, sizeof(cp), &cp,
- set_mode_complete, adapter, NULL) > 0)
+ if (mgmt_send(mgmt_if, MGMT_OP_SET_DISCOVERABLE, adapter_index,
+ sizeof(cp), &cp, set_mode_complete, NULL, NULL) > 0)
return true;
error("Failed to set mode discoverable");
@@ -1205,7 +1183,7 @@ static void get_address(void)
ev->props[0].type = HAL_PROP_ADAPTER_ADDR;
ev->props[0].len = sizeof(bdaddr_t);
- bdaddr2android(&adapter->bdaddr, ev->props[0].val);
+ bdaddr2android(&adapter_bdaddr, ev->props[0].val);
ipc_send(notification_sk, HAL_SERVICE_ID_BLUETOOTH,
HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), buf, -1);
@@ -1213,10 +1191,10 @@ static void get_address(void)
static bool get_name(void)
{
- if (!adapter->name)
+ if (!adapter_name)
return false;
- adapter_name_changed((uint8_t *) adapter->name);
+ adapter_name_changed((uint8_t *) adapter_name);
return true;
}
@@ -1288,7 +1266,7 @@ static bool get_discoverable_timeout(void)
ev->props[0].type = HAL_PROP_ADAPTER_DISC_TIMEOUT;
ev->props[0].len = sizeof(uint32_t);
- memcpy(&ev->props[0].val, &adapter->discoverable_timeout,
+ memcpy(&ev->props[0].val, &adapter_discoverable_timeout,
sizeof(uint32_t));
ipc_send(notification_sk, HAL_SERVICE_ID_BLUETOOTH,
@@ -1344,15 +1322,15 @@ static bool start_discovery(void)
struct mgmt_cp_start_discovery cp;
uint8_t type = 1 << BDADDR_BREDR;
- if (adapter->current_settings & type)
+ if (current_settings & type)
cp.type = type;
else
cp.type = 0;
DBG("type=0x%x", type);
- if (mgmt_send(adapter->mgmt, MGMT_OP_START_DISCOVERY, adapter->index,
- sizeof(cp), &cp, NULL, NULL, NULL) > 0)
+ if (mgmt_send(mgmt_if, MGMT_OP_START_DISCOVERY, adapter_index,
+ sizeof(cp), &cp, NULL, NULL, NULL) > 0)
return true;
error("Failed to start discovery");
@@ -1364,15 +1342,15 @@ static bool stop_discovery(void)
struct mgmt_cp_stop_discovery cp;
uint8_t type = 1 << BDADDR_BREDR;
- if (adapter->current_settings & type)
+ if (current_settings & type)
cp.type = type;
else
cp.type = 0;
DBG("type=0x%x", type);
- if (mgmt_send(adapter->mgmt, MGMT_OP_STOP_DISCOVERY, adapter->index,
- sizeof(cp), &cp, NULL, NULL, NULL) > 0)
+ if (mgmt_send(mgmt_if, MGMT_OP_STOP_DISCOVERY, adapter_index,
+ sizeof(cp), &cp, NULL, NULL, NULL) > 0)
return true;
error("Failed to start discovery");
@@ -1384,8 +1362,8 @@ static uint8_t set_scan_mode(void *buf, uint16_t len)
uint8_t *mode = buf;
bool conn, disc, cur_conn, cur_disc;
- cur_conn = adapter->current_settings & MGMT_SETTING_CONNECTABLE;
- cur_disc = adapter->current_settings & MGMT_SETTING_DISCOVERABLE;
+ cur_conn = current_settings & MGMT_SETTING_CONNECTABLE;
+ cur_disc = current_settings & MGMT_SETTING_DISCOVERABLE;
DBG("connectable %u discoverable %d mode %u", cur_conn, cur_disc,
*mode);
@@ -1499,9 +1477,8 @@ static bool create_bond(void *buf, uint16_t len)
cp.addr.type = BDADDR_BREDR;
android2bdaddr(cmd->bdaddr, &cp.addr.bdaddr);
- if (mgmt_send(adapter->mgmt, MGMT_OP_PAIR_DEVICE, adapter->index,
- sizeof(cp), &cp, pair_device_complete, NULL,
- NULL) == 0)
+ if (mgmt_send(mgmt_if, MGMT_OP_PAIR_DEVICE, adapter_index, sizeof(cp),
+ &cp, pair_device_complete, NULL, NULL) == 0)
return false;
send_bond_state_change(&cp.addr.bdaddr, HAL_STATUS_SUCCESS,
@@ -1518,9 +1495,8 @@ static bool cancel_bond(void *buf, uint16_t len)
cp.type = BDADDR_BREDR;
android2bdaddr(cmd->bdaddr, &cp.bdaddr);
- return mgmt_reply(adapter->mgmt, MGMT_OP_CANCEL_PAIR_DEVICE,
- adapter->index, sizeof(cp), &cp, NULL, NULL,
- NULL) > 0;
+ return mgmt_reply(mgmt_if, MGMT_OP_CANCEL_PAIR_DEVICE, adapter_index,
+ sizeof(cp), &cp, NULL, NULL, NULL) > 0;
}
static void unpair_device_complete(uint8_t status, uint16_t length,
@@ -1546,9 +1522,9 @@ static bool remove_bond(void *buf, uint16_t len)
cp.addr.type = BDADDR_BREDR;
android2bdaddr(cmd->bdaddr, &cp.addr.bdaddr);
- return mgmt_send(adapter->mgmt, MGMT_OP_UNPAIR_DEVICE,
- adapter->index, sizeof(cp), &cp,
- unpair_device_complete, NULL, NULL) > 0;
+ return mgmt_send(mgmt_if, MGMT_OP_UNPAIR_DEVICE, adapter_index,
+ sizeof(cp), &cp, unpair_device_complete,
+ NULL, NULL) > 0;
}
static uint8_t pin_reply(void *buf, uint16_t len)
@@ -1575,9 +1551,8 @@ static uint8_t pin_reply(void *buf, uint16_t len)
rp.pin_len = cmd->pin_len;
memcpy(rp.pin_code, cmd->pin_code, rp.pin_len);
- if (mgmt_reply(adapter->mgmt, MGMT_OP_PIN_CODE_REPLY,
- adapter->index, sizeof(rp), &rp,
- NULL, NULL, NULL) == 0)
+ if (mgmt_reply(mgmt_if, MGMT_OP_PIN_CODE_REPLY, adapter_index,
+ sizeof(rp), &rp, NULL, NULL, NULL) == 0)
return HAL_STATUS_FAILED;
} else {
struct mgmt_cp_pin_code_neg_reply rp;
@@ -1585,9 +1560,9 @@ static uint8_t pin_reply(void *buf, uint16_t len)
bacpy(&rp.addr.bdaddr, &bdaddr);
rp.addr.type = BDADDR_BREDR;
- if (mgmt_reply(adapter->mgmt, MGMT_OP_PIN_CODE_NEG_REPLY,
- adapter->index, sizeof(rp), &rp,
- NULL, NULL, NULL) == 0)
+ if (mgmt_reply(mgmt_if, MGMT_OP_PIN_CODE_NEG_REPLY,
+ adapter_index, sizeof(rp), &rp,
+ NULL, NULL, NULL) == 0)
return HAL_STATUS_FAILED;
}
@@ -1607,7 +1582,7 @@ static uint8_t user_confirm_reply(const bdaddr_t *bdaddr, bool accept)
bacpy(&cp.bdaddr, bdaddr);
cp.type = BDADDR_BREDR;
- if (mgmt_reply(adapter->mgmt, opcode, adapter->index, sizeof(cp), &cp,
+ if (mgmt_reply(mgmt_if, opcode, adapter_index, sizeof(cp), &cp,
NULL, NULL, NULL) > 0)
return HAL_STATUS_SUCCESS;
@@ -1627,9 +1602,9 @@ static uint8_t user_passkey_reply(const bdaddr_t *bdaddr, bool accept,
cp.addr.type = BDADDR_BREDR;
cp.passkey = htobl(passkey);
- id = mgmt_reply(adapter->mgmt, MGMT_OP_USER_PASSKEY_REPLY,
- adapter->index, sizeof(cp), &cp,
- NULL, NULL, NULL);
+ id = mgmt_reply(mgmt_if, MGMT_OP_USER_PASSKEY_REPLY,
+ adapter_index, sizeof(cp), &cp,
+ NULL, NULL, NULL);
} else {
struct mgmt_cp_user_passkey_neg_reply cp;
@@ -1637,9 +1612,9 @@ static uint8_t user_passkey_reply(const bdaddr_t *bdaddr, bool accept,
bacpy(&cp.addr.bdaddr, bdaddr);
cp.addr.type = BDADDR_BREDR;
- id = mgmt_reply(adapter->mgmt, MGMT_OP_USER_PASSKEY_NEG_REPLY,
- adapter->index, sizeof(cp), &cp,
- NULL, NULL, NULL);
+ id = mgmt_reply(mgmt_if, MGMT_OP_USER_PASSKEY_NEG_REPLY,
+ adapter_index, sizeof(cp), &cp,
+ NULL, NULL, NULL);
}
if (id == 0)
@@ -1702,7 +1677,7 @@ void bt_adapter_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
* enabling adapter */
get_properties();
- if (adapter->current_settings & MGMT_SETTING_POWERED) {
+ if (current_settings & MGMT_SETTING_POWERED) {
status = HAL_STATUS_DONE;
goto error;
}
@@ -1712,7 +1687,7 @@ void bt_adapter_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
break;
case HAL_OP_DISABLE:
- if (!(adapter->current_settings & MGMT_SETTING_POWERED)) {
+ if (!(current_settings & MGMT_SETTING_POWERED)) {
status = HAL_STATUS_DONE;
goto error;
}
@@ -1763,12 +1738,12 @@ void bt_adapter_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
goto error;
break;
case HAL_OP_START_DISCOVERY:
- if (adapter->discovering) {
+ if (adapter_discovering) {
status = HAL_STATUS_DONE;
goto error;
}
- if (!(adapter->current_settings & MGMT_SETTING_POWERED)) {
+ if (!(current_settings & MGMT_SETTING_POWERED)) {
status = HAL_STATUS_NOT_READY;
goto error;
}
@@ -1778,12 +1753,12 @@ void bt_adapter_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
break;
case HAL_OP_CANCEL_DISCOVERY:
- if (!adapter->discovering) {
+ if (!adapter_discovering) {
status = HAL_STATUS_DONE;
goto error;
}
- if (!(adapter->current_settings & MGMT_SETTING_POWERED)) {
+ if (!(current_settings & MGMT_SETTING_POWERED)) {
status = HAL_STATUS_NOT_READY;
goto error;
}
@@ -1813,7 +1788,7 @@ error:
const bdaddr_t *bt_adapter_get_address(void)
{
- return &adapter->bdaddr;
+ return &adapter_bdaddr;
}
bool bt_adapter_register(int sk)
--
1.8.4.2
^ permalink raw reply related
* [PATCH 2/7] android: Move adapter initialization to adapter.c
From: Szymon Janc @ 2013-11-12 0:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384215857-19679-1-git-send-email-szymon.janc@tieto.com>
There is no need to handle that in main.c. Also this removes mgmt
interface dependency from adapter API as all mgmt commands are handled
from adapter code.
Startup and shutdown timeouts handling is left in main.c.
---
android/adapter.c | 196 +++++++++++++++++++++++++++++++++--
android/adapter.h | 7 +-
android/main.c | 300 +++++++++---------------------------------------------
3 files changed, 244 insertions(+), 259 deletions(-)
diff --git a/android/adapter.c b/android/adapter.c
index e161f9d..0c090bf 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -58,6 +58,7 @@ static int notification_sk = -1;
/* This list contains addresses which are asked for records */
static GSList *browse_reqs;
+static uint16_t option_index = MGMT_INDEX_NONE;
static uint16_t adapter_index = MGMT_INDEX_NONE;
static struct mgmt *mgmt_if = NULL;
static bt_adapter_ready adapter_ready = NULL;
@@ -1140,20 +1141,201 @@ failed:
adapter_ready(err);
}
-void bt_adapter_init(uint16_t index, struct mgmt *mgmt, bt_adapter_ready cb)
+static void mgmt_index_added_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
{
- mgmt_if = mgmt_ref(mgmt);
- adapter_index = index;
- adapter_ready = cb;
+ DBG("index %u", index);
- if (mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL,
- read_info_complete, NULL, NULL) > 0)
+ if (adapter_index != MGMT_INDEX_NONE) {
+ DBG("skip event for index %u", index);
return;
+ }
- mgmt_unref(mgmt_if);
+ if (option_index != MGMT_INDEX_NONE && option_index != index) {
+ DBG("skip event for index %u (option %u)", index, option_index);
+ return;
+ }
+
+ if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
+ read_info_complete, NULL, NULL) == 0) {
+ adapter_ready(-EIO);
+ return;
+ }
+}
+
+static void mgmt_index_removed_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ DBG("index %u", index);
+
+ if (index != adapter_index)
+ return;
+
+ error("Adapter was removed. Exiting.");
+ raise(SIGTERM);
+}
+
+static void read_index_list_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_read_index_list *rp = param;
+ uint16_t num;
+ int i;
+
+ DBG("");
+
+ if (status) {
+ error("%s: Failed to read index list: %s (0x%02x)",
+ __func__, mgmt_errstr(status), status);
+ goto failed;
+ }
+
+ if (length < sizeof(*rp)) {
+ error("%s: Wrong size of read index list response", __func__);
+ goto failed;
+ }
+
+ num = btohs(rp->num_controllers);
+
+ DBG("Number of controllers: %u", num);
+
+ if (num * sizeof(uint16_t) + sizeof(*rp) != length) {
+ error("%s: Incorrect pkt size for index list rsp", __func__);
+ goto failed;
+ }
+
+ if (adapter_index != MGMT_INDEX_NONE)
+ return;
+
+ for (i = 0; i < num; i++) {
+ uint16_t index = btohs(rp->index[i]);
+
+ if (option_index != MGMT_INDEX_NONE && option_index != index)
+ continue;
+
+ if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
+ read_info_complete, NULL, NULL) == 0)
+ goto failed;
+
+ adapter_index = index;
+ return;
+ }
+
+ return;
+
+failed:
adapter_ready(-EIO);
}
+static void read_version_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_read_version *rp = param;
+ uint8_t mgmt_version, mgmt_revision;
+
+ DBG("");
+
+ if (status) {
+ error("Failed to read version information: %s (0x%02x)",
+ mgmt_errstr(status), status);
+ goto failed;
+ }
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size response");
+ goto failed;
+ }
+
+ mgmt_version = rp->version;
+ mgmt_revision = btohs(rp->revision);
+
+ info("Bluetooth management interface %u.%u initialized",
+ mgmt_version, mgmt_revision);
+
+ if (MGMT_VERSION(mgmt_version, mgmt_revision) < MGMT_VERSION(1, 3)) {
+ error("Version 1.3 or later of management interface required");
+ goto failed;
+ }
+
+ mgmt_register(mgmt_if, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
+ mgmt_index_added_event, NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
+ mgmt_index_removed_event, NULL, NULL);
+
+ if (mgmt_send(mgmt_if, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
+ NULL, read_index_list_complete, NULL, NULL) > 0)
+ return;
+
+ error("Failed to read controller index list");
+
+failed:
+ adapter_ready(-EIO);
+}
+
+bool bt_adapter_start(int index, bt_adapter_ready cb)
+{
+ DBG("index %d", index);
+
+ mgmt_if = mgmt_new_default();
+ if (!mgmt_if) {
+ error("Failed to access management interface");
+ return false;
+ }
+
+ if (mgmt_send(mgmt_if, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE, 0, NULL,
+ read_version_complete, NULL, NULL) == 0) {
+ error("Error sending READ_VERSION mgmt command");
+
+ mgmt_unref(mgmt_if);
+ mgmt_if = NULL;
+
+ return false;
+ }
+
+ if (index >= 0)
+ option_index = index;
+
+ adapter_ready = cb;
+
+ return true;
+}
+
+static void shutdown_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ bt_adapter_stopped cb = user_data;
+
+ if (status != MGMT_STATUS_SUCCESS)
+ error("Clean controller shutdown failed");
+
+ cb();
+}
+
+bool bt_adapter_stop(bt_adapter_stopped cb)
+{
+ struct mgmt_mode cp;
+
+ if (adapter_index == MGMT_INDEX_NONE)
+ return false;
+
+ info("Switching controller off");
+
+ memset(&cp, 0, sizeof(cp));
+
+ return mgmt_send(mgmt_if, MGMT_OP_SET_POWERED, adapter_index,
+ sizeof(cp), &cp, shutdown_complete, (void *)cb,
+ NULL) > 0;
+}
+
+void bt_adapter_cleanup(void)
+{
+ g_free(adapter_name);
+ adapter_name = NULL;
+
+ mgmt_unref(mgmt_if);
+ mgmt_if = NULL;
+}
+
static bool set_discoverable(uint8_t mode, uint16_t timeout)
{
struct mgmt_cp_set_discoverable cp;
diff --git a/android/adapter.h b/android/adapter.h
index c62b859..c9f0083 100644
--- a/android/adapter.h
+++ b/android/adapter.h
@@ -22,9 +22,12 @@
*/
typedef void (*bt_adapter_ready)(int err);
+bool bt_adapter_start(int index, bt_adapter_ready cb);
-void bt_adapter_init(uint16_t index, struct mgmt *mgmt_if,
- bt_adapter_ready cb);
+typedef void (*bt_adapter_stopped)(void);
+bool bt_adapter_stop(bt_adapter_stopped cb);
+
+void bt_adapter_cleanup(void);
void bt_adapter_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len);
diff --git a/android/main.c b/android/main.c
index 36cc8aa..f82e6d8 100644
--- a/android/main.c
+++ b/android/main.c
@@ -45,8 +45,6 @@
#include "src/sdpd.h"
#include "lib/bluetooth.h"
-#include "lib/mgmt.h"
-#include "src/shared/mgmt.h"
#include "adapter.h"
#include "socket.h"
@@ -65,11 +63,9 @@
#define STARTUP_GRACE_SECONDS 5
#define SHUTDOWN_GRACE_SECONDS 10
-static GMainLoop *event_loop;
-static struct mgmt *mgmt_if = NULL;
+static guint bluetooth_start_timeout = 0;
-static uint16_t adapter_index = MGMT_INDEX_NONE;
-static guint adapter_timeout = 0;
+static GMainLoop *event_loop;
static GIOChannel *hal_cmd_io = NULL;
static GIOChannel *hal_notif_io = NULL;
@@ -186,35 +182,32 @@ static void handle_service_core(uint8_t opcode, void *buf, uint16_t len)
}
}
-static void shutdown_complete(uint8_t status, uint16_t length,
- const void *param, void *user_data)
+static void bluetooth_stopped(void)
{
- if (status != MGMT_STATUS_SUCCESS)
- error("Clean controller shutdown failed");
+ g_main_loop_quit(event_loop);
+}
+static gboolean quit_eventloop(gpointer user_data)
+{
g_main_loop_quit(event_loop);
+ return FALSE;
}
-static void shutdown_controller(void)
+static void stop_bluetooth(void)
{
- static bool __shutdown = false;
- struct mgmt_mode cp;
+ static bool __stop = false;
- if (__shutdown)
+ if (__stop)
return;
- __shutdown = true;
-
- info("Switching controller off");
+ __stop = true;
- memset(&cp, 0, sizeof(cp));
- cp.val = 0x00;
-
- if (mgmt_send(mgmt_if, MGMT_OP_SET_POWERED, adapter_index,
- sizeof(cp), &cp, shutdown_complete, NULL, NULL) > 0)
+ if (!bt_adapter_stop(bluetooth_stopped)) {
+ g_main_loop_quit(event_loop);
return;
+ }
- g_main_loop_quit(event_loop);
+ g_timeout_add_seconds(SHUTDOWN_GRACE_SECONDS, quit_eventloop, NULL);
}
static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
@@ -279,7 +272,7 @@ static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
return TRUE;
fail:
- shutdown_controller();
+ stop_bluetooth();
return FALSE;
}
@@ -287,7 +280,7 @@ static gboolean notif_watch_cb(GIOChannel *io, GIOCondition cond,
gpointer user_data)
{
info("HAL notification socket closed, terminating");
- shutdown_controller();
+ stop_bluetooth();
return FALSE;
}
@@ -336,7 +329,7 @@ static gboolean notif_connect_cb(GIOChannel *io, GIOCondition cond,
DBG("");
if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
- g_main_loop_quit(event_loop);
+ stop_bluetooth();
return FALSE;
}
@@ -359,23 +352,38 @@ static gboolean cmd_connect_cb(GIOChannel *io, GIOCondition cond,
DBG("");
if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
- g_main_loop_quit(event_loop);
+ stop_bluetooth();
return FALSE;
}
hal_notif_io = connect_hal(notif_connect_cb);
if (!hal_notif_io) {
error("Cannot connect to HAL, terminating");
- g_main_loop_quit(event_loop);
+ stop_bluetooth();
}
return FALSE;
}
-static gboolean quit_eventloop(gpointer user_data)
+static void adapter_ready(int err)
{
- g_main_loop_quit(event_loop);
- return FALSE;
+ if (err < 0) {
+ error("Adapter initialization failed: %s", strerror(-err));
+ exit(EXIT_FAILURE);
+ }
+
+ if (bluetooth_start_timeout > 0) {
+ g_source_remove(bluetooth_start_timeout);
+ bluetooth_start_timeout = 0;
+ }
+
+ info("Adapter initialized");
+
+ hal_cmd_io = connect_hal(cmd_connect_cb);
+ if (!hal_cmd_io) {
+ error("Cannot connect to HAL, terminating");
+ stop_bluetooth();
+ }
}
static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
@@ -400,12 +408,7 @@ static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
case SIGTERM:
if (!__terminated) {
info("Terminating");
- if (adapter_index != MGMT_INDEX_NONE) {
- g_timeout_add_seconds(SHUTDOWN_GRACE_SECONDS,
- quit_eventloop, NULL);
- shutdown_controller();
- } else
- g_main_loop_quit(event_loop);
+ stop_bluetooth();
}
__terminated = true;
@@ -453,7 +456,7 @@ static guint setup_signalfd(void)
}
static gboolean option_version = FALSE;
-static gint option_index = MGMT_INDEX_NONE;
+static gint option_index = -1;
static GOptionEntry options[] = {
{ "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
@@ -463,216 +466,6 @@ static GOptionEntry options[] = {
{ NULL }
};
-static void adapter_ready(int err)
-{
- if (err < 0) {
- error("Adapter initialization failed: %s", strerror(-err));
- exit(EXIT_FAILURE);
- }
-
- info("Adapter initialized");
-
- hal_cmd_io = connect_hal(cmd_connect_cb);
- if (!hal_cmd_io) {
- error("Cannot connect to HAL, terminating");
- g_main_loop_quit(event_loop);
- }
-}
-
-static void mgmt_index_added_event(uint16_t index, uint16_t length,
- const void *param, void *user_data)
-{
- uint16_t opt_index = option_index;
-
- DBG("index %u", index);
-
- if (adapter_index != MGMT_INDEX_NONE) {
- DBG("skip event for index %u", index);
- return;
- }
-
- if (opt_index != MGMT_INDEX_NONE && opt_index != index) {
- DBG("skip event for index %u (option %u)", index, opt_index);
- return;
- }
-
- if (adapter_timeout > 0) {
- g_source_remove(adapter_timeout);
- adapter_timeout = 0;
- }
-
- adapter_index = index;
- bt_adapter_init(index, mgmt_if, adapter_ready);
-}
-
-static void mgmt_index_removed_event(uint16_t index, uint16_t length,
- const void *param, void *user_data)
-{
- DBG("index %u", index);
-
- if (index != adapter_index)
- return;
-
- error("Adapter was removed. Exiting.");
- g_main_loop_quit(event_loop);
-}
-
-static gboolean adapter_timeout_handler(gpointer user_data)
-{
- adapter_timeout = 0;
- g_main_loop_quit(event_loop);
-
- return FALSE;
-}
-
-static void read_index_list_complete(uint8_t status, uint16_t length,
- const void *param, void *user_data)
-{
- const struct mgmt_rp_read_index_list *rp = param;
- uint16_t opt_index = option_index;
- uint16_t num;
- int i;
-
- DBG("");
-
- if (status) {
- error("%s: Failed to read index list: %s (0x%02x)",
- __func__, mgmt_errstr(status), status);
- goto failed;
- }
-
- if (length < sizeof(*rp)) {
- error("%s: Wrong size of read index list response", __func__);
- goto failed;
- }
-
- num = btohs(rp->num_controllers);
-
- DBG("Number of controllers: %u", num);
-
- if (num * sizeof(uint16_t) + sizeof(*rp) != length) {
- error("%s: Incorrect pkt size for index list rsp", __func__);
- goto failed;
- }
-
- if (adapter_index != MGMT_INDEX_NONE)
- return;
-
- for (i = 0; i < num; i++) {
- uint16_t index = btohs(rp->index[i]);
-
- if (opt_index != MGMT_INDEX_NONE && opt_index != index)
- continue;
-
- adapter_index = index;
- bt_adapter_init(adapter_index, mgmt_if, adapter_ready);
- return;
- }
-
- if (adapter_index != MGMT_INDEX_NONE)
- return;
-
- adapter_timeout = g_timeout_add_seconds(STARTUP_GRACE_SECONDS,
- adapter_timeout_handler, NULL);
- if (adapter_timeout > 0)
- return;
-
- error("%s: Failed init timeout", __func__);
-
-failed:
- g_main_loop_quit(event_loop);
-}
-
-static void read_commands_complete(uint8_t status, uint16_t length,
- const void *param, void *user_data)
-{
- const struct mgmt_rp_read_commands *rp = param;
-
- DBG("");
-
- if (status) {
- error("Failed to read supported commands: %s (0x%02x)",
- mgmt_errstr(status), status);
- return;
- }
-
- if (length < sizeof(*rp)) {
- error("Wrong size response");
- return;
- }
-}
-
-static void read_version_complete(uint8_t status, uint16_t length,
- const void *param, void *user_data)
-{
- const struct mgmt_rp_read_version *rp = param;
- uint8_t mgmt_version, mgmt_revision;
-
- DBG("");
-
- if (status) {
- error("Failed to read version information: %s (0x%02x)",
- mgmt_errstr(status), status);
- goto failed;
- }
-
- if (length < sizeof(*rp)) {
- error("Wrong size response");
- goto failed;
- }
-
- mgmt_version = rp->version;
- mgmt_revision = btohs(rp->revision);
-
- info("Bluetooth management interface %u.%u initialized",
- mgmt_version, mgmt_revision);
-
- if (MGMT_VERSION(mgmt_version, mgmt_revision) < MGMT_VERSION(1, 3)) {
- error("Version 1.3 or later of management interface required");
- goto failed;
- }
-
- mgmt_send(mgmt_if, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE, 0, NULL,
- read_commands_complete, NULL, NULL);
-
- mgmt_register(mgmt_if, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
- mgmt_index_added_event, NULL, NULL);
- mgmt_register(mgmt_if, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
- mgmt_index_removed_event, NULL, NULL);
-
- if (mgmt_send(mgmt_if, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
- NULL, read_index_list_complete, NULL, NULL) > 0)
- return;
-
- error("Failed to read controller index list");
-
-failed:
- g_main_loop_quit(event_loop);
-}
-
-static bool init_mgmt_interface(void)
-{
- mgmt_if = mgmt_new_default();
- if (!mgmt_if) {
- error("Failed to access management interface");
- return false;
- }
-
- if (mgmt_send(mgmt_if, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE, 0, NULL,
- read_version_complete, NULL, NULL) == 0) {
- error("Error sending READ_VERSION mgmt command");
- return false;
- }
-
- return true;
-}
-
-static void cleanup_mgmt_interface(void)
-{
- mgmt_unref(mgmt_if);
- mgmt_if = NULL;
-}
-
static void cleanup_hal_connection(void)
{
if (hal_cmd_io) {
@@ -757,7 +550,14 @@ int main(int argc, char *argv[])
if (!set_capabilities())
return EXIT_FAILURE;
- if (!init_mgmt_interface())
+ bluetooth_start_timeout = g_timeout_add_seconds(STARTUP_GRACE_SECONDS,
+ quit_eventloop, NULL);
+ if (bluetooth_start_timeout == 0) {
+ error("Failed to init startup timeout");
+ return EXIT_FAILURE;
+ }
+
+ if (!bt_adapter_start(option_index, adapter_ready))
return EXIT_FAILURE;
/* Use params: mtu = 0, flags = 0 */
@@ -771,7 +571,7 @@ int main(int argc, char *argv[])
cleanup_hal_connection();
stop_sdp_server();
- cleanup_mgmt_interface();
+ bt_adapter_cleanup();
g_main_loop_unref(event_loop);
info("Exit");
--
1.8.4.2
^ permalink raw reply related
* [PATCH 3/7] android/hidhost: Use adapter address provided on register
From: Szymon Janc @ 2013-11-12 0:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384215857-19679-1-git-send-email-szymon.janc@tieto.com>
There is no need to use bt_adapter_get_address every time local address
is needed.
---
android/hidhost.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/android/hidhost.c b/android/hidhost.c
index 683938f..cdc6776 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -47,7 +47,6 @@
#include "hal-msg.h"
#include "ipc.h"
#include "hidhost.h"
-#include "adapter.h"
#include "utils.h"
#define L2CAP_PSM_HIDP_CTRL 0x11
@@ -77,6 +76,8 @@
/* HID Virtual Cable Unplug */
#define HID_VIRTUAL_CABLE_UNPLUG 0x05
+static const bdaddr_t *adapter_addr = NULL;
+
static int notification_sk = -1;
static GIOChannel *ctrl_io = NULL;
static GIOChannel *intr_io = NULL;
@@ -569,7 +570,6 @@ static void control_connect_cb(GIOChannel *chan, GError *conn_err,
{
struct hid_device *dev = user_data;
GError *err = NULL;
- const bdaddr_t *src = bt_adapter_get_address();
DBG("");
@@ -581,7 +581,7 @@ static void control_connect_cb(GIOChannel *chan, GError *conn_err,
/* Connect to the HID interrupt channel */
dev->intr_io = bt_io_connect(interrupt_connect_cb, dev, NULL, &err,
- BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_SOURCE_BDADDR, adapter_addr,
BT_IO_OPT_DEST_BDADDR, &dev->dst,
BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
@@ -607,7 +607,6 @@ static void hid_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
struct hid_device *dev = data;
sdp_list_t *list;
GError *gerr = NULL;
- const bdaddr_t *src = bt_adapter_get_address();
DBG("");
@@ -681,7 +680,7 @@ static void hid_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
}
dev->ctrl_io = bt_io_connect(control_connect_cb, dev, NULL, &gerr,
- BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_SOURCE_BDADDR, adapter_addr,
BT_IO_OPT_DEST_BDADDR, &dev->dst,
BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
@@ -706,7 +705,6 @@ static uint8_t bt_hid_connect(struct hal_cmd_hidhost_connect *cmd,
char addr[18];
bdaddr_t dst;
GSList *l;
- const bdaddr_t *src = bt_adapter_get_address();
uuid_t uuid;
DBG("");
@@ -728,8 +726,8 @@ static uint8_t bt_hid_connect(struct hal_cmd_hidhost_connect *cmd,
DBG("connecting to %s", addr);
bt_string2uuid(&uuid, HID_UUID);
- if (bt_search_service(src, &dev->dst, &uuid, hid_sdp_search_cb, dev,
- NULL) < 0) {
+ if (bt_search_service(adapter_addr, &dev->dst, &uuid,
+ hid_sdp_search_cb, dev, NULL) < 0) {
error("Failed to search sdp details");
hid_device_free(dev);
return HAL_STATUS_FAILED;
@@ -1167,12 +1165,13 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
bool bt_hid_register(int sk, const bdaddr_t *addr)
{
GError *err = NULL;
- const bdaddr_t *src = bt_adapter_get_address();
DBG("");
+ adapter_addr = addr;
+
ctrl_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &err,
- BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_SOURCE_BDADDR, adapter_addr,
BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
BT_IO_OPT_INVALID);
@@ -1183,7 +1182,7 @@ bool bt_hid_register(int sk, const bdaddr_t *addr)
}
intr_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &err,
- BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_SOURCE_BDADDR, adapter_addr,
BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
BT_IO_OPT_INVALID);
--
1.8.4.2
^ permalink raw reply related
* [PATCH 4/7] android: Report adapter address in adapter_ready callback
From: Szymon Janc @ 2013-11-12 0:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384215857-19679-1-git-send-email-szymon.janc@tieto.com>
Adapter is not going to change while daemon is running so its address
can be stored after init is complete.
---
android/adapter.c | 14 +++++++-------
android/adapter.h | 2 +-
android/main.c | 7 +++++--
3 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/android/adapter.c b/android/adapter.c
index 0c090bf..f337b5e 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -929,11 +929,11 @@ static void load_link_keys_complete(uint8_t status, uint16_t length,
DBG("status %u", status);
- adapter_ready(0);
+ adapter_ready(0, &adapter_bdaddr);
return;
failed:
- adapter_ready(err);
+ adapter_ready(err, NULL);
}
static void load_link_keys(GSList *keys)
@@ -968,7 +968,7 @@ static void load_link_keys(GSList *keys)
if (id == 0) {
error("Failed to load link keys");
- adapter_ready(-EIO);
+ adapter_ready(-EIO, NULL);
}
}
@@ -1138,7 +1138,7 @@ static void read_info_complete(uint8_t status, uint16_t length, const void *para
return;
failed:
- adapter_ready(err);
+ adapter_ready(err, NULL);
}
static void mgmt_index_added_event(uint16_t index, uint16_t length,
@@ -1158,7 +1158,7 @@ static void mgmt_index_added_event(uint16_t index, uint16_t length,
if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
read_info_complete, NULL, NULL) == 0) {
- adapter_ready(-EIO);
+ adapter_ready(-EIO, NULL);
return;
}
}
@@ -1224,7 +1224,7 @@ static void read_index_list_complete(uint8_t status, uint16_t length,
return;
failed:
- adapter_ready(-EIO);
+ adapter_ready(-EIO, NULL);
}
static void read_version_complete(uint8_t status, uint16_t length,
@@ -1269,7 +1269,7 @@ static void read_version_complete(uint8_t status, uint16_t length,
error("Failed to read controller index list");
failed:
- adapter_ready(-EIO);
+ adapter_ready(-EIO, NULL);
}
bool bt_adapter_start(int index, bt_adapter_ready cb)
diff --git a/android/adapter.h b/android/adapter.h
index c9f0083..96136bb 100644
--- a/android/adapter.h
+++ b/android/adapter.h
@@ -21,7 +21,7 @@
*
*/
-typedef void (*bt_adapter_ready)(int err);
+typedef void (*bt_adapter_ready)(int err, const bdaddr_t *addr);
bool bt_adapter_start(int index, bt_adapter_ready cb);
typedef void (*bt_adapter_stopped)(void);
diff --git a/android/main.c b/android/main.c
index f82e6d8..27513f8 100644
--- a/android/main.c
+++ b/android/main.c
@@ -65,6 +65,8 @@
static guint bluetooth_start_timeout = 0;
+static const bdaddr_t *adapter_bdaddr = NULL;
+
static GMainLoop *event_loop;
static GIOChannel *hal_cmd_io = NULL;
@@ -75,7 +77,6 @@ static bool services[HAL_SERVICE_ID_MAX + 1] = { false };
static void service_register(void *buf, uint16_t len)
{
struct hal_cmd_register_module *m = buf;
- const bdaddr_t *adapter_bdaddr = bt_adapter_get_address();
int sk = g_io_channel_unix_get_fd(hal_notif_io);
if (m->service_id > HAL_SERVICE_ID_MAX || services[m->service_id])
@@ -365,13 +366,15 @@ static gboolean cmd_connect_cb(GIOChannel *io, GIOCondition cond,
return FALSE;
}
-static void adapter_ready(int err)
+static void adapter_ready(int err, const bdaddr_t *addr)
{
if (err < 0) {
error("Adapter initialization failed: %s", strerror(-err));
exit(EXIT_FAILURE);
}
+ adapter_bdaddr = addr;
+
if (bluetooth_start_timeout > 0) {
g_source_remove(bluetooth_start_timeout);
bluetooth_start_timeout = 0;
--
1.8.4.2
^ permalink raw reply related
* [PATCH 5/7] android: Remove not needed bt_adapter_get_address function
From: Szymon Janc @ 2013-11-12 0:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384215857-19679-1-git-send-email-szymon.janc@tieto.com>
All services receive adapter address on init so there is no need for
this function. Removing it will also help keeping services not depend
on adapter service.
---
android/adapter.c | 5 -----
android/adapter.h | 2 --
2 files changed, 7 deletions(-)
diff --git a/android/adapter.c b/android/adapter.c
index f337b5e..e083131 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -1968,11 +1968,6 @@ error:
ipc_send_rsp(sk, HAL_SERVICE_ID_BLUETOOTH, status);
}
-const bdaddr_t *bt_adapter_get_address(void)
-{
- return &adapter_bdaddr;
-}
-
bool bt_adapter_register(int sk)
{
DBG("");
diff --git a/android/adapter.h b/android/adapter.h
index 96136bb..94c97ac 100644
--- a/android/adapter.h
+++ b/android/adapter.h
@@ -31,7 +31,5 @@ void bt_adapter_cleanup(void);
void bt_adapter_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len);
-const bdaddr_t *bt_adapter_get_address(void);
-
bool bt_adapter_register(int sk);
void bt_adapter_unregister(void);
--
1.8.4.2
^ permalink raw reply related
* [PATCH 7/7] android: Rename bluetooth service functions to match service name
From: Szymon Janc @ 2013-11-12 0:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384215857-19679-1-git-send-email-szymon.janc@tieto.com>
Make public functions match service name.
---
android/bluetooth.c | 16 ++++++++--------
android/bluetooth.h | 16 ++++++++--------
android/main.c | 13 +++++++------
3 files changed, 23 insertions(+), 22 deletions(-)
diff --git a/android/bluetooth.c b/android/bluetooth.c
index b3a6e20..9545ec4 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -61,7 +61,7 @@ static GSList *browse_reqs;
static uint16_t option_index = MGMT_INDEX_NONE;
static uint16_t adapter_index = MGMT_INDEX_NONE;
static struct mgmt *mgmt_if = NULL;
-static bt_adapter_ready adapter_ready = NULL;
+static bt_bluetooth_ready adapter_ready = NULL;
static bdaddr_t adapter_bdaddr;
static uint32_t adapter_dev_class = 0;
static char *adapter_name = NULL;
@@ -1272,7 +1272,7 @@ failed:
adapter_ready(-EIO, NULL);
}
-bool bt_adapter_start(int index, bt_adapter_ready cb)
+bool bt_bluetooth_start(int index, bt_bluetooth_ready cb)
{
DBG("index %d", index);
@@ -1303,7 +1303,7 @@ bool bt_adapter_start(int index, bt_adapter_ready cb)
static void shutdown_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
- bt_adapter_stopped cb = user_data;
+ bt_bluetooth_stopped cb = user_data;
if (status != MGMT_STATUS_SUCCESS)
error("Clean controller shutdown failed");
@@ -1311,7 +1311,7 @@ static void shutdown_complete(uint8_t status, uint16_t length,
cb();
}
-bool bt_adapter_stop(bt_adapter_stopped cb)
+bool bt_bluetooth_stop(bt_bluetooth_stopped cb)
{
struct mgmt_mode cp;
@@ -1327,7 +1327,7 @@ bool bt_adapter_stop(bt_adapter_stopped cb)
NULL) > 0;
}
-void bt_adapter_cleanup(void)
+void bt_bluetooth_cleanup(void)
{
g_free(adapter_name);
adapter_name = NULL;
@@ -1849,7 +1849,7 @@ static uint8_t get_remote_services(void *buf, uint16_t len)
return browse_remote_sdp(&addr);
}
-void bt_adapter_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
+void bt_bluetooth_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
{
uint8_t status = HAL_STATUS_FAILED;
@@ -1968,7 +1968,7 @@ error:
ipc_send_rsp(sk, HAL_SERVICE_ID_BLUETOOTH, status);
}
-bool bt_adapter_register(int sk)
+bool bt_bluetooth_register(int sk)
{
DBG("");
@@ -1977,7 +1977,7 @@ bool bt_adapter_register(int sk)
return true;
}
-void bt_adapter_unregister(void)
+void bt_bluetooth_unregister(void)
{
DBG("");
diff --git a/android/bluetooth.h b/android/bluetooth.h
index 94c97ac..88ec326 100644
--- a/android/bluetooth.h
+++ b/android/bluetooth.h
@@ -21,15 +21,15 @@
*
*/
-typedef void (*bt_adapter_ready)(int err, const bdaddr_t *addr);
-bool bt_adapter_start(int index, bt_adapter_ready cb);
+typedef void (*bt_bluetooth_ready)(int err, const bdaddr_t *addr);
+bool bt_bluetooth_start(int index, bt_bluetooth_ready cb);
-typedef void (*bt_adapter_stopped)(void);
-bool bt_adapter_stop(bt_adapter_stopped cb);
+typedef void (*bt_bluetooth_stopped)(void);
+bool bt_bluetooth_stop(bt_bluetooth_stopped cb);
-void bt_adapter_cleanup(void);
+void bt_bluetooth_cleanup(void);
-void bt_adapter_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len);
+void bt_bluetooth_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len);
-bool bt_adapter_register(int sk);
-void bt_adapter_unregister(void);
+bool bt_bluetooth_register(int sk);
+void bt_bluetooth_unregister(void);
diff --git a/android/main.c b/android/main.c
index e4c93ec..cbbfc06 100644
--- a/android/main.c
+++ b/android/main.c
@@ -84,7 +84,7 @@ static void service_register(void *buf, uint16_t len)
switch (m->service_id) {
case HAL_SERVICE_ID_BLUETOOTH:
- if (!bt_adapter_register(sk))
+ if (!bt_bluetooth_register(sk))
goto failed;
break;
@@ -134,7 +134,7 @@ static void service_unregister(void *buf, uint16_t len)
switch (m->service_id) {
case HAL_SERVICE_ID_BLUETOOTH:
- bt_adapter_unregister();
+ bt_bluetooth_unregister();
break;
case HAL_SERVICE_ID_SOCK:
bt_socket_unregister();
@@ -203,7 +203,7 @@ static void stop_bluetooth(void)
__stop = true;
- if (!bt_adapter_stop(bluetooth_stopped)) {
+ if (!bt_bluetooth_stop(bluetooth_stopped)) {
g_main_loop_quit(event_loop);
return;
}
@@ -251,7 +251,8 @@ static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
handle_service_core(msg->opcode, msg->payload, msg->len);
break;
case HAL_SERVICE_ID_BLUETOOTH:
- bt_adapter_handle_cmd(fd, msg->opcode, msg->payload, msg->len);
+ bt_bluetooth_handle_cmd(fd, msg->opcode, msg->payload,
+ msg->len);
break;
case HAL_SERVICE_ID_HIDHOST:
bt_hid_handle_cmd(fd, msg->opcode, msg->payload, msg->len);
@@ -560,7 +561,7 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
- if (!bt_adapter_start(option_index, adapter_ready))
+ if (!bt_bluetooth_start(option_index, adapter_ready))
return EXIT_FAILURE;
/* Use params: mtu = 0, flags = 0 */
@@ -574,7 +575,7 @@ int main(int argc, char *argv[])
cleanup_hal_connection();
stop_sdp_server();
- bt_adapter_cleanup();
+ bt_bluetooth_cleanup();
g_main_loop_unref(event_loop);
info("Exit");
--
1.8.4.2
^ permalink raw reply related
* Re: Problems with too many connections
From: Markus Roppelt @ 2013-11-12 8:29 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <A43EED3E-8B1F-4C4C-B7A9-26065DE55928@holtmann.org>
2013/9/27 Marcel Holtmann <marcel@holtmann.org>
>
> Hi Markus,
>
> > I want to write an application which repeats the following procedure
> > for several (100+) bluetooth (low energy) devices:
> >
> > 1. connect
> > 2. read register values
> > 3. disconnect
> >
> > Therefore I modified the source code from /attrib/interactive.c. For
> > testing purposes I am only looping over one device. See attached
> > source code.
> >
> > The code works fine. It connects, reads the values and disconnects.
> > However, after 1020 repetitions, the following error occurs:
> > (process:10205): GLib-WARNING **: poll(2) failed due to: Invalid argument.
> >
> > I think the problem has to do with some sockets / file descriptors not
> > being closed properly.
> >
> > Can someone help me to get this fixed?
>
> have you considered trying to write this from scratch and not basing this off existing code.
>
> And yes, this will be most likely an issues with GSource handling of the attribute IO channel, but since you hacked the code is extremely hard to debug. It was never designed for what you are doing.
>
> Regards
>
> Marcel
>
I found a solution myself. I quote from:
https://github.com/webOS-ports/nyx-modules/commit/bbcbbd64000ba76f39215e43a5179408ff96e097
"When a watch is added to the
glib mainloop it references internally a file descriptor to pass it
later to the poll
function (see poll(2)). Every watch gets an id which should be used by
the user to refer
to the watch whenever needed. When the io channel is destroyed the
watch should be remove
from the mainloop as well. If this isn't done probably by the user it
will cause the
internal list of fds which are passed to the poll function to exceed
the maximum of 256.
This finally results in poll returning EINVAL as error code."
With the additions from there my code runs without problems.
Greetings
Markus
^ permalink raw reply
* Re: [RFCv1 4/9] android/hal-sock: Initial listen handle
From: Marcin Kraglak @ 2013-11-12 8:45 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <1384178627-25991-5-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On 11 November 2013 15:03, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> 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);
shouldn't we free rfslot in case of error?
> + 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
>
> --
> 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
Best regards
Marcin
^ permalink raw reply
* Re: [PATCH] obex: Use user's cache dir as a default root
From: Luiz Augusto von Dentz @ 2013-11-12 8:58 UTC (permalink / raw)
To: Bastien Nocera; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1384093460.4593.8.camel@nuvo>
Hi Bastien,
On Sun, Nov 10, 2013 at 4:24 PM, Bastien Nocera <hadess@hadess.net> wrote:
>
> It's per-user, so we won't try to overwrite somebody else's
> files in /tmp when that happens. It's also (unless we have a
> particularly bizarre setup) on the same partition as the destination
> folder which means we can atomically move the file to the destination
> with a unique filename.
> ---
> obexd/src/main.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/obexd/src/main.c b/obexd/src/main.c
> index 61a06b2..2f7d723 100644
> --- a/obexd/src/main.c
> +++ b/obexd/src/main.c
> @@ -50,8 +50,6 @@
> #include "obexd.h"
> #include "server.h"
>
> -#define DEFAULT_ROOT_PATH "/tmp"
> -
> #define DEFAULT_CAP_FILE CONFIGDIR "/capability.xml"
>
> static GMainLoop *main_loop = NULL;
> @@ -285,8 +283,10 @@ int main(int argc, char *argv[])
> exit(EXIT_FAILURE);
> }
>
> - if (option_root == NULL)
> - option_root = g_strdup(DEFAULT_ROOT_PATH);
> + if (option_root == NULL) {
> + option_root = g_build_filename(g_get_user_cache_dir(), "obexd", NULL);
> + g_mkdir_with_parents(option_root, 0700);
> + }
>
> if (option_root[0] != '/') {
> char *old_root = option_root, *home = getenv("HOME");
> --
> 1.8.4.2
Pushed, thanks.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH 2/3] android/hidhost: Remove deprecated idle opcode from ipc document
From: Ravi Kumar Veeramally @ 2013-11-12 9:29 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <0C266DD4-7034-4D43-ADEB-E05BE0E54B32@holtmann.org>
Hi Marcel,
On 11/12/2013 01:05 AM, Marcel Holtmann wrote:
> 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
>
In HID_SPEC_V11 (3.1) Get Idle and Set Idle are deprecated. And even in
bt_hh.h
get_idle and set_idle interfaces are not available. Bluedroid had
implementation
of those two in bluedroid/btif/src/btif_hh.c but in interface struct
those are commented out.
I didn't find the call back call there. That's why I updated ipc-doc.
Please let me know if I miss anything.
Thanks,
Ravi.
^ permalink raw reply
* [PATCH] android/hidhost: Fix uhid create failure case
From: Ravi kumar Veeramally @ 2013-11-12 9:47 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
If uhid open or create fails then notify state and free the device.
Otherwise it replies bogus success return value on connect request.
---
android/hidhost.c | 19 +++++--------------
1 file changed, 5 insertions(+), 14 deletions(-)
diff --git a/android/hidhost.c b/android/hidhost.c
index 683938f..491eacd 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -514,6 +514,7 @@ static int uhid_create(struct hid_device *dev)
error("Failed to create uHID device: %s", strerror(errno));
close(dev->uhid_fd);
dev->uhid_fd = -1;
+ bt_hid_notify_state(dev, HAL_HIDHOST_STATE_NO_HID);
return -errno;
}
@@ -534,8 +535,10 @@ static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
DBG("");
- if (conn_err)
+ if (conn_err) {
+ error("%s", conn_err->message);
goto failed;
+ }
if (uhid_create(dev) < 0)
goto failed;
@@ -549,19 +552,7 @@ static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
return;
failed:
- /* So we guarantee the interrupt channel is closed before the
- * control channel (if we only do unref GLib will close it only
- * after returning control to the mainloop */
- if (!conn_err)
- g_io_channel_shutdown(dev->intr_io, FALSE, NULL);
-
- g_io_channel_unref(dev->intr_io);
- dev->intr_io = NULL;
-
- if (dev->ctrl_io) {
- g_io_channel_unref(dev->ctrl_io);
- dev->ctrl_io = NULL;
- }
+ hid_device_free(dev);
}
static void control_connect_cb(GIOChannel *chan, GError *conn_err,
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH 1/3] android/hidhost: Handle uhid output and feature events
From: Ravi Kumar Veeramally @ 2013-11-12 10:11 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384172130-29837-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Hi,
This patch is buggy. Conversion needs to be done like set_report and
send_data methods. I will send _v2 of this particular patch.
Sorry for inconvenience.
Thanks,
Ravi.
On 11/11/2013 02:15 PM, Ravi kumar Veeramally wrote:
> Data read on uhid events output and feature has to be send through
> SET_REPORT request to HID device.
> ---
> android/hidhost.c | 37 ++++++++++++++++++++++++++++++++++++-
> 1 file changed, 36 insertions(+), 1 deletion(-)
>
> diff --git a/android/hidhost.c b/android/hidhost.c
> index 683938f..816fe3e 100644
> --- a/android/hidhost.c
> +++ b/android/hidhost.c
> @@ -155,7 +155,42 @@ static void hid_device_free(struct hid_device *dev)
>
> static void handle_uhid_event(struct hid_device *dev, struct uhid_event *ev)
> {
> - DBG("UHID_OUTPUT UHID_FEATURE unsupported");
> + int fd;
> + uint8_t *req = NULL;
> + uint8_t req_size = 0;
> +
> + if (!(dev->ctrl_io))
> + return;
> +
> + switch (ev->type) {
> + case UHID_OUTPUT:
> + req_size = 1 + ev->u.output.size;
> + req = g_try_malloc0(req_size);
> + if (!req)
> + return;
> +
> + req[0] = HID_MSG_SET_REPORT | HID_DATA_TYPE_OUTPUT;
> + memcpy(req + 1, ev->u.output.data, ev->u.output.size);
> + break;
> +
> + case UHID_FEATURE:
> + req_size = sizeof(struct uhid_feature_req);
> + req = g_try_malloc0(req_size);
> + if (!req)
> + return;
> +
> + req[0] = HID_MSG_SET_REPORT | HID_DATA_TYPE_FEATURE;
> + memcpy(req + 1, (ev + sizeof(ev->type)), req_size - 1);
> + break;
> + }
> +
> + fd = g_io_channel_unix_get_fd(dev->ctrl_io);
> +
> + if (write(fd, req, req_size) < 0)
> + error("error writing hid_set_report: %s (%d)",
> + strerror(errno), errno);
> +
> + g_free(req);
> }
>
> static gboolean uhid_event_cb(GIOChannel *io, GIOCondition cond,
^ permalink raw reply
* [PATCH v2 0/5] Add support for registering local SDP records
From: Szymon Janc @ 2013-11-12 12:06 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
V2:
- don't use bt_uuid_t
- few bugfixes
V1 cover:
This adds support for manipulating local SDP database with
bt_adapter_add_record and bt_adapter_remove_record functions. Those should
be called when HAL service is registered or unregistered.
This also adds DeviceID record as at least 1 local UUID is needed by Android to
properly handle remote device profiles.
Last but not least: With this serie it is possible to connect HID device from
Android UI (Settings application). \O/
--
BR
Szymon Janc
Marcin Kraglak (3):
android: Add and remove sdp records and uuids
android: Clear adapter uuids during initialization
android: Add support for getting UUIDs property
Szymon Janc (2):
android: Remove not needed include
android: Register DeviceID record when adapter is initialized
android/adapter.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++----
android/adapter.h | 3 +
2 files changed, 178 insertions(+), 13 deletions(-)
--
1.8.4.2
^ permalink raw reply
* [PATCH v2 1/5] android: Add and remove sdp records and uuids
From: Szymon Janc @ 2013-11-12 12:06 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1384257985-26319-1-git-send-email-szymon.janc@tieto.com>
From: Marcin Kraglak <marcin.kraglak@tieto.com>
This is api for adding and removing sdp records and uuids
via mgmt interface. Local profiles have to store handle to
own records to remove them in cleanup. Additionally list of
uuids is created in bt_adapter struct.
---
android/adapter.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
android/adapter.h | 3 ++
2 files changed, 101 insertions(+)
diff --git a/android/adapter.c b/android/adapter.c
index 65b3170..b053043 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -40,6 +40,7 @@
#include "lib/sdp_lib.h"
#include "lib/uuid.h"
#include "src/sdp-client.h"
+#include "src/sdpd.h"
#include "log.h"
#include "hal-msg.h"
#include "ipc.h"
@@ -74,6 +75,7 @@ struct bt_adapter {
bool discovering;
uint32_t discoverable_timeout;
+ GSList *uuids;
};
struct browse_req {
@@ -986,6 +988,102 @@ static void load_link_keys(GSList *keys)
}
}
+/* output uint128 is in host order */
+static void uuid16_to_uint128(uint16_t uuid, uint128_t *u128)
+{
+ uuid_t uuid16, uuid128;
+
+ sdp_uuid16_create(&uuid16, uuid);
+ sdp_uuid16_to_uuid128(&uuid128, &uuid16);
+
+ ntoh128(&uuid128.value.uuid128, u128);
+}
+
+static void remove_uuid_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Failed to remove UUID: %s (0x%02x)",
+ mgmt_errstr(status), status);
+ return;
+ }
+
+ mgmt_dev_class_changed_event(adapter->index, length, param, NULL);
+}
+
+static void remove_uuid(uint128_t *uuid)
+{
+ struct mgmt_cp_remove_uuid cp;
+
+ htob128(uuid, (uint128_t *) cp.uuid);
+
+ mgmt_send(adapter->mgmt, MGMT_OP_REMOVE_UUID,
+ adapter->index, sizeof(cp), &cp,
+ remove_uuid_complete, NULL, NULL);
+}
+
+static void add_uuid_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Failed to add UUID: %s (0x%02x)",
+ mgmt_errstr(status), status);
+ return;
+ }
+
+ mgmt_dev_class_changed_event(adapter->index, length, param, NULL);
+}
+
+static void add_uuid(uint8_t svc_hint, uint128_t *uuid)
+{
+ struct mgmt_cp_add_uuid cp;
+
+ htob128(uuid, (uint128_t *) cp.uuid);
+ cp.svc_hint = svc_hint;
+
+ mgmt_send(adapter->mgmt, MGMT_OP_ADD_UUID,
+ adapter->index, sizeof(cp), &cp,
+ add_uuid_complete, NULL, NULL);
+}
+
+int bt_adapter_add_record(uint16_t uuid, sdp_record_t *rec, uint8_t svc_hint)
+{
+ uint128_t uint128;
+
+ if (g_slist_find(adapter->uuids, GUINT_TO_POINTER(uuid))) {
+ DBG("UUID 0x%x already added", uuid);
+ return -1;
+ }
+
+ adapter->uuids = g_slist_prepend(adapter->uuids,
+ GUINT_TO_POINTER(uuid));
+
+ uuid16_to_uint128(uuid, &uint128);
+
+ add_uuid(svc_hint, &uint128);
+
+ return add_record_to_server(&adapter->bdaddr, rec);
+}
+
+void bt_adapter_remove_record(uint16_t uuid, int handle)
+{
+ GSList *uuid_found;
+
+ uuid_found = g_slist_find(adapter->uuids, GUINT_TO_POINTER(uuid));
+ if (uuid_found) {
+ uint128_t uint128;
+
+ uuid16_to_uint128(uuid, &uint128);
+
+ remove_uuid(&uint128);
+
+ adapter->uuids = g_slist_remove(adapter->uuids,
+ uuid_found->data);
+ }
+
+ remove_record_from_server(handle);
+}
+
static void set_mode_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
diff --git a/android/adapter.h b/android/adapter.h
index c62b859..4c3100f 100644
--- a/android/adapter.h
+++ b/android/adapter.h
@@ -32,3 +32,6 @@ const bdaddr_t *bt_adapter_get_address(void);
bool bt_adapter_register(int sk);
void bt_adapter_unregister(void);
+
+int bt_adapter_add_record(uint16_t uuid, sdp_record_t *rec, uint8_t svc_hint);
+void bt_adapter_remove_record(uint16_t uuid, int handle);
--
1.8.4.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox