diff options
author | David S. Miller <davem@davemloft.net> | 2008-07-19 03:30:39 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-19 03:30:39 -0400 |
commit | 407d819cf0fd54c6fc1138a509225696aecafd15 (patch) | |
tree | b653a5c8c09f7c316f5f98947be262e27a4ca33a /net/bluetooth/rfcomm/core.c | |
parent | 7abbcd6a4c8d6179121f2915a761b1133bf1cd99 (diff) | |
parent | b1235d79611e78a07629b4cbe53291c9cffd1834 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6
Diffstat (limited to 'net/bluetooth/rfcomm/core.c')
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 92 |
1 files changed, 60 insertions, 32 deletions
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index b4fb84e398e5..6cfc7ba611b3 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -51,7 +51,7 @@ | |||
51 | #define BT_DBG(D...) | 51 | #define BT_DBG(D...) |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | #define VERSION "1.8" | 54 | #define VERSION "1.10" |
55 | 55 | ||
56 | static int disable_cfc = 0; | 56 | static int disable_cfc = 0; |
57 | static int channel_mtu = -1; | 57 | static int channel_mtu = -1; |
@@ -228,6 +228,21 @@ static int rfcomm_l2sock_create(struct socket **sock) | |||
228 | return err; | 228 | return err; |
229 | } | 229 | } |
230 | 230 | ||
231 | static inline int rfcomm_check_link_mode(struct rfcomm_dlc *d) | ||
232 | { | ||
233 | struct sock *sk = d->session->sock->sk; | ||
234 | |||
235 | if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) { | ||
236 | if (!hci_conn_encrypt(l2cap_pi(sk)->conn->hcon)) | ||
237 | return 1; | ||
238 | } else if (d->link_mode & RFCOMM_LM_AUTH) { | ||
239 | if (!hci_conn_auth(l2cap_pi(sk)->conn->hcon)) | ||
240 | return 1; | ||
241 | } | ||
242 | |||
243 | return 0; | ||
244 | } | ||
245 | |||
231 | /* ---- RFCOMM DLCs ---- */ | 246 | /* ---- RFCOMM DLCs ---- */ |
232 | static void rfcomm_dlc_timeout(unsigned long arg) | 247 | static void rfcomm_dlc_timeout(unsigned long arg) |
233 | { | 248 | { |
@@ -369,15 +384,23 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, | |||
369 | d->addr = __addr(s->initiator, dlci); | 384 | d->addr = __addr(s->initiator, dlci); |
370 | d->priority = 7; | 385 | d->priority = 7; |
371 | 386 | ||
372 | d->state = BT_CONFIG; | 387 | d->state = BT_CONFIG; |
373 | rfcomm_dlc_link(s, d); | 388 | rfcomm_dlc_link(s, d); |
374 | 389 | ||
390 | d->out = 1; | ||
391 | |||
375 | d->mtu = s->mtu; | 392 | d->mtu = s->mtu; |
376 | d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc; | 393 | d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc; |
377 | 394 | ||
378 | if (s->state == BT_CONNECTED) | 395 | if (s->state == BT_CONNECTED) { |
379 | rfcomm_send_pn(s, 1, d); | 396 | if (rfcomm_check_link_mode(d)) |
397 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); | ||
398 | else | ||
399 | rfcomm_send_pn(s, 1, d); | ||
400 | } | ||
401 | |||
380 | rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT); | 402 | rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT); |
403 | |||
381 | return 0; | 404 | return 0; |
382 | } | 405 | } |
383 | 406 | ||
@@ -1144,21 +1167,6 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci) | |||
1144 | return 0; | 1167 | return 0; |
1145 | } | 1168 | } |
1146 | 1169 | ||
1147 | static inline int rfcomm_check_link_mode(struct rfcomm_dlc *d) | ||
1148 | { | ||
1149 | struct sock *sk = d->session->sock->sk; | ||
1150 | |||
1151 | if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) { | ||
1152 | if (!hci_conn_encrypt(l2cap_pi(sk)->conn->hcon)) | ||
1153 | return 1; | ||
1154 | } else if (d->link_mode & RFCOMM_LM_AUTH) { | ||
1155 | if (!hci_conn_auth(l2cap_pi(sk)->conn->hcon)) | ||
1156 | return 1; | ||
1157 | } | ||
1158 | |||
1159 | return 0; | ||
1160 | } | ||
1161 | |||
1162 | static void rfcomm_dlc_accept(struct rfcomm_dlc *d) | 1170 | static void rfcomm_dlc_accept(struct rfcomm_dlc *d) |
1163 | { | 1171 | { |
1164 | struct sock *sk = d->session->sock->sk; | 1172 | struct sock *sk = d->session->sock->sk; |
@@ -1203,10 +1211,8 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci) | |||
1203 | if (rfcomm_check_link_mode(d)) { | 1211 | if (rfcomm_check_link_mode(d)) { |
1204 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); | 1212 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); |
1205 | rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); | 1213 | rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); |
1206 | return 0; | 1214 | } else |
1207 | } | 1215 | rfcomm_dlc_accept(d); |
1208 | |||
1209 | rfcomm_dlc_accept(d); | ||
1210 | } | 1216 | } |
1211 | return 0; | 1217 | return 0; |
1212 | } | 1218 | } |
@@ -1221,10 +1227,8 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci) | |||
1221 | if (rfcomm_check_link_mode(d)) { | 1227 | if (rfcomm_check_link_mode(d)) { |
1222 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); | 1228 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); |
1223 | rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); | 1229 | rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); |
1224 | return 0; | 1230 | } else |
1225 | } | 1231 | rfcomm_dlc_accept(d); |
1226 | |||
1227 | rfcomm_dlc_accept(d); | ||
1228 | } else { | 1232 | } else { |
1229 | rfcomm_send_dm(s, dlci); | 1233 | rfcomm_send_dm(s, dlci); |
1230 | } | 1234 | } |
@@ -1457,8 +1461,12 @@ static int rfcomm_recv_msc(struct rfcomm_session *s, int cr, struct sk_buff *skb | |||
1457 | clear_bit(RFCOMM_TX_THROTTLED, &d->flags); | 1461 | clear_bit(RFCOMM_TX_THROTTLED, &d->flags); |
1458 | 1462 | ||
1459 | rfcomm_dlc_lock(d); | 1463 | rfcomm_dlc_lock(d); |
1464 | |||
1465 | d->remote_v24_sig = msc->v24_sig; | ||
1466 | |||
1460 | if (d->modem_status) | 1467 | if (d->modem_status) |
1461 | d->modem_status(d, msc->v24_sig); | 1468 | d->modem_status(d, msc->v24_sig); |
1469 | |||
1462 | rfcomm_dlc_unlock(d); | 1470 | rfcomm_dlc_unlock(d); |
1463 | 1471 | ||
1464 | rfcomm_send_msc(s, 0, dlci, msc->v24_sig); | 1472 | rfcomm_send_msc(s, 0, dlci, msc->v24_sig); |
@@ -1634,7 +1642,11 @@ static void rfcomm_process_connect(struct rfcomm_session *s) | |||
1634 | d = list_entry(p, struct rfcomm_dlc, list); | 1642 | d = list_entry(p, struct rfcomm_dlc, list); |
1635 | if (d->state == BT_CONFIG) { | 1643 | if (d->state == BT_CONFIG) { |
1636 | d->mtu = s->mtu; | 1644 | d->mtu = s->mtu; |
1637 | rfcomm_send_pn(s, 1, d); | 1645 | if (rfcomm_check_link_mode(d)) { |
1646 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); | ||
1647 | rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); | ||
1648 | } else | ||
1649 | rfcomm_send_pn(s, 1, d); | ||
1638 | } | 1650 | } |
1639 | } | 1651 | } |
1640 | } | 1652 | } |
@@ -1707,7 +1719,11 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s) | |||
1707 | 1719 | ||
1708 | if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) { | 1720 | if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) { |
1709 | rfcomm_dlc_clear_timer(d); | 1721 | rfcomm_dlc_clear_timer(d); |
1710 | rfcomm_dlc_accept(d); | 1722 | if (d->out) { |
1723 | rfcomm_send_pn(s, 1, d); | ||
1724 | rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT); | ||
1725 | } else | ||
1726 | rfcomm_dlc_accept(d); | ||
1711 | if (d->link_mode & RFCOMM_LM_SECURE) { | 1727 | if (d->link_mode & RFCOMM_LM_SECURE) { |
1712 | struct sock *sk = s->sock->sk; | 1728 | struct sock *sk = s->sock->sk; |
1713 | hci_conn_change_link_key(l2cap_pi(sk)->conn->hcon); | 1729 | hci_conn_change_link_key(l2cap_pi(sk)->conn->hcon); |
@@ -1715,7 +1731,10 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s) | |||
1715 | continue; | 1731 | continue; |
1716 | } else if (test_and_clear_bit(RFCOMM_AUTH_REJECT, &d->flags)) { | 1732 | } else if (test_and_clear_bit(RFCOMM_AUTH_REJECT, &d->flags)) { |
1717 | rfcomm_dlc_clear_timer(d); | 1733 | rfcomm_dlc_clear_timer(d); |
1718 | rfcomm_send_dm(s, d->dlci); | 1734 | if (!d->out) |
1735 | rfcomm_send_dm(s, d->dlci); | ||
1736 | else | ||
1737 | d->state = BT_CLOSED; | ||
1719 | __rfcomm_dlc_close(d, ECONNREFUSED); | 1738 | __rfcomm_dlc_close(d, ECONNREFUSED); |
1720 | continue; | 1739 | continue; |
1721 | } | 1740 | } |
@@ -1724,7 +1743,7 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s) | |||
1724 | continue; | 1743 | continue; |
1725 | 1744 | ||
1726 | if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) && | 1745 | if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) && |
1727 | d->mscex == RFCOMM_MSCEX_OK) | 1746 | d->mscex == RFCOMM_MSCEX_OK) |
1728 | rfcomm_process_tx(d); | 1747 | rfcomm_process_tx(d); |
1729 | } | 1748 | } |
1730 | } | 1749 | } |
@@ -1952,7 +1971,8 @@ static void rfcomm_auth_cfm(struct hci_conn *conn, u8 status) | |||
1952 | list_for_each_safe(p, n, &s->dlcs) { | 1971 | list_for_each_safe(p, n, &s->dlcs) { |
1953 | d = list_entry(p, struct rfcomm_dlc, list); | 1972 | d = list_entry(p, struct rfcomm_dlc, list); |
1954 | 1973 | ||
1955 | if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) | 1974 | if ((d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) && |
1975 | !(conn->link_mode & HCI_LM_ENCRYPT) && !status) | ||
1956 | continue; | 1976 | continue; |
1957 | 1977 | ||
1958 | if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags)) | 1978 | if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags)) |
@@ -1986,6 +2006,14 @@ static void rfcomm_encrypt_cfm(struct hci_conn *conn, u8 status, u8 encrypt) | |||
1986 | list_for_each_safe(p, n, &s->dlcs) { | 2006 | list_for_each_safe(p, n, &s->dlcs) { |
1987 | d = list_entry(p, struct rfcomm_dlc, list); | 2007 | d = list_entry(p, struct rfcomm_dlc, list); |
1988 | 2008 | ||
2009 | if ((d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) && | ||
2010 | (d->state == BT_CONNECTED || | ||
2011 | d->state == BT_CONFIG) && | ||
2012 | !status && encrypt == 0x00) { | ||
2013 | __rfcomm_dlc_close(d, ECONNREFUSED); | ||
2014 | continue; | ||
2015 | } | ||
2016 | |||
1989 | if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags)) | 2017 | if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags)) |
1990 | continue; | 2018 | continue; |
1991 | 2019 | ||