Introduction
CoAP (Constrained Application Protocol) is a lightweight RESTful protocol ideal for low-power devices in mesh networks like Thread. In this episode, we explore how Thread nodes use CoAP for communication. We explain how to set up CoAP endpoints. We also describe how message exchange works using OpenThread on STM32WB.
Why CoAP in Thread?
Thread is designed for low-power, IP-based communication. CoAP is a perfect fit due to its:
- Low overhead (runs over UDP)
- RESTful semantics (GET, PUT, POST, DELETE)
- Support for asynchronous messages (observing resources)
- Small message size and binary encoding
CoAP Architecture in OpenThread
CoAP runs over UDP/IPv6 within the Thread network. The OpenThread stack exposes APIs to:
- Create CoAP servers and clients
- Register request handlers (resources)
- Send confirmable (CON) and non-confirmable (NON) messages
Enabling CoAP on STM32WB
To enable CoAP functionality, make sure OpenThread CoAP APIs are compiled by enabling:
#define OPENTHREAD_CONFIG_COAP_API_ENABLE 1
Then, initialize the CoAP server:
otCoapStart(instance, OT_DEFAULT_COAP_PORT);
Registering CoAP Resources
A resource is a URI path that can handle CoAP requests (like `/led` or `/status`). You can register it like this:
static void HandleCoapRequest(void *context, otMessage *message,
const otMessageInfo *messageInfo)
{
// Handle GET or POST requests here
}
static otCoapResource myResource = {
.mUriPath = "led",
.mHandler = HandleCoapRequest,
.mContext = NULL,
.mNext = NULL
};
otCoapAddResource(instance, &myResource);
Sending CoAP Requests
To send a CoAP POST or GET request to another node:
otMessage *msg = otCoapNewMessage(instance, NULL);
otCoapMessageInit(msg, OT_COAP_TYPE_NON_CONFIRMABLE, OT_COAP_CODE_PUT);
otCoapMessageAppendUriPathOptions(msg, "led");
otMessageAppend(msg, payload, payload_length);
otMessageInfo messageInfo = {0};
messageInfo.mPeerAddr = targetIp;
messageInfo.mPeerPort = OT_DEFAULT_COAP_PORT;
otCoapSendRequest(instance, msg, &messageInfo, NULL, NULL);
This would send a CoAP PUT request to a node’s `/led` resource.
Example Use Case: LED Control
Let’s say one Thread node controls an LED, and another sends a command. Here’s a simple flow:
- Device A registers the `/led` resource.
- Device B sends a PUT request to `/led` with payload “on” or “off”.
- Device A toggles the GPIO and optionally replies with a 2.04 Changed response.
CoAP Message Types
- CON (Confirmable): Requires ACK, used for reliable messages
- NON (Non-confirmable): No ACK expected
- ACK: Acknowledgement for a CON message
- RST: Reset if a message is not understood
Conclusion
CoAP makes Thread networks powerful and simple to interact with. It enables RESTful interactions between low-power devices over IPv6. In the next episode, we’ll learn how to discover other Thread nodes on the network. We will also implement service discovery using multicast and CoAP.

Leave a comment