aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMat Martineau <mathewm@codeaurora.org>2012-05-17 23:53:42 -0400
committerJohan Hedberg <johan.hedberg@intel.com>2012-06-04 23:34:03 -0400
commitd2a7ac5d5d3a0b166ac128883bd088064c029fe5 (patch)
treeb6a03c938d1ac579a5fd8f7a6095441e9c4505eb
parente31f76337257616aca0ea15abee271513b17426c (diff)
Bluetooth: Add the ERTM receive state machine
This adds a top-level state machine with handlers for two receive states defined in the ERTM spec, RECV and SREJ_SENT. The reqseq value of the incoming frame is also validated at the top level and a disconnection is forced if it is invalid. The actions for the RECV and SREJ_SENT states are implemented according to the state tables in the ERTM specification. Signed-off-by: Mat Martineau <mathewm@codeaurora.org> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
-rw-r--r--net/bluetooth/l2cap_core.c355
1 files changed, 353 insertions, 2 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index a7d96c937392..287d64cf2dd4 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1760,6 +1760,12 @@ static int l2cap_ertm_send(struct l2cap_chan *chan)
1760 return sent; 1760 return sent;
1761} 1761}
1762 1762
1763static void l2cap_retransmit_all(struct l2cap_chan *chan,
1764 struct l2cap_ctrl *control)
1765{
1766 /* Placeholder */
1767}
1768
1763static void l2cap_send_ack(struct l2cap_chan *chan) 1769static void l2cap_send_ack(struct l2cap_chan *chan)
1764{ 1770{
1765 struct l2cap_ctrl control; 1771 struct l2cap_ctrl control;
@@ -2127,6 +2133,21 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
2127 return err; 2133 return err;
2128} 2134}
2129 2135
2136static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
2137{
2138 /* Placeholder */
2139}
2140
2141static void l2cap_send_srej_tail(struct l2cap_chan *chan)
2142{
2143 /* Placeholder */
2144}
2145
2146static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
2147{
2148 /* Placeholder */
2149}
2150
2130static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq) 2151static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
2131{ 2152{
2132 struct sk_buff *acked_skb; 2153 struct sk_buff *acked_skb;
@@ -4327,6 +4348,24 @@ void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
4327 l2cap_tx(chan, 0, 0, event); 4348 l2cap_tx(chan, 0, 0, event);
4328} 4349}
4329 4350
4351static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
4352{
4353 /* Placeholder */
4354 return 0;
4355}
4356
4357static void l2cap_handle_srej(struct l2cap_chan *chan,
4358 struct l2cap_ctrl *control)
4359{
4360 /* Placeholder */
4361}
4362
4363static void l2cap_handle_rej(struct l2cap_chan *chan,
4364 struct l2cap_ctrl *control)
4365{
4366 /* Placeholder */
4367}
4368
4330static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq) 4369static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
4331{ 4370{
4332 BT_DBG("chan %p, txseq %d", chan, txseq); 4371 BT_DBG("chan %p, txseq %d", chan, txseq);
@@ -4414,11 +4453,323 @@ static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
4414 } 4453 }
4415} 4454}
4416 4455
4456static int l2cap_rx_state_recv(struct l2cap_chan *chan,
4457 struct l2cap_ctrl *control,
4458 struct sk_buff *skb, u8 event)
4459{
4460 int err = 0;
4461 bool skb_in_use = 0;
4462
4463 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4464 event);
4465
4466 switch (event) {
4467 case L2CAP_EV_RECV_IFRAME:
4468 switch (l2cap_classify_txseq(chan, control->txseq)) {
4469 case L2CAP_TXSEQ_EXPECTED:
4470 l2cap_pass_to_tx(chan, control);
4471
4472 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4473 BT_DBG("Busy, discarding expected seq %d",
4474 control->txseq);
4475 break;
4476 }
4477
4478 chan->expected_tx_seq = __next_seq(chan,
4479 control->txseq);
4480
4481 chan->buffer_seq = chan->expected_tx_seq;
4482 skb_in_use = 1;
4483
4484 err = l2cap_reassemble_sdu(chan, skb, control);
4485 if (err)
4486 break;
4487
4488 if (control->final) {
4489 if (!test_and_clear_bit(CONN_REJ_ACT,
4490 &chan->conn_state)) {
4491 control->final = 0;
4492 l2cap_retransmit_all(chan, control);
4493 l2cap_ertm_send(chan);
4494 }
4495 }
4496
4497 if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
4498 l2cap_send_ack(chan);
4499 break;
4500 case L2CAP_TXSEQ_UNEXPECTED:
4501 l2cap_pass_to_tx(chan, control);
4502
4503 /* Can't issue SREJ frames in the local busy state.
4504 * Drop this frame, it will be seen as missing
4505 * when local busy is exited.
4506 */
4507 if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
4508 BT_DBG("Busy, discarding unexpected seq %d",
4509 control->txseq);
4510 break;
4511 }
4512
4513 /* There was a gap in the sequence, so an SREJ
4514 * must be sent for each missing frame. The
4515 * current frame is stored for later use.
4516 */
4517 skb_queue_tail(&chan->srej_q, skb);
4518 skb_in_use = 1;
4519 BT_DBG("Queued %p (queue len %d)", skb,
4520 skb_queue_len(&chan->srej_q));
4521
4522 clear_bit(CONN_SREJ_ACT, &chan->conn_state);
4523 l2cap_seq_list_clear(&chan->srej_list);
4524 l2cap_send_srej(chan, control->txseq);
4525
4526 chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
4527 break;
4528 case L2CAP_TXSEQ_DUPLICATE:
4529 l2cap_pass_to_tx(chan, control);
4530 break;
4531 case L2CAP_TXSEQ_INVALID_IGNORE:
4532 break;
4533 case L2CAP_TXSEQ_INVALID:
4534 default:
4535 l2cap_send_disconn_req(chan->conn, chan,
4536 ECONNRESET);
4537 break;
4538 }
4539 break;
4540 case L2CAP_EV_RECV_RR:
4541 l2cap_pass_to_tx(chan, control);
4542 if (control->final) {
4543 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4544
4545 if (!test_and_clear_bit(CONN_REJ_ACT,
4546 &chan->conn_state)) {
4547 control->final = 0;
4548 l2cap_retransmit_all(chan, control);
4549 }
4550
4551 l2cap_ertm_send(chan);
4552 } else if (control->poll) {
4553 l2cap_send_i_or_rr_or_rnr(chan);
4554 } else {
4555 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4556 &chan->conn_state) &&
4557 chan->unacked_frames)
4558 __set_retrans_timer(chan);
4559
4560 l2cap_ertm_send(chan);
4561 }
4562 break;
4563 case L2CAP_EV_RECV_RNR:
4564 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4565 l2cap_pass_to_tx(chan, control);
4566 if (control && control->poll) {
4567 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4568 l2cap_send_rr_or_rnr(chan, 0);
4569 }
4570 __clear_retrans_timer(chan);
4571 l2cap_seq_list_clear(&chan->retrans_list);
4572 break;
4573 case L2CAP_EV_RECV_REJ:
4574 l2cap_handle_rej(chan, control);
4575 break;
4576 case L2CAP_EV_RECV_SREJ:
4577 l2cap_handle_srej(chan, control);
4578 break;
4579 default:
4580 break;
4581 }
4582
4583 if (skb && !skb_in_use) {
4584 BT_DBG("Freeing %p", skb);
4585 kfree_skb(skb);
4586 }
4587
4588 return err;
4589}
4590
4591static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
4592 struct l2cap_ctrl *control,
4593 struct sk_buff *skb, u8 event)
4594{
4595 int err = 0;
4596 u16 txseq = control->txseq;
4597 bool skb_in_use = 0;
4598
4599 BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
4600 event);
4601
4602 switch (event) {
4603 case L2CAP_EV_RECV_IFRAME:
4604 switch (l2cap_classify_txseq(chan, txseq)) {
4605 case L2CAP_TXSEQ_EXPECTED:
4606 /* Keep frame for reassembly later */
4607 l2cap_pass_to_tx(chan, control);
4608 skb_queue_tail(&chan->srej_q, skb);
4609 skb_in_use = 1;
4610 BT_DBG("Queued %p (queue len %d)", skb,
4611 skb_queue_len(&chan->srej_q));
4612
4613 chan->expected_tx_seq = __next_seq(chan, txseq);
4614 break;
4615 case L2CAP_TXSEQ_EXPECTED_SREJ:
4616 l2cap_seq_list_pop(&chan->srej_list);
4617
4618 l2cap_pass_to_tx(chan, control);
4619 skb_queue_tail(&chan->srej_q, skb);
4620 skb_in_use = 1;
4621 BT_DBG("Queued %p (queue len %d)", skb,
4622 skb_queue_len(&chan->srej_q));
4623
4624 err = l2cap_rx_queued_iframes(chan);
4625 if (err)
4626 break;
4627
4628 break;
4629 case L2CAP_TXSEQ_UNEXPECTED:
4630 /* Got a frame that can't be reassembled yet.
4631 * Save it for later, and send SREJs to cover
4632 * the missing frames.
4633 */
4634 skb_queue_tail(&chan->srej_q, skb);
4635 skb_in_use = 1;
4636 BT_DBG("Queued %p (queue len %d)", skb,
4637 skb_queue_len(&chan->srej_q));
4638
4639 l2cap_pass_to_tx(chan, control);
4640 l2cap_send_srej(chan, control->txseq);
4641 break;
4642 case L2CAP_TXSEQ_UNEXPECTED_SREJ:
4643 /* This frame was requested with an SREJ, but
4644 * some expected retransmitted frames are
4645 * missing. Request retransmission of missing
4646 * SREJ'd frames.
4647 */
4648 skb_queue_tail(&chan->srej_q, skb);
4649 skb_in_use = 1;
4650 BT_DBG("Queued %p (queue len %d)", skb,
4651 skb_queue_len(&chan->srej_q));
4652
4653 l2cap_pass_to_tx(chan, control);
4654 l2cap_send_srej_list(chan, control->txseq);
4655 break;
4656 case L2CAP_TXSEQ_DUPLICATE_SREJ:
4657 /* We've already queued this frame. Drop this copy. */
4658 l2cap_pass_to_tx(chan, control);
4659 break;
4660 case L2CAP_TXSEQ_DUPLICATE:
4661 /* Expecting a later sequence number, so this frame
4662 * was already received. Ignore it completely.
4663 */
4664 break;
4665 case L2CAP_TXSEQ_INVALID_IGNORE:
4666 break;
4667 case L2CAP_TXSEQ_INVALID:
4668 default:
4669 l2cap_send_disconn_req(chan->conn, chan,
4670 ECONNRESET);
4671 break;
4672 }
4673 break;
4674 case L2CAP_EV_RECV_RR:
4675 l2cap_pass_to_tx(chan, control);
4676 if (control->final) {
4677 clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4678
4679 if (!test_and_clear_bit(CONN_REJ_ACT,
4680 &chan->conn_state)) {
4681 control->final = 0;
4682 l2cap_retransmit_all(chan, control);
4683 }
4684
4685 l2cap_ertm_send(chan);
4686 } else if (control->poll) {
4687 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4688 &chan->conn_state) &&
4689 chan->unacked_frames) {
4690 __set_retrans_timer(chan);
4691 }
4692
4693 set_bit(CONN_SEND_FBIT, &chan->conn_state);
4694 l2cap_send_srej_tail(chan);
4695 } else {
4696 if (test_and_clear_bit(CONN_REMOTE_BUSY,
4697 &chan->conn_state) &&
4698 chan->unacked_frames)
4699 __set_retrans_timer(chan);
4700
4701 l2cap_send_ack(chan);
4702 }
4703 break;
4704 case L2CAP_EV_RECV_RNR:
4705 set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
4706 l2cap_pass_to_tx(chan, control);
4707 if (control->poll) {
4708 l2cap_send_srej_tail(chan);
4709 } else {
4710 struct l2cap_ctrl rr_control;
4711 memset(&rr_control, 0, sizeof(rr_control));
4712 rr_control.sframe = 1;
4713 rr_control.super = L2CAP_SUPER_RR;
4714 rr_control.reqseq = chan->buffer_seq;
4715 l2cap_send_sframe(chan, &rr_control);
4716 }
4717
4718 break;
4719 case L2CAP_EV_RECV_REJ:
4720 l2cap_handle_rej(chan, control);
4721 break;
4722 case L2CAP_EV_RECV_SREJ:
4723 l2cap_handle_srej(chan, control);
4724 break;
4725 }
4726
4727 if (skb && !skb_in_use) {
4728 BT_DBG("Freeing %p", skb);
4729 kfree_skb(skb);
4730 }
4731
4732 return err;
4733}
4734
4735static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
4736{
4737 /* Make sure reqseq is for a packet that has been sent but not acked */
4738 u16 unacked;
4739
4740 unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
4741 return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
4742}
4743
4417static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, 4744static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
4418 struct sk_buff *skb, u8 event) 4745 struct sk_buff *skb, u8 event)
4419{ 4746{
4420 /* Placeholder */ 4747 int err = 0;
4421 return -ENOTSUPP; 4748
4749 BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
4750 control, skb, event, chan->rx_state);
4751
4752 if (__valid_reqseq(chan, control->reqseq)) {
4753 switch (chan->rx_state) {
4754 case L2CAP_RX_STATE_RECV:
4755 err = l2cap_rx_state_recv(chan, control, skb, event);
4756 break;
4757 case L2CAP_RX_STATE_SREJ_SENT:
4758 err = l2cap_rx_state_srej_sent(chan, control, skb,
4759 event);
4760 break;
4761 default:
4762 /* shut it down */
4763 break;
4764 }
4765 } else {
4766 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
4767 control->reqseq, chan->next_tx_seq,
4768 chan->expected_ack_seq);
4769 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
4770 }
4771
4772 return err;
4422} 4773}
4423 4774
4424static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, 4775static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,