Skip to content

net/unicoap: Unified and Modular CoAP Stack: Resource Observation (pt 4)#22277

Draft
carl-tud wants to merge 23 commits into
RIOT-OS:masterfrom
carl-tud:unicoap-04-observation
Draft

net/unicoap: Unified and Modular CoAP Stack: Resource Observation (pt 4)#22277
carl-tud wants to merge 23 commits into
RIOT-OS:masterfrom
carl-tud:unicoap-04-observation

Conversation

@carl-tud
Copy link
Copy Markdown
Contributor

@carl-tud carl-tud commented May 11, 2026

This PR is the 4th in a series to introduce unicoap, a unified and modular CoAP implementation for RIOT. An overview of all PRs related to unicoap is presented in #21389, including reasons why unicoap is needed and a performance analysis.

What does this PR include?

  • Resource observation (RFC 7641) support
    • in client module
    • in server module
  • Observation demo added to
    • examples/networking/coap/unicoap_client and
    • examples/networking/coap/unicoap_server
  • TBD: Docs

How do I use this?

To use Observation, just import unicoap_observation in addition to the unicoap_client and/or unicoap_server imports. unicoap will import just the Observation support that's necessary.

Client

Pass UNICOAP_CLIENT_FLAG_OBSERVE to unicoap_send_request_async and watch your callback getting invoked for every notification sent from the server. You can explicitly cancel observing the resource by calling unicoap_client_cancel_observation, which sends another request with the Observe=1 option.

int ref = -1;
if ((ref = unicoap_send_request_async(&request, &destination, 
       handle_response, UNICOAP_CLIENT_FLAG_RELIABLE | UNICOAP_CLIENT_FLAG_OBSERVE, NULL)) < 0) {
  // handle error
}

// ... later, cancel observation
unicoap_client_cancel_observation(ref);

Server

Add the new UNICOAP_RESOURCE_FLAG_OBSERVABLE to your resource and send notifications using unicoap_send_notification, which mirrors the API of unicoap_send_response. Registrations from clients1 are managed automatically by unicoap.

// As usual, declare resource. 
UNICOAP_RESOURCE(hello) {
    .path = UNICOAP_PATH_ROOT,

    // Opt into Observation by specifying the OBSERVABLE flag.
    .flags = UNICOAP_RESOURCE_FLAG_RELIABLE | UNICOAP_RESOURCE_FLAG_OBSERVABLE,

    .methods = UNICOAP_METHODS(UNICOAP_METHOD_GET),
    .protocols = UNICOAP_PROTOCOLS(UNICOAP_PROTO_DTLS, UNICOAP_PROTO_UDP),
    .handler = handle_hello_request,
};

// Define handler as usual.
static int handle_hello_request(unicoap_message_t* message, const unicoap_aux_t* aux,
                                unicoap_request_context_t* ctx, void* arg) {
    unicoap_response_init_string(message, UNICOAP_STATUS_CONTENT, "Hello, World!");
    return unicoap_send_response(message, ctx);
}

// Then, send notifications whenever and as many times as you want.
static void notify(void) {
  // Craft response as you would for unicoap_send_response.
  unicoap_message_t response;
  unicoap_response_init_string(&response, UNICOAP_STATUS_CONTENT, "Reissack #1729 umgefallen!");
  // Call unicoap_send_notification instead of unicoap_send_response. Observe will be set automatically.
  if (unicoap_send_notification(&response, &unicoap_resource_hello) < 0) {
      // handle error
  }
}

I'll organise the monolithic commit into multiple structured commits once this has passed review, and rebase this PR onto #22266 once merged.

Footnotes

  1. gcoap only allows a single endpoint (i.e., for IP-based transports an IP address) to register for notifications from a resource. unicoap lifts this limitation. You can independently define CONFIG_UNICOAP_OBSERVATION_REGISTRATIONS_MAX and CONFIG_UNICOAP_OBSERVATION_CLIENTS_MAX. If nostalgia is your thing, don't worry, unicoap has mercy and graciously offers CONFIG_UNICOAP_OBSERVATION_SINGLE_CLIENT_PER_RESOURCE.

@carl-tud carl-tud changed the title net/unicoap: Unified and Modular CoAP stack: Resource observation (pt 4) net/unicoap: Unified and Modular CoAP Stack: Resource Observation (pt 4) May 11, 2026
@github-actions github-actions Bot added Area: network Area: Networking Area: doc Area: Documentation Area: tests Area: tests and testing framework Area: build system Area: Build system Area: CoAP Area: Constrained Application Protocol implementations labels May 12, 2026
@github-actions github-actions Bot added Area: sys Area: System Area: examples Area: Example Applications Area: Kconfig Area: Kconfig integration labels May 12, 2026
@carl-tud
Copy link
Copy Markdown
Contributor Author

server.c:37 Need to read .id from properties (set by driver) and set last notification id

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: doc Area: Documentation Area: examples Area: Example Applications Area: Kconfig Area: Kconfig integration Area: network Area: Networking 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