aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAndrei Emeltchenko <andrei.emeltchenko@intel.com>2012-09-27 10:26:21 -0400
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>2012-09-27 16:31:52 -0400
commit2766be48a7181d7f2a84831ca7e7be248fb6fdb5 (patch)
tree9d5554696f17b42a2724b652928450f745cb00a8 /net
parent93c284ee901f7d7bdd09087e92abefb7496c3777 (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')
-rw-r--r--net/bluetooth/a2mp.c28
-rw-r--r--net/bluetooth/l2cap_core.c2
2 files changed, 29 insertions, 1 deletions
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index 773e8fc41670..28d1246958be 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,
180 u16 len = le16_to_cpu(hdr->len); 180 u16 len = le16_to_cpu(hdr->len);
181 struct a2mp_cl *cl; 181 struct a2mp_cl *cl;
182 u16 ext_feat; 182 u16 ext_feat;
183 bool found = false;
183 184
184 if (len < sizeof(*rsp)) 185 if (len < sizeof(*rsp))
185 return -EINVAL; 186 return -EINVAL;
@@ -210,6 +211,7 @@ static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
210 if (cl->id != HCI_BREDR_ID && cl->type == HCI_AMP) { 211 if (cl->id != HCI_BREDR_ID && cl->type == HCI_AMP) {
211 struct a2mp_info_req req; 212 struct a2mp_info_req req;
212 213
214 found = true;
213 req.id = cl->id; 215 req.id = cl->id;
214 a2mp_send(mgr, A2MP_GETINFO_REQ, __next_ident(mgr), 216 a2mp_send(mgr, A2MP_GETINFO_REQ, __next_ident(mgr),
215 sizeof(req), &req); 217 sizeof(req), &req);
@@ -219,6 +221,32 @@ static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
219 cl = (void *) skb_pull(skb, sizeof(*cl)); 221 cl = (void *) skb_pull(skb, sizeof(*cl));
220 } 222 }
221 223
224 /* Fall back to L2CAP init sequence */
225 if (!found) {
226 struct l2cap_conn *conn = mgr->l2cap_conn;
227 struct l2cap_chan *chan;
228
229 mutex_lock(&conn->chan_lock);
230
231 list_for_each_entry(chan, &conn->chan_l, list) {
232
233 BT_DBG("chan %p state %s", chan,
234 state_to_string(chan->state));
235
236 if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP)
237 continue;
238
239 l2cap_chan_lock(chan);
240
241 if (chan->state == BT_CONNECT)
242 l2cap_send_conn_req(chan);
243
244 l2cap_chan_unlock(chan);
245 }
246
247 mutex_unlock(&conn->chan_lock);
248 }
249
222 return 0; 250 return 0;
223} 251}
224 252
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 781a085ae5bc..a347522b2144 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -958,7 +958,7 @@ static bool __amp_capable(struct l2cap_chan *chan)
958 return false; 958 return false;
959} 959}
960 960
961static void l2cap_send_conn_req(struct l2cap_chan *chan) 961void l2cap_send_conn_req(struct l2cap_chan *chan)
962{ 962{
963 struct l2cap_conn *conn = chan->conn; 963 struct l2cap_conn *conn = chan->conn;
964 struct l2cap_conn_req req; 964 struct l2cap_conn_req req;