Back to IoT Blog
Protocols 15 min read

CoAP for Constrained Devices

Master the Constrained Application Protocol (CoAP). Learn REST architecture, message types, observe pattern, and implement lightweight communication for low-power IoT devices.

What is CoAP?

CoAP (Constrained Application Protocol) is a specialized web transfer protocol for use with constrained nodes and networks in the Internet of Things. It's designed by the IETF CoRE working group for machine-to-machine (M2M) applications.

Key Features:
  • UDP-based with optional reliability
  • RESTful architecture (GET, POST, PUT, DELETE)
  • Low overhead (4-byte header)
  • Built-in discovery and resource observation
  • DTLS security support
  • Proxy and cachinging capabilities

CoAP vs HTTP

Understanding when to use CoAP over HTTP:

Feature CoAP HTTP
Transport UDP (with reliability) TCP
Header Size 4 bytes ~800 bytes
Power Consumption Very Low Moderate
Memory Footprint < 10 KB > 100 KB
Multicast Supported Not Supported
Observation Built-in Requires polling/WebSocket

Message Types

CoAP defines four message types for different communication patterns:

CON (Confirmable)

Requires acknowledgment from the receiver. Retransmitted until ACK received or timeout.

Client                    Server
  | -- CON [MsgID:123] --> |
  | <-- ACK [MsgID:123] -- |

NON (Non-confirmable)

Fire-and-forget messages. No acknowledgment required.

Client                    Server
  | -- NON [MsgID:124] --> |

ACK (Acknowledgment)

Confirms receipt of a CON message.

RST (Reset)

Indicates error or rejection of a message.

Message Layer vs Request/Response Layer:

CoAP separates the unreliable transport layer (message types) from the request/response layer. This allows REST semantics over UDP with optional reliability.

Request/Response Model

CoAP uses the same methods as HTTP:

Methods

Response Codes

Example Request/Response

GET coap://sensor.local/temperature
  Accept: application/json

Response:
2.05 Content
Content-Format: application/json
Payload: {"temp": 23.5, "unit": "C"}

Observe Pattern

CoAP's observe option enables pub/sub-like behavior for resource monitoring:

How It Works

  1. Client sends GET request with Observe: 0 option
  2. Server adds client to observer list
  3. Server sends notifications when resource changes
  4. Client cancels with Observe: 1 or times out
// Client subscribes
GET /temperature Observe: 0

// Server responds immediately
2.05 Content Observe: 100
{"temp": 23.5}

// Server notifies on change
CON 2.05 Content Observe: 101
{"temp": 24.1}

// Client cancels observation
GET /temperature Observe: 1
Use Cases for Observe:
  • Temperature/humidity monitoring
  • Motion detection alerts
  • Energy consumption tracking
  • Equipment status monitoring

Implementation Guide

Implementing CoAP on ESP32 using the libcoap library:

Server Implementation

#include <coap3/coap.h>

static coap_resource_t *temp_resource;
static float current_temp = 23.5;

// Resource handler
static void
temperature_get(coap_resource_t *resource,
                coap_session_t *session,
                const coap_pdu_t *request,
                const coap_string_t *query,
                coap_pdu_t *response) {
  
  char payload[32];
  snprintf(payload, sizeof(payload), "{\"temp\":%.1f}", current_temp);
  
  coap_add_data(response, strlen(payload), (uint8_t*)payload);
  coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
}

// Initialize server
void init_coap_server() {
  coap_context_t *ctx = coap_new_context(NULL);
  
  temp_resource = coap_resource_init(NULL, 0);
  coap_register_request_handler(temp_resource, 
                                COAP_REQUEST_GET, 
                                temperature_get);
  coap_add_resource(ctx, temp_resource);
  
  // Enable observation
  coap_resource_set_get_observable(temp_resource, 1);
}

Client Implementation

#include <coap3/coap.h>

// Subscribe to resource
void subscribe_temperature() {
  coap_pdu_t *pdu = coap_new_pdu(COAP_MESSAGE_CON,
                                  COAP_REQUEST_GET,
                                  session);
  
  coap_add_option(pdu, COAP_OPTION_OBSERVE,
                  1, (uint8_t*)&(uint8_t){0});
  
  coap_send(session, pdu);
}

// Handle notification
void handle_notification(coap_pdu_t *pdu) {
  uint8_t *data;
  size_t data_len;
  
  if (coap_get_data(pdu, &data_len, &data)) {
    printf("Temperature update: %s\n", data);
  }
}

Security Considerations

CoAP uses DTLS (Datagram TLS) for security:

Security Modes

Security Best Practices:
  • Always use DTLS in production (coaps://)
  • Rotate pre-shared keys periodically
  • Implement replay attack protection
  • Use secure random number generators
  • Limit observation subscriptions per client

Common Security Issues

Next Steps

Expand your CoAP knowledge with these topics:

  • Implement CoAP proxy for HTTP integration
  • Explore CoAP group communication (multicast)
  • Learn about CoAP over TCP/TLS
  • Build a complete sensor network with CoAP
  • Integrate with cloud platforms (AWS IoT, Azure IoT)