EMQ XでCoAPとMQTTを相互に変換する

CoAPとMQTTは、どちらもIoTの分野でよく利用されている軽量な通信プロトコルです。[EMQ X](https://www.emqx.io)はMQTTブローカーですが、CoAPを使って接続することもできます。そのため、あるデバイスがCoAPで送ったメッセージを他のデバイスがMQTTで受信することができ、その逆も可能となっています。今回は、EMQ XでCoAPを有効化する手順について説明します。

## はじめに：CoAP <=> MQTTでどのように変換されるか

実際に手順を説明する前に、EMQ XがCoAPとMQTTをどのように相互変換しているかについて説明します。

CoAPとMQTTはどちらもpub/subモデルを使っています。そして、MQTTが`トピック`でメッセージの行き先を振り分ける一方で、CoAPのURIはRESTの原則に基づいています。EMQ XのCoAPプラグインでは、以下のようにCoAPとMQTTを対応させました。

| CoAP | MQTT |
| :---: | :---: |
| PUT | Publish |
| GET | Subscribe |
| URIのパス | トピック |
| URIのクエリ | `client id`, `username`, `password` |

つまり、CoAPにおける

```
put "coap://host:port/mqtt/$topic?c=$client&u=$username&p=$password"
```

は、MQTTで`$topic`というトピックに

- client ID: $client
- username: $username
- password: $password

という接続情報で`publish`するのと同等になります（`$topic`にpublishするためには、CoAP側で`mqtt/$topic`とパスを指定する必要があります。

`get`の場合も同様で、

```
get "coap://host:port/mqtt/$topic?c=$client&u=$username&p=$password"
```

は、

は、MQTTで`$topic`というトピックに

- client ID: $client
- username: $username
- password: $password

という接続情報で`subscribe`するのと同等です。

それでは、実際にやってみましょう。

## EMQ Xを起動し、CoAPプラグインを有効化する

EMQ Xのインストール、起動については[こちら](https://docs.emqx.io/en/broker/v4.3/getting-started/install.html#one-click-installation-of-shell-script-linux)を参照してください。

EMQ Xを起動したらダッシュボードを開きます。デフォルトでは http://localhost:18083 からダッシュボードに接続できます。設定を変更していなければ、

- username: __admin__
- password: __password__

でログインできます。

ダッシュボードを開いたら、左にある`Plugins`をクリックしてCoAPのプラグインを探し、`Start`でプラグインを立ち上げます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763141/1af8bf88-bdc2-805c-3429-565ff525cc32.png)

## MQTTでEMQ Xに接続する

[MQTTX](https://mqttx.app/)でEMQ Xに接続し、トピック `coap_to_mqtt`にsubscribeします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763141/bba3be8a-8938-4904-236e-079a97ffbbf3.png)

## CoAPでEMQ Xに接続する

今回は[libcoap](https://github.com/obgm/libcoap)を使います。

```bash
# リンクからダウンロードもできます  https://github.com/obgm/libcoap/archive/refs/tags/v4.2.1.zip
git clone https://github.com/obgm/libcoap.git
# ↓リンクからダウンロードした場合はunzipしてください
# unzip libcoap-4.2.1.zip

# libcoapのディレクトリに移動
cd libcoap
# stable version (今回はv4.2.1）に切り替え
# ダウンロードリンクを使った場合は不要
git checkout v4.2.1
# Couldn't find 'autoconf'! などのエラーが出た場合は
# 指示に従って対象のpackageをインストールしてください
./autogen.sh
./configure --enable-documentation=no --enable-tests=no
# Package化
make
```

上記が完了したら、libcoapの`examples`フォルダにある`coap-client`を使います。

```bash
# CoAPクライアントで
# 'hello EMQ X world,  I am CoAP'というメッセージを
# トピック 'coap_to_mqtt' に送ります
./examples/coap-client -m put -e "hello EMQ X world, I am CoAP" "coap://127.0.0.1/mqtt/coap_to_mqtt?c=coap20211&u=tom&p=secret"
# 127.0.0.1はEMQ Xのエンドポイントに置き換えてください
```

このように、CoAPでメッセージを`PUT`すると、MQTT Xでメッセージが受信できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763141/ec8a5450-ccc8-010c-5468-5b43251229a2.png)

今度は、CoAPの`GET`を使ってsubscribeしてみます。

```bash
./examples/coap-client -m get -s 20 "coap://127.0.0.1/mqtt/mqtt_to_coap?c=client1&u=tom&p=secret"
```

MQTTからメッセージをpublishすると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763141/ea4d1b49-9b99-a66f-61c7-c734c8665a1c.png)

```bash
./examples/coap-client -m get -s 20 "coap://127.0.0.1/mqtt/mqtt_to_coap?c=client1&u=tom&p=secret"
hello CoAP, I am MQTT, welcome to EMQ X Wrold!
```

このように、メッセージがCoAP側に届きます。

## おわりに

EMQ Xはほかにも、LwM2M, JT808などのプロトコルをサポートしています。

この記事は[A「date」between MQTT and CoAP in the EMQ X world](https://www.emqx.io/blog/url-mqtt-and-coap)の翻訳です。