aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2010-05-01 15:15:38 -0400
committerMarcel Holtmann <marcel@holtmann.org>2010-05-10 03:28:47 -0400
commite072745f4adb01b909bd08a0cfc8f79348f4d2c6 (patch)
tree4c7edad6e6da11971c6057bacdf0943333777be6 /net/bluetooth
parent73edaa9933219e25d6733b78d1e2c881025705e2 (diff)
Bluetooth: Split l2cap_data_channel_sframe()
Create a function for each type fo S-frame and avoid a lot of nested code. Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi> Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/l2cap.c204
1 files changed, 115 insertions, 89 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index e5cd64ac6fb2..068edf7704bf 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3475,120 +3475,146 @@ expected:
3475 return 0; 3475 return 0;
3476} 3476}
3477 3477
3478static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb) 3478static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control)
3479{ 3479{
3480 struct l2cap_pinfo *pi = l2cap_pi(sk); 3480 struct l2cap_pinfo *pi = l2cap_pi(sk);
3481 u8 tx_seq = __get_reqseq(rx_control); 3481 u8 tx_seq = __get_reqseq(rx_control);
3482 3482
3483 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len); 3483 if (rx_control & L2CAP_CTRL_POLL) {
3484 3484 l2cap_send_i_or_rr_or_rnr(sk);
3485 if (L2CAP_CTRL_FINAL & rx_control) { 3485 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3486 del_timer(&pi->monitor_timer);
3487 if (pi->unacked_frames > 0)
3488 __mod_retrans_timer();
3489 pi->conn_state &= ~L2CAP_CONN_WAIT_F;
3490 }
3491 3486
3492 switch (rx_control & L2CAP_CTRL_SUPERVISE) { 3487 } else if (rx_control & L2CAP_CTRL_FINAL) {
3493 case L2CAP_SUPER_RCV_READY: 3488 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3494 if (rx_control & L2CAP_CTRL_POLL) { 3489 pi->expected_ack_seq = tx_seq;
3495 l2cap_send_i_or_rr_or_rnr(sk); 3490 l2cap_drop_acked_frames(sk);
3496 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3497
3498 } else if (rx_control & L2CAP_CTRL_FINAL) {
3499 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3500 pi->expected_ack_seq = tx_seq;
3501 l2cap_drop_acked_frames(sk);
3502
3503 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3504 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3505 else {
3506 sk->sk_send_head = TX_QUEUE(sk)->next;
3507 pi->next_tx_seq = pi->expected_ack_seq;
3508 l2cap_ertm_send(sk);
3509 }
3510 3491
3511 } else { 3492 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3512 pi->expected_ack_seq = tx_seq; 3493 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3513 l2cap_drop_acked_frames(sk); 3494 else {
3495 sk->sk_send_head = TX_QUEUE(sk)->next;
3496 pi->next_tx_seq = pi->expected_ack_seq;
3497 l2cap_ertm_send(sk);
3498 }
3514 3499
3515 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && 3500 } else {
3516 (pi->unacked_frames > 0)) 3501 pi->expected_ack_seq = tx_seq;
3517 __mod_retrans_timer(); 3502 l2cap_drop_acked_frames(sk);
3518 3503
3519 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; 3504 if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
3520 if (pi->conn_state & L2CAP_CONN_SREJ_SENT) 3505 (pi->unacked_frames > 0))
3521 l2cap_send_ack(pi); 3506 __mod_retrans_timer();
3522 else
3523 l2cap_ertm_send(sk);
3524 }
3525 break;
3526 3507
3527 case L2CAP_SUPER_REJECT:
3528 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; 3508 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3509 if (pi->conn_state & L2CAP_CONN_SREJ_SENT)
3510 l2cap_send_ack(pi);
3511 else
3512 l2cap_ertm_send(sk);
3513 }
3514}
3529 3515
3530 pi->expected_ack_seq = __get_reqseq(rx_control); 3516static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control)
3531 l2cap_drop_acked_frames(sk); 3517{
3518 struct l2cap_pinfo *pi = l2cap_pi(sk);
3519 u8 tx_seq = __get_reqseq(rx_control);
3532 3520
3533 if (rx_control & L2CAP_CTRL_FINAL) { 3521 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3534 if (pi->conn_state & L2CAP_CONN_REJ_ACT) 3522
3535 pi->conn_state &= ~L2CAP_CONN_REJ_ACT; 3523 pi->expected_ack_seq = __get_reqseq(rx_control);
3536 else { 3524 l2cap_drop_acked_frames(sk);
3537 sk->sk_send_head = TX_QUEUE(sk)->next; 3525
3538 pi->next_tx_seq = pi->expected_ack_seq; 3526 if (rx_control & L2CAP_CTRL_FINAL) {
3539 l2cap_ertm_send(sk); 3527 if (pi->conn_state & L2CAP_CONN_REJ_ACT)
3540 } 3528 pi->conn_state &= ~L2CAP_CONN_REJ_ACT;
3541 } else { 3529 else {
3542 sk->sk_send_head = TX_QUEUE(sk)->next; 3530 sk->sk_send_head = TX_QUEUE(sk)->next;
3543 pi->next_tx_seq = pi->expected_ack_seq; 3531 pi->next_tx_seq = pi->expected_ack_seq;
3544 l2cap_ertm_send(sk); 3532 l2cap_ertm_send(sk);
3545
3546 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3547 pi->srej_save_reqseq = tx_seq;
3548 pi->conn_state |= L2CAP_CONN_REJ_ACT;
3549 }
3550 } 3533 }
3534 } else {
3535 sk->sk_send_head = TX_QUEUE(sk)->next;
3536 pi->next_tx_seq = pi->expected_ack_seq;
3537 l2cap_ertm_send(sk);
3551 3538
3552 break; 3539 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3540 pi->srej_save_reqseq = tx_seq;
3541 pi->conn_state |= L2CAP_CONN_REJ_ACT;
3542 }
3543 }
3544}
3545static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control)
3546{
3547 struct l2cap_pinfo *pi = l2cap_pi(sk);
3548 u8 tx_seq = __get_reqseq(rx_control);
3553 3549
3554 case L2CAP_SUPER_SELECT_REJECT: 3550 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3555 pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
3556 3551
3557 if (rx_control & L2CAP_CTRL_POLL) { 3552 if (rx_control & L2CAP_CTRL_POLL) {
3558 pi->expected_ack_seq = tx_seq; 3553 pi->expected_ack_seq = tx_seq;
3559 l2cap_drop_acked_frames(sk); 3554 l2cap_drop_acked_frames(sk);
3560 l2cap_retransmit_frame(sk, tx_seq); 3555 l2cap_retransmit_frame(sk, tx_seq);
3561 l2cap_ertm_send(sk); 3556 l2cap_ertm_send(sk);
3562 if (pi->conn_state & L2CAP_CONN_WAIT_F) { 3557 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3563 pi->srej_save_reqseq = tx_seq; 3558 pi->srej_save_reqseq = tx_seq;
3564 pi->conn_state |= L2CAP_CONN_SREJ_ACT; 3559 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3565 }
3566 } else if (rx_control & L2CAP_CTRL_FINAL) {
3567 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3568 pi->srej_save_reqseq == tx_seq)
3569 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
3570 else
3571 l2cap_retransmit_frame(sk, tx_seq);
3572 } 3560 }
3573 else { 3561 } else if (rx_control & L2CAP_CTRL_FINAL) {
3562 if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
3563 pi->srej_save_reqseq == tx_seq)
3564 pi->conn_state &= ~L2CAP_CONN_SREJ_ACT;
3565 else
3574 l2cap_retransmit_frame(sk, tx_seq); 3566 l2cap_retransmit_frame(sk, tx_seq);
3575 if (pi->conn_state & L2CAP_CONN_WAIT_F) { 3567 } else {
3576 pi->srej_save_reqseq = tx_seq; 3568 l2cap_retransmit_frame(sk, tx_seq);
3577 pi->conn_state |= L2CAP_CONN_SREJ_ACT; 3569 if (pi->conn_state & L2CAP_CONN_WAIT_F) {
3578 } 3570 pi->srej_save_reqseq = tx_seq;
3571 pi->conn_state |= L2CAP_CONN_SREJ_ACT;
3579 } 3572 }
3573 }
3574}
3575
3576static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control)
3577{
3578 struct l2cap_pinfo *pi = l2cap_pi(sk);
3579 u8 tx_seq = __get_reqseq(rx_control);
3580
3581 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
3582 pi->expected_ack_seq = tx_seq;
3583 l2cap_drop_acked_frames(sk);
3584
3585 del_timer(&pi->retrans_timer);
3586 if (rx_control & L2CAP_CTRL_POLL) {
3587 u16 control = L2CAP_CTRL_FINAL;
3588 l2cap_send_rr_or_rnr(pi, control);
3589 }
3590}
3591
3592static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
3593{
3594 BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
3595
3596 if (L2CAP_CTRL_FINAL & rx_control) {
3597 del_timer(&l2cap_pi(sk)->monitor_timer);
3598 if (l2cap_pi(sk)->unacked_frames > 0)
3599 __mod_retrans_timer();
3600 l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F;
3601 }
3602
3603 switch (rx_control & L2CAP_CTRL_SUPERVISE) {
3604 case L2CAP_SUPER_RCV_READY:
3605 l2cap_data_channel_rrframe(sk, rx_control);
3580 break; 3606 break;
3581 3607
3582 case L2CAP_SUPER_RCV_NOT_READY: 3608 case L2CAP_SUPER_REJECT:
3583 pi->conn_state |= L2CAP_CONN_REMOTE_BUSY; 3609 l2cap_data_channel_rejframe(sk, rx_control);
3584 pi->expected_ack_seq = tx_seq; 3610 break;
3585 l2cap_drop_acked_frames(sk);
3586 3611
3587 del_timer(&pi->retrans_timer); 3612 case L2CAP_SUPER_SELECT_REJECT:
3588 if (rx_control & L2CAP_CTRL_POLL) { 3613 l2cap_data_channel_srejframe(sk, rx_control);
3589 u16 control = L2CAP_CTRL_FINAL; 3614 break;
3590 l2cap_send_rr_or_rnr(pi, control); 3615
3591 } 3616 case L2CAP_SUPER_RCV_NOT_READY:
3617 l2cap_data_channel_rnrframe(sk, rx_control);
3592 break; 3618 break;
3593 } 3619 }
3594 3620