COAP_ASYNC(3)

πŸ’… COAP_ASYNC β€” the libcoap manual, but make it make sense πŸ’…

okay bestie, so this is the libcoap manual page for the async squad β€” COAP_ASYNC(3), no cap. if you've ever wondered how a CoAP server goes "hold up, lemme get back to you on that," this is the page that spills the tea πŸ«–βœ¨


✨ NAME ✨

coap_async, coap_register_async, coap_async_trigger, coap_async_set_delay, coap_find_async, coap_free_async, coap_async_set_app_data, coap_async_get_app_data β€” literally all of these are for working with CoAP async support πŸ’–


πŸ¦‹ SYNOPSIS πŸ¦‹

#include <coap3/coap.h>

coap_async_t *coap_register_async(coap_session_t *session, const
coap_pdu_t *request, coap_tick_t delay);

void coap_async_trigger(coap_async_t *async);

void coap_async_set_delay(coap_async_t *async, coap_tick_t delay);

void coap_free_async(coap_session_t *session, coap_async_t *async);

coap_async_t *coap_find_async(coap_session_t *session, coap_bin_const_t
token);

void coap_async_set_app_data(coap_async_t *async, void *app_data);

void *coap_async_get_app_data(const coap_async_t *async);

so for specific (D)TLS library support, you link with -lcoap-3-notls, -lcoap-3-gnutls, -lcoap-3-openssl, -lcoap-3-mbedtls, -lcoap-3-wolfssl or -lcoap-3-tinydtls. otherwise? just link with -lcoap-3 and you get the default (D)TLS library support πŸŽ€


🌸 DESCRIPTION 🌸

CoAP server responses can be piggybacked (the manpage says "RFC7252 5.2.1. Piggybacked") or separate ("RFC7252 5.2.2. Separate"). iykyk πŸ’…

  • piggybacked responses β€” the response packet literally contains both the status and any data. one packet, no drama ✨
  • separate responses β€” you get an initial empty ACK response first (Confirmable only β€” it's there to stop the client re-transmitting the request), and then at a later time a packet shows up containing the status and any data πŸ¦‹

usually responses are piggybacked, but this man page is hyperfixated on the mechanism for providing separate (async) support. that's the whole vibe.

⚠️ NOTE: if a server is providing Proxy support, then the server code should return from the request handler with no response code set (i.e. respond with empty ACK) and then send back the response as provided by the upstream server when received, so no need to use the async support. okay? okay. πŸ’–

πŸŽ€ FUNCTIONS πŸŽ€

πŸ’œ Function: coap_register_async()

coap_register_async() is what you call to set up an asynchronous delayed request for the request PDU associated with the session. the application request handler will get called with a copy of request after delay ticks, which will then cause a response to be sent. and if delay is 0, then the application request handler will not get called until coap_async_trigger() or coap_async_set_delay() is called. it's giving "wait for my text back" energy 😭

🧚 Function: coap_async_trigger()

coap_async_trigger() expires the delay for the async definition, so the application request handler is almost immediately called. like, boom, it's happening πŸ”₯

πŸ“ Function: coap_async_set_delay()

coap_async_set_delay() updates the remaining delay before the application request handler is called for the async definition. if delay is set to 0, then the application request handler will not get called. periodt.

an example of usage here is coap_register_async() sets delay to 0, and then when the response is ready at an indeterminate point in the future, coap_async_set_delay() is called setting delay to 1. alternatively, coap_async_trigger() can be called. two paths, same slay ✨

🌈 Function: coap_free_async()

coap_free_async() deletes an async definition. bye bestie πŸ‘‹

⭐ Function: coap_find_async()

coap_find_async() determines if there is an async definition based on the session and token token. it's a vibe check for async definitions πŸ’…

🫢 Function: coap_async_set_app_data()

coap_async_set_app_data() adds in user defined app_data to the async definition. and heads up β€” it is the responsibility of the application to release this data if appropriate. this would usually be done when the application request handler is called under async control. don't forget to clean up, bestie 🧹

πŸ‘‘ Function: coap_async_get_app_data()

coap_async_get_app_data() retrieves any defined application data from the async definition. come get your data πŸ’–


πŸ”₯ RETURN VALUES πŸ”₯

  • coap_register_async() and coap_find_async() return a pointer to an async definition, or NULL if there is an error 😭
  • coap_async_get_app_data() returns a pointer to the user defined data ✨

πŸ’€ EXAMPLES πŸ’€

🌸 CoAP Server Non-Encrypted Setup 🌸

#include <coap3/coap.h>

/*
 * This example is used to demonstrate how to set up and use a "separate"
 * response (empty ACK followed by data response at a later stage).
 */
static void
hnd_get_with_delay(coap_session_t *session,
                   coap_resource_t *resource,
                   coap_pdu_t *request,
                   coap_string_t *query,
                   coap_pdu_t *response) {
  unsigned long delay = 5;
  size_t size;
  coap_async_t *async;
  coap_bin_const_t token = coap_pdu_get_token(request);

  /*
   * See if this is the initial, or delayed request
   */

  async = coap_find_async(session, token);
  if (!async) {
    /* Set up an async request to trigger delay in the future */
    if (query) {
      const uint8_t *p = query->s;

      delay = 0;
      for (size = query->length; size; --size, ++p)
        delay = delay * 10 + (*p - '0');
      if (delay == 0) {
        coap_log_info("async: delay of 0 not supported\n");
        coap_pdu_set_code(response, COAP_RESPONSE_CODE_BAD_REQUEST);
        return;
      }
    }
    async = coap_register_async(session,
                                request,
                                COAP_TICKS_PER_SECOND * delay);
    if (async == NULL) {
      coap_pdu_set_code(response, COAP_RESPONSE_CODE_SERVICE_UNAVAILABLE);
      return;
    }
    /*
     * Not setting response code will cause empty ACK to be sent
     * if Confirmable
     */
    return;
  }
  /* async is set up, so this is the delayed request */

  /* remove any stored app data associated with 'async' here */

  /* Send back the appropriate data */
  coap_add_data_large_response(resource, session, request, response,
                               query, COAP_MEDIATYPE_TEXT_PLAIN, -1, 0, 4,
                               (const uint8_t *)"done", NULL, NULL);
  coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);

  /* async is automatically removed by libcoap on return from this handler */
}

πŸ¦‹ SEE ALSO πŸ¦‹

coap_handler(3) and coap_supported(3) β€” go read those too, bestie, they're lowkey essential πŸ“š


🌈 FURTHER INFORMATION 🌈

see

"RFC7252: The Constrained Application Protocol (CoAP)"

for further information. the lore is all there πŸ’–


πŸ™ˆ BUGS πŸ™ˆ

please raise an issue on GitHub at https://github.com/obgm/libcoap/issues to report any bugs. and please raise a Pull Request at https://github.com/obgm/libcoap/pulls for any fixes. we love a contributor who actually follows through ✨


πŸ’œ AUTHORS πŸ’œ

The libcoap project <libcoap-developers@lists.sourceforge.net> β€” icons, the lot of them πŸ‘‘


okay that's the whole page, mwah πŸ’‹ this was coap_async version 4.3.5, dated 08/24/2026, and that's the libcoap manual wrapped with love πŸŽ€βœ¨ go forth and be asynchronous, bestie πŸ¦‹

πŸ“¦ where this page comes from