* Re: [PATCH] Bluetooth: Expose inquiry_cache debugfs only on BR/EDR controllers
From: Johan Hedberg @ 2013-10-16 15:20 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1381919335-59602-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Wed, Oct 16, 2013, Marcel Holtmann wrote:
> static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
> @@ -734,7 +772,22 @@ static int __hci_init(struct hci_dev *hdev)
> if (err < 0)
> return err;
>
> - return __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
> + err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
> + if (err < 0)
> + return err;
> +
> + /* Only create debugfs entries during the initial setup
> + * phase and not every time the controller gets powered on.
> + */
> + if (!test_bit(HCI_SETUP, &hdev->dev_flags))
> + return 0;
> +
> + if (lmp_bredr_capable(hdev)) {
> + debugfs_create_file("inquiry_cache", 0444, hdev->debugfs,
> + hdev, &inquiry_cache_fops);
> + }
The patch looks good but just a minor nit-pick here: do you really want
to have the curly braces for this one? Even though the function call is
split across two lines it doesn't make it any harder to read without the
braces, for me at least.
Johan
^ permalink raw reply
* Re: [PATCH v3 0/5] Stack independent BT HAL test tool
From: Johan Hedberg @ 2013-10-16 15:34 UTC (permalink / raw)
To: Jerzy Kasenberg; +Cc: linux-bluetooth
In-Reply-To: <1381932012-29641-1-git-send-email-jerzy.kasenberg@tieto.com>
Hi Jerzy,
On Wed, Oct 16, 2013, Jerzy Kasenberg wrote:
> v3:
> - underscores changed to dash in file names.
> - corrected cast style (space after cast).
> - structure initialization with explicit filed names.
> v2:
> - license changed to apache
> - source folder changed to hal-client (underscore to dash)
> v1:
> This tool is for testing Android HAL interfaces from command line.
> Due to lack of readline on Android simple equivalent is hand coded.
> This tool can be used with bluedroid stack so no glib dependency.
>
> Tool source code is in folder hal_client, please comment if it should be
> somewhere else.
>
> Comments welcome.
>
> Best regards
> Jerzy Kasenberg
>
> Jerzy Kasenberg (5):
> android: Add haltest skeleton
> android: Add line editing to haltest
> android: Add history to line editor in haltest
> android: Add text conversion helpers to haltest
> android: Add calls to adapter methods in haltest
>
> android/Android.mk | 21 ++
> android/client/haltest.c | 161 +++++++++++
> android/client/history.c | 98 +++++++
> android/client/history.h | 21 ++
> android/client/if-bt.c | 631 ++++++++++++++++++++++++++++++++++++++++++
> android/client/if-main.h | 99 +++++++
> android/client/pollhandler.c | 123 ++++++++
> android/client/pollhandler.h | 26 ++
> android/client/terminal.c | 538 +++++++++++++++++++++++++++++++++++
> android/client/terminal.h | 59 ++++
> android/client/textconv.c | 205 ++++++++++++++
> android/client/textconv.h | 113 ++++++++
> 12 files changed, 2095 insertions(+)
> create mode 100644 android/client/haltest.c
> create mode 100644 android/client/history.c
> create mode 100644 android/client/history.h
> create mode 100644 android/client/if-bt.c
> create mode 100644 android/client/if-main.h
> create mode 100644 android/client/pollhandler.c
> create mode 100644 android/client/pollhandler.h
> create mode 100644 android/client/terminal.c
> create mode 100644 android/client/terminal.h
> create mode 100644 android/client/textconv.c
> create mode 100644 android/client/textconv.h
All five patches have been pushed upstream. I did have to fix "empty
line before EOL" errors for each of the first three patches though, so
please avoid that in the future.
Johan
^ permalink raw reply
* [PATCH] Bluetooth: Remove not used struct sock
From: Gustavo Padovan @ 2013-10-16 15:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
It is a leftover from the recent effort of remove sk usage from L2CAP
core.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_core.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index b77e178..2681880 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3714,7 +3714,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
struct l2cap_conn_rsp rsp;
struct l2cap_chan *chan = NULL, *pchan;
- struct sock *parent, *sk = NULL;
+ struct sock *parent;
int result, status = L2CAP_CS_NO_INFO;
u16 dcid = 0, scid = __le16_to_cpu(req->scid);
@@ -3753,8 +3753,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
if (!chan)
goto response;
- sk = chan->sk;
-
/* For certain devices (ex: HID mouse), support for authentication,
* pairing and bonding is optional. For such devices, inorder to avoid
* the ACL alive for too long after L2CAP disconnection, reset the ACL
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCHv4 05/11] android: Add cap to bind to port < 1024
From: Johan Hedberg @ 2013-10-16 15:44 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1381934198-7955-6-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Wed, Oct 16, 2013, Andrei Emeltchenko wrote:
> For SDP server we need to bind to lower port, acquire this capability.
You might want to mention here exactly which capability it is instead of
just saying "this" :)
The patch also seems to do more than just related to POSIX capabilities
so you should also mention these things in the commit message.
> diff --git a/android/main.c b/android/main.c
> index 3a20148..091ef20 100644
> --- a/android/main.c
> +++ b/android/main.c
> @@ -32,6 +32,21 @@
> #include <stdlib.h>
> #include <stdbool.h>
> #include <string.h>
> +#include <unistd.h>
> +#include <errno.h>
> +#include <sys/prctl.h>
> +
> +/**
> + * Include <sys/capability.h> for host build and
> + * also for Android 4.3 when it is added to bionic
> + */
> +#if !defined(ANDROID) || (PLATFORM_SDK_VERSION > 17)
> +#include <sys/capability.h>
> +#endif
> +
> +#if defined(ANDROID)
> +#include <private/android_filesystem_config.h>
> +#endif
>
> #include <glib.h>
>
> @@ -230,6 +245,58 @@ static void cleanup_mgmt_interface(void)
> mgmt_if = NULL;
> }
>
> +static bool set_capabilities(void)
This whole function seems to me like something that's not needed on
non-android (since we can just execute the daemon as root if necessary),
so I'd consider putting its entire contents behind #if defined(ANDROID)
^ permalink raw reply
* Re: [PATCHv4 06/11] android: Implement read_info_complete callback
From: Johan Hedberg @ 2013-10-16 15:47 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1381934198-7955-7-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Wed, Oct 16, 2013, Andrei Emeltchenko wrote:
> --- a/android/adapter.h
> +++ b/android/adapter.h
> @@ -34,3 +34,7 @@ struct bt_adapter *bt_adapter_new(uint16_t index, struct mgmt *mgmt_if);
>
> void bt_adapter_start(struct bt_adapter *adapter);
> void bt_adapter_stop(struct bt_adapter *adapter);
> +
> +void read_info_complete(uint8_t status, uint16_t length, const void *param,
> + void *user_data);
> +void load_link_keys(struct bt_adapter *adapter, GSList *keys);
Shouldn't you be following the appropriate name space for this header
file? I.e. bt_adapter_*.
That said, it seems to me like you don't need to have any public
functions like this at all if you just do the read_info from the
bt_adapter_new function since you get the mgmt context there anyway.
Johan
^ permalink raw reply
* Re: [PATCHv4 04/11] android: sdp: Reuse BlueZ SDP server in Android
From: Johan Hedberg @ 2013-10-16 15:48 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1381934198-7955-5-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Wed, Oct 16, 2013, Andrei Emeltchenko wrote:
> Reuse existing SDP server code in Android GPL daemon.
> ---
> Makefile.android | 4 +++-
> android/Android.mk | 8 ++++++++
> android/main.c | 5 +++++
> 3 files changed, 16 insertions(+), 1 deletion(-)
I've applied patches 1-4 upstream, however from there onwards there were
some issues that will still need to be resolved.
Johan
^ permalink raw reply
* Re: [PATCH] Bluetooth: Expose inquiry_cache debugfs only on BR/EDR controllers
From: Marcel Holtmann @ 2013-10-16 16:07 UTC (permalink / raw)
To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <20131016152018.GA18754@x220.p-661hnu-f1>
Hi Johan,
>> static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
>> @@ -734,7 +772,22 @@ static int __hci_init(struct hci_dev *hdev)
>> if (err < 0)
>> return err;
>>
>> - return __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
>> + err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
>> + if (err < 0)
>> + return err;
>> +
>> + /* Only create debugfs entries during the initial setup
>> + * phase and not every time the controller gets powered on.
>> + */
>> + if (!test_bit(HCI_SETUP, &hdev->dev_flags))
>> + return 0;
>> +
>> + if (lmp_bredr_capable(hdev)) {
>> + debugfs_create_file("inquiry_cache", 0444, hdev->debugfs,
>> + hdev, &inquiry_cache_fops);
>> + }
>
> The patch looks good but just a minor nit-pick here: do you really want
> to have the curly braces for this one? Even though the function call is
> split across two lines it doesn't make it any harder to read without the
> braces, for me at least.
that is because I am planning to add more in future patches.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH 1/2] Bluetooth: Convert auto accept timer to use delayed work
From: Marcel Holtmann @ 2013-10-16 16:13 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth
In-Reply-To: <1381936300-18629-1-git-send-email-johan.hedberg@gmail.com>
Hi Johan,
> Since the entire Bluetooth subsystem runs in workqueues these days there
> is no need to use a timer for deferring work.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> include/net/bluetooth/hci_core.h | 2 +-
> net/bluetooth/hci_conn.c | 14 ++++++--------
> net/bluetooth/hci_event.c | 3 ++-
> 3 files changed, 9 insertions(+), 10 deletions(-)
patch has been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH 2/2] Bluetooth: Convert idle timer to use delayed work
From: Marcel Holtmann @ 2013-10-16 16:13 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth
In-Reply-To: <1381936300-18629-2-git-send-email-johan.hedberg@gmail.com>
Hi Johan,
> There is no need to use a timer since the entire Bluetooth subsystem
> runs using workqueues these days.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> include/net/bluetooth/hci_core.h | 4 ++--
> net/bluetooth/hci_conn.c | 22 +++++++---------------
> 2 files changed, 9 insertions(+), 17 deletions(-)
patch has been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] Bluetooth: Remove not used struct sock
From: Marcel Holtmann @ 2013-10-16 16:14 UTC (permalink / raw)
To: Gustavo Padovan; +Cc: linux-bluetooth, Gustavo Padovan
In-Reply-To: <1381937991-12645-1-git-send-email-gustavo@padovan.org>
Hi Gustavo,
> It is a leftover from the recent effort of remove sk usage from L2CAP
> core.
>
> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> ---
> net/bluetooth/l2cap_core.c | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index b77e178..2681880 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -3714,7 +3714,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
> struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
> struct l2cap_conn_rsp rsp;
> struct l2cap_chan *chan = NULL, *pchan;
> - struct sock *parent, *sk = NULL;
> + struct sock *parent;
> int result, status = L2CAP_CS_NO_INFO;
>
> u16 dcid = 0, scid = __le16_to_cpu(req->scid);
> @@ -3753,8 +3753,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
> if (!chan)
> goto response;
>
> - sk = chan->sk;
> -
can we already do that? I still do not like the chan->data != sk magic check.
Regards
Marcel
^ permalink raw reply
* [PATCH] Bluetooth: Socket address parameter for CID is in little endian
From: Marcel Holtmann @ 2013-10-16 16:31 UTC (permalink / raw)
To: linux-bluetooth
The L2CAP socket parameter for CID are actually provided in little
endian. So convert our constants into little endian before comparing
them.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/l2cap_sock.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 95498d5..34e5a58 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -77,7 +77,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
if (la.l2_psm)
return -EINVAL;
/* We only allow ATT user space socket */
- if (la.l2_cid != L2CAP_CID_ATT)
+ if (la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT))
return -EINVAL;
}
@@ -170,7 +170,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr,
if (la.l2_psm)
return -EINVAL;
/* We only allow ATT user space socket */
- if (la.l2_cid != L2CAP_CID_ATT)
+ if (la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT))
return -EINVAL;
}
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH] Bluetooth: Socket address parameter for CID is in little endian
From: Johan Hedberg @ 2013-10-16 16:53 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1381941077-6941-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Wed, Oct 16, 2013, Marcel Holtmann wrote:
> The L2CAP socket parameter for CID are actually provided in little
> endian. So convert our constants into little endian before comparing
> them.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> net/bluetooth/l2cap_sock.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] Bluetooth: Expose inquiry_cache debugfs only on BR/EDR controllers
From: Johan Hedberg @ 2013-10-16 16:54 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1381919335-59602-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Wed, Oct 16, 2013, Marcel Holtmann wrote:
> The inquiry_cache debugfs entry is only valid for BR/EDR capable
> controllers. In case of single mode LE-only controllers that
> entry is not valid.
>
> Move the creating of the debugfs entries to the end of controller
> init and only create the inquiry_cache entry if BR/EDR is actually
> supported.
>
> At the same time this avoids creating any debugfs entries for
> AMP controllers since none of the entries are valid there.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> net/bluetooth/hci_core.c | 57 +++++++++++++++++++++++++++++++++++++++++++++--
> net/bluetooth/hci_sysfs.c | 39 --------------------------------
> 2 files changed, 55 insertions(+), 41 deletions(-)
Applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] Bluetooth: Remove not used struct sock
From: Gustavo Padovan @ 2013-10-16 17:14 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth, Gustavo Padovan
In-Reply-To: <121AE7E9-6B79-4132-8B59-DEDB1F6EBEE3@holtmann.org>
Hi Marcel,
2013-10-16 Marcel Holtmann <marcel@holtmann.org>:
> Hi Gustavo,
>
> > It is a leftover from the recent effort of remove sk usage from L2CAP
> > core.
> >
> > Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> > ---
> > net/bluetooth/l2cap_core.c | 4 +---
> > 1 file changed, 1 insertion(+), 3 deletions(-)
> >
> > diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> > index b77e178..2681880 100644
> > --- a/net/bluetooth/l2cap_core.c
> > +++ b/net/bluetooth/l2cap_core.c
> > @@ -3714,7 +3714,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
> > struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
> > struct l2cap_conn_rsp rsp;
> > struct l2cap_chan *chan = NULL, *pchan;
> > - struct sock *parent, *sk = NULL;
> > + struct sock *parent;
> > int result, status = L2CAP_CS_NO_INFO;
> >
> > u16 dcid = 0, scid = __le16_to_cpu(req->scid);
> > @@ -3753,8 +3753,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
> > if (!chan)
> > goto response;
> >
> > - sk = chan->sk;
> > -
>
> can we already do that? I still do not like the chan->data != sk magic check.
Yes, this is just a dead assignment. It is totally safe to remove it.
Gustavo
^ permalink raw reply
* [PATCH BlueZ] l2test: Set CID due to socket restrictions for LE
From: Claudio Takahasi @ 2013-10-16 19:05 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
Bluetooth kernel now restricts LE L2CAP sockets to ATT channels only.
For LE L2CAP socket bind, ATT CID is now mandatory. Reference: kernel patch
bfe4655f05d7ec4a7c0c1c7e4051862f824cd8ec
---
tools/l2test.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tools/l2test.c b/tools/l2test.c
index 125532b..c5c8763 100644
--- a/tools/l2test.c
+++ b/tools/l2test.c
@@ -280,6 +280,8 @@ static int do_connect(char *svr)
addr.l2_family = AF_BLUETOOTH;
bacpy(&addr.l2_bdaddr, &bdaddr);
addr.l2_bdaddr_type = bdaddr_type;
+ if (cid)
+ addr.l2_cid = htobs(cid);
if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
syslog(LOG_ERR, "Can't bind socket: %s (%d)",
--
1.8.3.1
^ permalink raw reply related
* [PATCH 1/7] Bluetooth: Remove not used struct sock
From: Gustavo Padovan @ 2013-10-16 19:08 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
It is a leftover from the recent effort of remove sk usage from L2CAP
core.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_core.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 8af34d2..5d99394 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3718,7 +3718,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
struct l2cap_conn_rsp rsp;
struct l2cap_chan *chan = NULL, *pchan;
- struct sock *parent, *sk = NULL;
+ struct sock *parent;
int result, status = L2CAP_CS_NO_INFO;
u16 dcid = 0, scid = __le16_to_cpu(req->scid);
@@ -3757,8 +3757,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
if (!chan)
goto response;
- sk = chan->sk;
-
/* For certain devices (ex: HID mouse), support for authentication,
* pairing and bonding is optional. For such devices, inorder to avoid
* the ACL alive for too long after L2CAP disconnection, reset the ACL
--
1.8.3.1
^ permalink raw reply related
* [PATCH 2/7] Bluetooth: Hold socket in defer callback in L2CAP socket
From: Gustavo Padovan @ 2013-10-16 19:08 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1381950515-25256-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
In both places that we use the defer callback the socket lock is held for
a indirect sk access inside __l2cap_change_state() and chan->ops->defer(),
all the rest of the code between lock_sock() and release_sock() is
already protected by the channel lock and won't be affected by this
change.
We now use l2cap_change_state(), the locked version of the change state
function, and the defer callback does the locking itself now. This does
not affect other uses of the defer callback.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_core.c | 15 +++------------
net/bluetooth/l2cap_sock.c | 8 ++++++--
2 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 5d99394..95e78ca 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1299,20 +1299,16 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
rsp.dcid = cpu_to_le16(chan->scid);
if (l2cap_chan_check_security(chan)) {
- struct sock *sk = chan->sk;
-
- lock_sock(sk);
if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
chan->ops->defer(chan);
} else {
- __l2cap_state_change(chan, BT_CONFIG);
+ l2cap_state_change(chan, BT_CONFIG);
rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
}
- release_sock(sk);
} else {
rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
@@ -6633,31 +6629,26 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
}
} else if (chan->state == BT_CONNECT2) {
- struct sock *sk = chan->sk;
struct l2cap_conn_rsp rsp;
__u16 res, stat;
- lock_sock(sk);
-
if (!status) {
if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
res = L2CAP_CR_PEND;
stat = L2CAP_CS_AUTHOR_PEND;
chan->ops->defer(chan);
} else {
- __l2cap_state_change(chan, BT_CONFIG);
+ l2cap_state_change(chan, BT_CONFIG);
res = L2CAP_CR_SUCCESS;
stat = L2CAP_CS_NO_INFO;
}
} else {
- __l2cap_state_change(chan, BT_DISCONN);
+ l2cap_state_change(chan, BT_DISCONN);
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
res = L2CAP_CR_SEC_BLOCK;
stat = L2CAP_CS_NO_INFO;
}
- release_sock(sk);
-
rsp.scid = cpu_to_le16(chan->dcid);
rsp.dcid = cpu_to_le16(chan->scid);
rsp.result = cpu_to_le16(res);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 34e5a58..347cc63 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1171,11 +1171,15 @@ static void l2cap_sock_ready_cb(struct l2cap_chan *chan)
static void l2cap_sock_defer_cb(struct l2cap_chan *chan)
{
- struct sock *sk = chan->data;
- struct sock *parent = bt_sk(sk)->parent;
+ struct sock *parent, *sk = chan->data;
+
+ lock_sock(sk);
+ parent = bt_sk(sk)->parent;
if (parent)
parent->sk_data_ready(parent, 0);
+
+ release_sock(sk);
}
static void l2cap_sock_resume_cb(struct l2cap_chan *chan)
--
1.8.3.1
^ permalink raw reply related
* [PATCH 3/7] Bluetooth: Remove socket lock from l2cap_state_change()
From: Gustavo Padovan @ 2013-10-16 19:08 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1381950515-25256-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
This simplify and make safer the state change handling inside l2cap_core.c.
we got rid of __l2cap_state_change(). And l2cap_state_change() doesn't lock
the socket anymore, instead the socket is locked inside the ops callback for
state change in l2cap_sock.c.
It makes the code safer because in some we were using a unlocked version,
and now we are calls to l2cap_state_change(), when dealing with sockets, use
the locked version.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_core.c | 31 +++++++------------------------
1 file changed, 7 insertions(+), 24 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 95e78ca..8c757c0 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -223,7 +223,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
return 0;
}
-static void __l2cap_state_change(struct l2cap_chan *chan, int state)
+static void l2cap_state_change(struct l2cap_chan *chan, int state)
{
BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
state_to_string(state));
@@ -232,33 +232,16 @@ static void __l2cap_state_change(struct l2cap_chan *chan, int state)
chan->ops->state_change(chan, state, 0);
}
-static void l2cap_state_change(struct l2cap_chan *chan, int state)
-{
- struct sock *sk = chan->sk;
-
- lock_sock(sk);
- __l2cap_state_change(chan, state);
- release_sock(sk);
-}
-
static inline void l2cap_state_change_and_error(struct l2cap_chan *chan,
int state, int err)
{
- struct sock *sk = chan->sk;
-
- lock_sock(sk);
chan->state = state;
chan->ops->state_change(chan, chan->state, err);
- release_sock(sk);
}
static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
{
- struct sock *sk = chan->sk;
-
- lock_sock(sk);
chan->ops->state_change(chan, chan->state, err);
- release_sock(sk);
}
static void __set_retrans_timer(struct l2cap_chan *chan)
@@ -3779,7 +3762,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
if (l2cap_chan_check_security(chan)) {
if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
- __l2cap_state_change(chan, BT_CONNECT2);
+ l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
status = L2CAP_CS_AUTHOR_PEND;
chan->ops->defer(chan);
@@ -3789,21 +3772,21 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
* physical link is up.
*/
if (amp_id == AMP_ID_BREDR) {
- __l2cap_state_change(chan, BT_CONFIG);
+ l2cap_state_change(chan, BT_CONFIG);
result = L2CAP_CR_SUCCESS;
} else {
- __l2cap_state_change(chan, BT_CONNECT2);
+ l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
}
status = L2CAP_CS_NO_INFO;
}
} else {
- __l2cap_state_change(chan, BT_CONNECT2);
+ l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
status = L2CAP_CS_AUTHEN_PEND;
}
} else {
- __l2cap_state_change(chan, BT_CONNECT2);
+ l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
status = L2CAP_CS_NO_INFO;
}
@@ -4730,7 +4713,7 @@ static void l2cap_do_create(struct l2cap_chan *chan, int result,
sizeof(rsp), &rsp);
if (result == L2CAP_CR_SUCCESS) {
- __l2cap_state_change(chan, BT_CONFIG);
+ l2cap_state_change(chan, BT_CONFIG);
set_bit(CONF_REQ_SENT, &chan->conf_state);
l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
L2CAP_CONF_REQ,
--
1.8.3.1
^ permalink raw reply related
* [PATCH 4/7] Bluetooth: Remove parent socket usage from l2cap_core.c
From: Gustavo Padovan @ 2013-10-16 19:08 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1381950515-25256-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
The parent socket is not used inside the L2CAP core anymore. We only lock
it to indirect access through the new_connection() callback. The hold of
the socket lock was moved to the new_connection() callback.
Inside L2CAP core the channel lock is now used in l2cap_le_conn_ready()
and l2cap_conn_ready() to protect the execution of these two functions
during the handling of new incoming connections.
This change remove the socket lock usage from L2CAP core while keeping
the code safe against race conditions.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_core.c | 14 ++++----------
net/bluetooth/l2cap_sock.c | 4 ++++
2 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 8c757c0..e30a53a 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1361,7 +1361,6 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
static void l2cap_le_conn_ready(struct l2cap_conn *conn)
{
- struct sock *parent;
struct l2cap_chan *chan, *pchan;
BT_DBG("");
@@ -1376,9 +1375,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT))
return;
- parent = pchan->sk;
-
- lock_sock(parent);
+ l2cap_chan_lock(pchan);
chan = pchan->ops->new_connection(pchan);
if (!chan)
@@ -1394,7 +1391,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
__l2cap_chan_add(conn, chan);
clean:
- release_sock(parent);
+ l2cap_chan_unlock(pchan);
}
static void l2cap_conn_ready(struct l2cap_conn *conn)
@@ -3697,7 +3694,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
struct l2cap_conn_rsp rsp;
struct l2cap_chan *chan = NULL, *pchan;
- struct sock *parent;
int result, status = L2CAP_CS_NO_INFO;
u16 dcid = 0, scid = __le16_to_cpu(req->scid);
@@ -3713,10 +3709,8 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
goto sendresp;
}
- parent = pchan->sk;
-
mutex_lock(&conn->chan_lock);
- lock_sock(parent);
+ l2cap_chan_lock(pchan);
/* Check if the ACL is secure enough (if not SDP) */
if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
@@ -3792,7 +3786,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
}
response:
- release_sock(parent);
+ l2cap_chan_unlock(pchan);
mutex_unlock(&conn->chan_lock);
sendresp:
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 347cc63..f5a7c66 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1019,6 +1019,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
{
struct sock *sk, *parent = chan->data;
+ lock_sock(parent);
+
/* Check for backlog size */
if (sk_acceptq_is_full(parent)) {
BT_DBG("backlog full %d", parent->sk_ack_backlog);
@@ -1036,6 +1038,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
bt_accept_enqueue(parent, sk);
+ release_sock(parent);
+
return l2cap_pi(sk)->chan;
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH 5/7] Bluetooth: Create recv_raw() channel callback
From: Gustavo Padovan @ 2013-10-16 19:08 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1381950515-25256-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
This new callback isolates socket specific code from L2CAP core.
A dummy version of the callback, l2cap_chan_no_recv_raw() is provided for
users that do not need to receive raw data.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
include/net/bluetooth/l2cap.h | 8 ++++++++
net/bluetooth/a2mp.c | 1 +
net/bluetooth/l2cap_core.c | 12 +-----------
net/bluetooth/l2cap_sock.c | 22 ++++++++++++++++++++++
4 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 3d922b9..af5eb23 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -548,6 +548,8 @@ struct l2cap_ops {
struct l2cap_chan *(*new_connection) (struct l2cap_chan *chan);
int (*recv) (struct l2cap_chan * chan,
struct sk_buff *skb);
+ int (*recv_raw) (struct l2cap_chan * chan,
+ struct sk_buff *skb);
void (*teardown) (struct l2cap_chan *chan, int err);
void (*close) (struct l2cap_chan *chan);
void (*state_change) (struct l2cap_chan *chan,
@@ -785,6 +787,12 @@ static inline struct l2cap_chan *l2cap_chan_no_new_connection(struct l2cap_chan
return NULL;
}
+static inline int l2cap_chan_no_recv_raw(struct l2cap_chan *chan,
+ struct sk_buff *skb)
+{
+ return 0;
+}
+
static inline void l2cap_chan_no_teardown(struct l2cap_chan *chan, int err)
{
}
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index efcd108..72540a7 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -707,6 +707,7 @@ static struct l2cap_ops a2mp_chan_ops = {
/* Not implemented for A2MP */
.new_connection = l2cap_chan_no_new_connection,
+ .recv_raw = l2cap_chan_no_recv_raw,
.teardown = l2cap_chan_no_teardown,
.ready = l2cap_chan_no_ready,
.defer = l2cap_chan_no_defer,
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index e30a53a..45fcf5e 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2797,7 +2797,6 @@ static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
/* Copy frame to all raw sockets on that connection */
static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
{
- struct sk_buff *nskb;
struct l2cap_chan *chan;
BT_DBG("conn %p", conn);
@@ -2805,19 +2804,10 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
mutex_lock(&conn->chan_lock);
list_for_each_entry(chan, &conn->chan_l, list) {
- struct sock *sk = chan->sk;
if (chan->chan_type != L2CAP_CHAN_RAW)
continue;
- /* Don't send frame to the socket it came from */
- if (skb->sk == sk)
- continue;
- nskb = skb_clone(skb, GFP_KERNEL);
- if (!nskb)
- continue;
-
- if (chan->ops->recv(chan, nskb))
- kfree_skb(nskb);
+ chan->ops->recv_raw(chan, skb);
}
mutex_unlock(&conn->chan_lock);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index f5a7c66..b8be4fb 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1078,6 +1078,27 @@ done:
return err;
}
+static int l2cap_sock_recv_raw_cb(struct l2cap_chan *chan, struct sk_buff *skb)
+{
+ struct sock *sk = chan->data;
+ struct sk_buff *nskb;
+ int err;
+
+ /* Don't send frame to the socket it came from */
+ if (skb->sk == sk)
+ return 0;
+
+ nskb = skb_clone(skb, GFP_KERNEL);
+ if (!nskb)
+ return -ENOMEM;
+
+ err = sock_queue_rcv_skb(sk, nskb);
+ if (err < 0)
+ kfree_skb(nskb);
+
+ return err;
+}
+
static void l2cap_sock_close_cb(struct l2cap_chan *chan)
{
struct sock *sk = chan->data;
@@ -1214,6 +1235,7 @@ static struct l2cap_ops l2cap_chan_ops = {
.name = "L2CAP Socket Interface",
.new_connection = l2cap_sock_new_connection_cb,
.recv = l2cap_sock_recv_cb,
+ .recv_raw = l2cap_sock_recv_raw_cb,
.close = l2cap_sock_close_cb,
.teardown = l2cap_sock_teardown_cb,
.state_change = l2cap_sock_state_change_cb,
--
1.8.3.1
^ permalink raw reply related
* [PATCH 6/7] Bluetooth: Do not access chan->sk directly
From: Gustavo Padovan @ 2013-10-16 19:08 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1381950515-25256-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
In the process of removing socket usage from L2CAP we now access the L2CAP
socket from the data member of struct l2cap_chan. For the L2CAP socket
user the data member points to the L2CAP socket.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
net/bluetooth/l2cap_sock.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index b8be4fb..5c84f8a 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1161,11 +1161,12 @@ static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state,
static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
unsigned long len, int nb)
{
+ struct sock *sk = chan->data;
struct sk_buff *skb;
int err;
l2cap_chan_unlock(chan);
- skb = bt_skb_send_alloc(chan->sk, len, nb, &err);
+ skb = bt_skb_send_alloc(sk, len, nb, &err);
l2cap_chan_lock(chan);
if (!skb)
--
1.8.3.1
^ permalink raw reply related
* [PATCH 7/7] Bluetooth: Remove sk member from struct l2cap_chan
From: Gustavo Padovan @ 2013-10-16 19:08 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1381950515-25256-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
There is no access to chan->sk in L2CAP core now. This change marks the
of the task of splitting L2CAP between Core and Socket, thus sk is now
gone from struct l2cap_chan.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
include/net/bluetooth/l2cap.h | 2 --
net/bluetooth/l2cap_sock.c | 2 --
2 files changed, 4 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index af5eb23..65356bf 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -435,8 +435,6 @@ struct l2cap_seq_list {
#define L2CAP_SEQ_LIST_TAIL 0x8000
struct l2cap_chan {
- struct sock *sk;
-
struct l2cap_conn *conn;
struct hci_conn *hs_hcon;
struct hci_chan *hs_hchan;
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 5c84f8a..93fc464 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1371,8 +1371,6 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
l2cap_chan_hold(chan);
- chan->sk = sk;
-
l2cap_pi(sk)->chan = chan;
return sk;
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH BlueZ] l2test: Set CID due to socket restrictions for LE
From: Johan Hedberg @ 2013-10-16 20:35 UTC (permalink / raw)
To: Claudio Takahasi; +Cc: linux-bluetooth
In-Reply-To: <1381950307-7155-1-git-send-email-claudio.takahasi@openbossa.org>
Hi Claudio,
On Wed, Oct 16, 2013, Claudio Takahasi wrote:
> Bluetooth kernel now restricts LE L2CAP sockets to ATT channels only.
> For LE L2CAP socket bind, ATT CID is now mandatory. Reference: kernel patch
> bfe4655f05d7ec4a7c0c1c7e4051862f824cd8ec
> ---
> tools/l2test.c | 2 ++
> 1 file changed, 2 insertions(+)
Applied thanks.
Btw, I didn't realize that this check wasn't there before. It seems like
it shouldn't cause any "real life" issues as our btio has always done a
bind with the correct CID. Can you confirm that this should only be an
issue for l2test?
Johan
^ permalink raw reply
* [RFC 00/15] LE auto connection and connection parameters
From: Andre Guedes @ 2013-10-16 23:17 UTC (permalink / raw)
To: linux-bluetooth
Hi all,
This patchset adds support for the LE auto connection mechanism discussed
during the Wireless Summit in New Orleans.
The user configures the connection parameters and the auto connection
policy for each device according to the LE profiles that device supports.
The auto connection policies are:
* DISABLED: kernel never establishes connections autonomously.
* LINK_LOSS: kernel automatically reconnects if connection terminates due to
a link loss.
* ALWAYS: kernel always autonomously connects to device
In order to implement the auto connection mechanism, it was introduced the
background scanning infrastructure which keeps the controller (passively)
scanning as long as there is auto connection pending. Also, two new Mgmt
commands are introduced to add and remove connection parameters for a certain
device.
This patchset is organized as follows:
* Patch 1 - 3: Adds the new Mgmt commands.
* Patch 4 - 5: Use connection parameters specified by user.
* Patch 6: Introduce the background scan infrastructure.
* Patch 7 - 9: Implement the auto connection policies.
* Patch 10 - 11: Add special handling for devices that don't support scanning
and initiating connections at the same time.
* Patch 12 - 14: Add proper handling for auto connection and discovery running
at the same time.
* Patch 15: Add special handling for power off/on.
Regards,
Andre
Andre Guedes (15):
Bluetooth: Introduce connection parameters list
Bluetooth: Mgmt command for adding connection parameters
Bluetooth: Mgmt command for removing connection parameters
Bluetooth: Make find_conn_param() helper non-local
Bluetooth: Use connection parameters if any
Bluetooth: Background scanning
Bluetooth: Refactor hci_disconn_complete_evt
Bluetooth: Add support for BT_AUTO_CONN_ALWAYS
Bluetooth: Add support for BT_AUTO_CONN_LINK_LOSS option
Bluetooth: Create start_background_scan helper
Bluetooth: Temporarily stop background scanning on connection
Bluetooth: Temporarily stop background scanning on discovery
Bluetooth: Fix background trigger/untrigger functions
Bluetooth: Fix hci_create_le_conn()
Bluetooth: Auto connection and power off/on
include/net/bluetooth/bluetooth.h | 6 +
include/net/bluetooth/hci_core.h | 36 ++++
include/net/bluetooth/mgmt.h | 15 ++
net/bluetooth/hci_conn.c | 77 ++++++++-
net/bluetooth/hci_core.c | 338 ++++++++++++++++++++++++++++++++++++++
net/bluetooth/hci_event.c | 112 +++++++++----
net/bluetooth/mgmt.c | 76 ++++++++-
7 files changed, 626 insertions(+), 34 deletions(-)
--
1.8.4
^ permalink raw reply
* [RFC 01/15] Bluetooth: Introduce connection parameters list
From: Andre Guedes @ 2013-10-16 23:17 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1381965485-9159-1-git-send-email-andre.guedes@openbossa.org>
This patch adds to hdev the connection parameters list (hdev->
conn_param). The elements from this list (struct hci_conn_param)
contains the connection parameters (for now, minimum and maximum
connection interval) that should be used for establishing
connection.
The struct hci_conn_param also defines the 'auto_connect' field
which will be used to implement the auto connection mechanism.
Moreover, this patch adds helper functions to manipulate hdev->conn_
param list. Some of these functions are also declared in hci_core.h
since they will be used outside hci_core.c in upcoming patches.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 23 +++++++++++
net/bluetooth/hci_core.c | 88 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 111 insertions(+)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 07c2da4..5052bf0 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -266,6 +266,8 @@ struct hci_dev {
struct list_head remote_oob_data;
+ struct list_head conn_param;
+
struct hci_dev_stats stat;
atomic_t promisc;
@@ -368,6 +370,22 @@ struct hci_chan {
__u8 state;
};
+struct hci_conn_param {
+ struct list_head list;
+
+ bdaddr_t addr;
+ u8 addr_type;
+
+ enum {
+ HCI_AUTO_CONN_DISABLED,
+ HCI_AUTO_CONN_ALWAYS,
+ HCI_AUTO_CONN_LINK_LOSS,
+ } auto_connect;
+
+ u16 min_conn_interval;
+ u16 max_conn_interval;
+};
+
extern struct list_head hci_dev_list;
extern struct list_head hci_cb_list;
extern rwlock_t hci_dev_list_lock;
@@ -737,6 +755,11 @@ int hci_blacklist_clear(struct hci_dev *hdev);
int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
+int hci_add_conn_param(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
+ u8 auto_connect, u16 min_conn_interval,
+ u16 max_conn_interval);
+void hci_remove_conn_param(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
+
int hci_uuids_clear(struct hci_dev *hdev);
int hci_link_keys_clear(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 73c8def..a4242ac 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2151,6 +2151,92 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
return mgmt_device_unblocked(hdev, bdaddr, type);
}
+struct hci_conn_param *find_conn_param(struct hci_dev *hdev,
+ bdaddr_t *addr, u8 addr_type)
+{
+ struct hci_conn_param *param;
+
+ rcu_read_lock();
+
+ list_for_each_entry(param, &hdev->conn_param, list) {
+ if (bacmp(¶m->addr, addr))
+ continue;
+ if (param->addr_type != addr_type)
+ continue;
+
+ rcu_read_unlock();
+ return param;
+ }
+
+ rcu_read_unlock();
+ return NULL;
+}
+
+int hci_add_conn_param(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
+ u8 auto_connect, u16 min_conn_interval,
+ u16 max_conn_interval)
+{
+ struct hci_conn_param *param;
+
+ param = find_conn_param(hdev, addr, addr_type);
+ if (param)
+ return -EEXIST;
+
+ param = kmalloc(sizeof(*param), GFP_KERNEL);
+ if (!param)
+ return -ENOMEM;
+
+ bacpy(¶m->addr, addr);
+ param->addr_type = addr_type;
+ param->auto_connect = auto_connect;
+ param->min_conn_interval = min_conn_interval;
+ param->max_conn_interval = max_conn_interval;
+
+ hci_dev_lock(hdev);
+ list_add_rcu(¶m->list, &hdev->conn_param);
+ hci_dev_unlock(hdev);
+ return 0;
+}
+
+/*
+ * Remove from hdev->conn_param and free hci_conn_param.
+ *
+ * This function requires the caller holds hdev->lock.
+ */
+static void __remove_conn_param(struct hci_conn_param *param)
+{
+ list_del_rcu(¶m->list);
+ synchronize_rcu();
+
+ kfree(param);
+}
+
+void hci_remove_conn_param(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
+{
+ struct hci_conn_param *param;
+
+ param = find_conn_param(hdev, addr, addr_type);
+ if (!param)
+ return;
+
+ hci_dev_lock(hdev);
+ __remove_conn_param(param);
+ hci_dev_unlock(hdev);
+}
+
+/*
+ * Remove all elements from hdev->conn_param list.
+ *
+ * This function requires the caller holds hdev->lock.
+ */
+static void __clear_conn_param(struct hci_dev *hdev)
+{
+ struct hci_conn_param *param, *tmp;
+
+ list_for_each_entry_safe(param, tmp, &hdev->conn_param, list)
+ __remove_conn_param(param);
+}
+
static void inquiry_complete(struct hci_dev *hdev, u8 status)
{
if (status) {
@@ -2259,6 +2345,7 @@ struct hci_dev *hci_alloc_dev(void)
INIT_LIST_HEAD(&hdev->link_keys);
INIT_LIST_HEAD(&hdev->long_term_keys);
INIT_LIST_HEAD(&hdev->remote_oob_data);
+ INIT_LIST_HEAD(&hdev->conn_param);
INIT_LIST_HEAD(&hdev->conn_hash.list);
INIT_WORK(&hdev->rx_work, hci_rx_work);
@@ -2437,6 +2524,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
hci_link_keys_clear(hdev);
hci_smp_ltks_clear(hdev);
hci_remote_oob_data_clear(hdev);
+ __clear_conn_param(hdev);
hci_dev_unlock(hdev);
hci_dev_put(hdev);
--
1.8.4
^ 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