-
Notifications
You must be signed in to change notification settings - Fork 173
Description
Hi, in 47daf80 I changed the USBStreamOutEndpoint
endpoint to give a transfer oriented stream rather than a packet oriented stream, but there are a couple of corner cases that it still doesn't handle correctly.
The first one is a transfer consisting of one or more full packets; it doesn't know which packet is the last packet before the terminating ZLP arrives, and by that time the last byte of the transfer is already on the stream (or in the FIFO) without the last
flag set.
The simple and obvious solution would be to hold back the last byte of a full packet until the next packet arrives, so the last
flag can be correctly determined, but this can potentially cause issues with bytestream pipes like ACM, where some hosts will happily send you a series of full packets without following up with a ZLP.
Another corner case is zero length transfers -- with zero bytes of data, they would cause zero stream transfers and effectively get blackholed.
To solve both these cases, I propose adding a data mask to StreamInterface
. A zero length transfer can then be signalled as a single stream transfer with first=1, last=1, mask=0
, and a ZLP arriving after a full packet can terminate the ongoing transfer with last=1, mask=0
.
To make the stream easier for consumers to work with, I also propose a couple of stream filters that strips out transfers with mask=0
:
- A simple one that just does
valid = valid & mask
for consumers that doesn't care about transfer boundaries. - A buffered one that holds one byte back until it gets the
last
flag.
The mask field can also serve a dual purpose as a byte mask for a multibyte stream.