概要
CoAP(Constrained Application Protocol、制約付きアプリケーションプロトコル)は、メモリやCPUが限られた組み込み機器・センサーデバイス向けに設計された軽量なWebプロトコルです。IETFのCoRE(Constrained RESTful Environments)ワーキンググループが策定し、2014年にRFC 7252として標準化されました。
CoAPはHTTPのRESTfulなインターフェイス設計思想を継承しながら、UDP上で動作することでオーバーヘッドを最小限に抑えています。HTTPと比べてヘッダーが大幅にコンパクトであり、RAM数KB・フラッシュ数十KBのマイクロコントローラー上でも実装可能です。8バイトの固定ヘッダーを持ち、最小パケットサイズは4バイトと極めて小さいのが特徴です。
IoTデバイスから収集したセンサーデータをクラウドやゲートウェイに送る用途のほか、デバイス設定の読み書き、ファームウェアアップデートのトリガーなど、リクエスト/レスポンス型のやり取りが必要なあらゆる場面で活用されています。
歴史・背景
2000年代後半、ZigBeeやIEEE 802.15.4などのLow-Power Wireless Personal Area Network(6LoWPAN)が普及し始めると、これらのネットワーク上でWebの仕組みをどう活かすかが課題となりました。HTTPは機能豊富ですが、TCPコネクション管理・テキストヘッダーのオーバーヘッドが大きく、制約機器には不向きでした。
IETFのCoREワーキンググループは2009年から設計を開始し、以下の設計原則を定めました。
- RESTモデルの維持:HTTP同様GET/POST/PUT/DELETEを使い、既存のWebツールとの親和性を確保
- UDPベース:コネクションレスで省電力
- 非同期メッセージング:確認応答(CON)と非確認応答(NON)の選択
- プロキシ・キャッシュ対応:ゲートウェイでHTTP⇔CoAP変換を可能にする設計
2014年のRFC 7252公開後、観察機能(RFC 7641)、TCP対応(RFC 8323)、ブロック転送(RFC 7959)などの拡張が次々と標準化されています。
技術仕様
メッセージタイプ
CoAPには4種類のメッセージタイプがあります。
| タイプ | 説明 | 確認応答 |
|---|---|---|
| CON(Confirmable) | 確実な配信が必要なメッセージ | ACKが必要 |
| NON(Non-confirmable) | 確認不要の軽量メッセージ | 不要 |
| ACK(Acknowledgement) | CONへの応答 | — |
| RST(Reset) | エラー/拒否通知 | — |
メソッド
| メソッド | HTTP対応 | 説明 |
|---|---|---|
| GET | GET | リソース取得 |
| POST | POST | リソース作成/アクション |
| PUT | PUT | リソース更新 |
| DELETE | DELETE | リソース削除 |
| FETCH | — | フィルタ付き取得(RFC 8132) |
| PATCH/iPATCH | PATCH | 部分更新 |
パケットフォーマット
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Ver| T | TKL | Code | Message ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Token (if any, TKL bytes) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options (if any) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1 1 1 1 1 1 1 1| Payload (if any) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Ver: バージョン(常に01)
T: メッセージタイプ(CON/NON/ACK/RST)
TKL: トークン長(0〜8バイト)
Code: メソッドまたはレスポンスコード
最小ヘッダーはわずか4バイト。HTTPのヘッダーが数百バイト〜KBになるのとは対照的です。
レスポンスコード
HTTPと同様に3桁コードを使いますが、表記が異なります。
| CoAP | HTTP | 説明 |
|---|---|---|
| 2.05 | 200 OK | 成功 |
| 2.01 | 201 Created | 作成成功 |
| 4.04 | 404 Not Found | リソースなし |
| 5.00 | 500 Internal Error | サーバーエラー |
Observeオプション(RFC 7641)
通常のCoAPはリクエスト/レスポンス型ですが、ObserveオプションはPub/Sub的な使い方を可能にします。クライアントがGETリクエストにObserveオプションを付けると、サーバーはリソース変化のたびに通知を送り続けます。
Client Server
| |
|-- GET /temperature (Obs:0) --->| ← 購読開始
|<-- 2.05 Content (Obs:1) -------| ← 現在値(25.0)
|<-- 2.05 Content (Obs:2) -------| ← 変化通知(25.3)
|<-- 2.05 Content (Obs:3) -------| ← 変化通知(24.9)
|-- GET /temperature (Obs:1) --->| ← 購読解除
動作原理
リクエスト/レスポンスの流れ
Client CoAP Server
| |
|-- CON GET /sensors/1 ---->| (Message ID: 0x1234)
|<-- ACK 2.05 Content ------| (Message ID: 0x1234, Token同一)
| Payload: {"temp": 25.3}
再送制御
CONメッセージはACKが返らない場合、指数バックオフで再送されます。
初回送信: t=0
1回目再送: t=2〜3秒後(ACK_TIMEOUTのランダム化)
2回目再送: t=4〜6秒後
3回目再送: t=8〜12秒後
MAX_RETRANSMIT: 4回(デフォルト)
CoAP-HTTP変換プロキシ
CoAPネットワークとHTTPネットワークをブリッジするプロキシを設けることで、既存のWebサービスと透過的に連携できます。
[CoAPデバイス] --UDP/CoAP--> [CoAP-HTTPプロキシ] --TCP/HTTP--> [Webサーバー]
coap://proxy/http://api.example.com/data
DTLSによるセキュリティ
CoAPはDTLS(Datagram TLS)でセキュリティを確保します。PSK(事前共有鍵)、RPK(生公開鍵)、証明書の3モードをサポートします。
// tinydtls使用例(C言語)
dtls_context_t *ctx = dtls_new_context(&peer);
dtls_set_handler(ctx, &cb);
// PSKハンドラの実装
int get_psk_info(struct dtls_context_t *ctx,
const session_t *session,
dtls_credentials_type_t type,
const unsigned char *id, size_t id_len,
unsigned char *result, size_t result_length) {
memcpy(result, PSK_KEY, PSK_KEY_LEN);
return PSK_KEY_LEN;
}
用途・ユースケース
スマートホーム
照明・エアコン・センサーなどのホームIoTデバイスがCoAPで通信します。Philips HueやThread/Matter対応デバイスはCoAPを内部で活用しています。
GET coap://192.168.1.50/light/1 → 照明状態取得
PUT coap://192.168.1.50/light/1 → 照明制御
Payload: {"on": true, "brightness": 80}
産業センサー監視
工場の温度・圧力・振動センサーがCoAPで定期レポート。NONメッセージ(確認なし)を使えばCPU割り込みを最小化できます。
// libcoap使用例
#include <coap3/coap.h>
coap_context_t *ctx = coap_new_context(NULL);
coap_address_t server_addr;
coap_address_init(&server_addr);
coap_pdu_t *pdu = coap_new_pdu(COAP_MESSAGE_NON, COAP_REQUEST_CODE_POST,
coap_new_session(ctx, NULL, &server_addr,
COAP_PROTO_UDP));
coap_add_data(pdu, strlen(payload), (uint8_t*)payload);
coap_send(session, pdu);
ファームウェアOTA(SUIT/OSCORE連携)
IETFのSUITマニフェスト(RFC 9019)はCoAPをトランスポートとして使います。大容量のファームウェアはブロック転送(RFC 7959)で分割送信されます。
GET coap://server/fw/v2.1.bin (Block2: 0/MORE/512)
→ 最初の512バイト取得
GET coap://server/fw/v2.1.bin (Block2: 1/MORE/512)
→ 次の512バイト取得
...
6LoWPAN/Threadネットワーク
Threadプロトコル(Matter規格の基盤)はCoAPを必須プロトコルとして採用しています。IEEE 802.15.4上のIPv6(6LoWPAN)ネットワークで動作します。
実装・開発のポイント
主要実装ライブラリ
| ライブラリ | 言語 | 対象環境 |
|---|---|---|
| libcoap | C | Linux/組み込み |
| tinydtls | C | マイコン(DTLS付き) |
| Eclipse Californium | Java | サーバー/ゲートウェイ |
| CoAPthon3 | Python | テスト/プロトタイプ |
| microcoap | C | 超小型マイコン |
| Copper(Cu) | Firefox拡張 | デバッグツール |
libcoapを使ったサーバー実装
#include <coap3/coap.h>
// センサーリソースハンドラ
static void handle_get_temperature(
coap_resource_t *resource,
coap_session_t *session,
const coap_pdu_t *request,
const coap_string_t *query,
coap_pdu_t *response) {
float temp = read_temperature_sensor();
char buf[32];
int len = snprintf(buf, sizeof(buf), "{\"temp\":%.1f}", temp);
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
coap_add_option(response, COAP_OPTION_CONTENT_FORMAT,
coap_encode_var_safe(tmpbuf, sizeof(tmpbuf),
COAP_MEDIATYPE_APPLICATION_JSON),
tmpbuf);
coap_add_data(response, len, (uint8_t *)buf);
}
int main(void) {
coap_context_t *ctx = coap_new_context(NULL);
coap_resource_t *res = coap_resource_init(
coap_make_str_const("sensors/temperature"), 0);
coap_register_handler(res, COAP_REQUEST_GET, handle_get_temperature);
coap_add_resource(ctx, res);
coap_run_once(ctx, COAP_RUN_FOREVER);
return 0;
}
Content-Formatの選択
CoAPはJSONだけでなく、CBORなど軽量なバイナリ形式もサポートします。
// CBOR形式を指定してPublish(バイナリで省サイズ)
COAP_MEDIATYPE_APPLICATION_CBOR // 60
COAP_MEDIATYPE_APPLICATION_JSON // 50
他技術との比較
| 項目 | CoAP | HTTP/HTTPS | MQTT | MQTT-SN |
|---|---|---|---|---|
| トランスポート | UDP | TCP | TCP | UDP |
| 最小ヘッダー | 4バイト | 数百バイト | 2バイト | 2バイト |
| 通信モデル | Req/Res (+Observe) | Req/Res | Pub/Sub | Pub/Sub |
| RFC標準 | ○(RFC 7252) | ○ | OASIS標準 | — |
| ブラウザ対応 | △(プロキシ経由) | ◎ | △ | × |
| 制約機器適合 | ◎ | △ | ○ | ◎ |
HTTP/HTTPSはブラウザやサーバーとの相互運用性は最高ですが、制約機器には重すぎます。MQTTはPub/Subに特化しており、Observe機能付きのCoAPとは用途が棲み分けられます。MQTT-SNと比較すると、CoAPはゲートウェイなしで直接サーバーと通信できる点が利点です。