-
Notifications
You must be signed in to change notification settings - Fork 2.1k
sys/net/*coap: Make APIs (more) transport agnostic #20900
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
base: master
Are you sure you want to change the base?
sys/net/*coap: Make APIs (more) transport agnostic #20900
Conversation
|
This PR is not ready for review yet, I just want to make the work more transparent. |
99877b3 to
d832957
Compare
c13f6d0 to
34b0d34
Compare
|
Could the Then users who just upgrade their applications would see a deprecation rather than breakage, and would just need to follow that deprecation's pointers ("use the setters and getters") before either they go to the next release or they enable any of the new modules. The Rust wrappers (affected in RIOT-OS/rust-riot-wrappers#129) could then do the same: use the old ways unless a new module is enabled, and after the next release they can go all-in with the new accessor, and thus always work with the current release and with the mai^Wmaster branch. |
|
To clarify: If it's only the Rust wrappers affected, workarounds are possible (but necessary) to make things work there by detecting whether any code getter/setter is present. But if making it easier for riot-wrappers also eases other users' transitions, maybe we should do that. I can work with either outcome. |
I think adding an unnamed |
|
Yes, an unnamed union CI should probably not interfere here because that'd also impede the Rust side -- but after the next release, the old item can go away anyway, and then we're enforcing the deprecation. Until then I think we'll have to rely on people following the deprecation. |
6cc1b64 to
061ca01
Compare
ae84308 to
b03bb09
Compare
ecb9f9d to
ea5d544
Compare
benpicco
left a comment
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.
This is indeed least invasive and from what I gather has been tested with different transports already.
I'd say this still holds, doesn't it? |
|
I think it is quite clear that unicoap and nanocoap have sufficiently different use cases in mind that a leaner CoAP implementation remains useful. I can easily see unicoap replacing gcoap, but I don't see it replacing nanocoap. Im any case, this rather should not be rushed into the release. |
| * @returns 0 on success | ||
| * @returns <0 on error | ||
| * @return Number of bytes parsed (may not match @p len on stream | ||
| * transports) |
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.
This API change is actually not so benign.
Previously 0 would mean success, so code would check if (coap_parse(…)) {} as the error case.
Now we need to check if (coap_parse(…) <= 0) {}
This should at least be featured more prominently if no API compatibility is possible.
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.
This is indeed the main breaking change and highlighted as such in the PR description.
I think the fallout is pretty limited, though: User code will not really parse CoAP packets by hand, but rather use the CoAP server implementations and provide the resource handlers instead, which already will be called on fully parsed packets
|
This also appears to introduce some garbage into the CoAP request |
There seems to be a bug that needs fixing.
|
OK, we traced down the issue out of band and found it in #21048. The bug is not present in this PR. But given that a pretty obvious bug is not found by the unit tests indicates that we really should get the unit tests fixed first. |
ea5d544 to
50170f2
Compare
This changes the API of nanocoap with the goal to reduce the expose of
UDP specifics in the API. The plan is to eventually support transports
such as CoAP over TCP and CoAP over WebSocket directly in nanocoap
while sharing most of the code, as e.g. the CoAP Option processing
remains identical. Specifically, the plan is to unlock a transport with
modules and introduce overhead for dispatching to specific transport
only when multiple transports are actually in use.
Support for OSCORE directly in nanocoap is probably not sensible, as
the serialization is very much unlike the other transports. A unified
CoAP API for multiple transports including OSCORE is probably best
implemented on top. But when limited to the boring set of CoAP
transports, we probably can support them well with nanocoap with less
overhead.
Breaking API Changes:
=====================
- `coap_parse()` now returns `ssize_t` instead of `int`
- This function is not really user facing, so the impact should
be limited
- This is useful for stream transports where the buffer may
contain data of more than one packet. The return value contains
the number of bytes actually consumed, which will match the
buffer size for non-stream transports.
API Changes:
============
- `coap_pkt_t` now contains a `uint8_t *buf` pointer instead of a
`coap_hdr_t *hdr` pointer to the beginning of the buffer
- This will also work when the buffer is used by non-UDP
transports
- A deprecated `coap_udp_hdr_t *hdr` has been crammed into
an unnamed `union` with `uint8_t *buf`. For architectures
where pointers have the same memory layout regardless of type
(e.g. all of the supported ones), this will make `hdr` an
alias for `buf`.
- The alias will only be provided if no transport besides UDP is
used in nanocoap. So existing apps will continue to work, new
apps that want to support other transports need to move to
adapt.
- `coap_hdr_t` has been renamed to `coap_udp_hdr_t`
- A deprecated alias was created for deprecation
- `coap_hdr*()` functions have been deprecated
- Equivalent `coap_pkt*()` functions have been created that work
on `coap_pkt_t *` instead of `coap_hdr_t *`
- If non-UDP transports are used, the deprecated `coap_hdr*()`
will probably not be exposed to avoid footguns.
- `coap_build_hdr()` has been renamed to `coap_build_udp_hdr()` and
that works on an `uint8_t *` buffer with a given length, rather than
on a `coap_hdr_t *` with a *figers crossed* length
- a deprecated `coap_build_hdr()` function was added that calls
to `coap_build_udp_hdr()` and has the same signature, so that
users have time to update
50170f2 to
ce06c4f
Compare
Contribution description
This changes the API of nanocoap with the goal to reduce the expose of UDP specifics in the API. The plan is to eventually support transports such as CoAP over TCP and CoAP over WebSocket directly in nanocoap while sharing most of the code, as e.g. the CoAP Option processing remains identical. Specifically, the plan is to unlock a transport with modules and introduce overhead for dispatching to specific transport only when multiple transports are actually in use.
Support for OSCORE directly in nanocoap is probably not sensible, as the serialization is very much unlike the other transports. A unified CoAP API for multiple transports including OSCORE is probably best implemented on top. But when limited to the boring set of CoAP transports, we probably can support them well with nanocoap with less overhead.
API Changes:
Breaking API Changes:
coap_parse()now returnsssize_tinstead ofintAPI Changes:
coap_pkt_tnow contains auint8_t *bufpointer instead of acoap_hdr_t *hdrpointer to the beginning of the buffercoap_udp_hdr_t *hdrhas been crammed into an unnamedunionwithuint8_t *buf. For architectures where pointers have the same memory layout regardless of type (e.g. all of the supported ones), this will makehdran alias forbuf.coap_hdr_thas been renamed tocoap_udp_hdr_tcoap_hdr*()functions have been deprecatedcoap_pkt*()functions have been created that work oncoap_pkt_t *instead ofcoap_hdr_t *coap_hdr*()will probably not be exposed to avoid footguns.coap_build_hdr()has been renamed tocoap_build_udp_hdr()and that works on anuint8_t *buffer with a given length, rather than on acoap_hdr_t *with a figers crossed lengthcoap_build_hdr()function was added that calls tocoap_build_udp_hdr()and has the same signature, so that users have time to updateInternal users have been updated, except for tests.
The deprecated functions will probably exposed only when nanocoap is used with only UDP as transport, as those will wreak havoc on non-UDP CoAP packets. That should be fine, as existing apps hardly will make use of other transports anyway.
Testing procedure
Existing apps and tests should work as before. I will do some limited testing soon and do more rigorous testing once an implementation of nanocoap using TCP as transport is ready. Otherwise there are likely still UDP specifics in the API that I have overlooked.
Issues/PRs references
See also #20792