diff options
Diffstat (limited to 'net/bluetooth/l2cap_core.c')
-rw-r--r-- | net/bluetooth/l2cap_core.c | 295 |
1 files changed, 111 insertions, 184 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 3204ba8a701c..5ea94a1eecf2 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -251,7 +251,7 @@ static void l2cap_chan_timeout(unsigned long arg) | |||
251 | 251 | ||
252 | if (sock_owned_by_user(sk)) { | 252 | if (sock_owned_by_user(sk)) { |
253 | /* sk is owned by user. Try again later */ | 253 | /* sk is owned by user. Try again later */ |
254 | __set_chan_timer(chan, HZ / 5); | 254 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); |
255 | bh_unlock_sock(sk); | 255 | bh_unlock_sock(sk); |
256 | chan_put(chan); | 256 | chan_put(chan); |
257 | return; | 257 | return; |
@@ -907,6 +907,9 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) | |||
907 | if (!conn->hcon->out && conn->hcon->type == LE_LINK) | 907 | if (!conn->hcon->out && conn->hcon->type == LE_LINK) |
908 | l2cap_le_conn_ready(conn); | 908 | l2cap_le_conn_ready(conn); |
909 | 909 | ||
910 | if (conn->hcon->out && conn->hcon->type == LE_LINK) | ||
911 | smp_conn_security(conn, conn->hcon->pending_sec_level); | ||
912 | |||
910 | read_lock(&conn->chan_lock); | 913 | read_lock(&conn->chan_lock); |
911 | 914 | ||
912 | list_for_each_entry(chan, &conn->chan_l, list) { | 915 | list_for_each_entry(chan, &conn->chan_l, list) { |
@@ -986,8 +989,10 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) | |||
986 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) | 989 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) |
987 | del_timer_sync(&conn->info_timer); | 990 | del_timer_sync(&conn->info_timer); |
988 | 991 | ||
989 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend)) | 992 | if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend)) { |
990 | del_timer(&conn->security_timer); | 993 | del_timer(&conn->security_timer); |
994 | smp_chan_destroy(conn); | ||
995 | } | ||
991 | 996 | ||
992 | hcon->l2cap_data = NULL; | 997 | hcon->l2cap_data = NULL; |
993 | kfree(conn); | 998 | kfree(conn); |
@@ -1159,9 +1164,8 @@ int __l2cap_wait_ack(struct sock *sk) | |||
1159 | int timeo = HZ/5; | 1164 | int timeo = HZ/5; |
1160 | 1165 | ||
1161 | add_wait_queue(sk_sleep(sk), &wait); | 1166 | add_wait_queue(sk_sleep(sk), &wait); |
1162 | while ((chan->unacked_frames > 0 && chan->conn)) { | 1167 | set_current_state(TASK_INTERRUPTIBLE); |
1163 | set_current_state(TASK_INTERRUPTIBLE); | 1168 | while (chan->unacked_frames > 0 && chan->conn) { |
1164 | |||
1165 | if (!timeo) | 1169 | if (!timeo) |
1166 | timeo = HZ/5; | 1170 | timeo = HZ/5; |
1167 | 1171 | ||
@@ -1173,6 +1177,7 @@ int __l2cap_wait_ack(struct sock *sk) | |||
1173 | release_sock(sk); | 1177 | release_sock(sk); |
1174 | timeo = schedule_timeout(timeo); | 1178 | timeo = schedule_timeout(timeo); |
1175 | lock_sock(sk); | 1179 | lock_sock(sk); |
1180 | set_current_state(TASK_INTERRUPTIBLE); | ||
1176 | 1181 | ||
1177 | err = sock_error(sk); | 1182 | err = sock_error(sk); |
1178 | if (err) | 1183 | if (err) |
@@ -1240,7 +1245,7 @@ static void l2cap_drop_acked_frames(struct l2cap_chan *chan) | |||
1240 | __clear_retrans_timer(chan); | 1245 | __clear_retrans_timer(chan); |
1241 | } | 1246 | } |
1242 | 1247 | ||
1243 | void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) | 1248 | static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) |
1244 | { | 1249 | { |
1245 | struct hci_conn *hcon = chan->conn->hcon; | 1250 | struct hci_conn *hcon = chan->conn->hcon; |
1246 | u16 flags; | 1251 | u16 flags; |
@@ -1256,7 +1261,7 @@ void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) | |||
1256 | hci_send_acl(hcon, skb, flags); | 1261 | hci_send_acl(hcon, skb, flags); |
1257 | } | 1262 | } |
1258 | 1263 | ||
1259 | void l2cap_streaming_send(struct l2cap_chan *chan) | 1264 | static void l2cap_streaming_send(struct l2cap_chan *chan) |
1260 | { | 1265 | { |
1261 | struct sk_buff *skb; | 1266 | struct sk_buff *skb; |
1262 | u16 control, fcs; | 1267 | u16 control, fcs; |
@@ -1322,7 +1327,7 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) | |||
1322 | l2cap_do_send(chan, tx_skb); | 1327 | l2cap_do_send(chan, tx_skb); |
1323 | } | 1328 | } |
1324 | 1329 | ||
1325 | int l2cap_ertm_send(struct l2cap_chan *chan) | 1330 | static int l2cap_ertm_send(struct l2cap_chan *chan) |
1326 | { | 1331 | { |
1327 | struct sk_buff *skb, *tx_skb; | 1332 | struct sk_buff *skb, *tx_skb; |
1328 | u16 control, fcs; | 1333 | u16 control, fcs; |
@@ -1460,7 +1465,7 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in | |||
1460 | return sent; | 1465 | return sent; |
1461 | } | 1466 | } |
1462 | 1467 | ||
1463 | struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) | 1468 | static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) |
1464 | { | 1469 | { |
1465 | struct sock *sk = chan->sk; | 1470 | struct sock *sk = chan->sk; |
1466 | struct l2cap_conn *conn = chan->conn; | 1471 | struct l2cap_conn *conn = chan->conn; |
@@ -1490,7 +1495,7 @@ struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr | |||
1490 | return skb; | 1495 | return skb; |
1491 | } | 1496 | } |
1492 | 1497 | ||
1493 | struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) | 1498 | static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) |
1494 | { | 1499 | { |
1495 | struct sock *sk = chan->sk; | 1500 | struct sock *sk = chan->sk; |
1496 | struct l2cap_conn *conn = chan->conn; | 1501 | struct l2cap_conn *conn = chan->conn; |
@@ -1519,7 +1524,9 @@ struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *m | |||
1519 | return skb; | 1524 | return skb; |
1520 | } | 1525 | } |
1521 | 1526 | ||
1522 | struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len, u16 control, u16 sdulen) | 1527 | static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, |
1528 | struct msghdr *msg, size_t len, | ||
1529 | u16 control, u16 sdulen) | ||
1523 | { | 1530 | { |
1524 | struct sock *sk = chan->sk; | 1531 | struct sock *sk = chan->sk; |
1525 | struct l2cap_conn *conn = chan->conn; | 1532 | struct l2cap_conn *conn = chan->conn; |
@@ -1565,7 +1572,7 @@ struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, struct msghdr * | |||
1565 | return skb; | 1572 | return skb; |
1566 | } | 1573 | } |
1567 | 1574 | ||
1568 | int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) | 1575 | static int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) |
1569 | { | 1576 | { |
1570 | struct sk_buff *skb; | 1577 | struct sk_buff *skb; |
1571 | struct sk_buff_head sar_queue; | 1578 | struct sk_buff_head sar_queue; |
@@ -2481,7 +2488,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2481 | if (sock_owned_by_user(sk)) { | 2488 | if (sock_owned_by_user(sk)) { |
2482 | l2cap_state_change(chan, BT_DISCONN); | 2489 | l2cap_state_change(chan, BT_DISCONN); |
2483 | __clear_chan_timer(chan); | 2490 | __clear_chan_timer(chan); |
2484 | __set_chan_timer(chan, HZ / 5); | 2491 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); |
2485 | break; | 2492 | break; |
2486 | } | 2493 | } |
2487 | 2494 | ||
@@ -2654,7 +2661,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2654 | 2661 | ||
2655 | default: | 2662 | default: |
2656 | sk->sk_err = ECONNRESET; | 2663 | sk->sk_err = ECONNRESET; |
2657 | __set_chan_timer(chan, HZ * 5); | 2664 | __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT); |
2658 | l2cap_send_disconn_req(conn, chan, ECONNRESET); | 2665 | l2cap_send_disconn_req(conn, chan, ECONNRESET); |
2659 | goto done; | 2666 | goto done; |
2660 | } | 2667 | } |
@@ -2711,7 +2718,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd | |||
2711 | if (sock_owned_by_user(sk)) { | 2718 | if (sock_owned_by_user(sk)) { |
2712 | l2cap_state_change(chan, BT_DISCONN); | 2719 | l2cap_state_change(chan, BT_DISCONN); |
2713 | __clear_chan_timer(chan); | 2720 | __clear_chan_timer(chan); |
2714 | __set_chan_timer(chan, HZ / 5); | 2721 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); |
2715 | bh_unlock_sock(sk); | 2722 | bh_unlock_sock(sk); |
2716 | return 0; | 2723 | return 0; |
2717 | } | 2724 | } |
@@ -2745,7 +2752,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd | |||
2745 | if (sock_owned_by_user(sk)) { | 2752 | if (sock_owned_by_user(sk)) { |
2746 | l2cap_state_change(chan,BT_DISCONN); | 2753 | l2cap_state_change(chan,BT_DISCONN); |
2747 | __clear_chan_timer(chan); | 2754 | __clear_chan_timer(chan); |
2748 | __set_chan_timer(chan, HZ / 5); | 2755 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); |
2749 | bh_unlock_sock(sk); | 2756 | bh_unlock_sock(sk); |
2750 | return 0; | 2757 | return 0; |
2751 | } | 2758 | } |
@@ -3121,102 +3128,104 @@ static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, | |||
3121 | return 0; | 3128 | return 0; |
3122 | } | 3129 | } |
3123 | 3130 | ||
3124 | static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) | 3131 | static void append_skb_frag(struct sk_buff *skb, |
3132 | struct sk_buff *new_frag, struct sk_buff **last_frag) | ||
3125 | { | 3133 | { |
3126 | struct sk_buff *_skb; | 3134 | /* skb->len reflects data in skb as well as all fragments |
3127 | int err; | 3135 | * skb->data_len reflects only data in fragments |
3136 | */ | ||
3137 | if (!skb_has_frag_list(skb)) | ||
3138 | skb_shinfo(skb)->frag_list = new_frag; | ||
3139 | |||
3140 | new_frag->next = NULL; | ||
3141 | |||
3142 | (*last_frag)->next = new_frag; | ||
3143 | *last_frag = new_frag; | ||
3144 | |||
3145 | skb->len += new_frag->len; | ||
3146 | skb->data_len += new_frag->len; | ||
3147 | skb->truesize += new_frag->truesize; | ||
3148 | } | ||
3149 | |||
3150 | static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) | ||
3151 | { | ||
3152 | int err = -EINVAL; | ||
3128 | 3153 | ||
3129 | switch (control & L2CAP_CTRL_SAR) { | 3154 | switch (control & L2CAP_CTRL_SAR) { |
3130 | case L2CAP_SDU_UNSEGMENTED: | 3155 | case L2CAP_SDU_UNSEGMENTED: |
3131 | if (test_bit(CONN_SAR_SDU, &chan->conn_state)) | 3156 | if (chan->sdu) |
3132 | goto drop; | 3157 | break; |
3133 | 3158 | ||
3134 | return chan->ops->recv(chan->data, skb); | 3159 | err = chan->ops->recv(chan->data, skb); |
3160 | break; | ||
3135 | 3161 | ||
3136 | case L2CAP_SDU_START: | 3162 | case L2CAP_SDU_START: |
3137 | if (test_bit(CONN_SAR_SDU, &chan->conn_state)) | 3163 | if (chan->sdu) |
3138 | goto drop; | 3164 | break; |
3139 | 3165 | ||
3140 | chan->sdu_len = get_unaligned_le16(skb->data); | 3166 | chan->sdu_len = get_unaligned_le16(skb->data); |
3167 | skb_pull(skb, 2); | ||
3141 | 3168 | ||
3142 | if (chan->sdu_len > chan->imtu) | 3169 | if (chan->sdu_len > chan->imtu) { |
3143 | goto disconnect; | 3170 | err = -EMSGSIZE; |
3144 | 3171 | break; | |
3145 | chan->sdu = bt_skb_alloc(chan->sdu_len, GFP_ATOMIC); | 3172 | } |
3146 | if (!chan->sdu) | ||
3147 | return -ENOMEM; | ||
3148 | 3173 | ||
3149 | /* pull sdu_len bytes only after alloc, because of Local Busy | 3174 | if (skb->len >= chan->sdu_len) |
3150 | * condition we have to be sure that this will be executed | 3175 | break; |
3151 | * only once, i.e., when alloc does not fail */ | ||
3152 | skb_pull(skb, 2); | ||
3153 | 3176 | ||
3154 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); | 3177 | chan->sdu = skb; |
3178 | chan->sdu_last_frag = skb; | ||
3155 | 3179 | ||
3156 | set_bit(CONN_SAR_SDU, &chan->conn_state); | 3180 | skb = NULL; |
3157 | chan->partial_sdu_len = skb->len; | 3181 | err = 0; |
3158 | break; | 3182 | break; |
3159 | 3183 | ||
3160 | case L2CAP_SDU_CONTINUE: | 3184 | case L2CAP_SDU_CONTINUE: |
3161 | if (!test_bit(CONN_SAR_SDU, &chan->conn_state)) | ||
3162 | goto disconnect; | ||
3163 | |||
3164 | if (!chan->sdu) | 3185 | if (!chan->sdu) |
3165 | goto disconnect; | 3186 | break; |
3166 | 3187 | ||
3167 | chan->partial_sdu_len += skb->len; | 3188 | append_skb_frag(chan->sdu, skb, |
3168 | if (chan->partial_sdu_len > chan->sdu_len) | 3189 | &chan->sdu_last_frag); |
3169 | goto drop; | 3190 | skb = NULL; |
3170 | 3191 | ||
3171 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); | 3192 | if (chan->sdu->len >= chan->sdu_len) |
3193 | break; | ||
3172 | 3194 | ||
3195 | err = 0; | ||
3173 | break; | 3196 | break; |
3174 | 3197 | ||
3175 | case L2CAP_SDU_END: | 3198 | case L2CAP_SDU_END: |
3176 | if (!test_bit(CONN_SAR_SDU, &chan->conn_state)) | ||
3177 | goto disconnect; | ||
3178 | |||
3179 | if (!chan->sdu) | 3199 | if (!chan->sdu) |
3180 | goto disconnect; | 3200 | break; |
3181 | |||
3182 | chan->partial_sdu_len += skb->len; | ||
3183 | 3201 | ||
3184 | if (chan->partial_sdu_len > chan->imtu) | 3202 | append_skb_frag(chan->sdu, skb, |
3185 | goto drop; | 3203 | &chan->sdu_last_frag); |
3204 | skb = NULL; | ||
3186 | 3205 | ||
3187 | if (chan->partial_sdu_len != chan->sdu_len) | 3206 | if (chan->sdu->len != chan->sdu_len) |
3188 | goto drop; | 3207 | break; |
3189 | 3208 | ||
3190 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); | 3209 | err = chan->ops->recv(chan->data, chan->sdu); |
3191 | 3210 | ||
3192 | _skb = skb_clone(chan->sdu, GFP_ATOMIC); | 3211 | if (!err) { |
3193 | if (!_skb) { | 3212 | /* Reassembly complete */ |
3194 | return -ENOMEM; | 3213 | chan->sdu = NULL; |
3214 | chan->sdu_last_frag = NULL; | ||
3215 | chan->sdu_len = 0; | ||
3195 | } | 3216 | } |
3196 | |||
3197 | err = chan->ops->recv(chan->data, _skb); | ||
3198 | if (err < 0) { | ||
3199 | kfree_skb(_skb); | ||
3200 | return err; | ||
3201 | } | ||
3202 | |||
3203 | clear_bit(CONN_SAR_SDU, &chan->conn_state); | ||
3204 | |||
3205 | kfree_skb(chan->sdu); | ||
3206 | break; | 3217 | break; |
3207 | } | 3218 | } |
3208 | 3219 | ||
3209 | kfree_skb(skb); | 3220 | if (err) { |
3210 | return 0; | 3221 | kfree_skb(skb); |
3211 | 3222 | kfree_skb(chan->sdu); | |
3212 | drop: | 3223 | chan->sdu = NULL; |
3213 | kfree_skb(chan->sdu); | 3224 | chan->sdu_last_frag = NULL; |
3214 | chan->sdu = NULL; | 3225 | chan->sdu_len = 0; |
3226 | } | ||
3215 | 3227 | ||
3216 | disconnect: | 3228 | return err; |
3217 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); | ||
3218 | kfree_skb(skb); | ||
3219 | return 0; | ||
3220 | } | 3229 | } |
3221 | 3230 | ||
3222 | static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan) | 3231 | static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan) |
@@ -3270,99 +3279,6 @@ void l2cap_chan_busy(struct l2cap_chan *chan, int busy) | |||
3270 | } | 3279 | } |
3271 | } | 3280 | } |
3272 | 3281 | ||
3273 | static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) | ||
3274 | { | ||
3275 | struct sk_buff *_skb; | ||
3276 | int err = -EINVAL; | ||
3277 | |||
3278 | /* | ||
3279 | * TODO: We have to notify the userland if some data is lost with the | ||
3280 | * Streaming Mode. | ||
3281 | */ | ||
3282 | |||
3283 | switch (control & L2CAP_CTRL_SAR) { | ||
3284 | case L2CAP_SDU_UNSEGMENTED: | ||
3285 | if (test_bit(CONN_SAR_SDU, &chan->conn_state)) { | ||
3286 | kfree_skb(chan->sdu); | ||
3287 | break; | ||
3288 | } | ||
3289 | |||
3290 | err = chan->ops->recv(chan->data, skb); | ||
3291 | if (!err) | ||
3292 | return 0; | ||
3293 | |||
3294 | break; | ||
3295 | |||
3296 | case L2CAP_SDU_START: | ||
3297 | if (test_bit(CONN_SAR_SDU, &chan->conn_state)) { | ||
3298 | kfree_skb(chan->sdu); | ||
3299 | break; | ||
3300 | } | ||
3301 | |||
3302 | chan->sdu_len = get_unaligned_le16(skb->data); | ||
3303 | skb_pull(skb, 2); | ||
3304 | |||
3305 | if (chan->sdu_len > chan->imtu) { | ||
3306 | err = -EMSGSIZE; | ||
3307 | break; | ||
3308 | } | ||
3309 | |||
3310 | chan->sdu = bt_skb_alloc(chan->sdu_len, GFP_ATOMIC); | ||
3311 | if (!chan->sdu) { | ||
3312 | err = -ENOMEM; | ||
3313 | break; | ||
3314 | } | ||
3315 | |||
3316 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); | ||
3317 | |||
3318 | set_bit(CONN_SAR_SDU, &chan->conn_state); | ||
3319 | chan->partial_sdu_len = skb->len; | ||
3320 | err = 0; | ||
3321 | break; | ||
3322 | |||
3323 | case L2CAP_SDU_CONTINUE: | ||
3324 | if (!test_bit(CONN_SAR_SDU, &chan->conn_state)) | ||
3325 | break; | ||
3326 | |||
3327 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); | ||
3328 | |||
3329 | chan->partial_sdu_len += skb->len; | ||
3330 | if (chan->partial_sdu_len > chan->sdu_len) | ||
3331 | kfree_skb(chan->sdu); | ||
3332 | else | ||
3333 | err = 0; | ||
3334 | |||
3335 | break; | ||
3336 | |||
3337 | case L2CAP_SDU_END: | ||
3338 | if (!test_bit(CONN_SAR_SDU, &chan->conn_state)) | ||
3339 | break; | ||
3340 | |||
3341 | memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); | ||
3342 | |||
3343 | clear_bit(CONN_SAR_SDU, &chan->conn_state); | ||
3344 | chan->partial_sdu_len += skb->len; | ||
3345 | |||
3346 | if (chan->partial_sdu_len > chan->imtu) | ||
3347 | goto drop; | ||
3348 | |||
3349 | if (chan->partial_sdu_len == chan->sdu_len) { | ||
3350 | _skb = skb_clone(chan->sdu, GFP_ATOMIC); | ||
3351 | err = chan->ops->recv(chan->data, _skb); | ||
3352 | if (err < 0) | ||
3353 | kfree_skb(_skb); | ||
3354 | } | ||
3355 | err = 0; | ||
3356 | |||
3357 | drop: | ||
3358 | kfree_skb(chan->sdu); | ||
3359 | break; | ||
3360 | } | ||
3361 | |||
3362 | kfree_skb(skb); | ||
3363 | return err; | ||
3364 | } | ||
3365 | |||
3366 | static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq) | 3282 | static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq) |
3367 | { | 3283 | { |
3368 | struct sk_buff *skb; | 3284 | struct sk_buff *skb; |
@@ -3377,7 +3293,7 @@ static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq) | |||
3377 | 3293 | ||
3378 | skb = skb_dequeue(&chan->srej_q); | 3294 | skb = skb_dequeue(&chan->srej_q); |
3379 | control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; | 3295 | control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; |
3380 | err = l2cap_ertm_reassembly_sdu(chan, skb, control); | 3296 | err = l2cap_reassemble_sdu(chan, skb, control); |
3381 | 3297 | ||
3382 | if (err < 0) { | 3298 | if (err < 0) { |
3383 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); | 3299 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); |
@@ -3537,7 +3453,7 @@ expected: | |||
3537 | return 0; | 3453 | return 0; |
3538 | } | 3454 | } |
3539 | 3455 | ||
3540 | err = l2cap_ertm_reassembly_sdu(chan, skb, rx_control); | 3456 | err = l2cap_reassemble_sdu(chan, skb, rx_control); |
3541 | chan->buffer_seq = (chan->buffer_seq + 1) % 64; | 3457 | chan->buffer_seq = (chan->buffer_seq + 1) % 64; |
3542 | if (err < 0) { | 3458 | if (err < 0) { |
3543 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); | 3459 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); |
@@ -3853,12 +3769,20 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
3853 | 3769 | ||
3854 | tx_seq = __get_txseq(control); | 3770 | tx_seq = __get_txseq(control); |
3855 | 3771 | ||
3856 | if (chan->expected_tx_seq == tx_seq) | 3772 | if (chan->expected_tx_seq != tx_seq) { |
3857 | chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; | 3773 | /* Frame(s) missing - must discard partial SDU */ |
3858 | else | 3774 | kfree_skb(chan->sdu); |
3859 | chan->expected_tx_seq = (tx_seq + 1) % 64; | 3775 | chan->sdu = NULL; |
3776 | chan->sdu_last_frag = NULL; | ||
3777 | chan->sdu_len = 0; | ||
3778 | |||
3779 | /* TODO: Notify userland of missing data */ | ||
3780 | } | ||
3781 | |||
3782 | chan->expected_tx_seq = (tx_seq + 1) % 64; | ||
3860 | 3783 | ||
3861 | l2cap_streaming_reassembly_sdu(chan, skb, control); | 3784 | if (l2cap_reassemble_sdu(chan, skb, control) == -EMSGSIZE) |
3785 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); | ||
3862 | 3786 | ||
3863 | goto done; | 3787 | goto done; |
3864 | 3788 | ||
@@ -4074,7 +3998,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt) | |||
4074 | if (encrypt == 0x00) { | 3998 | if (encrypt == 0x00) { |
4075 | if (chan->sec_level == BT_SECURITY_MEDIUM) { | 3999 | if (chan->sec_level == BT_SECURITY_MEDIUM) { |
4076 | __clear_chan_timer(chan); | 4000 | __clear_chan_timer(chan); |
4077 | __set_chan_timer(chan, HZ * 5); | 4001 | __set_chan_timer(chan, L2CAP_ENC_TIMEOUT); |
4078 | } else if (chan->sec_level == BT_SECURITY_HIGH) | 4002 | } else if (chan->sec_level == BT_SECURITY_HIGH) |
4079 | l2cap_chan_close(chan, ECONNREFUSED); | 4003 | l2cap_chan_close(chan, ECONNREFUSED); |
4080 | } else { | 4004 | } else { |
@@ -4093,6 +4017,11 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
4093 | 4017 | ||
4094 | BT_DBG("conn %p", conn); | 4018 | BT_DBG("conn %p", conn); |
4095 | 4019 | ||
4020 | if (hcon->type == LE_LINK) { | ||
4021 | smp_distribute_keys(conn, 0); | ||
4022 | del_timer(&conn->security_timer); | ||
4023 | } | ||
4024 | |||
4096 | read_lock(&conn->chan_lock); | 4025 | read_lock(&conn->chan_lock); |
4097 | 4026 | ||
4098 | list_for_each_entry(chan, &conn->chan_l, list) { | 4027 | list_for_each_entry(chan, &conn->chan_l, list) { |
@@ -4105,9 +4034,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
4105 | if (chan->scid == L2CAP_CID_LE_DATA) { | 4034 | if (chan->scid == L2CAP_CID_LE_DATA) { |
4106 | if (!status && encrypt) { | 4035 | if (!status && encrypt) { |
4107 | chan->sec_level = hcon->sec_level; | 4036 | chan->sec_level = hcon->sec_level; |
4108 | del_timer(&conn->security_timer); | ||
4109 | l2cap_chan_ready(sk); | 4037 | l2cap_chan_ready(sk); |
4110 | smp_distribute_keys(conn, 0); | ||
4111 | } | 4038 | } |
4112 | 4039 | ||
4113 | bh_unlock_sock(sk); | 4040 | bh_unlock_sock(sk); |
@@ -4139,7 +4066,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
4139 | L2CAP_CONN_REQ, sizeof(req), &req); | 4066 | L2CAP_CONN_REQ, sizeof(req), &req); |
4140 | } else { | 4067 | } else { |
4141 | __clear_chan_timer(chan); | 4068 | __clear_chan_timer(chan); |
4142 | __set_chan_timer(chan, HZ / 10); | 4069 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); |
4143 | } | 4070 | } |
4144 | } else if (chan->state == BT_CONNECT2) { | 4071 | } else if (chan->state == BT_CONNECT2) { |
4145 | struct l2cap_conn_rsp rsp; | 4072 | struct l2cap_conn_rsp rsp; |
@@ -4159,7 +4086,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
4159 | } | 4086 | } |
4160 | } else { | 4087 | } else { |
4161 | l2cap_state_change(chan, BT_DISCONN); | 4088 | l2cap_state_change(chan, BT_DISCONN); |
4162 | __set_chan_timer(chan, HZ / 10); | 4089 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); |
4163 | res = L2CAP_CR_SEC_BLOCK; | 4090 | res = L2CAP_CR_SEC_BLOCK; |
4164 | stat = L2CAP_CS_NO_INFO; | 4091 | stat = L2CAP_CS_NO_INFO; |
4165 | } | 4092 | } |