aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/l2cap.c166
1 files changed, 118 insertions, 48 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 6e180d255505..2e3abdfbd69d 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -55,7 +55,7 @@
55#define BT_DBG(D...) 55#define BT_DBG(D...)
56#endif 56#endif
57 57
58#define VERSION "2.9" 58#define VERSION "2.10"
59 59
60static u32 l2cap_feat_mask = 0x0000; 60static u32 l2cap_feat_mask = 0x0000;
61 61
@@ -253,6 +253,21 @@ static void l2cap_chan_del(struct sock *sk, int err)
253 sk->sk_state_change(sk); 253 sk->sk_state_change(sk);
254} 254}
255 255
256/* Service level security */
257static inline int l2cap_check_link_mode(struct sock *sk)
258{
259 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
260
261 if ((l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) ||
262 (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE))
263 return hci_conn_encrypt(conn->hcon);
264
265 if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH)
266 return hci_conn_auth(conn->hcon);
267
268 return 1;
269}
270
256static inline u8 l2cap_get_ident(struct l2cap_conn *conn) 271static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
257{ 272{
258 u8 id; 273 u8 id;
@@ -287,6 +302,34 @@ static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16
287 return hci_send_acl(conn->hcon, skb, 0); 302 return hci_send_acl(conn->hcon, skb, 0);
288} 303}
289 304
305static void l2cap_do_start(struct sock *sk)
306{
307 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
308
309 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
310 struct l2cap_conn_req req;
311 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
312 req.psm = l2cap_pi(sk)->psm;
313
314 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
315
316 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
317 L2CAP_CONN_REQ, sizeof(req), &req);
318 } else {
319 struct l2cap_info_req req;
320 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
321
322 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
323 conn->info_ident = l2cap_get_ident(conn);
324
325 mod_timer(&conn->info_timer, jiffies +
326 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
327
328 l2cap_send_cmd(conn, conn->info_ident,
329 L2CAP_INFO_REQ, sizeof(req), &req);
330 }
331}
332
290/* ---- L2CAP connections ---- */ 333/* ---- L2CAP connections ---- */
291static void l2cap_conn_start(struct l2cap_conn *conn) 334static void l2cap_conn_start(struct l2cap_conn *conn)
292{ 335{
@@ -301,16 +344,35 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
301 bh_lock_sock(sk); 344 bh_lock_sock(sk);
302 345
303 if (sk->sk_type != SOCK_SEQPACKET) { 346 if (sk->sk_type != SOCK_SEQPACKET) {
304 l2cap_sock_clear_timer(sk); 347 bh_unlock_sock(sk);
305 sk->sk_state = BT_CONNECTED; 348 continue;
306 sk->sk_state_change(sk); 349 }
307 } else if (sk->sk_state == BT_CONNECT) { 350
351 if (sk->sk_state == BT_CONNECT) {
308 struct l2cap_conn_req req; 352 struct l2cap_conn_req req;
309 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
310 req.scid = cpu_to_le16(l2cap_pi(sk)->scid); 353 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
311 req.psm = l2cap_pi(sk)->psm; 354 req.psm = l2cap_pi(sk)->psm;
355
356 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
357
312 l2cap_send_cmd(conn, l2cap_pi(sk)->ident, 358 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
313 L2CAP_CONN_REQ, sizeof(req), &req); 359 L2CAP_CONN_REQ, sizeof(req), &req);
360 } else if (sk->sk_state == BT_CONNECT2) {
361 struct l2cap_conn_rsp rsp;
362 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
363 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
364
365 if (l2cap_check_link_mode(sk)) {
366 sk->sk_state = BT_CONFIG;
367 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
368 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
369 } else {
370 rsp.result = cpu_to_le16(L2CAP_CR_PEND);
371 rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
372 }
373
374 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
375 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
314 } 376 }
315 377
316 bh_unlock_sock(sk); 378 bh_unlock_sock(sk);
@@ -321,22 +383,27 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
321 383
322static void l2cap_conn_ready(struct l2cap_conn *conn) 384static void l2cap_conn_ready(struct l2cap_conn *conn)
323{ 385{
324 BT_DBG("conn %p", conn); 386 struct l2cap_chan_list *l = &conn->chan_list;
387 struct sock *sk;
325 388
326 if (conn->chan_list.head || !hlist_empty(&l2cap_sk_list.head)) { 389 BT_DBG("conn %p", conn);
327 struct l2cap_info_req req;
328 390
329 req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); 391 read_lock(&l->lock);
330 392
331 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; 393 for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
332 conn->info_ident = l2cap_get_ident(conn); 394 bh_lock_sock(sk);
333 395
334 mod_timer(&conn->info_timer, 396 if (sk->sk_type != SOCK_SEQPACKET) {
335 jiffies + msecs_to_jiffies(L2CAP_INFO_TIMEOUT)); 397 l2cap_sock_clear_timer(sk);
398 sk->sk_state = BT_CONNECTED;
399 sk->sk_state_change(sk);
400 } else if (sk->sk_state == BT_CONNECT)
401 l2cap_do_start(sk);
336 402
337 l2cap_send_cmd(conn, conn->info_ident, 403 bh_unlock_sock(sk);
338 L2CAP_INFO_REQ, sizeof(req), &req);
339 } 404 }
405
406 read_unlock(&l->lock);
340} 407}
341 408
342/* Notify sockets that we cannot guaranty reliability anymore */ 409/* Notify sockets that we cannot guaranty reliability anymore */
@@ -729,22 +796,11 @@ static int l2cap_do_connect(struct sock *sk)
729 l2cap_sock_set_timer(sk, sk->sk_sndtimeo); 796 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
730 797
731 if (hcon->state == BT_CONNECTED) { 798 if (hcon->state == BT_CONNECTED) {
732 if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)) { 799 if (sk->sk_type != SOCK_SEQPACKET) {
733 l2cap_conn_ready(conn);
734 goto done;
735 }
736
737 if (sk->sk_type == SOCK_SEQPACKET) {
738 struct l2cap_conn_req req;
739 l2cap_pi(sk)->ident = l2cap_get_ident(conn);
740 req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
741 req.psm = l2cap_pi(sk)->psm;
742 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
743 L2CAP_CONN_REQ, sizeof(req), &req);
744 } else {
745 l2cap_sock_clear_timer(sk); 800 l2cap_sock_clear_timer(sk);
746 sk->sk_state = BT_CONNECTED; 801 sk->sk_state = BT_CONNECTED;
747 } 802 } else
803 l2cap_do_start(sk);
748 } 804 }
749 805
750done: 806done:
@@ -1477,7 +1533,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
1477 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; 1533 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
1478 struct l2cap_conn_rsp rsp; 1534 struct l2cap_conn_rsp rsp;
1479 struct sock *sk, *parent; 1535 struct sock *sk, *parent;
1480 int result = 0, status = 0; 1536 int result, status = 0;
1481 1537
1482 u16 dcid = 0, scid = __le16_to_cpu(req->scid); 1538 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
1483 __le16 psm = req->psm; 1539 __le16 psm = req->psm;
@@ -1526,25 +1582,24 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
1526 1582
1527 l2cap_sock_set_timer(sk, sk->sk_sndtimeo); 1583 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
1528 1584
1529 /* Service level security */
1530 result = L2CAP_CR_PEND;
1531 status = L2CAP_CS_AUTHEN_PEND;
1532 sk->sk_state = BT_CONNECT2;
1533 l2cap_pi(sk)->ident = cmd->ident; 1585 l2cap_pi(sk)->ident = cmd->ident;
1534 1586
1535 if ((l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) || 1587 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
1536 (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE)) { 1588 if (l2cap_check_link_mode(sk)) {
1537 if (!hci_conn_encrypt(conn->hcon)) 1589 sk->sk_state = BT_CONFIG;
1538 goto done; 1590 result = L2CAP_CR_SUCCESS;
1539 } else if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH) { 1591 status = L2CAP_CS_NO_INFO;
1540 if (!hci_conn_auth(conn->hcon)) 1592 } else {
1541 goto done; 1593 sk->sk_state = BT_CONNECT2;
1594 result = L2CAP_CR_PEND;
1595 status = L2CAP_CS_AUTHEN_PEND;
1596 }
1597 } else {
1598 sk->sk_state = BT_CONNECT2;
1599 result = L2CAP_CR_PEND;
1600 status = L2CAP_CS_NO_INFO;
1542 } 1601 }
1543 1602
1544 sk->sk_state = BT_CONFIG;
1545 result = status = 0;
1546
1547done:
1548 write_unlock_bh(&list->lock); 1603 write_unlock_bh(&list->lock);
1549 1604
1550response: 1605response:
@@ -1556,6 +1611,21 @@ sendresp:
1556 rsp.result = cpu_to_le16(result); 1611 rsp.result = cpu_to_le16(result);
1557 rsp.status = cpu_to_le16(status); 1612 rsp.status = cpu_to_le16(status);
1558 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); 1613 l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
1614
1615 if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
1616 struct l2cap_info_req info;
1617 info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
1618
1619 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
1620 conn->info_ident = l2cap_get_ident(conn);
1621
1622 mod_timer(&conn->info_timer, jiffies +
1623 msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
1624
1625 l2cap_send_cmd(conn, conn->info_ident,
1626 L2CAP_INFO_REQ, sizeof(info), &info);
1627 }
1628
1559 return 0; 1629 return 0;
1560} 1630}
1561 1631
@@ -1664,9 +1734,9 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
1664 } 1734 }
1665 1735
1666 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) { 1736 if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
1667 u8 req[64]; 1737 u8 buf[64];
1668 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, 1738 l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
1669 l2cap_build_conf_req(sk, req), req); 1739 l2cap_build_conf_req(sk, buf), buf);
1670 } 1740 }
1671 1741
1672unlock: 1742unlock: