diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2010-05-01 15:15:38 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2010-05-10 03:28:47 -0400 |
commit | e072745f4adb01b909bd08a0cfc8f79348f4d2c6 (patch) | |
tree | 4c7edad6e6da11971c6057bacdf0943333777be6 | |
parent | 73edaa9933219e25d6733b78d1e2c881025705e2 (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>
-rw-r--r-- | net/bluetooth/l2cap.c | 204 |
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 | ||
3478 | static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb) | 3478 | static 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); | 3516 | static 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 | } | ||
3545 | static 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 | |||
3576 | static 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 | |||
3592 | static 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 | ||