-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Ringbuf: fix PacketBuffer; clean up ringbuf implementation and use #2799
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The single subjob build failure is bogus: it's a job failure fetching dependencies. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think packet_size needs to be asymmetric because WRITES can be as long as the attribute length while NOTIFY is limited by the MTU. Based on the doc here it needs to be the larger of the two: https://github.com/adafruit/circuitpython/blob/master/shared-bindings/_bleio/PacketBuffer.c#L100
We'll want to validate that outgoing data fits into the mtu if NOTIFY is being used.
Overall, a very nice cleanup! Just a couple details to sort out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a few notes, but I think they're mostly because I lacked the context or (in one case) talking about a preexisting shortcoming that is not affected by this PR.
@tannewt I am adding
The logic for computing In either case we will need to update the libraries that use |
I don't think you will be able to raise an exception because a Connection object doesn't exist prior to it being established. How will you know the maximum amount of bytes you can read out? If you are a server with a write and notify characteristic, then a client could write more than the MTU to you even though you can only write an MTU back. |
Right, sorry, I was calling
That's a bit pathological (WRITE/NOTIFY vs the typical READ/NOTIFY), but I"m thinking the point of |
It's not pathological. That's how USB MIDI works. |
All right, I stand corrected. So I'm thinking that what one wants |
How about renaming it |
@tannewt OK, I think this is finally ready for review again. I decided not to rename This has been tested with BLE MIDI both out and in, with Also, taking a cue from @jepler (thanks!), I changed a bunch of makefile |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple questions about packet_size. Thanks for taking this on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few minor comments. Should be good to go shortly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for all of these fixes!
Whew, thanks! A lot of technical debt paid off, at the cost of too much time. |
ringbuf
usage inPacketBuffer
formerly would wrap around and overwrite an older packet on overflow, including its length field, which would cause a bad packet. Now an overflow simply drops the excess packet, preserving the older packets. (This is the bug that this PR is fixing.)In various UART implementations,
ringbuf
used to overwrite the oldest data with newer data if there was an overflow. Now excess new characters are simply dropped. Per @jepler, this is how Linux works, and is a better idea. This is a change in the semantics. But the old way was not documented, so I don't think we have to worry too much about changing this.ringbuf
used two indices to keep track of the last written and last read positions. In this kind of implementation, the capacity of ann
byte buffer isn-1
. The calling routines didn't know this, so they were actually allocating ann-1
ring buffer when they though they were allocatingn
slots. ForUART
this was not so critical, but forPacketBuffer
it made theringbuf
buffer too small.ringbuf
formerly was implemented solely as a set ofinline
routines and a macro inringbuf.h
.ringbuf.c
was added, and theinline
s inringbuf.h
were made regular C routines. The allocation macro was turned into a routine. We can rely on the compiler to do the inlining as needed.ringbuf
was used as a very leaky abstraction in a number of places. Various routines reached into its struct. New routines were added to add needed functionality, and all the calling code was fixed to respect the abstraction.Struct fields named
rbuf
were renamed toringbuf
for clarity.The
ringbuf
routines to read and write multiple bytes could be used in more places, and now are.The
m.iMX
implementation usedringbuf
to allocation a simple buffer. But i.MX has its own ringbuf routines, so usingringbuf
was unnecessary, and was changed to a simple alloc.ports/nrf/mpconfigport.mk
was not providing defaults for some build options. @jepler: take a look here. I didn't know about?=
in makefiles; we could probably simplify a bunch ofifdef
code later by using?=
, though I have not done that right now.PacketBuffer.packet_size
was rewritten to returnmin(packet size, mtu-3)
in all cases. When there is no connection, the default MTU size is used. @tannewt: take a look at this especially.