Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 203855
b: refs/heads/master
c: cf6c2c0
h: refs/heads/master
i:
  203853: abf8a46
  203851: 9554671
  203847: 7aef3d4
  203839: 43b93b5
v: v3
  • Loading branch information
Gustavo F. Padovan authored and Marcel Holtmann committed Jul 21, 2010
1 parent 35d3b5d commit db48468
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2ba13ed678775195e8255b4e503c59d48b615bd8
refs/heads/master: cf6c2c0b9f47ee3cd12684b905725c8376d52135
5 changes: 5 additions & 0 deletions trunk/include/net/bluetooth/l2cap.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,11 @@ struct l2cap_conn {
struct l2cap_chan_list chan_list;
};

struct sock_del_list {
struct sock *sk;
struct list_head list;
};

#define L2CAP_INFO_CL_MTU_REQ_SENT 0x01
#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04
#define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08
Expand Down
56 changes: 40 additions & 16 deletions trunk/net/bluetooth/l2cap.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,22 @@ static void l2cap_do_start(struct sock *sk)
}
}

static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
{
u32 local_feat_mask = l2cap_feat_mask;
if (enable_ertm)
local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;

switch (mode) {
case L2CAP_MODE_ERTM:
return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
case L2CAP_MODE_STREAMING:
return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
default:
return 0x00;
}
}

static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err)
{
struct l2cap_disconn_req req;
Expand Down Expand Up @@ -484,10 +500,13 @@ static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int
static void l2cap_conn_start(struct l2cap_conn *conn)
{
struct l2cap_chan_list *l = &conn->chan_list;
struct sock_del_list del, *tmp1, *tmp2;
struct sock *sk;

BT_DBG("conn %p", conn);

INIT_LIST_HEAD(&del.list);

read_lock(&l->lock);

for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
Expand All @@ -503,6 +522,19 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
if (l2cap_check_security(sk) &&
__l2cap_no_conn_pending(sk)) {
struct l2cap_conn_req req;

if (!l2cap_mode_supported(l2cap_pi(sk)->mode,
conn->feat_mask)
&& l2cap_pi(sk)->conf_state &
L2CAP_CONF_STATE2_DEVICE) {
tmp1 = kzalloc(sizeof(struct srej_list),
GFP_ATOMIC);
tmp1->sk = sk;
list_add_tail(&tmp1->list, &del.list);
bh_unlock_sock(sk);
continue;
}

req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
req.psm = l2cap_pi(sk)->psm;

Expand Down Expand Up @@ -542,6 +574,14 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
}

read_unlock(&l->lock);

list_for_each_entry_safe(tmp1, tmp2, &del.list, list) {
bh_lock_sock(tmp1->sk);
__l2cap_sock_close(tmp1->sk, ECONNRESET);
bh_unlock_sock(tmp1->sk);
list_del(&tmp1->list);
kfree(tmp1);
}
}

static void l2cap_conn_ready(struct l2cap_conn *conn)
Expand Down Expand Up @@ -2429,22 +2469,6 @@ static inline void l2cap_ertm_init(struct sock *sk)
INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work);
}

static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
{
u32 local_feat_mask = l2cap_feat_mask;
if (enable_ertm)
local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;

switch (mode) {
case L2CAP_MODE_ERTM:
return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
case L2CAP_MODE_STREAMING:
return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
default:
return 0x00;
}
}

static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
{
switch (mode) {
Expand Down

0 comments on commit db48468

Please sign in to comment.