Back

CoAP

Loading views...

CoAP

Category: Networking/IoT

Overview

CoAP (Constrained Application Protocol) is a lightweight RESTful protocol designed for constrained IoT devices. It uses UDP (optionally DTLS for security) and follows a request/response model similar to HTTP but with much smaller overhead, making it ideal for 6LoWPAN, NB-IoT, and other low-bandwidth networks.

1. Theory & Fundamentals

  • REST-based: GET, POST, PUT, DELETE methods like HTTP
  • Transport: UDP (unreliable) with reliability built into CoAP (CON/NON/ACK/RST)
  • Port: 5683 (CoAP), 5684 (CoAPS with DTLS)
  • Header: Only 4 bytes fixed header
  • Max payload: Fits in single UDP datagram (typically <1KB)
  • Observe: Server pushes updates to subscribed clients (like MQTT subscribe)
  • Block-wise: Transfer large resources in blocks (RFC 7959)

2. Frame / Packet Structure

CoAP Message Format:
  Ver(2b) | T(2b) | TKL(4b) | Code(8b) | Message ID(16b)
  Token (0โ€“8 bytes)
  Options (delta-encoded)
  0xFF | Payload

T (Type): 0=CON, 1=NON, 2=ACK, 3=RST
Code: class.detail (e.g., 2.05 = Content, 4.04 = Not Found)
  Request codes: 0.01=GET, 0.02=POST, 0.03=PUT, 0.04=DELETE
  Response: 2.01=Created, 2.05=Content, 4.00=Bad Request, 5.00=Internal Error

Options (key ones):
  If-Match, Uri-Host, ETag, Uri-Path, Content-Format, Max-Age, Uri-Query, Accept, Location-Path, Block2, Block1, Size2, Observe

3. Protocol Mechanics

  • CON (Confirmable): Retransmitted until ACK; reliable delivery
  • NON (Non-Confirmable): Fire and forget; less overhead
  • Piggy-backed ACK: Response included in ACK (same message)
  • Separate response: ACK first, then response (for slow processing)
  • Observe: Client sends GET with Observe=0; server pushes updates with Observe counter
  • DTLS: CoAP + DTLS (UDP-based TLS) for security

4. Hardware Implementation

  • Any MCU with UDP/IP stack: ESP32, nRF52, STM32 + LwIP
  • 6LoWPAN devices: Contiki-NG, Zephyr with CoAP
  • NB-IoT modules: Some have built-in CoAP client (Quectel BC66)
  • Libraries: libcoap (C), aiocoap (Python), Californium (Java)

5. Register-Level / Configuration

// Using libcoap on embedded Linux or Contiki-NG
#include <coap3/coap.h>
coap_context_t *ctx = coap_new_context(NULL);
coap_address_t dst;
coap_address_init(&dst);
dst.addr.sin.sin_family = AF_INET;
inet_pton(AF_INET, "192.168.1.100", &dst.addr.sin.sin_addr);
dst.addr.sin.sin_port = htons(5683);
coap_session_t *session = coap_new_client_session(ctx, NULL, &dst, COAP_PROTO_UDP);
coap_pdu_t *pdu = coap_new_pdu(session);
coap_pdu_set_type(pdu, COAP_MESSAGE_CON);
coap_pdu_set_code(pdu, COAP_REQUEST_CODE_GET);
coap_add_option(pdu, COAP_OPTION_URI_PATH, 11, (uint8_t*)"temperature");
coap_send(session, pdu);

6. Driver / Software Development

// CoAP server resource handler (Contiki-NG)
RESOURCE(temperature, "title="Temperature";rt="Temperature"",
    temperature_get_handler, NULL, NULL, NULL);
void temperature_get_handler(coap_message_t *req, coap_message_t *res,
                              uint8_t *buf, uint16_t len, int32_t *offset) {
    int temp = read_temperature(); // Your sensor read
    int n = snprintf((char*)buf, len, "%d.%02d", temp/100, temp%100);
    coap_set_payload(res, buf, n);
    coap_set_header_content_format(res, APPLICATION_JSON);
}

7. Debugging & Testing

  • coap-client / coap-server (libcoap CLI tools)
  • Copper (Cu) Firefox plugin (legacy) or CoAP Explorer
  • Wireshark: CoAP dissector built-in
  • Common issues: Retransmission causing duplicate processing; Observe notifications not received; Block-wise not aligned

8. Real-World Applications

  1. IoT sensor data (temperature, humidity, energy) over 6LoWPAN
  2. NB-IoT device data submission
  3. Smart building device control (lights, HVAC)
  4. Industrial SCADA over constrained networks
  5. OMA LwM2M uses CoAP as transport

9. Advanced Topics & Edge Cases

  • CoAP over TCP (RFC 8323): For reliable transport; used in LwM2M
  • OSCORE: Object Security for CoAP (encrypt without DTLS per-hop)
  • Multicast: CoAP group communication over IPv6 multicast
  • Resource Directory: Devices register resources for discovery

10. Standards & Variants

RFC Feature
RFC 7252 Core CoAP
RFC 7641 Observe extension
RFC 7959 Block-wise transfers
RFC 8613 OSCORE security
RFC 8323 CoAP over TCP/TLS

๐Ÿ’ก Practical Examples

Example 1: GET temperature

coap-client -m get coap://192.168.1.1/temperature
# Returns: 23.50

Example 2: Observe resource

coap-client -m get -s 60 coap://192.168.1.1/temperature  # Subscribe 60s
# Server pushes updates every time value changes

Example 3: POST actuator

coap-client -m post -e '{"state":"on"}' coap://device/led

๐Ÿงช Practice Questions

Beginner

  1. What transport does CoAP use?
  2. What is the difference between CON and NON messages?
  3. What is CoAP Observe?
  4. What is the default CoAP port?
  5. How is CoAP similar to HTTP?

Intermediate

  1. Implement a CoAP GET server on Contiki-NG.
  2. Explain CoAP block-wise transfer.
  3. How does DTLS secure CoAP?
  4. Implement CoAP Observe subscription.
  5. How does CoAP handle reliability over UDP?

Advanced

  1. Implement OSCORE for end-to-end CoAP encryption.
  2. Build a Resource Directory for CoAP device discovery.
  3. Implement CoAP multicast for group control.
  4. Compare CoAP vs MQTT for NB-IoT sensor data.
  5. Build CoAP proxy/gateway to HTTP REST.

Hands-on Projects

  1. CoAP Sensor Server: 6LoWPAN device serves temperature/humidity via CoAP.
  2. CoAP Dashboard: Python client polls all CoAP devices, displays on web.
  3. LwM2M Device: Implement OMA LwM2M management over CoAP.

Checklist

  • [ ] Explain CoAP message types (CON, NON, ACK, RST)
  • [ ] Implement CoAP GET server resource
  • [ ] Implement CoAP client GET/POST
  • [ ] Use CoAP Observe for push updates
  • [ ] Implement block-wise for large resources
  • [ ] Secure with DTLS or OSCORE
  • [ ] Debug with Wireshark CoAP dissector
  • [ ] Deploy on constrained device (Contiki/Zephyr)
  • [ ] Build CoAP-to-HTTP gateway
  • [ ] Implement LwM2M device management