diff options
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 77 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 8 |
2 files changed, 51 insertions, 34 deletions
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 0c2c93735e93..1f92f9ab4959 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -53,7 +53,7 @@ | |||
53 | #define BT_DBG(D...) | 53 | #define BT_DBG(D...) |
54 | #endif | 54 | #endif |
55 | 55 | ||
56 | #define VERSION "1.8" | 56 | #define VERSION "1.9" |
57 | 57 | ||
58 | static int disable_cfc = 0; | 58 | static int disable_cfc = 0; |
59 | static int channel_mtu = -1; | 59 | static int channel_mtu = -1; |
@@ -230,6 +230,21 @@ static int rfcomm_l2sock_create(struct socket **sock) | |||
230 | return err; | 230 | return err; |
231 | } | 231 | } |
232 | 232 | ||
233 | static inline int rfcomm_check_link_mode(struct rfcomm_dlc *d) | ||
234 | { | ||
235 | struct sock *sk = d->session->sock->sk; | ||
236 | |||
237 | if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) { | ||
238 | if (!hci_conn_encrypt(l2cap_pi(sk)->conn->hcon)) | ||
239 | return 1; | ||
240 | } else if (d->link_mode & RFCOMM_LM_AUTH) { | ||
241 | if (!hci_conn_auth(l2cap_pi(sk)->conn->hcon)) | ||
242 | return 1; | ||
243 | } | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
233 | /* ---- RFCOMM DLCs ---- */ | 248 | /* ---- RFCOMM DLCs ---- */ |
234 | static void rfcomm_dlc_timeout(unsigned long arg) | 249 | static void rfcomm_dlc_timeout(unsigned long arg) |
235 | { | 250 | { |
@@ -371,15 +386,23 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, | |||
371 | d->addr = __addr(s->initiator, dlci); | 386 | d->addr = __addr(s->initiator, dlci); |
372 | d->priority = 7; | 387 | d->priority = 7; |
373 | 388 | ||
374 | d->state = BT_CONFIG; | 389 | d->state = BT_CONFIG; |
375 | rfcomm_dlc_link(s, d); | 390 | rfcomm_dlc_link(s, d); |
376 | 391 | ||
392 | d->out = 1; | ||
393 | |||
377 | d->mtu = s->mtu; | 394 | d->mtu = s->mtu; |
378 | d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc; | 395 | d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc; |
379 | 396 | ||
380 | if (s->state == BT_CONNECTED) | 397 | if (s->state == BT_CONNECTED) { |
381 | rfcomm_send_pn(s, 1, d); | 398 | if (rfcomm_check_link_mode(d)) |
399 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); | ||
400 | else | ||
401 | rfcomm_send_pn(s, 1, d); | ||
402 | } | ||
403 | |||
382 | rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT); | 404 | rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT); |
405 | |||
383 | return 0; | 406 | return 0; |
384 | } | 407 | } |
385 | 408 | ||
@@ -1146,21 +1169,6 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci) | |||
1146 | return 0; | 1169 | return 0; |
1147 | } | 1170 | } |
1148 | 1171 | ||
1149 | static inline int rfcomm_check_link_mode(struct rfcomm_dlc *d) | ||
1150 | { | ||
1151 | struct sock *sk = d->session->sock->sk; | ||
1152 | |||
1153 | if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) { | ||
1154 | if (!hci_conn_encrypt(l2cap_pi(sk)->conn->hcon)) | ||
1155 | return 1; | ||
1156 | } else if (d->link_mode & RFCOMM_LM_AUTH) { | ||
1157 | if (!hci_conn_auth(l2cap_pi(sk)->conn->hcon)) | ||
1158 | return 1; | ||
1159 | } | ||
1160 | |||
1161 | return 0; | ||
1162 | } | ||
1163 | |||
1164 | static void rfcomm_dlc_accept(struct rfcomm_dlc *d) | 1172 | static void rfcomm_dlc_accept(struct rfcomm_dlc *d) |
1165 | { | 1173 | { |
1166 | struct sock *sk = d->session->sock->sk; | 1174 | struct sock *sk = d->session->sock->sk; |
@@ -1205,10 +1213,8 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci) | |||
1205 | if (rfcomm_check_link_mode(d)) { | 1213 | if (rfcomm_check_link_mode(d)) { |
1206 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); | 1214 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); |
1207 | rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); | 1215 | rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); |
1208 | return 0; | 1216 | } else |
1209 | } | 1217 | rfcomm_dlc_accept(d); |
1210 | |||
1211 | rfcomm_dlc_accept(d); | ||
1212 | } | 1218 | } |
1213 | return 0; | 1219 | return 0; |
1214 | } | 1220 | } |
@@ -1223,10 +1229,8 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci) | |||
1223 | if (rfcomm_check_link_mode(d)) { | 1229 | if (rfcomm_check_link_mode(d)) { |
1224 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); | 1230 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); |
1225 | rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); | 1231 | rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); |
1226 | return 0; | 1232 | } else |
1227 | } | 1233 | rfcomm_dlc_accept(d); |
1228 | |||
1229 | rfcomm_dlc_accept(d); | ||
1230 | } else { | 1234 | } else { |
1231 | rfcomm_send_dm(s, dlci); | 1235 | rfcomm_send_dm(s, dlci); |
1232 | } | 1236 | } |
@@ -1636,7 +1640,11 @@ static void rfcomm_process_connect(struct rfcomm_session *s) | |||
1636 | d = list_entry(p, struct rfcomm_dlc, list); | 1640 | d = list_entry(p, struct rfcomm_dlc, list); |
1637 | if (d->state == BT_CONFIG) { | 1641 | if (d->state == BT_CONFIG) { |
1638 | d->mtu = s->mtu; | 1642 | d->mtu = s->mtu; |
1639 | rfcomm_send_pn(s, 1, d); | 1643 | if (rfcomm_check_link_mode(d)) { |
1644 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); | ||
1645 | rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); | ||
1646 | } else | ||
1647 | rfcomm_send_pn(s, 1, d); | ||
1640 | } | 1648 | } |
1641 | } | 1649 | } |
1642 | } | 1650 | } |
@@ -1709,7 +1717,11 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s) | |||
1709 | 1717 | ||
1710 | if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) { | 1718 | if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) { |
1711 | rfcomm_dlc_clear_timer(d); | 1719 | rfcomm_dlc_clear_timer(d); |
1712 | rfcomm_dlc_accept(d); | 1720 | if (d->out) { |
1721 | rfcomm_send_pn(s, 1, d); | ||
1722 | rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT); | ||
1723 | } else | ||
1724 | rfcomm_dlc_accept(d); | ||
1713 | if (d->link_mode & RFCOMM_LM_SECURE) { | 1725 | if (d->link_mode & RFCOMM_LM_SECURE) { |
1714 | struct sock *sk = s->sock->sk; | 1726 | struct sock *sk = s->sock->sk; |
1715 | hci_conn_change_link_key(l2cap_pi(sk)->conn->hcon); | 1727 | hci_conn_change_link_key(l2cap_pi(sk)->conn->hcon); |
@@ -1717,7 +1729,10 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s) | |||
1717 | continue; | 1729 | continue; |
1718 | } else if (test_and_clear_bit(RFCOMM_AUTH_REJECT, &d->flags)) { | 1730 | } else if (test_and_clear_bit(RFCOMM_AUTH_REJECT, &d->flags)) { |
1719 | rfcomm_dlc_clear_timer(d); | 1731 | rfcomm_dlc_clear_timer(d); |
1720 | rfcomm_send_dm(s, d->dlci); | 1732 | if (!d->out) |
1733 | rfcomm_send_dm(s, d->dlci); | ||
1734 | else | ||
1735 | d->state = BT_CLOSED; | ||
1721 | __rfcomm_dlc_close(d, ECONNREFUSED); | 1736 | __rfcomm_dlc_close(d, ECONNREFUSED); |
1722 | continue; | 1737 | continue; |
1723 | } | 1738 | } |
@@ -1726,7 +1741,7 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s) | |||
1726 | continue; | 1741 | continue; |
1727 | 1742 | ||
1728 | if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) && | 1743 | if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) && |
1729 | d->mscex == RFCOMM_MSCEX_OK) | 1744 | d->mscex == RFCOMM_MSCEX_OK) |
1730 | rfcomm_process_tx(d); | 1745 | rfcomm_process_tx(d); |
1731 | } | 1746 | } |
1732 | } | 1747 | } |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 5083adcbfae5..cacb1ab51f99 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -309,13 +309,13 @@ static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int | |||
309 | sk->sk_destruct = rfcomm_sock_destruct; | 309 | sk->sk_destruct = rfcomm_sock_destruct; |
310 | sk->sk_sndtimeo = RFCOMM_CONN_TIMEOUT; | 310 | sk->sk_sndtimeo = RFCOMM_CONN_TIMEOUT; |
311 | 311 | ||
312 | sk->sk_sndbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10; | 312 | sk->sk_sndbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10; |
313 | sk->sk_rcvbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10; | 313 | sk->sk_rcvbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10; |
314 | 314 | ||
315 | sock_reset_flag(sk, SOCK_ZAPPED); | 315 | sock_reset_flag(sk, SOCK_ZAPPED); |
316 | 316 | ||
317 | sk->sk_protocol = proto; | 317 | sk->sk_protocol = proto; |
318 | sk->sk_state = BT_OPEN; | 318 | sk->sk_state = BT_OPEN; |
319 | 319 | ||
320 | bt_sock_link(&rfcomm_sk_list, sk); | 320 | bt_sock_link(&rfcomm_sk_list, sk); |
321 | 321 | ||
@@ -413,6 +413,8 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a | |||
413 | bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr); | 413 | bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr); |
414 | rfcomm_pi(sk)->channel = sa->rc_channel; | 414 | rfcomm_pi(sk)->channel = sa->rc_channel; |
415 | 415 | ||
416 | d->link_mode = rfcomm_pi(sk)->link_mode; | ||
417 | |||
416 | err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel); | 418 | err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel); |
417 | if (!err) | 419 | if (!err) |
418 | err = bt_sock_wait_state(sk, BT_CONNECTED, | 420 | err = bt_sock_wait_state(sk, BT_CONNECTED, |