diff options
author | Andrei Emeltchenko <andrei.emeltchenko@intel.com> | 2012-09-27 17:26:21 +0300 |
---|---|---|
committer | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2012-09-27 17:31:52 -0300 |
commit | 2766be48a7181d7f2a84831ca7e7be248fb6fdb5 (patch) | |
tree | 9d5554696f17b42a2724b652928450f745cb00a8 /net/bluetooth/a2mp.c | |
parent | 93c284ee901f7d7bdd09087e92abefb7496c3777 (diff) |
Bluetooth: A2MP: Add fallback to normal l2cap init sequence
When there is no remote AMP controller found fallback to normal
L2CAP sequence.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Diffstat (limited to 'net/bluetooth/a2mp.c')
-rw-r--r-- | net/bluetooth/a2mp.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 773e8fc4167..28d1246958b 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -180,6 +180,7 @@ static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb, u16 len = le16_to_cpu(hdr->len); struct a2mp_cl *cl; u16 ext_feat; + bool found = false; if (len < sizeof(*rsp)) return -EINVAL; @@ -210,6 +211,7 @@ static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb, if (cl->id != HCI_BREDR_ID && cl->type == HCI_AMP) { struct a2mp_info_req req; + found = true; req.id = cl->id; a2mp_send(mgr, A2MP_GETINFO_REQ, __next_ident(mgr), sizeof(req), &req); @@ -219,6 +221,32 @@ static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb, cl = (void *) skb_pull(skb, sizeof(*cl)); } + /* Fall back to L2CAP init sequence */ + if (!found) { + struct l2cap_conn *conn = mgr->l2cap_conn; + struct l2cap_chan *chan; + + mutex_lock(&conn->chan_lock); + + list_for_each_entry(chan, &conn->chan_l, list) { + + BT_DBG("chan %p state %s", chan, + state_to_string(chan->state)); + + if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) + continue; + + l2cap_chan_lock(chan); + + if (chan->state == BT_CONNECT) + l2cap_send_conn_req(chan); + + l2cap_chan_unlock(chan); + } + + mutex_unlock(&conn->chan_lock); + } + return 0; } |