IoTプロトコル

CoAP

制約機器向けの軽量Webプロトコル。

概要

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対応説明
GETGETリソース取得
POSTPOSTリソース作成/アクション
PUTPUTリソース更新
DELETEDELETEリソース削除
FETCHフィルタ付き取得(RFC 8132)
PATCH/iPATCHPATCH部分更新

パケットフォーマット

 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桁コードを使いますが、表記が異なります。

CoAPHTTP説明
2.05200 OK成功
2.01201 Created作成成功
4.04404 Not Foundリソースなし
5.00500 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)ネットワークで動作します。


実装・開発のポイント

主要実装ライブラリ

ライブラリ言語対象環境
libcoapCLinux/組み込み
tinydtlsCマイコン(DTLS付き)
Eclipse CaliforniumJavaサーバー/ゲートウェイ
CoAPthon3Pythonテスト/プロトタイプ
microcoapC超小型マイコン
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

他技術との比較

項目CoAPHTTP/HTTPSMQTTMQTT-SN
トランスポートUDPTCPTCPUDP
最小ヘッダー4バイト数百バイト2バイト2バイト
通信モデルReq/Res (+Observe)Req/ResPub/SubPub/Sub
RFC標準○(RFC 7252)OASIS標準
ブラウザ対応△(プロキシ経由)×
制約機器適合

HTTP/HTTPSはブラウザやサーバーとの相互運用性は最高ですが、制約機器には重すぎます。MQTTはPub/Subに特化しており、Observe機能付きのCoAPとは用途が棲み分けられます。MQTT-SNと比較すると、CoAPはゲートウェイなしで直接サーバーと通信できる点が利点です。

関連用語

参考リンク