* Re: double Connect req: psm 1 scid 0x0040 ?
From: Andrei Emeltchenko @ 2010-06-16 14:14 UTC (permalink / raw)
To: Ed Tsang; +Cc: Marcel Holtmann, Bluettooth Linux, liejuntao001
In-Reply-To: <497946.31108.qm@web52603.mail.re2.yahoo.com>
On Wed, Jun 16, 2010 at 4:39 PM, Ed Tsang <netdesign_98@yahoo.com> wrote:
> Anrel, =A0what kernel version are you using?
> Previously it was happening with a Blackberry on 2.6.31-17. I was plannin=
g to dig into it, then I upgraded my ubuntu with (2.6.32-22) and the proble=
m disappeared. I am guessing it might be a raising condition with certain p=
hone during certain circumstance. I think Liejun Tao <liejuntao001@gmail.co=
m> has investigate this one too.
I guess that new kernel have different timing. This condition is not
easy to get as several packets have milliseconds between each other
...
We are using kernel 2.6.32-xx and it is a bit different since several
patches which fixes kernel crashes are not yet in bluez ...
Regards,
Andrei Emeltchenko
MeeGo Devices
>
> Cheers,
> Ed
>
>
>
> ----- Original Message ----
> From: Andrei Emeltchenko <andrei.emeltchenko.news@gmail.com>
> To: Marcel Holtmann <marcel@holtmann.org>
> Cc: Ed Tsang <netdesign_98@yahoo.com>; Bluettooth Linux <linux-bluetooth@=
vger.kernel.org>
> Sent: Wed, June 16, 2010 6:21:55 AM
> Subject: Re: double Connect req: psm 1 scid 0x0040 ?
>
> Hi,
>
> On Wed, Feb 3, 2010 at 6:07 PM, Marcel Holtmann <marcel@holtmann.org> wro=
te:
>>> >> In hcidump I seem to see a problem in #3. After the Encrypt Change t=
here seem to be 2 >con. req. psm 1 scid 0x0040
>>>
>>> >what kernel version is this? I think we fixed that already.
>>> It is a ubutunu distribution. 2.6.31-17-generic.
>>
>> can you test with a 2.6.33-rc6 vanilla kernel. I really thing this got
>> fixed and you might see a side effect or bad patch here.
>
> Marcel we are seeing "double L2CAP connect also" when connecting to
> some smartphones using contran profile. What about following patch
> proposal:
>
> The idea is to use existing flag L2CAP_CONF_CONNECT_PEND to mark that
> L2CAP request has been sent.
>
> Currently it is durty hack, I will send modified patch later today.
>
> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index fc81acb..27bff6e 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -394,6 +394,12 @@ static void l2cap_do_start(struct sock *sk)
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0l2cap_pi(sk)->ident =3D l2=
cap_get_ident(conn);
>
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (l2cap_pi(sk)->conf_stat=
e &
> L2CAP_CONF_CONNECT_PEND) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN=
_ERR "\n!!! %s: Connection
> pending !!!\n", __FUNCTION__);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 l2cap_pi(sk)->conf_state |=
=3D L2CAP_CONF_CONNECT_PEND;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0l2cap_send_cmd(conn, l2cap=
_pi(sk)->ident,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0L2CAP_CONN_REQ, sizeof(req), &req);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0}
> @@ -448,6 +454,13 @@ static void l2cap_conn_start(struct l2cap_conn *conn=
)
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0l2cap_pi(s=
k)->ident =3D l2cap_get_ident(conn);
>
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (l2cap_p=
i(sk)->conf_state &
> L2CAP_CONF_CONNECT_PEND) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 printk(KERN_ERR "\n!!! %s:
> Connection pending !!!\n", __FUNCTION__);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 bh_unlock_sock(sk);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 continue;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 l2cap_pi(sk=
)->conf_state |=3D
> L2CAP_CONF_CONNECT_PEND;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0l2cap_send=
_cmd(conn, l2cap_pi(sk)->ident,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0L2CAP_CONN_REQ, sizeof(req), &req);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0}
> @@ -3809,6 +3822,7 @@ static int l2cap_security_cfm(struct hci_conn
> *hcon, u8 status, u8 encrypt)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0bh_lock_sock(sk);
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (l2cap_pi(sk)->conf_state & L2CAP_CONF_=
CONNECT_PEND) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_ERR "\n!!! %s: =
Connection pending
> !!!\n", __FUNCTION__);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0bh_unlock_sock(sk);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0continue;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0}
> @@ -3828,6 +3842,7 @@ static int l2cap_security_cfm(struct hci_conn
> *hcon, u8 status, u8 encrypt)
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0l2cap_pi(s=
k)->ident =3D l2cap_get_ident(conn);
>
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 l2cap_pi(sk=
)->conf_state |=3D
> L2CAP_CONF_CONNECT_PEND;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0l2cap_send=
_cmd(conn, l2cap_pi(sk)->ident,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0L2CAP_CONN_REQ, sizeof(req), &req);
>
>
>
>>
>> Regards
>>
>> Marcel
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-bluetoot=
h" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at =A0http://vger.kernel.org/majordomo-info.html
>>
>
>
>
>
^ permalink raw reply
* Re: RFC: Allow Bluez to select flushable or non-flushable ACL packets with L2CAP_LM_RELIABLE
From: Nick Pelly @ 2010-06-16 14:15 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: Marcel Holtmann, linux-bluetooth
In-Reply-To: <AANLkTinOFG0NcADz2ewxyaPWiLpe52MFLP8GCEvFna2a@mail.gmail.com>
On Wed, Jun 16, 2010 at 4:40 AM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi,
>
> On Tue, Mar 9, 2010 at 11:45 PM, Marcel Holtmann <marcel@holtmann.org> wr=
ote:
>> Hi Nick,
>>
>>> >>> >> Right now Bluez always requests flushable ACL packets (but does =
not
>>> >>> >> set a flush timeout, so effectively they are non-flushable):
>>> >>> >>
>>> >>> >> However it is desirable to use an ACL flush timeout on A2DP pack=
ets so
>>> >>> >> that if the ACL packets block for some reason then the LM can fl=
ush
>>> >>> >> them to make room for newer packets.
>>> >>> >>
>>> >>> >> Is it reasonable for Bluez to use the 0x00 ACL packet boundary f=
lag by
>>> >>> >> default (non-flushable packet), and let userspace request flusha=
ble
>>> >>> >> packets on A2DP L2CAP sockets with the socket option
>>> >>> >> L2CAP_LM_RELIABLE.
>>> >>> >
>>> >>> > the reliable option has a different meaning. It comes back from t=
he old
>>> >>> > Bluetooth 1.1 qualification days where we had to tests on L2CAP t=
hat had
>>> >>> > to confirm that we can detect malformed packets and report them. =
These
>>> >>> > days it is just fine to drop them.
>>> >>>
>>> >>> Got it, how about introducing
>>> >>>
>>> >>> #define L2CAP_LM_FLUSHABLE 0x0040
>>> >>
>>> >> that l2cap_sock_setsockopt_old() sets this didn't give you a hint th=
at
>>> >> we might wanna deprecate this socket options ;)
>>> >>
>>> >> I need to read up on the flushable stuff, but in the end it deserves=
its
>>> >> own socket option. Also an ioctl() to actually trigger Enhanced flus=
h
>>> >> might be needed.
>>> >>
>>> >>> struct l2cap_pinfo {
>>> >>> =A0 =A0...
>>> >>> =A0 =A0__u8 flushable;
>>> >>> }
>>> >>
>>> >> Sure. In the long run we need to turn this into a bitmask. We are ju=
st
>>> >> wasting memory here.
>>> >
>>> > Attached is an updated patch, that checks the LMP features bitmask
>>> > before using the new non-flushable packet type.
>>> >
>>> > I am still using L2CAP_LM_FLUSHABLE socket option in
>>> > l2cap_sock_setsockopt_old(), which I don't think you are happy with.
>>> > So how about a new option:
>>> >
>>> > SOL_L2CAP, L2CAP_ACL_FLUSH
>>> > which has a default value of 0, and can be set to 1 to make the ACL
>>> > data sent by this L2CAP socket flushable.
>>> >
>>> > In a later commit we would then add
>>> > SOL_ACL, ACL_FLUSH_TIMEOUT
>>> > That is used to set an automatic flush timeout for the ACL link on a
>>> > L2CAP socket. Note that SOL_ACL is new.
>>> >
>>> > But maybe this is not what you had in mind, so I'm looking for your
>>> > advice before I implement this.
>>>
>>> Attached an updated patch for 2.6.32 kernel. We've been using this
>>> patch successfully on production devices.
>>
>> can see anything wrong with that patch. However we need to use
>> SOL_BLUETOOTH for it of course. So we need to come up with something to
>> make this simple.
>>
>> An additional change I like to see is to use flags for booleans like
>> flushable in the structures. Can you work on changing that.
>>
>> Also do we have decoding support for this in hcidump. It might be nice
>> to include some really simple examples in the commit message.
>>
>> Regards
>
> I would like to play a little bit with this, so is there any missing upda=
tes?
Nope, that is our most recent version.
Nick
^ permalink raw reply
* Re: RFC: Allow Bluez to select flushable or non-flushable ACL packets with L2CAP_LM_RELIABLE
From: Luiz Augusto von Dentz @ 2010-06-16 15:14 UTC (permalink / raw)
To: Suraj; +Cc: Marcel Holtmann, Nick Pelly, linux-bluetooth@vger.kernel.org
In-Reply-To: <4C18BDDF.7030002@Atheros.com>
Hi,
On Wed, Jun 16, 2010 at 3:04 PM, Suraj <suraj@atheros.com> wrote:
> Hi Luis,
>
> On 6/16/2010 5:10 PM, Luiz Augusto von Dentz wrote:
>>
>> Hi,
>>
>> On Tue, Mar 9, 2010 at 11:45 PM, Marcel Holtmann<marcel@holtmann.org>
>> =A0wrote:
>>>
>>> Hi Nick,
>>>
>>>>>>>>> Right now Bluez always requests flushable ACL packets (but does n=
ot
>>>>>>>>> set a flush timeout, so effectively they are non-flushable):
>>>>>>>>>
>>>>>>>>> However it is desirable to use an ACL flush timeout on A2DP packe=
ts
>>>>>>>>> so
>>>>>>>>> that if the ACL packets block for some reason then the LM can flu=
sh
>>>>>>>>> them to make room for newer packets.
>>>>>>>>>
>>>>>>>>> Is it reasonable for Bluez to use the 0x00 ACL packet boundary fl=
ag
>>>>>>>>> by
>>>>>>>>> default (non-flushable packet), and let userspace request flushab=
le
>>>>>>>>> packets on A2DP L2CAP sockets with the socket option
>>>>>>>>> L2CAP_LM_RELIABLE.
>>>>>>>>
>>>>>>>> the reliable option has a different meaning. It comes back from th=
e
>>>>>>>> old
>>>>>>>> Bluetooth 1.1 qualification days where we had to tests on L2CAP th=
at
>>>>>>>> had
>>>>>>>> to confirm that we can detect malformed packets and report them.
>>>>>>>> These
>>>>>>>> days it is just fine to drop them.
>>>>>>>
>>>>>>> Got it, how about introducing
>>>>>>>
>>>>>>> #define L2CAP_LM_FLUSHABLE 0x0040
>>>>>>
>>>>>> that l2cap_sock_setsockopt_old() sets this didn't give you a hint th=
at
>>>>>> we might wanna deprecate this socket options ;)
>>>>>>
>>>>>> I need to read up on the flushable stuff, but in the end it deserves
>>>>>> its
>>>>>> own socket option. Also an ioctl() to actually trigger Enhanced flus=
h
>>>>>> might be needed.
>>>>>>
>>>>>>> struct l2cap_pinfo {
>>>>>>> =A0 =A0...
>>>>>>> =A0 =A0__u8 flushable;
>>>>>>> }
>>>>>>
>>>>>> Sure. In the long run we need to turn this into a bitmask. We are ju=
st
>>>>>> wasting memory here.
>>>>>
>>>>> Attached is an updated patch, that checks the LMP features bitmask
>>>>> before using the new non-flushable packet type.
>>>>>
>>>>> I am still using L2CAP_LM_FLUSHABLE socket option in
>>>>> l2cap_sock_setsockopt_old(), which I don't think you are happy with.
>>>>> So how about a new option:
>>>>>
>>>>> SOL_L2CAP, L2CAP_ACL_FLUSH
>>>>> which has a default value of 0, and can be set to 1 to make the ACL
>>>>> data sent by this L2CAP socket flushable.
>>>>>
>>>>> In a later commit we would then add
>>>>> SOL_ACL, ACL_FLUSH_TIMEOUT
>>>>> That is used to set an automatic flush timeout for the ACL link on a
>>>>> L2CAP socket. Note that SOL_ACL is new.
>>>>>
>>>>> But maybe this is not what you had in mind, so I'm looking for your
>>>>> advice before I implement this.
>>>>
>>>> Attached an updated patch for 2.6.32 kernel. We've been using this
>>>> patch successfully on production devices.
>>>
>>> can see anything wrong with that patch. However we need to use
>>> SOL_BLUETOOTH for it of course. So we need to come up with something to
>>> make this simple.
>>>
>>> An additional change I like to see is to use flags for booleans like
>>> flushable in the structures. Can you work on changing that.
>>>
>>> Also do we have decoding support for this in hcidump. It might be nice
>>> to include some really simple examples in the commit message.
>>>
>>> Regards
>>
>> I would like to play a little bit with this, so is there any missing
>> updates?
>>
> This is not exactly something related to your question, but there is anot=
her
> side effect for the current implementation.
>
> Assume you have 2 ACL links, FTP and A2DP. A2DP streaming and FTP doing F=
TP
> Put.
> When the A2DP packets start blocking, it effectively start blocking the
> packets available for FTP too. But, the host has no idea about it and kee=
p
> pumping in A2DP data until all available buffers are blocked. Effectively
> blocking both A2DP and FTP.
>
> So at the user level you will see your FTP connection stalling as long yo=
ur
> A2DP connection is stalled (out of range). FTP will restart as soon as A2=
DP
> comes back in range.
>
> I had raised this issue sometime before, but could not follow it up.
I got the impression that we can still control which packets are
Automatically-Flushable and which are not, so even thought we set the
timeout in a per ACL link fashion we can still mark which packets
should be flushable in a per socket basis.
Is that correct, Nick?
--=20
Luiz Augusto von Dentz
Computer Engineer
^ permalink raw reply
* Re: RFC: Allow Bluez to select flushable or non-flushable ACL packets with L2CAP_LM_RELIABLE
From: Suraj @ 2010-06-16 15:45 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: Suraj Sumangala, Marcel Holtmann, Nick Pelly,
linux-bluetooth@vger.kernel.org
In-Reply-To: <AANLkTimZB71m9zGxTjmKjTiKNo-hDHsrCLrOLXr1EjyY@mail.gmail.com>
Hi,
On 6/16/2010 8:44 PM, Luiz Augusto von Dentz wrote:
> Hi,
>
> On Wed, Jun 16, 2010 at 3:04 PM, Suraj<suraj@atheros.com> wrote:
>> Hi Luis,
>>
>> On 6/16/2010 5:10 PM, Luiz Augusto von Dentz wrote:
>>>
>>> Hi,
>>>
>>> On Tue, Mar 9, 2010 at 11:45 PM, Marcel Holtmann<marcel@holtmann.org>
>>> wrote:
>>>>
>>>> Hi Nick,
>>>>
>>>>>>>>>> Right now Bluez always requests flushable ACL packets (but does not
>>>>>>>>>> set a flush timeout, so effectively they are non-flushable):
>>>>>>>>>>
>>>>>>>>>> However it is desirable to use an ACL flush timeout on A2DP packets
>>>>>>>>>> so
>>>>>>>>>> that if the ACL packets block for some reason then the LM can flush
>>>>>>>>>> them to make room for newer packets.
>>>>>>>>>>
>>>>>>>>>> Is it reasonable for Bluez to use the 0x00 ACL packet boundary flag
>>>>>>>>>> by
>>>>>>>>>> default (non-flushable packet), and let userspace request flushable
>>>>>>>>>> packets on A2DP L2CAP sockets with the socket option
>>>>>>>>>> L2CAP_LM_RELIABLE.
>>>>>>>>>
>>>>>>>>> the reliable option has a different meaning. It comes back from the
>>>>>>>>> old
>>>>>>>>> Bluetooth 1.1 qualification days where we had to tests on L2CAP that
>>>>>>>>> had
>>>>>>>>> to confirm that we can detect malformed packets and report them.
>>>>>>>>> These
>>>>>>>>> days it is just fine to drop them.
>>>>>>>>
>>>>>>>> Got it, how about introducing
>>>>>>>>
>>>>>>>> #define L2CAP_LM_FLUSHABLE 0x0040
>>>>>>>
>>>>>>> that l2cap_sock_setsockopt_old() sets this didn't give you a hint that
>>>>>>> we might wanna deprecate this socket options ;)
>>>>>>>
>>>>>>> I need to read up on the flushable stuff, but in the end it deserves
>>>>>>> its
>>>>>>> own socket option. Also an ioctl() to actually trigger Enhanced flush
>>>>>>> might be needed.
>>>>>>>
>>>>>>>> struct l2cap_pinfo {
>>>>>>>> ...
>>>>>>>> __u8 flushable;
>>>>>>>> }
>>>>>>>
>>>>>>> Sure. In the long run we need to turn this into a bitmask. We are just
>>>>>>> wasting memory here.
>>>>>>
>>>>>> Attached is an updated patch, that checks the LMP features bitmask
>>>>>> before using the new non-flushable packet type.
>>>>>>
>>>>>> I am still using L2CAP_LM_FLUSHABLE socket option in
>>>>>> l2cap_sock_setsockopt_old(), which I don't think you are happy with.
>>>>>> So how about a new option:
>>>>>>
>>>>>> SOL_L2CAP, L2CAP_ACL_FLUSH
>>>>>> which has a default value of 0, and can be set to 1 to make the ACL
>>>>>> data sent by this L2CAP socket flushable.
>>>>>>
>>>>>> In a later commit we would then add
>>>>>> SOL_ACL, ACL_FLUSH_TIMEOUT
>>>>>> That is used to set an automatic flush timeout for the ACL link on a
>>>>>> L2CAP socket. Note that SOL_ACL is new.
>>>>>>
>>>>>> But maybe this is not what you had in mind, so I'm looking for your
>>>>>> advice before I implement this.
>>>>>
>>>>> Attached an updated patch for 2.6.32 kernel. We've been using this
>>>>> patch successfully on production devices.
>>>>
>>>> can see anything wrong with that patch. However we need to use
>>>> SOL_BLUETOOTH for it of course. So we need to come up with something to
>>>> make this simple.
>>>>
>>>> An additional change I like to see is to use flags for booleans like
>>>> flushable in the structures. Can you work on changing that.
>>>>
>>>> Also do we have decoding support for this in hcidump. It might be nice
>>>> to include some really simple examples in the commit message.
>>>>
>>>> Regards
>>>
>>> I would like to play a little bit with this, so is there any missing
>>> updates?
>>>
>> This is not exactly something related to your question, but there is another
>> side effect for the current implementation.
>>
>> Assume you have 2 ACL links, FTP and A2DP. A2DP streaming and FTP doing FTP
>> Put.
>> When the A2DP packets start blocking, it effectively start blocking the
>> packets available for FTP too. But, the host has no idea about it and keep
>> pumping in A2DP data until all available buffers are blocked. Effectively
>> blocking both A2DP and FTP.
>>
>> So at the user level you will see your FTP connection stalling as long your
>> A2DP connection is stalled (out of range). FTP will restart as soon as A2DP
>> comes back in range.
>>
>> I had raised this issue sometime before, but could not follow it up.
>
> I got the impression that we can still control which packets are
> Automatically-Flushable and which are not, so even thought we set the
> timeout in a per ACL link fashion we can still mark which packets
> should be flushable in a per socket basis.
>
> Is that correct, Nick?
>
Yes, it is possible to flush packets selectively. But the buffer
management is between Host and Controller, not per ACL link.
The root cause of the issue is that A2DP packets are not at all flushed
and keeps clogging the available buffers.
So, Implementing option to actually flush A2DP packet should solve the
above mentioned problem.
Regards
Suraj
^ permalink raw reply
* Re: RFC: Allow Bluez to select flushable or non-flushable ACL packets with L2CAP_LM_RELIABLE
From: Nick Pelly @ 2010-06-16 16:26 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: Suraj, Marcel Holtmann, linux-bluetooth@vger.kernel.org
In-Reply-To: <AANLkTimZB71m9zGxTjmKjTiKNo-hDHsrCLrOLXr1EjyY@mail.gmail.com>
On Wed, Jun 16, 2010 at 8:14 AM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi,
>
> On Wed, Jun 16, 2010 at 3:04 PM, Suraj <suraj@atheros.com> wrote:
>> Hi Luis,
>>
>> On 6/16/2010 5:10 PM, Luiz Augusto von Dentz wrote:
>>>
>>> Hi,
>>>
>>> On Tue, Mar 9, 2010 at 11:45 PM, Marcel Holtmann<marcel@holtmann.org>
>>> =A0wrote:
>>>>
>>>> Hi Nick,
>>>>
>>>>>>>>>> Right now Bluez always requests flushable ACL packets (but does =
not
>>>>>>>>>> set a flush timeout, so effectively they are non-flushable):
>>>>>>>>>>
>>>>>>>>>> However it is desirable to use an ACL flush timeout on A2DP pack=
ets
>>>>>>>>>> so
>>>>>>>>>> that if the ACL packets block for some reason then the LM can fl=
ush
>>>>>>>>>> them to make room for newer packets.
>>>>>>>>>>
>>>>>>>>>> Is it reasonable for Bluez to use the 0x00 ACL packet boundary f=
lag
>>>>>>>>>> by
>>>>>>>>>> default (non-flushable packet), and let userspace request flusha=
ble
>>>>>>>>>> packets on A2DP L2CAP sockets with the socket option
>>>>>>>>>> L2CAP_LM_RELIABLE.
>>>>>>>>>
>>>>>>>>> the reliable option has a different meaning. It comes back from t=
he
>>>>>>>>> old
>>>>>>>>> Bluetooth 1.1 qualification days where we had to tests on L2CAP t=
hat
>>>>>>>>> had
>>>>>>>>> to confirm that we can detect malformed packets and report them.
>>>>>>>>> These
>>>>>>>>> days it is just fine to drop them.
>>>>>>>>
>>>>>>>> Got it, how about introducing
>>>>>>>>
>>>>>>>> #define L2CAP_LM_FLUSHABLE 0x0040
>>>>>>>
>>>>>>> that l2cap_sock_setsockopt_old() sets this didn't give you a hint t=
hat
>>>>>>> we might wanna deprecate this socket options ;)
>>>>>>>
>>>>>>> I need to read up on the flushable stuff, but in the end it deserve=
s
>>>>>>> its
>>>>>>> own socket option. Also an ioctl() to actually trigger Enhanced flu=
sh
>>>>>>> might be needed.
>>>>>>>
>>>>>>>> struct l2cap_pinfo {
>>>>>>>> =A0 =A0...
>>>>>>>> =A0 =A0__u8 flushable;
>>>>>>>> }
>>>>>>>
>>>>>>> Sure. In the long run we need to turn this into a bitmask. We are j=
ust
>>>>>>> wasting memory here.
>>>>>>
>>>>>> Attached is an updated patch, that checks the LMP features bitmask
>>>>>> before using the new non-flushable packet type.
>>>>>>
>>>>>> I am still using L2CAP_LM_FLUSHABLE socket option in
>>>>>> l2cap_sock_setsockopt_old(), which I don't think you are happy with.
>>>>>> So how about a new option:
>>>>>>
>>>>>> SOL_L2CAP, L2CAP_ACL_FLUSH
>>>>>> which has a default value of 0, and can be set to 1 to make the ACL
>>>>>> data sent by this L2CAP socket flushable.
>>>>>>
>>>>>> In a later commit we would then add
>>>>>> SOL_ACL, ACL_FLUSH_TIMEOUT
>>>>>> That is used to set an automatic flush timeout for the ACL link on a
>>>>>> L2CAP socket. Note that SOL_ACL is new.
>>>>>>
>>>>>> But maybe this is not what you had in mind, so I'm looking for your
>>>>>> advice before I implement this.
>>>>>
>>>>> Attached an updated patch for 2.6.32 kernel. We've been using this
>>>>> patch successfully on production devices.
>>>>
>>>> can see anything wrong with that patch. However we need to use
>>>> SOL_BLUETOOTH for it of course. So we need to come up with something t=
o
>>>> make this simple.
>>>>
>>>> An additional change I like to see is to use flags for booleans like
>>>> flushable in the structures. Can you work on changing that.
>>>>
>>>> Also do we have decoding support for this in hcidump. It might be nice
>>>> to include some really simple examples in the commit message.
>>>>
>>>> Regards
>>>
>>> I would like to play a little bit with this, so is there any missing
>>> updates?
>>>
>> This is not exactly something related to your question, but there is ano=
ther
>> side effect for the current implementation.
>>
>> Assume you have 2 ACL links, FTP and A2DP. A2DP streaming and FTP doing =
FTP
>> Put.
>> When the A2DP packets start blocking, it effectively start blocking the
>> packets available for FTP too. But, the host has no idea about it and ke=
ep
>> pumping in A2DP data until all available buffers are blocked. Effectivel=
y
>> blocking both A2DP and FTP.
>>
>> So at the user level you will see your FTP connection stalling as long y=
our
>> A2DP connection is stalled (out of range). FTP will restart as soon as A=
2DP
>> comes back in range.
>>
>> I had raised this issue sometime before, but could not follow it up.
>
> I got the impression that we can still control which packets are
> Automatically-Flushable and which are not, so even thought we set the
> timeout in a per ACL link fashion we can still mark which packets
> should be flushable in a per socket basis.
>
> Is that correct, Nick?
Yes, as Suraj explains, my patch will solve the problem of a stalled
A2DP link preventing FTP packets on another ACL - because the A2DP
packets will be marked flushable.
However its worth bringing up that my patch does not solve the reverse
problem - if an FTP link is stalled then all ACL packets will be
temporarily stalled - because you would not normally mark FTP packets
as flushable. For this you would need the kernel to set a high level
watermark on a per-ACL-link or per-socket basis, so that a single ACL
link or a single socket can not use all available ACL buffers
regardless of whether they are flushable or not.
Nick
^ permalink raw reply
* Re: [PATCH] Adding support for bluetooth controller shipped with iMac i5
From: Cyril Lacoux (Yack) @ 2010-06-16 16:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1276695209.2301.73.camel@localhost.localdomain>
[-- Attachment #1: Type: Text/Plain, Size: 438 bytes --]
Le mercredi 16 juin 2010 17:33:29, vous avez écrit :
> please show the output of /proc/bus/usb/devices or usb-devices script
> for this device.
>
> And I want a proper kernel patch from git format-patch.
Ok,
Here is the output of command `git format-patch -1 --stdout` against current
bluetooth-next-2.6 tree - hope that's ok.
Regards,
--
Cyril Lacoux -- BOFH excuse #170:
popper unable to process jumbo kernel
[-- Attachment #2: usb-devices.txt --]
[-- Type: text/plain, Size: 576 bytes --]
T: Bus=01 Lev=03 Prnt=03 Port=00 Cnt=01 Dev#= 6 Spd=12 MxCh= 0
D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=05ac ProdID=8215 Rev=01.82
S: Manufacturer=Apple Inc.
S: Product=Bluetooth USB Host Controller
S: SerialNumber=7C6D62936607
C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=0mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
I: If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=00 Driver=(none)
[-- Attachment #3: bt-imac-i5_git.patch --]
[-- Type: text/x-patch, Size: 794 bytes --]
From 6275e99d05b88010d729ed1b62657b3ab477d661 Mon Sep 17 00:00:00 2001
From: Cyril Lacoux <clacoux@ifeelgood.org>
Date: Wed, 16 Jun 2010 20:09:46 +0400
Subject: [PATCH] Add support for bluetooth controller shipped with iMac i5 (0x05ac, 0x8215)
---
drivers/bluetooth/btusb.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 5d9cc53..ce129de 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -75,6 +75,9 @@ static struct usb_device_id btusb_table[] = {
/* Canyon CN-BTU1 with HID interfaces */
{ USB_DEVICE(0x0c10, 0x0000) },
+ /* Apple iMac11,1 with HID interfaces */
+ { USB_DEVICE(0x05ac, 0x8215) },
+
{ } /* Terminating entry */
};
--
1.7.1
^ permalink raw reply related
* [PATCH] Fixes sdp_get_supp_feat function
From: Elvis Pfützenreuter @ 2010-06-16 16:30 UTC (permalink / raw)
To: linux-bluetooth; +Cc: epx
In case of string data items, value is a pointer by itself.
---
lib/sdp.c | 25 ++++++++++++++++++++++---
1 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/lib/sdp.c b/lib/sdp.c
index 79f4ae5..17745ac 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -4769,13 +4769,32 @@ int sdp_get_supp_feat(const sdp_record_t *rec, sdp_list_t **seqp)
if (d->dtd < SDP_SEQ8 || d->dtd > SDP_SEQ32)
goto fail;
+
subseq = NULL;
+
for (dd = d->val.dataseq; dd; dd = dd->next) {
sdp_data_t *data;
- if (dd->dtd != SDP_UINT8 && dd->dtd != SDP_UINT16 &&
- dd->dtd != SDP_TEXT_STR8)
+ void *val;
+ int length;
+
+ switch (dd->dtd) {
+ case SDP_URL_STR8:
+ case SDP_URL_STR16:
+ case SDP_TEXT_STR8:
+ case SDP_TEXT_STR16:
+ val = dd->val.str;
+ length = dd->unitSize - sizeof(uint8_t);
+ break;
+ case SDP_UINT8:
+ case SDP_UINT16:
+ val = &dd->val;
+ length = 0;
+ break;
+ default:
goto fail;
- data = sdp_data_alloc(dd->dtd, &dd->val);
+ }
+
+ data = sdp_data_alloc_with_length(dd->dtd, val, length);
if (data)
subseq = sdp_list_append(subseq, data);
}
--
1.7.0.4
^ permalink raw reply related
* Re: RFC: Allow Bluez to select flushable or non-flushable ACL packets with L2CAP_LM_RELIABLE
From: Suraj @ 2010-06-17 5:09 UTC (permalink / raw)
To: Nick Pelly
Cc: Luiz Augusto von Dentz, Suraj Sumangala, Marcel Holtmann,
linux-bluetooth@vger.kernel.org
In-Reply-To: <AANLkTinzTubv9p_AOUnm_HCjpn8DWaSMmft57NhFVli8@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 5557 bytes --]
Hi,
On 6/16/2010 9:56 PM, Nick Pelly wrote:
> On Wed, Jun 16, 2010 at 8:14 AM, Luiz Augusto von Dentz
> <luiz.dentz@gmail.com> wrote:
>> Hi,
>>
>> On Wed, Jun 16, 2010 at 3:04 PM, Suraj<suraj@atheros.com> wrote:
>>> Hi Luis,
>>>
>>> On 6/16/2010 5:10 PM, Luiz Augusto von Dentz wrote:
>>>>
>>>> Hi,
>>>>
>>>> On Tue, Mar 9, 2010 at 11:45 PM, Marcel Holtmann<marcel@holtmann.org>
>>>> wrote:
>>>>>
>>>>> Hi Nick,
>>>>>
>>>>>>>>>>> Right now Bluez always requests flushable ACL packets (but does not
>>>>>>>>>>> set a flush timeout, so effectively they are non-flushable):
>>>>>>>>>>>
>>>>>>>>>>> However it is desirable to use an ACL flush timeout on A2DP packets
>>>>>>>>>>> so
>>>>>>>>>>> that if the ACL packets block for some reason then the LM can flush
>>>>>>>>>>> them to make room for newer packets.
>>>>>>>>>>>
>>>>>>>>>>> Is it reasonable for Bluez to use the 0x00 ACL packet boundary flag
>>>>>>>>>>> by
>>>>>>>>>>> default (non-flushable packet), and let userspace request flushable
>>>>>>>>>>> packets on A2DP L2CAP sockets with the socket option
>>>>>>>>>>> L2CAP_LM_RELIABLE.
>>>>>>>>>>
>>>>>>>>>> the reliable option has a different meaning. It comes back from the
>>>>>>>>>> old
>>>>>>>>>> Bluetooth 1.1 qualification days where we had to tests on L2CAP that
>>>>>>>>>> had
>>>>>>>>>> to confirm that we can detect malformed packets and report them.
>>>>>>>>>> These
>>>>>>>>>> days it is just fine to drop them.
>>>>>>>>>
>>>>>>>>> Got it, how about introducing
>>>>>>>>>
>>>>>>>>> #define L2CAP_LM_FLUSHABLE 0x0040
>>>>>>>>
>>>>>>>> that l2cap_sock_setsockopt_old() sets this didn't give you a hint that
>>>>>>>> we might wanna deprecate this socket options ;)
>>>>>>>>
>>>>>>>> I need to read up on the flushable stuff, but in the end it deserves
>>>>>>>> its
>>>>>>>> own socket option. Also an ioctl() to actually trigger Enhanced flush
>>>>>>>> might be needed.
>>>>>>>>
>>>>>>>>> struct l2cap_pinfo {
>>>>>>>>> ...
>>>>>>>>> __u8 flushable;
>>>>>>>>> }
>>>>>>>>
>>>>>>>> Sure. In the long run we need to turn this into a bitmask. We are just
>>>>>>>> wasting memory here.
>>>>>>>
>>>>>>> Attached is an updated patch, that checks the LMP features bitmask
>>>>>>> before using the new non-flushable packet type.
>>>>>>>
>>>>>>> I am still using L2CAP_LM_FLUSHABLE socket option in
>>>>>>> l2cap_sock_setsockopt_old(), which I don't think you are happy with.
>>>>>>> So how about a new option:
>>>>>>>
>>>>>>> SOL_L2CAP, L2CAP_ACL_FLUSH
>>>>>>> which has a default value of 0, and can be set to 1 to make the ACL
>>>>>>> data sent by this L2CAP socket flushable.
>>>>>>>
>>>>>>> In a later commit we would then add
>>>>>>> SOL_ACL, ACL_FLUSH_TIMEOUT
>>>>>>> That is used to set an automatic flush timeout for the ACL link on a
>>>>>>> L2CAP socket. Note that SOL_ACL is new.
>>>>>>>
>>>>>>> But maybe this is not what you had in mind, so I'm looking for your
>>>>>>> advice before I implement this.
>>>>>>
>>>>>> Attached an updated patch for 2.6.32 kernel. We've been using this
>>>>>> patch successfully on production devices.
>>>>>
>>>>> can see anything wrong with that patch. However we need to use
>>>>> SOL_BLUETOOTH for it of course. So we need to come up with something to
>>>>> make this simple.
>>>>>
>>>>> An additional change I like to see is to use flags for booleans like
>>>>> flushable in the structures. Can you work on changing that.
>>>>>
>>>>> Also do we have decoding support for this in hcidump. It might be nice
>>>>> to include some really simple examples in the commit message.
>>>>>
>>>>> Regards
>>>>
>>>> I would like to play a little bit with this, so is there any missing
>>>> updates?
>>>>
>>> This is not exactly something related to your question, but there is another
>>> side effect for the current implementation.
>>>
>>> Assume you have 2 ACL links, FTP and A2DP. A2DP streaming and FTP doing FTP
>>> Put.
>>> When the A2DP packets start blocking, it effectively start blocking the
>>> packets available for FTP too. But, the host has no idea about it and keep
>>> pumping in A2DP data until all available buffers are blocked. Effectively
>>> blocking both A2DP and FTP.
>>>
>>> So at the user level you will see your FTP connection stalling as long your
>>> A2DP connection is stalled (out of range). FTP will restart as soon as A2DP
>>> comes back in range.
>>>
>>> I had raised this issue sometime before, but could not follow it up.
>>
>> I got the impression that we can still control which packets are
>> Automatically-Flushable and which are not, so even thought we set the
>> timeout in a per ACL link fashion we can still mark which packets
>> should be flushable in a per socket basis.
>>
>> Is that correct, Nick?
>
> Yes, as Suraj explains, my patch will solve the problem of a stalled
> A2DP link preventing FTP packets on another ACL - because the A2DP
> packets will be marked flushable.
>
> However its worth bringing up that my patch does not solve the reverse
> problem - if an FTP link is stalled then all ACL packets will be
> temporarily stalled - because you would not normally mark FTP packets
> as flushable. For this you would need the kernel to set a high level
> watermark on a per-ACL-link or per-socket basis, so that a single ACL
> link or a single socket can not use all available ACL buffers
> regardless of whether they are flushable or not.
>
> Nick
Exactly, this was the problem I raised sometime before.
Attached is a patch that works for me.
Not sure if this is the best solution. I can send a formal patch if this
is worth a try.
Regards
Suraj
[-- Attachment #2: 0001-Fix-for-Link-starvation-if-device-goes-out-of-range.patch --]
[-- Type: text/plain, Size: 2214 bytes --]
>From cbcb5fd9d126e490a7b12469a0a1e1fb09ce535b Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Tue, 4 May 2010 13:52:04 +0530
Subject: [PATCH] Fix for Link starvation if device goes out of range
---
include/net/bluetooth/hci_core.h | 2 ++
net/bluetooth/hci_core.c | 5 +++++
net/bluetooth/hci_event.c | 4 ++++
3 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 25b8a03..4216a7b 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -178,6 +178,8 @@ struct hci_conn {
unsigned int sent;
+ unsigned int avail_buffer;
+
struct sk_buff_head data_q;
struct timer_list disc_timer;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 406ad07..f8a99cf 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1325,6 +1325,8 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
continue;
+ if (c->avail_buffer == 0)
+ continue;
num++;
@@ -1390,6 +1392,9 @@ static inline void hci_sched_acl(struct hci_dev *hdev)
hdev->acl_cnt--;
conn->sent++;
+
+ if (conn->avail_buffer != 0)
+ conn->avail_buffer--;
}
}
}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index e99fe38..2f3b6dc 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -900,6 +900,9 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
if (conn->type == ACL_LINK) {
struct hci_cp_read_remote_features cp;
cp.handle = ev->handle;
+
+ conn->avail_buffer = hdev->acl_pkts;
+
hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
sizeof(cp), &cp);
}
@@ -1447,6 +1450,7 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
if (conn->type == ACL_LINK) {
if ((hdev->acl_cnt += count) > hdev->acl_pkts)
hdev->acl_cnt = hdev->acl_pkts;
+ conn->avail_buffer = count;
} else {
if ((hdev->sco_cnt += count) > hdev->sco_pkts)
hdev->sco_cnt = hdev->sco_pkts;
--
1.6.0.6
^ permalink raw reply related
* Timeout in hciattach
From: Vladimir Davydov @ 2010-06-17 10:20 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sergey Kovalev
[-- Attachment #1: Type: text/plain, Size: 961 bytes --]
Hi, All
I have found that in the latest release of the bluez4 (4.66) timeout in
hciattach doesn't work.
Look at this code of hciattach.c:
static void bcsp_tshy_sig_alarm(int sig)
{
unsigned char bcsp_sync_pkt[10] =
{0xc0,0x00,0x41,0x00,0xbe,0xda,0xdc,0xed,0xed,0xc0};
int len, retries = 0;
if (retries < bcsp_max_retries) {
retries++;
len = write(serial_fd, &bcsp_sync_pkt, 10);
alarm(1);
return;
}
tcflush(serial_fd, TCIOFLUSH);
fprintf(stderr, "BCSP initialization timed out\n");
exit(1);
}
The variable 'retries' will be always 0. Why is it not static? It was static
in oldest releases (3.33 for example).
I have attached simple patch to fix that.
Best regards,
Vladimir
--
Vladimir Davydov
Senior Developer
Promwad Innovation Company
Web: www.promwad.com
22, Olshevskogo St.,
220073, Minsk,
BELARUS
Phone/Fax: +375 (17) 312–1246
E-mail: vladimir.davydov@promwad.com
Skype: v_davydov
[-- Attachment #2: hciattach-timeout.patch --]
[-- Type: text/x-patch, Size: 483 bytes --]
diff -urN bluez-4.42.orig/tools/hciattach.c bluez-4.42/tools/hciattach.c
--- bluez-4.42.orig/tools/hciattach.c 2009-05-19 12:04:10.000000000 +0300
+++ bluez-4.42/tools/hciattach.c 2010-06-16 17:39:01.477248730 +0300
@@ -326,7 +326,8 @@
static void bcsp_tshy_sig_alarm(int sig)
{
unsigned char bcsp_sync_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xda,0xdc,0xed,0xed,0xc0};
- int len, retries = 0;
+ int len;
+ static int retries = 0;
if (retries < bcsp_max_retries) {
retries++;
^ permalink raw reply
* [PATCH 0/2] Enhanced support for Extended Inquiry Response
From: Inga Stotland @ 2010-06-17 17:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: rshaffer, marcel
Added code to update EIR whenever local SDP record is changed.
Added support for sending UUID128 in EIR.
--
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply
* [PATCH 1/2] Added Code Aurora Forum Copyrights
From: Inga Stotland @ 2010-06-17 17:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: rshaffer, marcel, Inga Stotland
In-Reply-To: <1276795490-17262-1-git-send-email-ingas@codeaurora.org>
---
plugins/service.c | 1 +
src/adapter.c | 1 +
src/adapter.h | 1 +
src/dbus-hci.c | 1 +
src/sdpd-service.c | 1 +
src/sdpd.h | 1 +
6 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/plugins/service.c b/plugins/service.c
index 96280bd..33cb27d 100644
--- a/plugins/service.c
+++ b/plugins/service.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2006-2010 Nokia Corporation
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2010, Code Aurora Forum. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/adapter.c b/src/adapter.c
index 7100191..ef41d83 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2006-2010 Nokia Corporation
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2010, Code Aurora Forum. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/adapter.h b/src/adapter.h
index 71d3387..d141e32 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -4,6 +4,7 @@
*
* Copyright (C) 2006-2010 Nokia Corporation
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2010, Code Aurora Forum. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/dbus-hci.c b/src/dbus-hci.c
index 19748a7..daec192 100644
--- a/src/dbus-hci.c
+++ b/src/dbus-hci.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2006-2010 Nokia Corporation
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2010, Code Aurora Forum. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/sdpd-service.c b/src/sdpd-service.c
index cdbb4f4..798e49d 100644
--- a/src/sdpd-service.c
+++ b/src/sdpd-service.c
@@ -6,6 +6,7 @@
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
* Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
* Copyright (C) 2002-2003 Stephen Crane <steve.crane@rococosoft.com>
+ * Copyright (C) 2010, Code Aurora Forum. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/sdpd.h b/src/sdpd.h
index e93b0b6..1d2e169 100644
--- a/src/sdpd.h
+++ b/src/sdpd.h
@@ -6,6 +6,7 @@
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
* Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
* Copyright (C) 2002-2003 Stephen Crane <steve.crane@rococosoft.com>
+ * Copyright (C) 2010, Code Aurora Forum. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
--
1.7.1
--
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply related
* [PATCH 2/2] Added support for updating EIR whenever record is added or removed
From: Inga Stotland @ 2010-06-17 17:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: rshaffer, marcel, Inga Stotland
In-Reply-To: <1276795490-17262-1-git-send-email-ingas@codeaurora.org>
---
plugins/service.c | 18 ++++++
src/adapter.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++--
src/adapter.h | 5 +-
src/dbus-hci.c | 6 +-
src/sdpd-service.c | 106 +++++++++++++++++++++++++++++++------
src/sdpd.h | 20 +++++++
6 files changed, 277 insertions(+), 26 deletions(-)
diff --git a/plugins/service.c b/plugins/service.c
index 33cb27d..8ec4df4 100644
--- a/plugins/service.c
+++ b/plugins/service.c
@@ -446,6 +446,8 @@ static DBusMessage *update_record(DBusConnection *conn, DBusMessage *msg,
strerror(EIO));
}
+ adapter_update_ext_inquiry_response(&src);
+
return dbus_message_new_method_return(msg);
}
@@ -517,6 +519,7 @@ static DBusMessage *add_service_record(DBusConnection *conn,
const char *sender, *record;
dbus_uint32_t handle;
int err;
+ bdaddr_t addr;
if (dbus_message_get_args(msg, NULL,
DBUS_TYPE_STRING, &record, DBUS_TYPE_INVALID) == FALSE)
@@ -527,6 +530,13 @@ static DBusMessage *add_service_record(DBusConnection *conn,
if (err < 0)
return failed_strerror(msg, err);
+ if (serv_adapter->adapter)
+ adapter_get_address(serv_adapter->adapter, &addr);
+ else
+ bacpy(&addr, BDADDR_ANY);
+
+ adapter_update_ext_inquiry_response(&addr);
+
reply = dbus_message_new_method_return(msg);
if (!reply)
return NULL;
@@ -551,6 +561,7 @@ static DBusMessage *remove_service_record(DBusConnection *conn,
struct service_adapter *serv_adapter = data;
dbus_uint32_t handle;
const char *sender;
+ bdaddr_t addr;
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle,
DBUS_TYPE_INVALID) == FALSE)
@@ -561,6 +572,13 @@ static DBusMessage *remove_service_record(DBusConnection *conn,
if (remove_record(conn, sender, serv_adapter, handle) < 0)
return not_available(msg);
+ if (serv_adapter->adapter)
+ adapter_get_address(serv_adapter->adapter, &addr);
+ else
+ bacpy(&addr, BDADDR_ANY);
+
+ adapter_update_ext_inquiry_response(&addr);
+
return dbus_message_new_method_return(msg);
}
diff --git a/src/adapter.c b/src/adapter.c
index ef41d83..e5330f0 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -803,7 +803,7 @@ static DBusMessage *set_pairable_timeout(DBusConnection *conn,
static void update_ext_inquiry_response(struct btd_adapter *adapter)
{
- uint8_t fec = 0, data[240];
+ uint8_t fec = 0, data[EIR_DATA_LENGTH];
struct hci_dev *dev = &adapter->dev;
int dd;
@@ -829,6 +829,27 @@ static void update_ext_inquiry_response(struct btd_adapter *adapter)
hci_close_dev(dd);
}
+void adapter_update_ext_inquiry_response(const bdaddr_t *src)
+{
+ struct btd_adapter *adapter;
+ GSList *adapters;
+
+ if (bacmp(src, BDADDR_ANY) != 0) {
+ adapter = manager_find_adapter(src);
+ if (adapter)
+ update_ext_inquiry_response(adapter);
+ else
+ error("Updating EIR failed: device not found");
+ } else {
+
+ /* Update extended inquiry reponse for ANY adapter */
+ for (adapters = manager_get_adapters(); adapters; adapters = adapters->next) {
+ adapter = adapters->data;
+ update_ext_inquiry_response(adapter);
+ }
+ }
+}
+
void adapter_set_class_complete(bdaddr_t *bdaddr, uint8_t status)
{
uint8_t class[3];
@@ -2677,6 +2698,7 @@ static void append_dict_valist(DBusMessageIter *iter,
DBusMessageIter dict;
const char *key;
int type;
+ int n_elements;
void *val;
dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
@@ -2688,7 +2710,12 @@ static void append_dict_valist(DBusMessageIter *iter,
while (key) {
type = va_arg(var_args, int);
val = va_arg(var_args, void *);
- dict_append_entry(&dict, key, type, val);
+ if (type == DBUS_TYPE_ARRAY) {
+ n_elements = va_arg(var_args, int);
+ if (n_elements > 0)
+ dict_append_array(&dict, key, DBUS_TYPE_STRING, val, n_elements);
+ } else
+ dict_append_entry(&dict, key, type, val);
key = va_arg(var_args, char *);
}
@@ -2719,8 +2746,106 @@ static void emit_device_found(const char *path, const char *address,
g_dbus_send_message(connection, signal);
}
+
+static int get_uuid_count_eir (uint8_t *eir_data)
+{
+ uint8_t type;
+ uint8_t len = 0;
+ uint8_t field_len;
+ int count = 0;
+
+ while (len < EIR_DATA_LENGTH) {
+ type = eir_data[1];
+ field_len = eir_data[0];
+ if ((type == EIR_UUID16_SOME) || (type == EIR_UUID16_ALL))
+ count += field_len/2;
+ else if ((type == EIR_UUID32_SOME) || (type == EIR_UUID32_ALL))
+ count += field_len/4;
+ else if ((type == EIR_UUID128_SOME) || (type == EIR_UUID128_ALL))
+ count += field_len/16;
+ len += field_len + 1;
+ eir_data += field_len + 1;
+ }
+
+ return count;
+}
+
+static void get_uuids_eir(char **uuids, uint8_t *eir_data)
+{
+ uint8_t type;
+ uint8_t len = 0;
+ uint8_t field_len = 0;
+ int count = 0;
+ int size;
+ uuid_t service;
+ gboolean service_found;
+
+ /* Count UUID16, UUID32 and UUID128 */
+ while (len < EIR_DATA_LENGTH) {
+ type = eir_data[1];
+ field_len = eir_data[0];
+ service_found = FALSE;
+ if ((type == EIR_UUID16_SOME) || (type == EIR_UUID16_ALL)) {
+ size = 2;
+ service.type = SDP_UUID16;
+ service_found = TRUE;
+ } else if ((type == EIR_UUID32_SOME) || (type == EIR_UUID32_ALL)) {
+ size = 4;
+ service.type = SDP_UUID32;
+ service_found = TRUE;
+ } else if ((type == EIR_UUID128_SOME) || (type == EIR_UUID128_ALL)) {
+ size = 16;
+ service.type = SDP_UUID128;
+ service_found = TRUE;
+ }
+
+ if (service_found) {
+ uint8_t *data = &eir_data[2];
+ uint16_t val16;
+ uint32_t val32;
+ int i, k;
+
+ count = field_len/size;
+
+ /* Generate uuids in SDP format (EIR data is Little Endian) */
+ switch (service.type) {
+ case SDP_UUID16:
+ for (i = 0; i < count; i++) {
+ val16 = data[1];
+ val16 = (val16<<8) + data[0];
+ service.value.uuid16 = val16;
+ *uuids++ = bt_uuid2string(&service);
+ data += size;
+ }
+ break;
+ case SDP_UUID32:
+ for (i = 0; i < count; i++) {
+ val32 = data[3];
+ for (k = size-2 ; k >= 0; k--)
+ val32 = (val32<<8) + data[k];
+ service.value.uuid32 = val32;
+ *uuids++ = bt_uuid2string(&service);
+ data += size;
+ }
+ break;
+ case SDP_UUID128:
+ for (i = 0; i < count; i++) {
+ for (k = 0; k < size; k++)
+ service.value.uuid128.data[k] = data[size-k-1];
+ *uuids++ = bt_uuid2string(&service);
+ data += size;
+ }
+ break;
+ }
+ }
+
+ len += field_len + 1;
+ eir_data += field_len + 1;
+ }
+}
+
void adapter_emit_device_found(struct btd_adapter *adapter,
- struct remote_dev_info *dev)
+ struct remote_dev_info *dev, uint8_t *eir_data)
{
struct btd_device *device;
char peer_addr[18], local_addr[18];
@@ -2728,6 +2853,8 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
dbus_bool_t paired = FALSE;
dbus_int16_t rssi = dev->rssi;
char *alias;
+ char **uuids = NULL;
+ int uuid_count = 0;
ba2str(&dev->bdaddr, peer_addr);
ba2str(&adapter->bdaddr, local_addr);
@@ -2747,6 +2874,15 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
} else
alias = g_strdup(dev->alias);
+ /* Extract UUIDs from extended inquiry response if any*/
+ if (eir_data != NULL)
+ uuid_count = get_uuid_count_eir(eir_data);
+
+ if (uuid_count > 0) {
+ uuids = g_new0(char *, uuid_count + 1);
+ get_uuids_eir(uuids, eir_data);
+ }
+
emit_device_found(adapter->path, paddr,
"Address", DBUS_TYPE_STRING, &paddr,
"Class", DBUS_TYPE_UINT32, &dev->class,
@@ -2756,15 +2892,17 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
"Alias", DBUS_TYPE_STRING, &alias,
"LegacyPairing", DBUS_TYPE_BOOLEAN, &dev->legacy,
"Paired", DBUS_TYPE_BOOLEAN, &paired,
+ "UUIDs", DBUS_TYPE_ARRAY, &uuids, uuid_count,
NULL);
g_free(alias);
+ g_strfreev(uuids);
}
void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
int8_t rssi, uint32_t class, const char *name,
const char *alias, gboolean legacy,
- name_status_t name_status)
+ name_status_t name_status, uint8_t *eir_data)
{
struct remote_dev_info *dev, match;
@@ -2803,7 +2941,7 @@ done:
adapter->found_devices = g_slist_sort(adapter->found_devices,
(GCompareFunc) dev_rssi_cmp);
- adapter_emit_device_found(adapter, dev);
+ adapter_emit_device_found(adapter, dev, eir_data);
}
int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr)
diff --git a/src/adapter.h b/src/adapter.h
index d141e32..891a133 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -114,10 +114,10 @@ struct remote_dev_info *adapter_search_found_devices(struct btd_adapter *adapter
void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
int8_t rssi, uint32_t class, const char *name,
const char *alias, gboolean legacy,
- name_status_t name_status);
+ name_status_t name_status, uint8_t *eir_data);
int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr);
void adapter_emit_device_found(struct btd_adapter *adapter,
- struct remote_dev_info *dev);
+ struct remote_dev_info *dev, uint8_t *eir_data);
void adapter_update_oor_devices(struct btd_adapter *adapter);
void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode);
void adapter_setname_complete(bdaddr_t *local, uint8_t status);
@@ -127,6 +127,7 @@ void adapter_service_insert(const bdaddr_t *bdaddr, void *rec);
void adapter_service_remove(const bdaddr_t *bdaddr, void *rec);
sdp_list_t *adapter_get_services(struct btd_adapter *adapter);
void adapter_set_class_complete(bdaddr_t *bdaddr, uint8_t status);
+void adapter_update_ext_inquiry_response(const bdaddr_t *src);
struct agent *adapter_get_agent(struct btd_adapter *adapter);
void adapter_add_connection(struct btd_adapter *adapter,
diff --git a/src/dbus-hci.c b/src/dbus-hci.c
index daec192..64f8186 100644
--- a/src/dbus-hci.c
+++ b/src/dbus-hci.c
@@ -516,7 +516,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
if (dev) {
adapter_update_found_devices(adapter, peer, rssi, class,
NULL, NULL, dev->legacy,
- NAME_NOT_REQUIRED);
+ NAME_NOT_REQUIRED, data);
return;
}
@@ -567,7 +567,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
/* add in the list to track name sent/pending */
adapter_update_found_devices(adapter, peer, rssi, class, name, alias,
- legacy, name_status);
+ legacy, name_status, data);
g_free(name);
g_free(alias);
@@ -643,7 +643,7 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status,
if (dev_info) {
g_free(dev_info->name);
dev_info->name = g_strdup(name);
- adapter_emit_device_found(adapter, dev_info);
+ adapter_emit_device_found(adapter, dev_info, NULL);
}
if (device)
diff --git a/src/sdpd-service.c b/src/sdpd-service.c
index 798e49d..5aa00f1 100644
--- a/src/sdpd-service.c
+++ b/src/sdpd-service.c
@@ -181,23 +181,30 @@ void create_ext_inquiry_response(const char *name,
{
sdp_list_t *list = services;
uint8_t *ptr = data;
- uint16_t uuid[24];
- int i, index = 0;
+ uint16_t eir_len = 0;
+ int len;
+ uint16_t uuid16[EIR_DATA_LENGTH/2];
+ uint8_t *uuid128;
+ int i, k, index = 0;
+ gboolean truncated = FALSE;
if (name) {
- int len = strlen(name);
+ len = strlen(name);
+ /* EIR Data type */
if (len > 48) {
len = 48;
- ptr[1] = 0x08;
+ ptr[1] = EIR_NAME_SHORT;
} else
- ptr[1] = 0x09;
+ ptr[1] = EIR_NAME_COMPLETE;
+ /* EIR Data length */
ptr[0] = len + 1;
memcpy(ptr + 2, name, len);
- ptr += len + 2;
+ eir_len += (len + 2);
+ ptr += (len + 2);
}
if (tx_power != 0) {
@@ -209,7 +216,7 @@ void create_ext_inquiry_response(const char *name,
if (did_vendor != 0x0000) {
uint16_t source = 0x0002;
*ptr++ = 9;
- *ptr++ = 0x10;
+ *ptr++ = EIR_DEVICE_ID;
*ptr++ = (source & 0x00ff);
*ptr++ = (source & 0xff00) >> 8;
*ptr++ = (did_vendor & 0x00ff);
@@ -218,9 +225,11 @@ void create_ext_inquiry_response(const char *name,
*ptr++ = (did_product & 0xff00) >> 8;
*ptr++ = (did_version & 0x00ff);
*ptr++ = (did_version & 0xff00) >> 8;
+ eir_len += 10;
}
- ptr[1] = 0x03;
+
+ /* Group all UUID16 types */
for (; list; list = list->next) {
sdp_record_t *rec = (sdp_record_t *) list->data;
@@ -234,28 +243,93 @@ void create_ext_inquiry_response(const char *name,
if (rec->svclass.value.uuid16 == PNP_INFO_SVCLASS_ID)
continue;
- if (index > 23) {
- ptr[1] = 0x02;
+ /* Stop if not enough space to put next UUID16 */
+ if ((eir_len + 2 + sizeof(uint16_t)) > EIR_DATA_LENGTH) {
+ truncated = TRUE;
break;
}
+ /* Check for duplicates */
for (i = 0; i < index; i++)
- if (uuid[i] == rec->svclass.value.uuid16)
+ if (uuid16[i] == rec->svclass.value.uuid16)
break;
- if (i == index - 1)
+ if (i < index)
continue;
- uuid[index++] = rec->svclass.value.uuid16;
+ uuid16[index++] = rec->svclass.value.uuid16;
+ eir_len += sizeof(uint16_t);
}
if (index > 0) {
- ptr[0] = (index * 2) + 1;
+ /* EIR Data length */
+ ptr[0] = (index * sizeof(uint16_t)) + 1;
+ /* EIR Data type */
+ ptr[1] = (truncated) ? EIR_UUID16_SOME : EIR_UUID16_ALL;
+
ptr += 2;
+ eir_len += 2;
+
for (i = 0; i < index; i++) {
- *ptr++ = (uuid[i] & 0x00ff);
- *ptr++ = (uuid[i] & 0xff00) >> 8;
+ *ptr++ = (uuid16[i] & 0x00ff);
+ *ptr++ = (uuid16[i] & 0xff00) >> 8;
+ }
+ }
+
+ /* Group all UUID128 types */
+ if (!truncated && (eir_len <= EIR_DATA_LENGTH - 2 )) {
+
+ list = services;
+ index = 0;
+
+ /* Store UUID128 in place, skipping first 2 bytes to insert type and length later */
+ uuid128 = ptr + 2;
+
+ for (; list; list = list->next) {
+ sdp_record_t *rec = (sdp_record_t *) list->data;
+
+ if (rec->svclass.type != SDP_UUID128)
+ continue;
+
+ /* Stop if not enough space to put next UUID128 */
+ if ((eir_len + 2 + SIZEOF_UUID128) > EIR_DATA_LENGTH) {
+ truncated = TRUE;
+ break;
+ }
+
+ /* Check for duplicates, EIR data is Little Endian */
+ for (i = 0; i < index; i++) {
+ for (k = 0; k < SIZEOF_UUID128; k++) {
+ if (uuid128[i*SIZEOF_UUID128 + k] !=
+ rec->svclass.value.uuid128.data[SIZEOF_UUID128 - k])
+ break;
+ }
+ if (k == SIZEOF_UUID128)
+ break;
+ }
+
+ if (i < index)
+ continue;
+
+ /* EIR data is Little Endian */
+ for (k = 0; k < SIZEOF_UUID128; k++)
+ uuid128[index*SIZEOF_UUID128 + k] =
+ rec->svclass.value.uuid128.data[SIZEOF_UUID128 - 1 - k];
+
+ eir_len += SIZEOF_UUID128;
+ index++;
+ }
+
+ if (index > 0 || truncated) {
+ /* EIR Data length */
+ ptr[0] = (index * SIZEOF_UUID128) + 1;
+ /* EIR Data type */
+ ptr[1] = (truncated) ? EIR_UUID128_SOME : EIR_UUID128_ALL;
+
+ eir_len += 2;
+
+ ptr = data + eir_len;
}
}
}
diff --git a/src/sdpd.h b/src/sdpd.h
index 1d2e169..1425c64 100644
--- a/src/sdpd.h
+++ b/src/sdpd.h
@@ -35,6 +35,26 @@
#define SDPDBG(fmt...)
#endif
+#define EIR_DATA_LENGTH 240
+
+#define EIR_FLAGS 0x01 /* Flags */
+#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
+#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
+#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */
+#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
+#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */
+#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
+#define EIR_NAME_SHORT 0x08 /* shortened local name */
+#define EIR_NAME_COMPLETE 0x09 /* complete local name */
+#define EIR_TX_POWER 0x0A /* Transmit power level */
+#define OOB_CLASS_OF_DEVICE 0x0D /* Class of Device (OOB only) */
+#define OOB_SIMPLE_PAIRING_HASH_C 0x0E /* Simple Pairing HashC (OOB only) */
+#define OOB_SIMPLE_PAIRING_RAND_R 0x0F /* Simple Pairing RandR (OOB only) */
+#define EIR_DEVICE_ID 0x10 /* Device ID */
+#define EIR_MANF_DATA 0xFF /* Manufacturer Specific Data */
+
+#define SIZEOF_UUID128 16
+
typedef struct request {
bdaddr_t device;
bdaddr_t bdaddr;
--
1.7.1
--
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply related
* [PATCH] Bluetooth: Reset the security level after an authentication failure
From: johan.hedberg @ 2010-06-18 8:08 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Johan Hedberg
From: Johan Hedberg <johan.hedberg@nokia.com>
When authentication fails for a connection the assumed security level
should be set back to BT_SECURITY_LOW so that subsequent connect
attempts over the same link don't falsely assume that security is
adequate enough.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/hci_event.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 6c57fc7..786b5de 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1049,6 +1049,8 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
if (conn) {
if (!ev->status)
conn->link_mode |= HCI_LM_AUTH;
+ else
+ conn->sec_level = BT_SECURITY_LOW;
clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH] Fixes sdp_get_supp_feat function
From: Johan Hedberg @ 2010-06-18 8:14 UTC (permalink / raw)
To: Elvis Pfützenreuter; +Cc: linux-bluetooth
In-Reply-To: <1276705848-22401-1-git-send-email-epx@signove.com>
Hi Elvis,
On Wed, Jun 16, 2010, Elvis Pfützenreuter wrote:
> In case of string data items, value is a pointer by itself.
> ---
> lib/sdp.c | 25 ++++++++++++++++++++++---
> 1 files changed, 22 insertions(+), 3 deletions(-)
The patch is now upstream. Thanks.
Johan
^ permalink raw reply
* hci_scodata_packet: hci1 SCO packet for unknown connection handle 42
From: Andrei Moraru @ 2010-06-18 12:29 UTC (permalink / raw)
To: linux-bluetooth
Hello,
the machine is running CentOS and Asterisk 1.4.32
there are installed bluez-4.66 and asterisk module chan_mobile
The Asterisk crashes sometimes when is using FXO over the bluetooth
connection via chan_mobile
uname -a:
2.6.18-164.el5 #1 SMP Thu Sep 3 03:33:56 EDT 2009 i686 athlon i386 GNU/Linux
[root@voip ~]# lsusb
Bus 001 Device 001: ID 0000:0000
Bus 003 Device 001: ID 0000:0000
Bus 002 Device 001: ID 0000:0000
Bus 004 Device 001: ID 0000:0000
Bus 004 Device 002: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth
Dongle (HCI mode)
Bus 004 Device 003: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth
Dongle (HCI mode)
the /var/log/messages
Jun 18 15:14:45 voip kernel: hci_scodata_packet: hci1 SCO packet for unknown
connection handle 42
Jun 18 15:14:45 voip kernel: hci_scodata_packet: hci1 SCO packet for unknown
connection handle 42
Jun 18 15:21:05 voip kernel: hci_scodata_packet: hci0 SCO packet for unknown
connection handle 42
Jun 18 15:21:05 voip last message repeated 2 times
Jun 18 15:21:21 voip kernel: hci_scodata_packet: hci0 SCO packet for unknown
connection handle 43
Jun 18 15:21:21 voip kernel: hci_scodata_packet: hci0 SCO packet for unknown
connection handle 43
Jun 18 15:22:02 voip kernel: hci_scodata_packet: hci0 SCO packet for unknown
connection handle 42
Jun 18 15:25:16 voip last message repeated 3 times
Please suggest your opinion.
^ permalink raw reply
* Re: hci_scodata_packet: hci1 SCO packet for unknown connection handle 42
From: Gustavo F. Padovan @ 2010-06-18 18:49 UTC (permalink / raw)
To: Andrei Moraru; +Cc: linux-bluetooth
In-Reply-To: <AANLkTin25xCMcVDCzbeXO-ZZfxhS4O0foXU8wl4h3tds@mail.gmail.com>
Hi Andrei,
* Andrei Moraru <andrei.moraru.n@gmail.com> [2010-06-18 15:29:41 +0300]:
> Hello,
>
> the machine is running CentOS and Asterisk 1.4.32
>
> there are installed bluez-4.66 and asterisk module chan_mobile
>
> The Asterisk crashes sometimes when is using FXO over the bluetooth
> connection via chan_mobile
>
> uname -a:
> 2.6.18-164.el5 #1 SMP Thu Sep 3 03:33:56 EDT 2009 i686 athlon i386 GNU/Linux
Update your kernel to a 2.6.34 at least and see if you still have this
issue.
--
Gustavo F. Padovan
http://padovan.org
^ permalink raw reply
* potential bug in bnep_net_set_mc_list()
From: Dan Carpenter @ 2010-06-18 23:09 UTC (permalink / raw)
To: Jiri Pirko; +Cc: linux-bluetooth, netdev
This is from ff6e2163f28a: "net: convert multiple drivers to use
netdev_for_each_mc_addr, part7"
net/bluetooth/bnep/netdev.c
101 i = 0;
102 netdev_for_each_mc_addr(ha, dev) {
103 if (i == BNEP_MAX_MULTICAST_FILTERS)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
104 break;
105 memcpy(__skb_put(skb, ETH_ALEN), ha->addr, ETH_ALEN);
106 memcpy(__skb_put(skb, ETH_ALEN), ha->addr, ETH_ALEN);
107 }
"i" is never incremented here so the check is always false.
regards,
dan carpenter
^ permalink raw reply
* Re: [PATCH] Bluetooth: Don't accept ConfigReq if we aren't in the BT_CONFIG state
From: Gustavo F. Padovan @ 2010-06-18 23:59 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo F. Padovan
In-Reply-To: <1276493175-9650-1-git-send-email-gustavo@padovan.org>
* Gustavo F. Padovan <gustavo@padovan.org> [2010-06-14 02:26:15 -0300]:
> From: Gustavo F. Padovan <padovan@profusion.mobi>
>
> If such event happens we shall reply with a Command Reject, because we are
> not expecting any configure request.
>
> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
> ---
> net/bluetooth/l2cap.c | 8 +++++++-
> 1 files changed, 7 insertions(+), 1 deletions(-)
>
> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index 9753b69..f725fcc 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -2741,8 +2741,14 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
> if (!sk)
> return -ENOENT;
>
> - if (sk->sk_state == BT_DISCONN)
> + if (sk->sk_state != BT_CONFIG) {
> + struct l2cap_cmd_rej rej;
> +
> + rej.reason = cpu_to_le16(0x0002);
> + l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
> + sizeof(rej), &rej);
> goto unlock;
> + }
>
> /* Reject if config buffer is too small. */
> len = cmd_len - sizeof(*req);
I tested this one by myself. I'm queueing it for -next.
With a little modification it works.
- l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ,
+ l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
i.e., the original patch even compile. ;)
--
Gustavo F. Padovan
http://padovan.org
^ permalink raw reply
* Re: potential bug in bnep_net_set_mc_list()
From: Gustavo F. Padovan @ 2010-06-19 0:22 UTC (permalink / raw)
To: Dan Carpenter; +Cc: Jiri Pirko, linux-bluetooth, netdev
In-Reply-To: <20100618230916.GA5467@bicker>
Hi Dan,
* Dan Carpenter <error27@gmail.com> [2010-06-19 01:09:17 +0200]:
> This is from ff6e2163f28a: "net: convert multiple drivers to use
> netdev_for_each_mc_addr, part7"
>
> net/bluetooth/bnep/netdev.c
> 101 i = 0;
> 102 netdev_for_each_mc_addr(ha, dev) {
> 103 if (i == BNEP_MAX_MULTICAST_FILTERS)
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> 104 break;
> 105 memcpy(__skb_put(skb, ETH_ALEN), ha->addr, ETH_ALEN);
> 106 memcpy(__skb_put(skb, ETH_ALEN), ha->addr, ETH_ALEN);
> 107 }
>
> "i" is never incremented here so the check is always false.
Bring back the increment should fix this. I'll send a fix for this.
--
Gustavo F. Padovan
http://padovan.org
^ permalink raw reply
* [PATCH] Bluetooth: Bring back var 'i' increment
From: Gustavo F. Padovan @ 2010-06-19 0:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: gustavo, netdev
In-Reply-To: <20100619002213.GC14514@vigoh>
commit ff6e2163f28a1094fb5ca5950fe2b43c3cf6bc7a accidentally added a
regression on the bnep code. Fixing it.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
net/bluetooth/bnep/netdev.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c
index 0faad5c..8c100c9 100644
--- a/net/bluetooth/bnep/netdev.c
+++ b/net/bluetooth/bnep/netdev.c
@@ -104,6 +104,8 @@ static void bnep_net_set_mc_list(struct net_device *dev)
break;
memcpy(__skb_put(skb, ETH_ALEN), ha->addr, ETH_ALEN);
memcpy(__skb_put(skb, ETH_ALEN), ha->addr, ETH_ALEN);
+
+ i++;
}
r->len = htons(skb->len - len);
}
--
1.6.4.4
^ permalink raw reply related
* Re: [PATCH] Bluetooth: Bring back var 'i' increment
From: Gustavo F. Padovan @ 2010-06-19 0:28 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: linux-bluetooth, netdev, marcel
In-Reply-To: <1276907040-23229-1-git-send-email-padovan@profusion.mobi>
* Gustavo F. Padovan <padovan@profusion.mobi> [2010-06-18 21:24:00 -0300]:
> commit ff6e2163f28a1094fb5ca5950fe2b43c3cf6bc7a accidentally added a
> regression on the bnep code. Fixing it.
>
> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
> ---
> net/bluetooth/bnep/netdev.c | 2 ++
> 1 files changed, 2 insertions(+), 0 deletions(-)
>
> diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c
> index 0faad5c..8c100c9 100644
> --- a/net/bluetooth/bnep/netdev.c
> +++ b/net/bluetooth/bnep/netdev.c
> @@ -104,6 +104,8 @@ static void bnep_net_set_mc_list(struct net_device *dev)
> break;
> memcpy(__skb_put(skb, ETH_ALEN), ha->addr, ETH_ALEN);
> memcpy(__skb_put(skb, ETH_ALEN), ha->addr, ETH_ALEN);
> +
> + i++;
> }
> r->len = htons(skb->len - len);
> }
> --
Marcel, if you want I can carry the fix on my tree for -next.
--
Gustavo F. Padovan
http://padovan.org
^ permalink raw reply
* Re: [PATCH] Bluetooth: check l2cap pending status before sending l2cap connect request
From: Gustavo F. Padovan @ 2010-06-19 0:53 UTC (permalink / raw)
To: Emeltchenko Andrei; +Cc: linux-bluetooth
In-Reply-To: <1276692725-10284-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
* Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2010-06-16 15:52:05 +0300]:
> From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
>
> Due to race condition in L2CAP state machine L2CAP Connection Request
> may be sent twice for SDP with the same source channel id. Problems
> reported connecting to Apple products, some carkit, Blackberry phones.
>
> ...
> 2010-06-07 21:18:03.651031 < ACL data: handle 1 flags 0x02 dlen 12
> L2CAP(s): Connect req: psm 1 scid 0x0040
> 2010-06-07 21:18:03.653473 > HCI Event: Number of Completed Packets (0x13) plen 5
> handle 1 packets 1
> 2010-06-07 21:18:03.653808 > HCI Event: Auth Complete (0x06) plen 3
> status 0x00 handle 1
> 2010-06-07 21:18:03.653869 < ACL data: handle 1 flags 0x02 dlen 12
> L2CAP(s): Connect req: psm 1 scid 0x0040
> ...
>
> Patch uses L2CAP_CONF_CONNECT_PEND flag to mark that L2CAP Connection
> Request has been sent.
>
> Modified version of Ville Tervo patch.
>
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
> ---
> net/bluetooth/l2cap.c | 11 +++++++++--
> 1 files changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index fc81acb..1ed51ad 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -387,13 +387,16 @@ static void l2cap_do_start(struct sock *sk)
> if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
> return;
>
> - if (l2cap_check_security(sk)) {
> + if (l2cap_check_security(sk) &&
> + ! l2cap_pi(sk)->conf_state &
> + L2CAP_CONF_CONNECT_PEND) {
This is wrong, you have to add parentheses here:
!(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND)
> struct l2cap_conn_req req;
> req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
> req.psm = l2cap_pi(sk)->psm;
>
> l2cap_pi(sk)->ident = l2cap_get_ident(conn);
>
> + l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
> l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
> L2CAP_CONN_REQ, sizeof(req), &req);
> }
> @@ -441,13 +444,16 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
> }
>
> if (sk->sk_state == BT_CONNECT) {
> - if (l2cap_check_security(sk)) {
> + if (l2cap_check_security(sk) &&
> + ! l2cap_pi(sk)->conf_state &
> + L2CAP_CONF_CONNECT_PEND) {
Here too.
> struct l2cap_conn_req req;
> req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
> req.psm = l2cap_pi(sk)->psm;
>
> l2cap_pi(sk)->ident = l2cap_get_ident(conn);
>
> + l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
> l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
> L2CAP_CONN_REQ, sizeof(req), &req);
> }
> @@ -3828,6 +3834,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
>
> l2cap_pi(sk)->ident = l2cap_get_ident(conn);
>
> + l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
> l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
> L2CAP_CONN_REQ, sizeof(req), &req);
> } else {
> --
> 1.7.0.4
Otherwise the patch seem fine to me.
>
> --
> 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
--
Gustavo F. Padovan
http://padovan.org
^ permalink raw reply
* Re: Users need to manually run "hid2hci --method dell -v 413c -p 8158 --mode hci" even when udev rule is installed
From: Pacho Ramos @ 2010-06-19 15:05 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1272134552.7585.9.camel@localhost.localdomain>
[-- Attachment #1: Type: text/plain, Size: 730 bytes --]
El sáb, 24-04-2010 a las 20:42 +0200, Pacho Ramos escribió:
> Hello
>
> I would like to ask for help to try to find where could be the problem
> causing this:
> http://bugs.gentoo.org/show_bug.cgi?id=315749
>
> Reporter seems to need to manually run:
> hid2hci --method dell -v 413c -p 8158 --mode hci
>
> to get bluetooth switched to hci mode.
>
> I don't understand why he needs to run it since involved udev rule file
> seems to be properly installed.
>
> Could anybody help us on this please?
>
> Thanks a lot
This is still affecting to some users, can anybody help us? At least,
how could we check if udev is, at least, trying to execute hid2hci from
97-bluetooth-hid2hci.rules file?
Thanks
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* Re: Users need to manually run "hid2hci --method dell -v 413c -p 8158 --mode hci" even when udev rule is installed
From: Bastien Nocera @ 2010-06-19 15:55 UTC (permalink / raw)
To: pacho; +Cc: linux-bluetooth
In-Reply-To: <1276959945.16187.0.camel@localhost.localdomain>
On Sat, 2010-06-19 at 17:05 +0200, Pacho Ramos wrote:
> El sáb, 24-04-2010 a las 20:42 +0200, Pacho Ramos escribió:
> > Hello
> >
> > I would like to ask for help to try to find where could be the problem
> > causing this:
> > http://bugs.gentoo.org/show_bug.cgi?id=315749
> >
> > Reporter seems to need to manually run:
> > hid2hci --method dell -v 413c -p 8158 --mode hci
> >
> > to get bluetooth switched to hci mode.
> >
> > I don't understand why he needs to run it since involved udev rule file
> > seems to be properly installed.
> >
> > Could anybody help us on this please?
> >
> > Thanks a lot
>
> This is still affecting to some users, can anybody help us? At least,
> how could we check if udev is, at least, trying to execute hid2hci from
> 97-bluetooth-hid2hci.rules file?
2 things.
This is already fixed in udev upstream, and hid2hci doesn't live in
bluez, but in udev now.
This was also fixed recently in Fedora 14.
Cheers
^ permalink raw reply
* Re: [PATCH 1/1] Bluetooth: hidp: Add support for hidraw HIDIOCGFEATURE and HIDIOCSFEATURE
From: Jiri Kosina @ 2010-06-19 17:49 UTC (permalink / raw)
To: Alan Ott
Cc: Marcel Holtmann, David S Miller, Michael Poole, Bastien Nocera,
Eric Dumazet, linux-bluetooth, linux-kernel, netdev
In-Reply-To: <1276467601-9066-1-git-send-email-alan@signal11.us>
On Sun, 13 Jun 2010, Alan Ott wrote:
> This patch adds support or getting and setting feature reports for bluetooth
> HID devices from HIDRAW.
>
> Signed-off-by: Alan Ott <alan@signal11.us>
Marcel, any word on this please? We already have USB counterpart in, so
it'd be nice to finalize the Bluetooth part as well.
Thanks.
> ---
> net/bluetooth/hidp/core.c | 121 +++++++++++++++++++++++++++++++++++++++++++--
> net/bluetooth/hidp/hidp.h | 8 +++
> 2 files changed, 125 insertions(+), 4 deletions(-)
>
> diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
> index bfe641b..0f068a0 100644
> --- a/net/bluetooth/hidp/core.c
> +++ b/net/bluetooth/hidp/core.c
> @@ -36,6 +36,7 @@
> #include <linux/file.h>
> #include <linux/init.h>
> #include <linux/wait.h>
> +#include <linux/mutex.h>
> #include <net/sock.h>
>
> #include <linux/input.h>
> @@ -313,6 +314,93 @@ static int hidp_send_report(struct hidp_session *session, struct hid_report *rep
> return hidp_queue_report(session, buf, rsize);
> }
>
> +static int hidp_get_raw_report(struct hid_device *hid,
> + unsigned char report_number,
> + unsigned char *data, size_t count,
> + unsigned char report_type)
> +{
> + struct hidp_session *session = hid->driver_data;
> + struct sk_buff *skb;
> + size_t len;
> + int numbered_reports = hid->report_enum[report_type].numbered;
> +
> + switch (report_type) {
> + case HID_FEATURE_REPORT:
> + report_type = HIDP_TRANS_GET_REPORT | HIDP_DATA_RTYPE_FEATURE;
> + break;
> + case HID_INPUT_REPORT:
> + report_type = HIDP_TRANS_GET_REPORT | HIDP_DATA_RTYPE_INPUT;
> + break;
> + case HID_OUTPUT_REPORT:
> + report_type = HIDP_TRANS_GET_REPORT | HIDP_DATA_RTYPE_OUPUT;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + if (mutex_lock_interruptible(&session->report_mutex))
> + return -ERESTARTSYS;
> +
> + /* Set up our wait, and send the report request to the device. */
> + session->waiting_report_type = report_type & HIDP_DATA_RTYPE_MASK;
> + session->waiting_report_number = numbered_reports ? report_number : -1;
> + set_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
> + data[0] = report_number;
> + if (hidp_send_ctrl_message(hid->driver_data, report_type, data, 1))
> + goto err_eio;
> +
> + /* Wait for the return of the report. The returned report
> + gets put in session->report_return. */
> + while (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags)) {
> + int res;
> +
> + res = wait_event_interruptible_timeout(session->report_queue,
> + !test_bit(HIDP_WAITING_FOR_RETURN, &session->flags),
> + 5*HZ);
> + if (res == 0) {
> + /* timeout */
> + goto err_eio;
> + }
> + if (res < 0) {
> + /* signal */
> + goto err_restartsys;
> + }
> + }
> +
> + skb = session->report_return;
> + if (skb) {
> + if (numbered_reports) {
> + /* Strip off the report number. */
> + size_t rpt_len = skb->len-1;
> + len = rpt_len < count ? rpt_len : count;
> + memcpy(data, skb->data+1, len);
> + } else {
> + len = skb->len < count ? skb->len : count;
> + memcpy(data, skb->data, len);
> + }
> +
> + kfree_skb(skb);
> + session->report_return = NULL;
> + } else {
> + /* Device returned a HANDSHAKE, indicating protocol error. */
> + len = -EIO;
> + }
> +
> + clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
> + mutex_unlock(&session->report_mutex);
> +
> + return len;
> +
> +err_restartsys:
> + clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
> + mutex_unlock(&session->report_mutex);
> + return -ERESTARTSYS;
> +err_eio:
> + clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
> + mutex_unlock(&session->report_mutex);
> + return -EIO;
> +}
> +
> static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count,
> unsigned char report_type)
> {
> @@ -367,6 +455,10 @@ static void hidp_process_handshake(struct hidp_session *session,
> case HIDP_HSHK_ERR_INVALID_REPORT_ID:
> case HIDP_HSHK_ERR_UNSUPPORTED_REQUEST:
> case HIDP_HSHK_ERR_INVALID_PARAMETER:
> + if (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags)) {
> + clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
> + wake_up_interruptible(&session->report_queue);
> + }
> /* FIXME: Call into SET_ GET_ handlers here */
> break;
>
> @@ -403,9 +495,11 @@ static void hidp_process_hid_control(struct hidp_session *session,
> }
> }
>
> -static void hidp_process_data(struct hidp_session *session, struct sk_buff *skb,
> +/* Returns true if the passed-in skb should be freed by the caller. */
> +static int hidp_process_data(struct hidp_session *session, struct sk_buff *skb,
> unsigned char param)
> {
> + int done_with_skb = 1;
> BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param);
>
> switch (param) {
> @@ -417,7 +511,6 @@ static void hidp_process_data(struct hidp_session *session, struct sk_buff *skb,
>
> if (session->hid)
> hid_input_report(session->hid, HID_INPUT_REPORT, skb->data, skb->len, 0);
> -
> break;
>
> case HIDP_DATA_RTYPE_OTHER:
> @@ -429,12 +522,27 @@ static void hidp_process_data(struct hidp_session *session, struct sk_buff *skb,
> __hidp_send_ctrl_message(session,
> HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
> }
> +
> + if (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags) &&
> + param == session->waiting_report_type) {
> + if (session->waiting_report_number < 0 ||
> + session->waiting_report_number == skb->data[0]) {
> + /* hidp_get_raw_report() is waiting on this report. */
> + session->report_return = skb;
> + done_with_skb = 0;
> + clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
> + wake_up_interruptible(&session->report_queue);
> + }
> + }
> +
> + return done_with_skb;
> }
>
> static void hidp_recv_ctrl_frame(struct hidp_session *session,
> struct sk_buff *skb)
> {
> unsigned char hdr, type, param;
> + int free_skb = 1;
>
> BT_DBG("session %p skb %p len %d", session, skb, skb->len);
>
> @@ -454,7 +562,7 @@ static void hidp_recv_ctrl_frame(struct hidp_session *session,
> break;
>
> case HIDP_TRANS_DATA:
> - hidp_process_data(session, skb, param);
> + free_skb = hidp_process_data(session, skb, param);
> break;
>
> default:
> @@ -463,7 +571,8 @@ static void hidp_recv_ctrl_frame(struct hidp_session *session,
> break;
> }
>
> - kfree_skb(skb);
> + if (free_skb)
> + kfree_skb(skb);
> }
>
> static void hidp_recv_intr_frame(struct hidp_session *session,
> @@ -797,6 +906,7 @@ static int hidp_setup_hid(struct hidp_session *session,
> hid->dev.parent = hidp_get_device(session);
> hid->ll_driver = &hidp_hid_driver;
>
> + hid->hid_get_raw_report = hidp_get_raw_report;
> hid->hid_output_raw_report = hidp_output_raw_report;
>
> err = hid_add_device(hid);
> @@ -857,6 +967,9 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
> skb_queue_head_init(&session->ctrl_transmit);
> skb_queue_head_init(&session->intr_transmit);
>
> + mutex_init(&session->report_mutex);
> + init_waitqueue_head(&session->report_queue);
> +
> session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID);
> session->idle_to = req->idle_to;
>
> diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h
> index 8d934a1..00e71dd 100644
> --- a/net/bluetooth/hidp/hidp.h
> +++ b/net/bluetooth/hidp/hidp.h
> @@ -80,6 +80,7 @@
> #define HIDP_VIRTUAL_CABLE_UNPLUG 0
> #define HIDP_BOOT_PROTOCOL_MODE 1
> #define HIDP_BLUETOOTH_VENDOR_ID 9
> +#define HIDP_WAITING_FOR_RETURN 10
>
> struct hidp_connadd_req {
> int ctrl_sock; // Connected control socket
> @@ -154,6 +155,13 @@ struct hidp_session {
> struct sk_buff_head ctrl_transmit;
> struct sk_buff_head intr_transmit;
>
> + /* Used in hidp_get_raw_report() */
> + int waiting_report_type; /* HIDP_DATA_RTYPE_* */
> + int waiting_report_number; /* -1 for not numbered */
> + struct mutex report_mutex;
> + struct sk_buff *report_return;
> + wait_queue_head_t report_queue;
> +
> /* Report descriptor */
> __u8 *rd_data;
> uint rd_size;
> --
> 1.7.0.4
>
>
--
Jiri Kosina
SUSE Labs, Novell Inc.
^ permalink raw reply
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