Skip to content
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

sys/net/nanocoap: Add CoAP over TCP support #21048

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from

Conversation

maribu
Copy link
Member

@maribu maribu commented Nov 26, 2024

Contribution description

This PR adds CoAP over TCP support to nanocoap. It is still work in progress, with many rough edges. This will get updated and filled in with more details as the PR evolves.

Testing procedure

Run sudo ./dist/tools/tapsetup/tapsetup

Server

NETWORK_STACK=lwip make BOARD=native -C examples/nanocoap_server -j && ./examples/nanocoap_server/bin/native/nanocoap_server.elf -w tap1

Wait for the IPv6 address to show up

Client

USEMODULE=nanocoap_tcp make BOARD=native -C tests/net/nanocoap_cli all flash term -j

Then in the RIOT shell run e.g.

url get coap+tcp://[fe80::24de:d0ff:fe85:bdb2]/riot/ver

Issues/PRs references

Depends on and includes: #20900

@github-actions github-actions bot added Area: network Area: Networking Area: tests Area: tests and testing framework Area: build system Area: Build system Area: pkg Area: External package ports Area: CoAP Area: Constrained Application Protocol implementations Area: sys Area: System Area: examples Area: Example Applications labels Nov 26, 2024
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
@maribu maribu force-pushed the sys/net/nanocoap/transport-tcp branch from f4aa45f to ec3b453 Compare December 17, 2024 09:28
In TCP server mode, the sock_tcp_t sockets are managed by the network
stack and can be reused if a previous connection is no longer in used.
However, an event may still be posted in the event queue when the socket
is reused. Wiping it will result in the `next` pointer in that event to
be NULL, which will cause the event handler fetching that event to
crash.

This adds an `event_cancel()` at two places:
1. Just before reusing the socket
2. During sock_tcp_disconnect()

The former catches issues in server mode e.g. when a connect has been
closed (e.g. due to timeout) and is reused before a pending event (e.g.
a timeout event) has been processed.

The letter may be an issue on client side. E.g. when `sock_tcp_t` was
allocated on stack and goes out of scope after `sock_tcp_disconnect`
but before the event handler was run.
This changes the Makefile to easily setup lwIP as network stack, while
keeping GNRC as the default.

If lwIP is used on one of the larger boards, the app will be build with
CoAP over TCP support enabled.
We need to clear `event->next` while IRQs are still disabled to
avoid another thread from calling `event_cancel()` just in-between.
@maribu maribu force-pushed the sys/net/nanocoap/transport-tcp branch from ec3b453 to 765fdf1 Compare December 17, 2024 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: build system Area: Build system Area: CoAP Area: Constrained Application Protocol implementations Area: examples Area: Example Applications Area: network Area: Networking Area: pkg Area: External package ports Area: sys Area: System Area: tests Area: tests and testing framework
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant