opengitway / btstack

Automatically exported from code.google.com/p/btstack
0 stars 0 forks source link

L2CAP fragmentation and recombination #381

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
as of r2352

I don't see any automatic fragmentation done on L2CAP, it would be nice to have.

I am expecting to send and receive 700-800 byte packets in my application, and 
it seems like my RN-42 only supports a local buffer of 310 bytes

I will implement this myself and submit a patch when I am done

I am unsure how to do this in a way that is friendly to developers. Because of 
the way that the transport data source works, I can't simply add a loop to send 
all the fragments. If I wait for "can send next packet", I also need to 
constantly check if the previous ACL has been sent. However, there is no way 
for me to access execute_once, or access the transport->data_source->process, 
so the wait-loop will freeze.

Another option is to queue up the fragment. The user can then check if a 
fragment is waiting on the next packet complete event, or even make it automatic

For receiving fragmented packets, I suggest adding "L2CAP_DATA_PACKET_START" 
and "L2CAP_DATA_PACKET_FRAGMENT" as additional packet types, so the user's 
packet handler can distinguish between them

Original issue reported on code.google.com by frank.zhao.main@gmail.com on 6 Feb 2014 at 6:30

GoogleCodeExporter commented 9 years ago
short overview: BTstack does recombination up to the size of ACL packets. So 
even if your RN42 only has 310 bytes ACL buffered, BTstack will deliver a 
complete L2CAP packet up to whatever you've configured as packet size. 

It doesn't do fragmentation though. If you use 1021 bytes as ACL packets, it 
allows for 1+ kB L2CAP packets which is above the default MTU of 672 (or  so) 
and I haven't seen a service, maybe aside from BNEP, that requires larger MTUs.

Adding fragmentation wouldn't be too hard to do under the assumption that the 
data provided by the app needs to be available until a "l2cap data packet sent" 
event is received. Then, l2cap could fragment and send the fragments one by one 
with only a few extra bytes in the l2cap channel struct.

Fragmentation isn't that hard to implement. BTstack assumes that the data for 
an L2CAP is available until the packet is sent and a DAEMON_EVENT_PAKCET_SENT 
event was received (that might be not as clear.
Or.. if your data stays within the size of a packet buffer, that buffer could 
also be sent in fragments without further changes to the expected behavior. (so 
this is clearly welcome.. although modern chipset have the max ACL buffers)

I can see the need for l2cap packet fragments but also are worried about the 
additional complexity and the fact that I don't see many cases where these 
fragments could be used without recombining them first.

Where do you need 700-800 bytes packets btw?

Original comment by matthias.ringwald@gmail.com on 6 Feb 2014 at 1:06

GoogleCodeExporter commented 9 years ago
The SDP packet used by the DualShock 4 is 717 bytes

I've made changes to your code that simply keeps track of another index in the 
acl_buffer array, such that the entire buffer is written once and only once, 
and the fragmentation is done automatically. The user is not allowed to 
overwrite the buffer until all fragments have been sent.

This only works in my single threaded system with only one or two tightly 
controlled connections. It also does not handle errors or disconnections yet.

Original comment by frank.zhao.main@gmail.com on 6 Feb 2014 at 2:53

GoogleCodeExporter commented 9 years ago
Well. Large SDP records are fine. SDP was designed to work with less than the 
minimal MTU of 48 bytes as it allows the SDP server to respond "here's the 
first 50 of your answer, if you wan the rest, ask me again and tell me to use 
offset 50". BTstack implements that fully, so you don't need to do anything to 
server large SDP records.

Original comment by matthias.ringwald@gmail.com on 6 Feb 2014 at 6:13

GoogleCodeExporter commented 9 years ago
BTstack supports packet fragmentation since Fall 2014 and it has been tested 
exensively with both sync and async transport, closing this.

Original comment by matthias.ringwald@gmail.com on 15 Jan 2015 at 3:42