L2CAP Extended Features on 2.6.36

On October 20th, Linus released the 2.6.36 kernel and one of the new features released with it was the support in the Linux Bluetooth stack for the L2CAP Extended Features. Also called eL2CAP, the L2CAP Extended Features add some new features to the L2CAP layer, like the Enhanced Retransmission Mode(ERTM), a reliable protocol with error and flow control; the Streaming Mode, an unreliable protocol for streaming purpouses; the Frame Check Sequence, a checksum for each received packet; and Segmentation and Reassembly of L2CAP packets which make retransmission easier. The L2CAP Extended Features were in the kernel before, but in an experimental mode and disabled by default.

Other Bluetooth changes in 2.6.36: In-kernel blacklist for incoming connections, that allow dropping selected incoming connections in kernel space without having to wake up bluetoothd. Support for the Atheros AR300x chip. A new hci_recv_stream_fragment() function which is part of a refactory in the HCI recv path to make the life of some drivers easier.

Now git tree hosted at kernel.org

Some days ago I requested  a account to the kernel.org admins, today I finished to setup my kernel git tree there.  If you were following my git tree at git.profusion.mobi please change your remote to the kernel.org one.

git clone git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-testing.git

You can also browse on the gitweb view here. =)

L2CAP Extended Features

Here at ProFUSION I’m working to finish the L2CAP Extended Features introduced in the Core Specification Addendum 1 of the Bluetooth Specification. As you can see in older posts in this blog I have started that implementation by myself during the last year’s Google Summer of Code. The project was too big and I wasn’t able to finish it in 3 months.

The L2CAP Extended Features comprehends the Enhanced Retransmission Mode (ERTM), Streaming Mode, Segmentation and Reassembly, and Frame Check Sequence(FCS).

During the last month I worked to complete the ERTM state machine. All the events and its respective actions were coded. Unfortunately that doesn’t mean that it has no bugs.  Now it is time to run a lots of tests on the code to check  if it is working as specified and fix all the issues we found.

If you want to help testing just clone my git tree and enable the Kconfig option for the L2CAP Extended Features and if you have any suggestion, bug report or patch don’t hesitate in contact me. :)

The git tree is hosted here and you can clone it directly with this line:

git clone git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-testing.git

I expect that soon this work will be merged into the bluetooth-testing tree and then it will be available on the 2.6.35 kernel as an experimental work.

UPDATE:  changed the git tree url.

BlueZ: status update into the L2CAP layer

Since the last post here (it was a long time ago :-) too much work was done, but ERTM isn’t fully implemented yet. So, what did I do last month?
I’ll explain each of the features I implemented on the next paragraphs, but if this are boring for you just take a look at the roadmap at the end of this post.

First I did the support to send and receive I-frames (the data frames) and created the support to RR S-frames to acknowledge the received I-frames. It first worked with a txWindow=1 (which means only one packet can be send without receive acknowledge from the receiver side). The next step was support a txWindow up to 63 (the maximum value specified). To bring this support I have been using sk_buff lists from the net core implementation.

Support for Segmentation and Reassembly(SAR) of L2CAP SDUs: this feature allows upper applications to use a buffer greater than the L2CAP size packet. The buffer is break down in many packet on the transmitter side and then reassembled on the receiver side and pushed to the upper layer.

REJ frame exception: When a packet is lost we need to start the recoveries procedures. BlueZ won’t support raise of REJ exception (we support only raise of SREJ exception by now, spec says that we can choose one of them). But we need to support the receipt of a REJ-exception (i.e. receive a REJ frame). On the receipt of a REJ frame the L2CAP entity needs to stop the transmission and starts to retransmit the requested packets.  A REJ frame tells the ReqSeq(packet id sequence) and all packets up to ReqSeq – 1 shall be considered acknowledged, the others shall be retransmitted.

SREJ frame exception: BlueZ starts a SREJ exception when it detects lost packets. It sets its state to SREJ_SENT(It means that L2CAP entity is under recovery proccess) and sends a SREJ S-frame for each lost packets. The transmitter side shall resend the packets requested in the SREJ frames without stops transmission of new frames. SREJ exception saves retransmission of unneeded frames.

Retransmission And Monitor Timers: The Retransmission Timer shall be (re)started each time we send a I-frame. If it expires we send a RR-frame and start the Monitor Timer. The other side should response the RR frame immediately, if the the other side do not response and the Monitor Timer expires we resend the RR frame. A maximum value for the of Monitor Timer’s timeouts can be defined. If a L2CAP entity exceeds this value the channel shall be disconnected.

Busy condition on the remote side: If the remote side enters in a busy condition it will send a RNR frame. So, when the local side receives this frame it should mark the remote busy flag as true and stop the transmission of packets. It restarts the sending of packets only when the remote sides send a REJ, SREJ or RR frame. This says the remote busy condition was cleared.

Streaming mode: This mode of operation is useful to the Bluetooth Streaming Profiles such as A2DP and VDP(not yet implemented). It can take advantages of the Segmentation and Reassembly features.

FCS Option: It is a crc16 check for L2CAP packets. It is the default if both sides support it. If a L2CAP entity receives a packet with a broken crc16 it will drop. The receive procedure will miss it and start the recovery procedure.

Roadmap updated:

  1. Implement ERTM with txWindow=1 and retransmission disabled.
    1. send I-frames
    2. receive I-frames
    3. support RR S-frames to acknowledge I-frames received
    4. acknowledge I-frames
  2. Support txWindow up to 63
  3. Support segmentation and reassembly of L2CAP SDUs
  4. Enable retransmission
    1. support receipt REJ S-Frame
    2. support receipt SREJ S-Frame
    3. support raise of SREJ exception
  5. Support busy conditions exceptions
  6. Enable Retransmission Timer
  7. Enable Monitor Timer
  8. Implement Streaming Mode
  9. Implement FCS Option
  10. Support duplex channel
  11. Use SOCK_STREAM as default for Enhanced Retransmission and Streaming Modes.
  12. Test BlueZ against others stacks

What’s next?

Now I’m working the busy condition exception and the support for the ERTM duplex channel. Today, just one side can send data packets. Then I’ll put ERTM as default when SOCK_STREAM is selected. I expect finish these issues on the coming weeks. After, I’ll spend my time fixing the bugs I find trough the code.

ps: Sorry for my too not bad English ;-)