* obex: isolate btio.[ch] as a library and do some cleanup
From: Zhenhua Zhang @ 2010-09-09 9:41 UTC (permalink / raw)
To: linux-bluetooth
Hi,
These patches move obexd/src/btio.[ch] out from source directory and make it identical with bluez's btio.[ch]. So we can freely copy them among bluez, obex and ofono.
Regards,
Zhenhua
^ permalink raw reply
* Bluez 4.70 Compiling issues
From: steven bluez @ 2010-09-09 9:33 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcel Holtmann, Gustavo F. Padovan"
In-Reply-To: <AANLkTik3Lr0NqDyn1Rpi=X3dvGTGcVuUbYnr7_+weaBD@mail.gmail.com>
Hi all ,
=A0=A0=A0=A0=A0=A0=A0 While I compile Bluez4.70 in my lucidlynx (ubuntu 10.=
04
&10.10). I am facing issues please do suggest on how to compile the
same & i have attached the logs
>
> =A0 CC=A0=A0=A0=A0 src/manager.o
> =A0 CC=A0=A0=A0=A0 src/adapter.o
> =A0 CC=A0=A0=A0=A0 src/device.o
> =A0 CC=A0=A0=A0=A0 src/dbus-common.o
> =A0 CC=A0=A0=A0=A0 src/dbus-hci.o
> =A0 GEN=A0=A0=A0 audio/telephony.c
> =A0 CC=A0=A0=A0=A0 audio/telephony.o
> =A0 GEN=A0=A0=A0 src/bluetooth.exp
> =A0 GEN=A0=A0=A0 src/bluetooth.ver
> =A0 CCLD=A0=A0 src/bluetoothd
> src/attrib-server.o: In function `send_notification':
> attrib-server.c:(.text+0x21d): undefined reference to `enc_notification'
> attrib-server.c:(.text+0x272): undefined reference to `g_attrib_send'
> src/attrib-server.o: In function `connect_event':
> attrib-server.c:(.text+0x9bc): undefined reference to `g_attrib_new'
> attrib-server.c:(.text+0x9e7): undefined reference to `g_attrib_register'
> src/attrib-server.o: In function `channel_destroy':
> attrib-server.c:(.text+0xa31): undefined reference to `g_attrib_unregiste=
r_all'
> attrib-server.c:(.text+0xa3c): undefined reference to `g_attrib_unref'
> src/attrib-server.o: In function `.L59':
> attrib-server.c:(.text+0xaf4): undefined reference to `dec_read_by_grp_re=
q'
> attrib-server.c:(.text+0xb2e): undefined reference to `enc_error_resp'
> attrib-server.c:(.text+0xb6d): undefined reference to `g_attrib_send'
> src/attrib-server.o: In function `.L58':
> attrib-server.c:(.text+0xb9e): undefined reference to `dec_read_req'
> attrib-server.c:(.text+0xc05): undefined reference to `enc_read_resp'
> src/attrib-server.o: In function `.L57':
> attrib-server.c:(.text+0xc3c): undefined reference to `dec_read_by_type_r=
eq'
> attrib-server.c:(.text+0xe09): undefined reference to `enc_read_by_type_r=
esp'
> attrib-server.c:(.text+0xe1d): undefined reference to `att_data_list_free=
'
> src/attrib-server.o: In function `.L56':
> attrib-server.c:(.text+0xe5f): undefined reference to `dec_find_info_req'
> attrib-server.c:(.text+0x102a): undefined reference to `enc_find_info_res=
p'
> attrib-server.c:(.text+0x1038): undefined reference to `att_data_list_fre=
e'
> attrib-server.c:(.text+0x12da): undefined reference to `enc_error_resp'
> attrib-server.c:(.text+0x1314): undefined reference to `enc_error_resp'
> attrib-server.c:(.text+0x134c): undefined reference to `enc_error_resp'
> attrib-server.c:(.text+0x1382): undefined reference to `enc_error_resp'
> attrib-server.c:(.text+0x13b5): undefined reference to `enc_error_resp'
> attrib-server.c:(.text+0x13dc): undefined reference to `enc_read_by_grp_r=
esp'
> attrib-server.c:(.text+0x13f0): undefined reference to `att_data_list_fre=
e'
> attrib-server.c:(.text+0x145a): undefined reference to `enc_error_resp'
> attrib-server.c:(.text+0x148f): undefined reference to `enc_error_resp'
> collect2: ld returned 1 exit status
> make[1]: *** [src/bluetoothd] Error 1
> make: *** [all] Error 2
Regards,
Steven
^ permalink raw reply
* [PATCHv3 3/3] Bluetooth: check L2CAP length in first ACL fragment
From: Emeltchenko Andrei @ 2010-09-09 7:43 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1284018181-29928-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
Current Bluetooth code assembles fragments of big L2CAP packets
in l2cap_recv_acldata and then checks allowed L2CAP size in
assemled L2CAP packet (pi->imtu < skb->len).
The patch moves allowed L2CAP size check to the early stage when
we receive the first fragment of L2CAP packet. We do not need to
reserve and keep L2CAP fragments for bad packets.
Updated version after comments from Mat Martineau <mathewm@codeaurora.org>
Trace below is received when using stress tools sending big
fragmented L2CAP packets.
...
[ 1712.798492] swapper: page allocation failure. order:4, mode:0x4020
[ 1712.804809] [<c0031870>] (unwind_backtrace+0x0/0xdc) from [<c00a1f70>]
(__alloc_pages_nodemask+0x4)
[ 1712.814666] [<c00a1f70>] (__alloc_pages_nodemask+0x47c/0x4d4) from
[<c00a1fd8>] (__get_free_pages+)
[ 1712.824645] [<c00a1fd8>] (__get_free_pages+0x10/0x3c) from [<c026eb5c>]
(__alloc_skb+0x4c/0xfc)
[ 1712.833465] [<c026eb5c>] (__alloc_skb+0x4c/0xfc) from [<bf28c738>]
(l2cap_recv_acldata+0xf0/0x1f8 )
[ 1712.843322] [<bf28c738>] (l2cap_recv_acldata+0xf0/0x1f8 [l2cap]) from
[<bf0094ac>] (hci_rx_task+0x)
...
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
---
net/bluetooth/l2cap.c | 17 +++++++++++++++++
1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index ce8f5e4..c95fbd8 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -4654,6 +4654,8 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
if (flags & ACL_START) {
struct l2cap_hdr *hdr;
+ struct sock *sk;
+ u16 cid;
int len;
if (conn->rx_len) {
@@ -4673,6 +4675,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
hdr = (struct l2cap_hdr *) skb->data;
len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
+ cid = __le16_to_cpu(hdr->cid);
if (len == skb->len) {
/* Complete frame received */
@@ -4689,6 +4692,20 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
goto drop;
}
+ sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
+
+ if (sk && l2cap_pi(sk)->imtu < len) {
+ BT_ERR("Frame exceeding recv MTU (len %d, MTU %d)",
+ len, l2cap_pi(sk)->imtu);
+ conn->rx_len = 0; /* needed? */
+ bh_unlock_sock(sk);
+ l2cap_conn_unreliable(conn, ECOMM);
+ goto drop;
+ }
+
+ if (sk)
+ bh_unlock_sock(sk);
+
/* Allocate skb for the complete frame (with header) */
conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
if (!conn->rx_skb)
--
1.7.0.4
^ permalink raw reply related
* [PATCHv3 2/3] Bluetooth: check for l2cap header in start fragment
From: Emeltchenko Andrei @ 2010-09-09 7:43 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1284018181-29928-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
BLUETOOTH SPECIFICATION Version 4.0 [Vol 3] page 36 mentioned
"Note: Start Fragments always begin with the Basic L2CAP header
of a PDU."
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
---
net/bluetooth/l2cap.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 9fad312..ce8f5e4 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -4664,7 +4664,8 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
l2cap_conn_unreliable(conn, ECOMM);
}
- if (skb->len < 2) {
+ /* Start fragment always begin with Basic L2CAP header */
+ if (skb->len < L2CAP_HDR_SIZE) {
BT_ERR("Frame is too short (len %d)", skb->len);
l2cap_conn_unreliable(conn, ECOMM);
goto drop;
--
1.7.0.4
^ permalink raw reply related
* [PATCHv3 1/3] Bluetooth: fix MTU L2CAP configuration parameter
From: Emeltchenko Andrei @ 2010-09-09 7:42 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1284018181-29928-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
When receiving L2CAP negative configuration response with respect
to MTU parameter we modify wrong field. MTU here means proposed
value of MTU that the remote device intends to transmit. So for local
L2CAP socket it is pi->imtu.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
Acked-by: Ville Tervo <ville.tervo@nokia.com>
Acked-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
net/bluetooth/l2cap.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index c784703..9fad312 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2771,10 +2771,10 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
case L2CAP_CONF_MTU:
if (val < L2CAP_DEFAULT_MIN_MTU) {
*result = L2CAP_CONF_UNACCEPT;
- pi->omtu = L2CAP_DEFAULT_MIN_MTU;
+ pi->imtu = L2CAP_DEFAULT_MIN_MTU;
} else
- pi->omtu = val;
- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+ pi->imtu = val;
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
break;
case L2CAP_CONF_FLUSH_TO:
--
1.7.0.4
^ permalink raw reply related
* [PATCHv3 0/3] Bluetooth: L2CAP robustness fixes
From: Emeltchenko Andrei @ 2010-09-09 7:42 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
Fixes increase L2CAP robustness to DOS attacks to BT stack.
Andrei Emeltchenko (3):
Bluetooth: fix MTU L2CAP configuration parameter
Bluetooth: check for l2cap header in start fragment
Bluetooth: check L2CAP length in first ACL fragment
net/bluetooth/l2cap.c | 26 ++++++++++++++++++++++----
1 files changed, 22 insertions(+), 4 deletions(-)
^ permalink raw reply
* [PATCH] Bluetooth: Don't clear the blacklist when closing the HCI device
From: johan.hedberg @ 2010-09-09 7:32 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Johan Hedberg
From: Johan Hedberg <johan.hedberg@nokia.com>
Clearing the blacklist in hci_dev_do_close() would mean that user space
needs to do extra work to re-block devices after a DEVDOWN-DEVUP cycle.
This patch removes the clearing of the blacklist in this case and
thereby saves user space from the extra work.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/hci_core.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index c52f091..bc2a052 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -562,7 +562,6 @@ static int hci_dev_do_close(struct hci_dev *hdev)
hci_dev_lock_bh(hdev);
inquiry_cache_flush(hdev);
hci_conn_hash_flush(hdev);
- hci_blacklist_clear(hdev);
hci_dev_unlock_bh(hdev);
hci_notify(hdev, HCI_DEV_DOWN);
--
1.7.0.4
^ permalink raw reply related
* [PATCH] Bluetooth: Simplify L2CAP Streaming mode sending
From: Gustavo F. Padovan @ 2010-09-08 23:32 UTC (permalink / raw)
To: linux-bluetooth; +Cc: netdev, linux-kernel, marcel, davem
In-Reply-To: <1283988727-1456-1-git-send-email-padovan@profusion.mobi>
As we don't have any error control on the Streaming mode, i.e., we don't
need to keep a copy of the skb for later resending we don't need to
call skb_clone() on it.
Then we can go one further here, and dequeue the skb before sending it,
that also means we don't need to look to sk->sk_send_head anymore.
The patch saves memory and time when sending Streaming mode data, so
it is good to mainline.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
net/bluetooth/l2cap.c | 24 +++++++-----------------
1 files changed, 7 insertions(+), 17 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 9fad312..f2062aa 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1441,33 +1441,23 @@ static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
static void l2cap_streaming_send(struct sock *sk)
{
- struct sk_buff *skb, *tx_skb;
+ struct sk_buff *skb;
struct l2cap_pinfo *pi = l2cap_pi(sk);
u16 control, fcs;
- while ((skb = sk->sk_send_head)) {
- tx_skb = skb_clone(skb, GFP_ATOMIC);
-
- control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
+ while ((skb = skb_dequeue(TX_QUEUE(sk)))) {
+ control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE);
control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
- put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
+ put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE);
if (pi->fcs == L2CAP_FCS_CRC16) {
- fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
- put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
+ fcs = crc16(0, (u8 *)skb->data, skb->len - 2);
+ put_unaligned_le16(fcs, skb->data + skb->len - 2);
}
- l2cap_do_send(sk, tx_skb);
+ l2cap_do_send(sk, skb);
pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
-
- if (skb_queue_is_last(TX_QUEUE(sk), skb))
- sk->sk_send_head = NULL;
- else
- sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
-
- skb = skb_dequeue(TX_QUEUE(sk));
- kfree_skb(skb);
}
}
--
1.7.2.2
^ permalink raw reply related
* Possible regression with skb_clone() in 2.6.36
From: Gustavo F. Padovan @ 2010-09-08 23:32 UTC (permalink / raw)
To: linux-bluetooth; +Cc: netdev, linux-kernel, marcel, davem
I've been experiencing some problems when running the L2CAP Streaming mode in
2.6.36. The system quickly runs in an Out Of Memory condition and crash. That
wasn't happening before, so I think we may have a regression here (I didn't
find where yet). The crash log is below.
The following patch does not fix the regression, but shows that removing the
skb_clone() call from l2cap_streaming_send() we workaround the problem. The
patch is good anyway because it saves memory and time.
By now I have no idea on how to fix this.
[ 5066.137533] Bluetooth: L2CAP ver 2.15
[ 5066.137873] Bluetooth: L2CAP socket layer initialized
[ 5066.545179] Bluetooth: RFCOMM TTY layer initialized
[ 5066.545879] Bluetooth: RFCOMM socket layer initialized
[ 5066.546582] Bluetooth: RFCOMM ver 1.11
[ 5092.268021] l2test invoked oom-killer: gfp_mask=0x4d0, order=0, oom_adj=0, oom_sc
ore_adj=0
[ 5092.268872] Pid: 3897, comm: l2test Not tainted 2.6.36-rc3 #5
[ 5092.269863] Call Trace:
[ 5092.270265] [<ffffffff8138b6a6>] ? _raw_spin_unlock+0x26/0x30
[ 5092.270878] [<ffffffff810c0827>] T.427+0x77/0x1e0
[ 5092.271874] [<ffffffff811b85e7>] ? security_real_capable_noaudit+0x37/0x60
[ 5092.272956] [<ffffffff810c0e3a>] out_of_memory+0x2ca/0x2f0
[ 5092.273894] [<ffffffff810c3d43>] __alloc_pages_nodemask+0x693/0x6b0
[ 5092.274871] [<ffffffff810ea3e6>] cache_alloc_refill+0x2d6/0x5c0
[ 5092.275864] [<ffffffff810ea805>] __kmalloc+0x135/0x150
[ 5092.276876] [<ffffffff8130f2ae>] __alloc_skb+0x6e/0x150
[ 5092.277865] [<ffffffff810d3a00>] ? might_fault+0x40/0x90
[ 5092.278652] [<ffffffff8130ace2>] sock_alloc_send_pskb+0x1c2/0x320
[ 5092.278927] [<ffffffff810d3a00>] ? might_fault+0x40/0x90
[ 5092.279864] [<ffffffff81312add>] ? memcpy_fromiovec+0x6d/0x90
[ 5092.280864] [<ffffffff8130ae50>] sock_alloc_send_skb+0x10/0x20
[ 5092.281867] [<ffffffffa00e600f>] l2cap_create_iframe_pdu+0x9f/0x2c0 [l2cap]
[ 5092.282865] [<ffffffffa00e84b9>] l2cap_sock_sendmsg+0x5d9/0x910 [l2cap]
[ 5092.283932] [<ffffffff8138ba3c>] ? restore_args+0x0/0x30
[ 5092.284865] [<ffffffff8130725b>] sock_sendmsg+0xdb/0x100
[ 5092.285652] [<ffffffff8138ba3c>] ? restore_args+0x0/0x30
[ 5092.285864] [<ffffffff8138ba3c>] ? restore_args+0x0/0x30
[ 5092.286864] [<ffffffff813073c0>] sys_sendto+0xf0/0x130
[ 5092.287864] [<ffffffff8138b60b>] ? _raw_spin_unlock_irq+0x2b/0x40
[ 5092.288872] [<ffffffff81093cfd>] ? trace_hardirqs_on_caller+0x13d/0x180
[ 5092.289927] [<ffffffff81093d4d>] ? trace_hardirqs_on+0xd/0x10
[ 5092.290864] [<ffffffff810d3a00>] ? might_fault+0x40/0x90
[ 5092.291649] [<ffffffff810d3a00>] ? might_fault+0x40/0x90
[ 5092.291864] [<ffffffff810d3a00>] ? might_fault+0x40/0x90
[ 5092.292864] [<ffffffff8130740f>] sys_send+0xf/0x20
[ 5092.293870] [<ffffffff8132ccd6>] compat_sys_socketcall+0x146/0x1f0
[ 5092.294875] [<ffffffff81053ee4>] sysenter_dispatch+0x7/0x30
[ 5092.295673] Mem-Info:
[ 5092.295863] DMA per-cpu:
[ 5092.296214] CPU 0: hi: 0, btch: 1 usd: 0
[ 5092.296925] DMA32 per-cpu:
[ 5092.297298] CPU 0: hi: 90, btch: 15 usd: 85
[ 5092.297864] active_anon:504 inactive_anon:543 isolated_anon:0
[ 5092.297865] active_file:14 inactive_file:3 isolated_file:0
[ 5092.297866] unevictable:0 dirty:0 writeback:3 unstable:0
[ 5092.297866] free:728 slab_reclaimable:559 slab_unreclaimable:39895
[ 5092.297867] mapped:12 shmem:35 pagetables:84 bounce:0
[ 5092.299944] DMA free:1064kB min:124kB low:152kB high:184kB active_anon:0kB inacti
ve_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB iso
lated(file):0kB present:15768kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem
:0kB slab_reclaimable:0kB slab_unreclaimable:14916kB kernel_stack:0kB pagetables:0kB
unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? yes
[ 5092.301862] lowmem_reserve[]: 0 236 236 236
[ 5092.303134] DMA32 free:1848kB min:1904kB low:2380kB high:2856kB active_anon:2016k
B inactive_anon:2172kB active_file:56kB inactive_file:12kB unevictable:0kB isolated(
anon):0kB isolated(file):0kB present:242380kB mlocked:0kB dirty:0kB writeback:12kB m
apped:48kB shmem:140kB slab_reclaimable:2236kB slab_unreclaimable:144664kB kernel_st
ack:456kB pagetables:336kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:1
03 all_unreclaimable? yes
[ 5092.304962] lowmem_reserve[]: 0 0 0 0
[ 5092.306066] DMA: 0*4kB 1*8kB 0*16kB 1*32kB 0*64kB 0*128kB 0*256kB 0*512kB 1*1024k
B 0*2048kB 0*4096kB = 1064kB
[ 5092.307862] DMA32: 10*4kB 2*8kB 0*16kB 0*32kB 0*64kB 0*128kB 1*256kB 1*512kB 1*10
24kB 0*2048kB 0*4096kB = 1848kB
[ 5092.309467] 52 total pagecache pages
[ 5092.309862] 0 pages in swap cache
[ 5092.310317] Swap cache stats: add 0, delete 0, find 0/0
[ 5092.310862] Free swap = 0kB
[ 5092.311260] Total swap = 0kB
[ 5092.313796] 65530 pages RAM
[ 5092.313868] 22603 pages reserved
[ 5092.314324] 206 pages shared
[ 5092.314862] 39353 pages non-shared
[ 5092.315348] [ pid ] uid tgid total_vm rss cpu oom_adj oom_score_adj name
[ 5092.315867] [ 1] 0 1 438 19 0 0 0 init
[ 5092.316871] [ 1018] 0 1018 537 75 0 -17 -1000 udevd
[ 5092.318867] [ 2217] 101 2217 606 39 0 0 0 dbus-
daemon
[ 5092.319865] [ 2825] 0 2825 481 29 0 0 0 dhcpc
d
[ 5092.320865] [ 3497] 0 3497 1091 83 0 0 0 sshd
[ 5092.321969] [ 3535] 0 3535 477 31 0 0 0 agett
y
[ 5092.322864] [ 3536] 0 3536 477 30 0 0 0 agett
y
[ 5092.323864] [ 3537] 0 3537 477 29 0 0 0 agett
y
[ 5092.325937] [ 3538] 0 3538 477 31 0 0 0 agett
y
[ 5092.326865] [ 3539] 0 3539 477 31 0 0 0 agett
y
[ 5092.327864] [ 3540] 0 3540 477 31 0 0 0 agett
y
[ 5092.328864] [ 3541] 0 3541 1738 105 0 0 0 sshd
[ 5092.329865] [ 3545] 0 3545 745 72 0 0 0 bash
[ 5092.330864] [ 3550] 0 3550 706 43 0 0 0 scree
n
[ 5092.331866] [ 3551] 0 3551 772 124 0 0 0 scree
n
[ 5092.332965] [ 3552] 0 3552 745 77 0 0 0 bash
[ 5092.333865] [ 3557] 0 3557 745 77 0 0 0 bash
[ 5092.334867] [ 3562] 0 3562 536 75 0 -17 -1000 udevd
[ 5092.336865] [ 3567] 0 3567 536 75 0 -17 -1000 udevd
[ 5092.337865] [ 3887] 0 3887 935 54 0 0 0 bluet
oothd
[ 5092.338864] [ 3896] 0 3896 458 24 0 0 0 l2tes
t
[ 5092.339864] [ 3897] 0 3897 458 24 0 0 0 l2tes
t
[ 5092.340933] [ 3942] 0 3942 458 29 0 0 0 l2tes
t
[ 5092.341863] Kernel panic - not syncing: Out of memory and no killable processes..
.
[ 5092.341864]
[ 5092.342864] Pid: 3897, comm: l2test Not tainted 2.6.36-rc3 #5
[ 5092.343862] Call Trace:
[ 5092.344934] [<ffffffff813884d9>] panic+0x8c/0x199
[ 5092.345621] [<ffffffff810c0e54>] out_of_memory+0x2e4/0x2f0
[ 5092.345864] [<ffffffff810c3d43>] __alloc_pages_nodemask+0x693/0x6b0
[ 5092.346894] [<ffffffff810ea3e6>] cache_alloc_refill+0x2d6/0x5c0
[ 5092.347864] [<ffffffff810ea805>] __kmalloc+0x135/0x150
[ 5092.348871] [<ffffffff8130f2ae>] __alloc_skb+0x6e/0x150
[ 5092.349865] [<ffffffff810d3a00>] ? might_fault+0x40/0x90
[ 5092.350628] [<ffffffff8130ace2>] sock_alloc_send_pskb+0x1c2/0x320
[ 5092.350935] [<ffffffff810d3a00>] ? might_fault+0x40/0x90
[ 5092.351864] [<ffffffff81312add>] ? memcpy_fromiovec+0x6d/0x90
[ 5092.352864] [<ffffffff8130ae50>] sock_alloc_send_skb+0x10/0x20
[ 5092.353867] [<ffffffffa00e600f>] l2cap_create_iframe_pdu+0x9f/0x2c0 [l2cap]
[ 5092.354865] [<ffffffffa00e84b9>] l2cap_sock_sendmsg+0x5d9/0x910 [l2cap]
[ 5092.355864] [<ffffffff8138ba3c>] ? restore_args+0x0/0x30
[ 5092.356864] [<ffffffff8130725b>] sock_sendmsg+0xdb/0x100
[ 5092.357612] [<ffffffff8138ba3c>] ? restore_args+0x0/0x30
[ 5092.357931] [<ffffffff8138ba3c>] ? restore_args+0x0/0x30
[ 5092.358864] [<ffffffff813073c0>] sys_sendto+0xf0/0x130
[ 5092.359864] [<ffffffff8138b60b>] ? _raw_spin_unlock_irq+0x2b/0x40
[ 5092.360929] [<ffffffff81093cfd>] ? trace_hardirqs_on_caller+0x13d/0x180
[ 5092.361866] [<ffffffff81093d4d>] ? trace_hardirqs_on+0xd/0x10
[ 5092.362864] [<ffffffff810d3a00>] ? might_fault+0x40/0x90
[ 5092.363653] [<ffffffff810d3a00>] ? might_fault+0x40/0x90
[ 5092.364868] [<ffffffff810d3a00>] ? might_fault+0x40/0x90
[ 5092.365865] [<ffffffff8130740f>] sys_send+0xf/0x20
[ 5092.366945] [<ffffffff8132ccd6>] compat_sys_socketcall+0x146/0x1f0
[ 5092.367865] [<ffffffff81053ee4>] sysenter_dispatch+0x7/0x30
Gustavo F. Padovan (1):
Bluetooth: Simplify L2CAP Streaming mode sending
^ permalink raw reply
* Re: [PATCH 1/2] Bluetooth: Implement LE Set Advertise Enable cmd
From: Gustavo F. Padovan @ 2010-09-08 22:06 UTC (permalink / raw)
To: Anderson Briglia; +Cc: linux-bluetooth
In-Reply-To: <20100908214359.GM16973@vigoh>
* Gustavo F. Padovan <padovan@profusion.mobi> [2010-09-08 18:43:59 -0300]:
> Hi Anderson,
>
> * Anderson Briglia <anderson.briglia@openbossa.org> [2010-08-23 15:30:14 -0400]:
>
> > This patch implements LE Set Advertise Enable command for dual mode and
> > Low Energy hci controllers. It also adds new HCI flags in order to
> > indicate the Advertising state for userland applications and kernel
> > itself.
> >
> > Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
> > ---
> > include/net/bluetooth/hci.h | 6 ++++++
> > net/bluetooth/hci_event.c | 27 +++++++++++++++++++++++++++
> > 2 files changed, 33 insertions(+), 0 deletions(-)
> >
> > diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> > index bcbdd6d..cae1816 100644
> > --- a/include/net/bluetooth/hci.h
> > +++ b/include/net/bluetooth/hci.h
> > @@ -76,6 +76,7 @@ enum {
> > HCI_INQUIRY,
> >
> > HCI_RAW,
>
> Skip a line here and then add the new LE commands
>
> > + HCI_LE_ADV,
> > };
> >
> > /* HCI ioctl defines */
> > @@ -593,6 +594,11 @@ struct hci_rp_read_bd_addr {
> > bdaddr_t bdaddr;
> > } __packed;
> >
> > +/* --- HCI LE Commands --- */
> > +#define HCI_OP_LE_SET_ADVERTISE_ENABLE 0x200a
> > + #define ADVERTISE_ENABLED 0x01
> > + #define ADVERTISE_DISABLED 0x00
And make these LE_ADVERTISE...
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply
* Re: [PATCH 2/2] Bluetooth: Implement LE Set Scan Enable cmd
From: Gustavo F. Padovan @ 2010-09-08 22:05 UTC (permalink / raw)
To: Anderson Briglia; +Cc: linux-bluetooth
In-Reply-To: <1282591815-26934-2-git-send-email-anderson.briglia@openbossa.org>
Hi Anderson,
* Anderson Briglia <anderson.briglia@openbossa.org> [2010-08-23 15:30:15 -0400]:
> This patch implements LE Set Scan Enable command for dual
> mode and Low Energy hci controllers. It also adds new HCI flags
> in order to indicate the LE Scanning state for userland applications
> and kernel itself.
>
> Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
> ---
> include/net/bluetooth/hci.h | 5 +++++
> net/bluetooth/hci_event.c | 25 +++++++++++++++++++++++++
> 2 files changed, 30 insertions(+), 0 deletions(-)
>
> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> index cae1816..268aa94 100644
> --- a/include/net/bluetooth/hci.h
> +++ b/include/net/bluetooth/hci.h
> @@ -77,6 +77,7 @@ enum {
>
> HCI_RAW,
> HCI_LE_ADV,
> + HCI_LE_SCAN,
> };
>
> /* HCI ioctl defines */
> @@ -599,6 +600,10 @@ struct hci_rp_read_bd_addr {
> #define ADVERTISE_ENABLED 0x01
> #define ADVERTISE_DISABLED 0x00
>
> +#define HCI_OP_LE_SET_SCAN_ENABLE 0x200c
> + #define LESCAN_ENABLED 0x01
> + #define LESCAN_DISABLED 0x00
Make these LE_SCAN_ENABLED and LE_SCAN_DISABLED.
> /* ---- HCI Events ---- */
> #define HCI_EV_INQUIRY_COMPLETE 0x01
>
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index c86c655..f483801 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -845,6 +845,27 @@ static void hci_cc_le_set_advertise(struct hci_dev *hdev, struct sk_buff *skb)
> hci_req_complete(hdev, status);
> }
>
> +static void hci_cc_le_set_scan(struct hci_dev *hdev, struct sk_buff *skb)
> +{
> + __u8 status = *((__u8 *) skb->data);
> + void *sent;
> +
> + BT_DBG("%s status 0x%x", hdev->name, status);
> +
> + sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
> + if (!sent)
> + return;
> +
> + clear_bit(HCI_LE_SCAN, &hdev->flags);
Why do you have this clear_bit() outside of the if below? if
status != 0, i.e, the command has failed we can say for sure that
scanning is disabled.
> + if (!status) {
> + __u8 param = *((__u8 *) sent);
> + if (param & LESCAN_ENABLED)
> + set_bit(HCI_LE_SCAN, &hdev->flags);
> + }
> +
> + hci_req_complete(hdev, status);
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply
* Re: [PATCH 1/2] Bluetooth: Implement LE Set Advertise Enable cmd
From: Gustavo F. Padovan @ 2010-09-08 21:43 UTC (permalink / raw)
To: Anderson Briglia; +Cc: linux-bluetooth
In-Reply-To: <1282591815-26934-1-git-send-email-anderson.briglia@openbossa.org>
Hi Anderson,
* Anderson Briglia <anderson.briglia@openbossa.org> [2010-08-23 15:30:14 -0400]:
> This patch implements LE Set Advertise Enable command for dual mode and
> Low Energy hci controllers. It also adds new HCI flags in order to
> indicate the Advertising state for userland applications and kernel
> itself.
>
> Signed-off-by: Anderson Briglia <anderson.briglia@openbossa.org>
> ---
> include/net/bluetooth/hci.h | 6 ++++++
> net/bluetooth/hci_event.c | 27 +++++++++++++++++++++++++++
> 2 files changed, 33 insertions(+), 0 deletions(-)
>
> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> index bcbdd6d..cae1816 100644
> --- a/include/net/bluetooth/hci.h
> +++ b/include/net/bluetooth/hci.h
> @@ -76,6 +76,7 @@ enum {
> HCI_INQUIRY,
>
> HCI_RAW,
Skip a line here and then add the new LE commands
> + HCI_LE_ADV,
> };
>
> /* HCI ioctl defines */
> @@ -593,6 +594,11 @@ struct hci_rp_read_bd_addr {
> bdaddr_t bdaddr;
> } __packed;
>
> +/* --- HCI LE Commands --- */
> +#define HCI_OP_LE_SET_ADVERTISE_ENABLE 0x200a
> + #define ADVERTISE_ENABLED 0x01
> + #define ADVERTISE_DISABLED 0x00
> +
> /* ---- HCI Events ---- */
> #define HCI_EV_INQUIRY_COMPLETE 0x01
>
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index bfef5ba..c86c655 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -822,6 +822,29 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
> hci_dev_unlock(hdev);
> }
>
> +static void hci_cc_le_set_advertise(struct hci_dev *hdev, struct sk_buff *skb)
> +{
> + __u8 status = *((__u8 *) skb->data);
> + void *sent;
> +
> + BT_DBG("%s status 0x%x", hdev->name, status);
> +
> + sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADVERTISE_ENABLE);
> + if (!sent)
> + return;
> +
> + if (!status) {
> + __u8 param = *((__u8 *) sent);
> +
> + clear_bit(HCI_LE_ADV, &hdev->flags);
> +
> + if (param & ADVERTISE_ENABLED)
> + set_bit(HCI_LE_ADV, &hdev->flags);
We could do that this way:
if (param == ADVERTISE_ENABLED)
set_bit(HCI_LE_ADV, &hdev->flags);
else
clear_bit(HCI_LE_ADV, &hdev->flags);
> --
> 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
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply
* Re: [PATCH 4/4] Bluetooth: Use a stream-oriented recvmsg with SOCK_STREAM L2CAP sockets.
From: Gustavo F. Padovan @ 2010-09-08 19:47 UTC (permalink / raw)
To: Mat Martineau; +Cc: linux-bluetooth, marcel, gustavo, rshaffer, linux-arm-msm
In-Reply-To: <1283965529-17068-5-git-send-email-mathewm@codeaurora.org>
* Mat Martineau <mathewm@codeaurora.org> [2010-09-08 10:05:29 -0700]:
> L2CAP ERTM sockets can be opened with the SOCK_STREAM socket type,
> which is a mandatory request for ERTM mode.
>
> However, these sockets still have SOCK_SEQPACKET read semantics when
> bt_sock_recvmsg() is used to pull data from the receive queue. If the
> application is only reading part of a frame, then the unread portion
> of the frame is discarded. If the application requests more bytes
> than are in the current frame, only the current frame's data is
> returned.
>
> This patch utilizes common code derived from RFCOMM's recvmsg()
> function to make L2CAP SOCK_STREAM reads behave like RFCOMM reads (and
> other SOCK_STREAM sockets in general). The application may read one
> byte at a time from the input stream and not lose any data, and may
> also read across L2CAP frame boundaries.
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
> ---
> net/bluetooth/l2cap.c | 3 +++
> 1 files changed, 3 insertions(+), 0 deletions(-)
Acked-by: Gustavo F. Padovan <padovan@profusion.mobi>
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply
* Re: [PATCH 3/4] Bluetooth: Use common SOCK_STREAM receive code in RFCOMM
From: Gustavo F. Padovan @ 2010-09-08 19:47 UTC (permalink / raw)
To: Mat Martineau; +Cc: linux-bluetooth, marcel, gustavo, rshaffer, linux-arm-msm
In-Reply-To: <1283965529-17068-4-git-send-email-mathewm@codeaurora.org>
* Mat Martineau <mathewm@codeaurora.org> [2010-09-08 10:05:28 -0700]:
> To reduce code duplication, have rfcomm_sock_recvmsg() call
> bt_sock_stream_recvmsg(). The common bt_sock_stream_recvmsg()
> code is nearly identical, with the RFCOMM-specific functionality
> for deferred setup and connection unthrottling left in
> rfcomm_sock_recvmsg().
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
> ---
> net/bluetooth/rfcomm/sock.c | 104 +++----------------------------------------
> 1 files changed, 6 insertions(+), 98 deletions(-)
Acked-by: Gustavo F. Padovan <padovan@profusion.mobi>
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply
* Re: [PATCH 2/4] Bluetooth: Add common code for stream-oriented recvmsg()
From: Gustavo F. Padovan @ 2010-09-08 19:46 UTC (permalink / raw)
To: Mat Martineau; +Cc: linux-bluetooth, marcel, gustavo, rshaffer, linux-arm-msm
In-Reply-To: <1283965529-17068-3-git-send-email-mathewm@codeaurora.org>
* Mat Martineau <mathewm@codeaurora.org> [2010-09-08 10:05:27 -0700]:
> This commit adds a bt_sock_stream_recvmsg() function for use by any
> Bluetooth code that uses SOCK_STREAM sockets. This code is copied
> from rfcomm_sock_recvmsg() with minimal modifications to remove
> RFCOMM-specific functionality and improve readability.
>
> L2CAP (with the SOCK_STREAM socket type) and RFCOMM have common needs
> when it comes to reading data. Proper stream read semantics require
> that applications can read from a stream one byte at a time and not
> lose any data. The RFCOMM code already operated on and pulled data
> from the underlying L2CAP socket, so very few changes were required to
> make the code more generic for use with non-RFCOMM data over L2CAP.
>
> Applications that need more awareness of L2CAP frame boundaries are
> still free to use SOCK_SEQPACKET sockets, and may verify that they
> connection did not fall back to basic mode by calling getsockopt().
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
> ---
> include/net/bluetooth/bluetooth.h | 2 +
> net/bluetooth/af_bluetooth.c | 109 +++++++++++++++++++++++++++++++++++++
> 2 files changed, 111 insertions(+), 0 deletions(-)
Acked-by: Gustavo F. Padovan <padovan@profusion.mobi>
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply
* Re: [PATCH 1/4] Bluetooth: Validate PSM values in calls to connect() and bind()
From: Gustavo F. Padovan @ 2010-09-08 19:45 UTC (permalink / raw)
To: Mat Martineau; +Cc: linux-bluetooth, marcel, gustavo, rshaffer, linux-arm-msm
In-Reply-To: <1283965529-17068-2-git-send-email-mathewm@codeaurora.org>
* Mat Martineau <mathewm@codeaurora.org> [2010-09-08 10:05:26 -0700]:
> Valid L2CAP PSMs are odd numbers, and the least significant bit of the
> most significant byte must be 0.
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
> ---
> net/bluetooth/l2cap.c | 25 +++++++++++++++++++++----
> 1 files changed, 21 insertions(+), 4 deletions(-)
Acked-by: Gustavo F. Padovan <padovan@profusion.mobi>
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply
* [bluetooth-next-2.6 v3 2/2] Bluetooth: Initial move of L2CAP socket to l2cap_sock.c
From: Gustavo F. Padovan @ 2010-09-08 18:25 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1283970347-23477-1-git-send-email-padovan@profusion.mobi>
This patch tries to do the minimal to move l2cap_sock_create() and its
dependencies to l2cap_sock.c. It create a API to initialize and cleanup
the L2CAP sockets from l2cap_core.c through l2cap_init_sockets() and
l2cap_cleanup_sockets().
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 12 +++
net/bluetooth/Makefile | 2 +-
net/bluetooth/l2cap_core.c | 172 ++---------------------------------
net/bluetooth/l2cap_sock.c | 201 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 222 insertions(+), 165 deletions(-)
create mode 100644 net/bluetooth/l2cap_sock.c
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 6c24144..0bc0329 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -423,6 +423,18 @@ static inline int l2cap_tx_window_full(struct sock *sk)
#define __is_sframe(ctrl) (ctrl) & L2CAP_CTRL_FRAME_TYPE
#define __is_sar_start(ctrl) ((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START
+extern int disable_ertm;
+extern const struct proto_ops l2cap_sock_ops;
+extern struct bt_sock_list l2cap_sk_list;
+
+int l2cap_init_sockets(void);
+void l2cap_cleanup_sockets(void);
+
+void __l2cap_sock_close(struct sock *sk, int reason);
+void l2cap_sock_kill(struct sock *sk);
+void l2cap_sock_init(struct sock *sk, struct sock *parent);
+struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio);
+
void l2cap_load(void);
#endif /* __L2CAP_H */
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index 94e1f57..6d1b1a3 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -12,4 +12,4 @@ obj-$(CONFIG_BT_HIDP) += hidp/
bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o
-l2cap-objs := l2cap_core.o
+l2cap-objs := l2cap_core.o l2cap_sock.o
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 44a8fb0..ec6fc96 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -57,24 +57,20 @@
#define VERSION "2.15"
-static int disable_ertm = 0;
+int disable_ertm = 0;
static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
static u8 l2cap_fixed_chan[8] = { 0x02, };
-static const struct proto_ops l2cap_sock_ops;
-
static struct workqueue_struct *_busy_wq;
-static struct bt_sock_list l2cap_sk_list = {
+struct bt_sock_list l2cap_sk_list = {
.lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
};
static void l2cap_busy_work(struct work_struct *work);
-static void __l2cap_sock_close(struct sock *sk, int reason);
static void l2cap_sock_close(struct sock *sk);
-static void l2cap_sock_kill(struct sock *sk);
static int l2cap_build_conf_req(struct sock *sk, void *data);
static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
@@ -83,31 +79,6 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
/* ---- L2CAP timers ---- */
-static void l2cap_sock_timeout(unsigned long arg)
-{
- struct sock *sk = (struct sock *) arg;
- int reason;
-
- BT_DBG("sock %p state %d", sk, sk->sk_state);
-
- bh_lock_sock(sk);
-
- if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
- reason = ECONNREFUSED;
- else if (sk->sk_state == BT_CONNECT &&
- l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
- reason = ECONNREFUSED;
- else
- reason = ETIMEDOUT;
-
- __l2cap_sock_close(sk, reason);
-
- bh_unlock_sock(sk);
-
- l2cap_sock_kill(sk);
- sock_put(sk);
-}
-
static void l2cap_sock_set_timer(struct sock *sk, long timeout)
{
BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
@@ -778,14 +749,6 @@ static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t
return s;
}
-static void l2cap_sock_destruct(struct sock *sk)
-{
- BT_DBG("sk %p", sk);
-
- skb_queue_purge(&sk->sk_receive_queue);
- skb_queue_purge(&sk->sk_write_queue);
-}
-
static void l2cap_sock_cleanup_listen(struct sock *parent)
{
struct sock *sk;
@@ -803,7 +766,7 @@ static void l2cap_sock_cleanup_listen(struct sock *parent)
/* Kill socket (only if zapped and orphan)
* Must be called on unlocked socket.
*/
-static void l2cap_sock_kill(struct sock *sk)
+void l2cap_sock_kill(struct sock *sk)
{
if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
return;
@@ -816,7 +779,7 @@ static void l2cap_sock_kill(struct sock *sk)
sock_put(sk);
}
-static void __l2cap_sock_close(struct sock *sk, int reason)
+void __l2cap_sock_close(struct sock *sk, int reason)
{
BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
@@ -880,109 +843,6 @@ static void l2cap_sock_close(struct sock *sk)
l2cap_sock_kill(sk);
}
-static void l2cap_sock_init(struct sock *sk, struct sock *parent)
-{
- struct l2cap_pinfo *pi = l2cap_pi(sk);
-
- BT_DBG("sk %p", sk);
-
- if (parent) {
- sk->sk_type = parent->sk_type;
- bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
-
- pi->imtu = l2cap_pi(parent)->imtu;
- pi->omtu = l2cap_pi(parent)->omtu;
- pi->conf_state = l2cap_pi(parent)->conf_state;
- pi->mode = l2cap_pi(parent)->mode;
- pi->fcs = l2cap_pi(parent)->fcs;
- pi->max_tx = l2cap_pi(parent)->max_tx;
- pi->tx_win = l2cap_pi(parent)->tx_win;
- pi->sec_level = l2cap_pi(parent)->sec_level;
- pi->role_switch = l2cap_pi(parent)->role_switch;
- pi->force_reliable = l2cap_pi(parent)->force_reliable;
- } else {
- pi->imtu = L2CAP_DEFAULT_MTU;
- pi->omtu = 0;
- if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
- pi->mode = L2CAP_MODE_ERTM;
- pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
- } else {
- pi->mode = L2CAP_MODE_BASIC;
- }
- pi->max_tx = L2CAP_DEFAULT_MAX_TX;
- pi->fcs = L2CAP_FCS_CRC16;
- pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
- pi->sec_level = BT_SECURITY_LOW;
- pi->role_switch = 0;
- pi->force_reliable = 0;
- }
-
- /* Default config options */
- pi->conf_len = 0;
- pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
- skb_queue_head_init(TX_QUEUE(sk));
- skb_queue_head_init(SREJ_QUEUE(sk));
- skb_queue_head_init(BUSY_QUEUE(sk));
- INIT_LIST_HEAD(SREJ_LIST(sk));
-}
-
-static struct proto l2cap_proto = {
- .name = "L2CAP",
- .owner = THIS_MODULE,
- .obj_size = sizeof(struct l2cap_pinfo)
-};
-
-static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
-{
- struct sock *sk;
-
- sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
- if (!sk)
- return NULL;
-
- sock_init_data(sock, sk);
- INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
-
- sk->sk_destruct = l2cap_sock_destruct;
- sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
-
- sock_reset_flag(sk, SOCK_ZAPPED);
-
- sk->sk_protocol = proto;
- sk->sk_state = BT_OPEN;
-
- setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
-
- bt_sock_link(&l2cap_sk_list, sk);
- return sk;
-}
-
-static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
- int kern)
-{
- struct sock *sk;
-
- BT_DBG("sock %p", sock);
-
- sock->state = SS_UNCONNECTED;
-
- if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
- sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
- return -ESOCKTNOSUPPORT;
-
- if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
- return -EPERM;
-
- sock->ops = &l2cap_sock_ops;
-
- sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
- if (!sk)
- return -ENOMEM;
-
- l2cap_sock_init(sk, NULL);
- return 0;
-}
-
static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
{
struct sock *sk = sock->sk;
@@ -4752,7 +4612,7 @@ static const struct file_operations l2cap_debugfs_fops = {
static struct dentry *l2cap_debugfs;
-static const struct proto_ops l2cap_sock_ops = {
+const struct proto_ops l2cap_sock_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = l2cap_sock_release,
@@ -4772,12 +4632,6 @@ static const struct proto_ops l2cap_sock_ops = {
.getsockopt = l2cap_sock_getsockopt
};
-static const struct net_proto_family l2cap_sock_family_ops = {
- .family = PF_BLUETOOTH,
- .owner = THIS_MODULE,
- .create = l2cap_sock_create,
-};
-
static struct hci_proto l2cap_hci_proto = {
.name = "L2CAP",
.id = HCI_PROTO_L2CAP,
@@ -4793,7 +4647,7 @@ static int __init l2cap_init(void)
{
int err;
- err = proto_register(&l2cap_proto, 0);
+ err = l2cap_init_sockets();
if (err < 0)
return err;
@@ -4801,16 +4655,9 @@ static int __init l2cap_init(void)
if (!_busy_wq)
goto error;
- err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
- if (err < 0) {
- BT_ERR("L2CAP socket registration failed");
- goto error;
- }
-
err = hci_register_proto(&l2cap_hci_proto);
if (err < 0) {
BT_ERR("L2CAP protocol registration failed");
- bt_sock_unregister(BTPROTO_L2CAP);
goto error;
}
@@ -4827,7 +4674,7 @@ static int __init l2cap_init(void)
return 0;
error:
- proto_unregister(&l2cap_proto);
+ l2cap_cleanup_sockets();
return err;
}
@@ -4838,13 +4685,10 @@ static void __exit l2cap_exit(void)
flush_workqueue(_busy_wq);
destroy_workqueue(_busy_wq);
- if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
- BT_ERR("L2CAP socket unregistration failed");
-
if (hci_unregister_proto(&l2cap_hci_proto) < 0)
BT_ERR("L2CAP protocol unregistration failed");
- proto_unregister(&l2cap_proto);
+ l2cap_cleanup_sockets();
}
void l2cap_load(void)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
new file mode 100644
index 0000000..463fb11
--- /dev/null
+++ b/net/bluetooth/l2cap_sock.c
@@ -0,0 +1,201 @@
+/*
+ BlueZ - Bluetooth protocol stack for Linux
+ Copyright (C) 2000-2001 Qualcomm Incorporated
+ Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
+
+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 2 as
+ published by the Free Software Foundation;
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
+ SOFTWARE IS DISCLAIMED.
+*/
+
+/* Bluetooth L2CAP sockets. */
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/l2cap.h>
+
+static void l2cap_sock_timeout(unsigned long arg)
+{
+ struct sock *sk = (struct sock *) arg;
+ int reason;
+
+ BT_DBG("sock %p state %d", sk, sk->sk_state);
+
+ bh_lock_sock(sk);
+
+ if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
+ reason = ECONNREFUSED;
+ else if (sk->sk_state == BT_CONNECT &&
+ l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
+ reason = ECONNREFUSED;
+ else
+ reason = ETIMEDOUT;
+
+ __l2cap_sock_close(sk, reason);
+
+ bh_unlock_sock(sk);
+
+ l2cap_sock_kill(sk);
+ sock_put(sk);
+}
+
+static void l2cap_sock_destruct(struct sock *sk)
+{
+ BT_DBG("sk %p", sk);
+
+ skb_queue_purge(&sk->sk_receive_queue);
+ skb_queue_purge(&sk->sk_write_queue);
+}
+
+void l2cap_sock_init(struct sock *sk, struct sock *parent)
+{
+ struct l2cap_pinfo *pi = l2cap_pi(sk);
+
+ BT_DBG("sk %p", sk);
+
+ if (parent) {
+ sk->sk_type = parent->sk_type;
+ bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
+
+ pi->imtu = l2cap_pi(parent)->imtu;
+ pi->omtu = l2cap_pi(parent)->omtu;
+ pi->conf_state = l2cap_pi(parent)->conf_state;
+ pi->mode = l2cap_pi(parent)->mode;
+ pi->fcs = l2cap_pi(parent)->fcs;
+ pi->max_tx = l2cap_pi(parent)->max_tx;
+ pi->tx_win = l2cap_pi(parent)->tx_win;
+ pi->sec_level = l2cap_pi(parent)->sec_level;
+ pi->role_switch = l2cap_pi(parent)->role_switch;
+ pi->force_reliable = l2cap_pi(parent)->force_reliable;
+ } else {
+ pi->imtu = L2CAP_DEFAULT_MTU;
+ pi->omtu = 0;
+ if (!disable_ertm && sk->sk_type == SOCK_STREAM) {
+ pi->mode = L2CAP_MODE_ERTM;
+ pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
+ } else {
+ pi->mode = L2CAP_MODE_BASIC;
+ }
+ pi->max_tx = L2CAP_DEFAULT_MAX_TX;
+ pi->fcs = L2CAP_FCS_CRC16;
+ pi->tx_win = L2CAP_DEFAULT_TX_WINDOW;
+ pi->sec_level = BT_SECURITY_LOW;
+ pi->role_switch = 0;
+ pi->force_reliable = 0;
+ }
+
+ /* Default config options */
+ pi->conf_len = 0;
+ pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
+ skb_queue_head_init(TX_QUEUE(sk));
+ skb_queue_head_init(SREJ_QUEUE(sk));
+ skb_queue_head_init(BUSY_QUEUE(sk));
+ INIT_LIST_HEAD(SREJ_LIST(sk));
+}
+
+static struct proto l2cap_proto = {
+ .name = "L2CAP",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct l2cap_pinfo)
+};
+
+struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
+{
+ struct sock *sk;
+
+ sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
+ if (!sk)
+ return NULL;
+
+ sock_init_data(sock, sk);
+ INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
+
+ sk->sk_destruct = l2cap_sock_destruct;
+ sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
+
+ sock_reset_flag(sk, SOCK_ZAPPED);
+
+ sk->sk_protocol = proto;
+ sk->sk_state = BT_OPEN;
+
+ setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
+
+ bt_sock_link(&l2cap_sk_list, sk);
+ return sk;
+}
+
+static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
+ int kern)
+{
+ struct sock *sk;
+
+ BT_DBG("sock %p", sock);
+
+ sock->state = SS_UNCONNECTED;
+
+ if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM &&
+ sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
+ return -ESOCKTNOSUPPORT;
+
+ if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
+ return -EPERM;
+
+ sock->ops = &l2cap_sock_ops;
+
+ sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
+ if (!sk)
+ return -ENOMEM;
+
+ l2cap_sock_init(sk, NULL);
+ return 0;
+}
+
+static const struct net_proto_family l2cap_sock_family_ops = {
+ .family = PF_BLUETOOTH,
+ .owner = THIS_MODULE,
+ .create = l2cap_sock_create,
+};
+
+int __init l2cap_init_sockets(void)
+{
+ int err;
+
+ err = proto_register(&l2cap_proto, 0);
+ if (err < 0)
+ return err;
+
+ err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops);
+ if (err < 0)
+ goto error;
+
+ BT_INFO("L2CAP socket layer initialized");
+
+ return 0;
+
+error:
+ BT_ERR("L2CAP socket registration failed");
+ proto_unregister(&l2cap_proto);
+ return err;
+}
+
+void l2cap_cleanup_sockets(void)
+{
+ if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
+ BT_ERR("L2CAP socket unregistration failed");
+
+ proto_unregister(&l2cap_proto);
+}
--
1.7.2.2
^ permalink raw reply related
* [PATCH v3] Bluetooth: Add socket option definitions for AMP
From: Mat Martineau @ 2010-09-08 17:16 UTC (permalink / raw)
To: linux-bluetooth
Cc: marcel, gustavo, rshaffer, haijun.liu, linux-arm-msm,
Mat Martineau
This adds a new BT_AMP socket option to control the use of AMP channels.
It is for use with the SOL_BLUETOOTH option level on L2CAP sockets.
Available option values are defined as:
BT_AMP_REQUIRE_BR_EDR
* Default
* AMP controllers cannot be used
* Channel move requests from the remote device are denied
* If the L2CAP channel is currently using AMP, move the channel to
BR/EDR
BT_AMP_PREFER_AMP
* Allow use of AMP controllers
* If the L2CAP channel is currently on BR/EDR and AMP controller
resources are available, initiate a channel move to AMP
* Channel move requests from the remote device are allowed
* If the L2CAP socket has not been connected yet, try to create
and configure the channel directly on an AMP controller rather
than BR/EDR
BT_AMP_PREFER_BR_EDR
* Allow use of AMP controllers
* If the L2CAP channel is currently on AMP, move it to BR/EDR
* Channel move requests from the remote device are allowed
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
include/net/bluetooth/bluetooth.h | 28 ++++++++++++++++++++++++++++
1 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 27a902d..d2c62dc 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -64,6 +64,34 @@ struct bt_security {
#define BT_DEFER_SETUP 7
+
+#define BT_AMP_POLICY 8
+
+/* Require BR/EDR (default policy)
+ * AMP controllers cannot be used
+ * Channel move requests from the remote device are denied
+ * If the L2CAP channel is currently using AMP, move the channel to BR/EDR
+ */
+#define BT_AMP_POLICY_REQUIRE_BR_EDR 0
+
+/* Prefer AMP
+ * Allow use of AMP controllers
+ * If the L2CAP channel is currently on BR/EDR and AMP controller
+ * resources are available, initiate a channel move to AMP
+ * Channel move requests from the remote device are allowed
+ * If the L2CAP socket has not been connected yet, try to create
+ * and configure the channel directly on an AMP controller rather
+ * than BR/EDR
+ */
+#define BT_AMP_POLICY_PREFER_AMP 1
+
+/* Prefer BR/EDR
+ * Allow use of AMP controllers
+ * If the L2CAP channel is currently on AMP, move it to BR/EDR
+ * Channel move requests from the remote device are allowed
+ */
+#define BT_AMP_POLICY_PREFER_BR_EDR 2
+
#define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg)
#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
#define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg)
--
1.7.1
^ permalink raw reply related
* [PATCH 4/4] Bluetooth: Use a stream-oriented recvmsg with SOCK_STREAM L2CAP sockets.
From: Mat Martineau @ 2010-09-08 17:05 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1283965529-17068-1-git-send-email-mathewm@codeaurora.org>
L2CAP ERTM sockets can be opened with the SOCK_STREAM socket type,
which is a mandatory request for ERTM mode.
However, these sockets still have SOCK_SEQPACKET read semantics when
bt_sock_recvmsg() is used to pull data from the receive queue. If the
application is only reading part of a frame, then the unread portion
of the frame is discarded. If the application requests more bytes
than are in the current frame, only the current frame's data is
returned.
This patch utilizes common code derived from RFCOMM's recvmsg()
function to make L2CAP SOCK_STREAM reads behave like RFCOMM reads (and
other SOCK_STREAM sockets in general). The application may read one
byte at a time from the input stream and not lose any data, and may
also read across L2CAP frame boundaries.
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
net/bluetooth/l2cap.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index b5eff42..38aa78c 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1961,6 +1961,9 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms
release_sock(sk);
+ if (sock->type == SOCK_STREAM)
+ return bt_sock_stream_recvmsg(iocb, sock, msg, len, flags);
+
return bt_sock_recvmsg(iocb, sock, msg, len, flags);
}
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
* [PATCH 3/4] Bluetooth: Use common SOCK_STREAM receive code in RFCOMM
From: Mat Martineau @ 2010-09-08 17:05 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1283965529-17068-1-git-send-email-mathewm@codeaurora.org>
To reduce code duplication, have rfcomm_sock_recvmsg() call
bt_sock_stream_recvmsg(). The common bt_sock_stream_recvmsg()
code is nearly identical, with the RFCOMM-specific functionality
for deferred setup and connection unthrottling left in
rfcomm_sock_recvmsg().
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
net/bluetooth/rfcomm/sock.c | 104 +++----------------------------------------
1 files changed, 6 insertions(+), 98 deletions(-)
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 44a6232..4396f47 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -617,121 +617,29 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
return sent;
}
-static long rfcomm_sock_data_wait(struct sock *sk, long timeo)
-{
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue(sk_sleep(sk), &wait);
- for (;;) {
- set_current_state(TASK_INTERRUPTIBLE);
-
- if (!skb_queue_empty(&sk->sk_receive_queue) ||
- sk->sk_err ||
- (sk->sk_shutdown & RCV_SHUTDOWN) ||
- signal_pending(current) ||
- !timeo)
- break;
-
- set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
- release_sock(sk);
- timeo = schedule_timeout(timeo);
- lock_sock(sk);
- clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
- }
-
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(sk_sleep(sk), &wait);
- return timeo;
-}
-
static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size, int flags)
{
struct sock *sk = sock->sk;
struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
- int err = 0;
- size_t target, copied = 0;
- long timeo;
+ int len;
if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
rfcomm_dlc_accept(d);
return 0;
}
- if (flags & MSG_OOB)
- return -EOPNOTSUPP;
-
- msg->msg_namelen = 0;
-
- BT_DBG("sk %p size %zu", sk, size);
+ len = bt_sock_stream_recvmsg(iocb, sock, msg, size, flags);
lock_sock(sk);
+ if (!(flags & MSG_PEEK) && len > 0)
+ atomic_sub(len, &sk->sk_rmem_alloc);
- target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
- timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
-
- do {
- struct sk_buff *skb;
- int chunk;
-
- skb = skb_dequeue(&sk->sk_receive_queue);
- if (!skb) {
- if (copied >= target)
- break;
-
- if ((err = sock_error(sk)) != 0)
- break;
- if (sk->sk_shutdown & RCV_SHUTDOWN)
- break;
-
- err = -EAGAIN;
- if (!timeo)
- break;
-
- timeo = rfcomm_sock_data_wait(sk, timeo);
-
- if (signal_pending(current)) {
- err = sock_intr_errno(timeo);
- goto out;
- }
- continue;
- }
-
- chunk = min_t(unsigned int, skb->len, size);
- if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
- skb_queue_head(&sk->sk_receive_queue, skb);
- if (!copied)
- copied = -EFAULT;
- break;
- }
- copied += chunk;
- size -= chunk;
-
- sock_recv_ts_and_drops(msg, sk, skb);
-
- if (!(flags & MSG_PEEK)) {
- atomic_sub(chunk, &sk->sk_rmem_alloc);
-
- skb_pull(skb, chunk);
- if (skb->len) {
- skb_queue_head(&sk->sk_receive_queue, skb);
- break;
- }
- kfree_skb(skb);
-
- } else {
- /* put message back and return */
- skb_queue_head(&sk->sk_receive_queue, skb);
- break;
- }
- } while (size);
-
-out:
if (atomic_read(&sk->sk_rmem_alloc) <= (sk->sk_rcvbuf >> 2))
rfcomm_dlc_unthrottle(rfcomm_pi(sk)->dlc);
-
release_sock(sk);
- return copied ? : err;
+
+ return len;
}
static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
* [PATCH 2/4] Bluetooth: Add common code for stream-oriented recvmsg()
From: Mat Martineau @ 2010-09-08 17:05 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1283965529-17068-1-git-send-email-mathewm@codeaurora.org>
This commit adds a bt_sock_stream_recvmsg() function for use by any
Bluetooth code that uses SOCK_STREAM sockets. This code is copied
from rfcomm_sock_recvmsg() with minimal modifications to remove
RFCOMM-specific functionality and improve readability.
L2CAP (with the SOCK_STREAM socket type) and RFCOMM have common needs
when it comes to reading data. Proper stream read semantics require
that applications can read from a stream one byte at a time and not
lose any data. The RFCOMM code already operated on and pulled data
from the underlying L2CAP socket, so very few changes were required to
make the code more generic for use with non-RFCOMM data over L2CAP.
Applications that need more awareness of L2CAP frame boundaries are
still free to use SOCK_SEQPACKET sockets, and may verify that they
connection did not fall back to basic mode by calling getsockopt().
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
include/net/bluetooth/bluetooth.h | 2 +
net/bluetooth/af_bluetooth.c | 109 +++++++++++++++++++++++++++++++++++++
2 files changed, 111 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 27a902d..08b6c2a 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -126,6 +126,8 @@ int bt_sock_unregister(int proto);
void bt_sock_link(struct bt_sock_list *l, struct sock *s);
void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags);
+int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+ struct msghdr *msg, size_t len, int flags);
uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 421c45b..77a26fe 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -265,6 +265,115 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
}
EXPORT_SYMBOL(bt_sock_recvmsg);
+static long bt_sock_data_wait(struct sock *sk, long timeo)
+{
+ DECLARE_WAITQUEUE(wait, current);
+
+ add_wait_queue(sk_sleep(sk), &wait);
+ for (;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ if (!skb_queue_empty(&sk->sk_receive_queue))
+ break;
+
+ if (sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN))
+ break;
+
+ if (signal_pending(current) || !timeo)
+ break;
+
+ set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+ release_sock(sk);
+ timeo = schedule_timeout(timeo);
+ lock_sock(sk);
+ clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+ }
+
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(sk_sleep(sk), &wait);
+ return timeo;
+}
+
+int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+ struct msghdr *msg, size_t size, int flags)
+{
+ struct sock *sk = sock->sk;
+ int err = 0;
+ size_t target, copied = 0;
+ long timeo;
+
+ if (flags & MSG_OOB)
+ return -EOPNOTSUPP;
+
+ msg->msg_namelen = 0;
+
+ BT_DBG("sk %p size %zu", sk, size);
+
+ lock_sock(sk);
+
+ target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
+ timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
+
+ do {
+ struct sk_buff *skb;
+ int chunk;
+
+ skb = skb_dequeue(&sk->sk_receive_queue);
+ if (!skb) {
+ if (copied >= target)
+ break;
+
+ if ((err = sock_error(sk)) != 0)
+ break;
+ if (sk->sk_shutdown & RCV_SHUTDOWN)
+ break;
+
+ err = -EAGAIN;
+ if (!timeo)
+ break;
+
+ timeo = bt_sock_data_wait(sk, timeo);
+
+ if (signal_pending(current)) {
+ err = sock_intr_errno(timeo);
+ goto out;
+ }
+ continue;
+ }
+
+ chunk = min_t(unsigned int, skb->len, size);
+ if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ if (!copied)
+ copied = -EFAULT;
+ break;
+ }
+ copied += chunk;
+ size -= chunk;
+
+ sock_recv_ts_and_drops(msg, sk, skb);
+
+ if (!(flags & MSG_PEEK)) {
+ skb_pull(skb, chunk);
+ if (skb->len) {
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ break;
+ }
+ kfree_skb(skb);
+
+ } else {
+ /* put message back and return */
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ break;
+ }
+ } while (size);
+
+out:
+ release_sock(sk);
+ return copied ? : err;
+}
+EXPORT_SYMBOL(bt_sock_stream_recvmsg);
+
static inline unsigned int bt_accept_poll(struct sock *parent)
{
struct list_head *p, *n;
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
* [PATCH 1/4] Bluetooth: Validate PSM values in calls to connect() and bind()
From: Mat Martineau @ 2010-09-08 17:05 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1283965529-17068-1-git-send-email-mathewm@codeaurora.org>
Valid L2CAP PSMs are odd numbers, and the least significant bit of the
most significant byte must be 0.
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
net/bluetooth/l2cap.c | 25 +++++++++++++++++++++----
1 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index c784703..b5eff42 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1008,10 +1008,20 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
goto done;
}
- if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
- !capable(CAP_NET_BIND_SERVICE)) {
- err = -EACCES;
- goto done;
+ if (la.l2_psm) {
+ __u16 psm = __le16_to_cpu(la.l2_psm);
+
+ /* PSM must be odd and lsb of upper byte must be 0 */
+ if ((psm & 0x0101) != 0x0001) {
+ err = -EINVAL;
+ goto done;
+ }
+
+ /* Restrict usage of well-known PSMs */
+ if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) {
+ err = -EACCES;
+ goto done;
+ }
}
write_lock_bh(&l2cap_sk_list.lock);
@@ -1190,6 +1200,13 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
goto done;
}
+ /* PSM must be odd and lsb of upper byte must be 0 */
+ if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 &&
+ sk->sk_type != SOCK_RAW) {
+ err = -EINVAL;
+ goto done;
+ }
+
/* Set destination address and psm */
bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
l2cap_pi(sk)->psm = la.l2_psm;
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
* [PATCH 0/4 v6] L2CAP updates for valid PSMs, SOCK_STREAM reads
From: Mat Martineau @ 2010-09-08 17:05 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm
This patch set is the same as 'v5', with a fix to PSM validation.
[PATCH 1/4] Bluetooth: Validate PSM values in calls to connect() and bind()
Modified to bypass PSM validation for SOCK_RAW (bonding) sockets.
[PATCH 2/4] Bluetooth: Add common code for stream-oriented recvmsg()
[PATCH 3/4] Bluetooth: Use common SOCK_STREAM receive code in RFCOMM
[PATCH 4/4] Bluetooth: Use a stream-oriented recvmsg with SOCK_STREAM L2CAP sockets.
These patches change the read behavior of SOCK_STREAM L2CAP sockets to
allow reading of partial SDUs. Same as the 'v5' patches.
^ permalink raw reply
* Re: [PATCH v2] Bluetooth: Add socket option definitions for AMP
From: Gustavo F. Padovan @ 2010-09-08 16:58 UTC (permalink / raw)
To: Mat Martineau
Cc: linux-bluetooth, marcel, rshaffer, haijun.liu, linux-arm-msm
In-Reply-To: <1283964374-16885-1-git-send-email-mathewm@codeaurora.org>
Hi Mat,
* Mat Martineau <mathewm@codeaurora.org> [2010-09-08 09:46:14 -0700]:
> This adds a new BT_AMP socket option to control the use of AMP channels.
> It is for use with the SOL_BLUETOOTH option level on L2CAP sockets.
>
> Available option values are defined as:
>
> BT_AMP_REQUIRE_BR_EDR
> * Default
> * AMP controllers cannot be used
> * Channel move requests from the remote device are denied
> * If the L2CAP channel is currently using AMP, move the channel to
> BR/EDR
>
> BT_AMP_PREFER_AMP
> * Allow use of AMP controllers
> * If the L2CAP channel is currently on BR/EDR and AMP controller
> resources are available, initiate a channel move to AMP
> * Channel move requests from the remote device are allowed
> * If the L2CAP socket has not been connected yet, try to create
> and configure the channel directly on an AMP controller rather
> than BR/EDR
>
> BT_AMP_PREFER_BR_EDR
> * Allow use of AMP controllers
> * If the L2CAP channel is currently on AMP, move it to BR/EDR
> * Channel move requests from the remote device are allowed
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
> ---
> include/net/bluetooth/bluetooth.h | 25 +++++++++++++++++++++++++
> 1 files changed, 25 insertions(+), 0 deletions(-)
>
> diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
> index 27a902d..5e8b6c3 100644
> --- a/include/net/bluetooth/bluetooth.h
> +++ b/include/net/bluetooth/bluetooth.h
> @@ -64,6 +64,31 @@ struct bt_security {
>
> #define BT_DEFER_SETUP 7
>
> +
> +#define BT_AMP_POLICY 8
Please add a empty line here.
> +/* Require BR/EDR (default policy)
> + * AMP controllers cannot be used
> + * Channel move requests from the remote device are denied
> + * If the L2CAP channel is currently using AMP, move the channel to BR/EDR
> + */
> +#define BT_AMP_POLICY_REQUIRE_BR_EDR 0
And here.
> +/* Prefer AMP
> + * Allow use of AMP controllers
> + * If the L2CAP channel is currently on BR/EDR and AMP controller
> + * resources are available, initiate a channel move to AMP
> + * Channel move requests from the remote device are allowed
> + * If the L2CAP socket has not been connected yet, try to create
> + * and configure the channel directly on an AMP controller rather
> + * than BR/EDR
> + */
> +#define BT_AMP_POLICY_PREFER_AMP 1
And here.
> +/* Prefer BR/EDR
> + * Allow use of AMP controllers
> + * If the L2CAP channel is currently on AMP, move it to BR/EDR
> + * Channel move requests from the remote device are allowed
> + */
> +#define BT_AMP_POLICY_PREFER_BR_EDR 2
> +
> #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg)
> #define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
> #define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg)
> --
> 1.7.1
>
> --
> 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
roFUSION embedded systems - http://profusion.mobi
^ permalink raw reply
* Re: [PATCH] Fix closing stream of locked sep when reconfiguring
From: Johan Hedberg @ 2010-09-08 16:48 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1283958823-4811-1-git-send-email-luiz.dentz@gmail.com>
Hi Luiz,
On Wed, Sep 08, 2010, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
>
> Stream should only be closed if sep is unlocked otherwise there is a
> possibility that sep reconfiguration is triggered although the sep is in
> use by the user application.
> ---
> audio/a2dp.c | 2 ++
> 1 files changed, 2 insertions(+), 0 deletions(-)
>
> diff --git a/audio/a2dp.c b/audio/a2dp.c
> index b062aed..ef0df17 100644
> --- a/audio/a2dp.c
> +++ b/audio/a2dp.c
> @@ -1393,6 +1393,8 @@ unsigned int a2dp_config(struct avdtp *session, struct a2dp_sep *sep,
> }
>
> if (l != NULL) {
> + if (a2dp_sep_get_lock(tmp))
> + goto failed;
> setup->reconfigure = TRUE;
> if (avdtp_close(session, tmp->stream, FALSE) < 0) {
> error("avdtp_close failed");
Thanks for the patch! It's now in the upstream tree.
Johan
^ 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