Filter results by

CoAP

CoAP (Constrained Application Protocol) is a lightweight protocol designed for Machine-to-Machine (M2M) communications within Internet of Things (IoT) applications. It allows machines to interact with each other using RESTful (HTTP-like) methods, while keeping message overhead and parsing complexity low.

ARTIK Cloud devices can communicate to ARTIK Cloud via CoAP. ARTIK Cloud acts as the CoAP server and ARTIK Cloud devices act as CoAP clients. An ARTIK Cloud device can POST data-only messages to ARTIK Cloud or GET (Observe) Actions from ARTIK Cloud.

A device token is used to connect to ARTIK Cloud via CoAP.

DTLS CoAP

DTLS (Datagram Transport Layer Security) is used to secure CoAP communication. In addition, DTLS solves the problems caused by UDP.

CoAP uses UDP, not TCP, as the transport layer. UDP is suitable for small amounts of data, such as sensor data. However, it brings the issues of unreliable transmission and out-of-order packet delivery. DTLS implements the following mechanism to address these issues:

  • packet retransmission
  • assigning sequence number within the handshake
  • replay detection

The following diagram illustrates where CoAP and DTLS are in the protocol stack, and the DTLS handshake process between the client and server. DTLS CoAP diagram

ARTIK Cloud CoAP

ARTIK Cloud CoAP only supports secure CoAP – DTLS CoAP. The service requires all communication to be encrypted with a server certificate that should be validated by the client.

A device can only maintain at most one persistent connection with ARTIK Cloud with its device token.

Specifically, the restriction is reinforced for the connection using one of the following endpoints:

WebSocket: /websocket
MQTT: /v1.1/messages/ and /v1.1/actions/
CoAP: /v1.1/actions/

Here is the ARTIK Cloud CoAP endpoint:

1
coaps://coaps-api.artik.cloud

A CoAP client should connect to the ARTIK Cloud CoAP server at the coaps default port 5684. The client can explicitly specify the port number by using coaps-api.artik.cloud:5684.

The service supports the following CoAP RESTful paths:

RESTful Service Service Path URL Parameter Body Parameter Description
POST /v1.1/messages/ <deviceToken> Valid JSON Message Send message type message to ARTIK Cloud for the device, which is identified by the specified device token
GET (Observe) /v1.1/actions/ <deviceToken> N/A Receive Actions from ARTIK Cloud

We implemented the ARTIK Cloud CoAP server based on Eclipse Californium, a CoAP framework with DTLS. The DTLS is provided by Scandium. We recommend the Californium framework for developing a CoAP client in Java.

To connect to the ARTIK Cloud CoAP server, the client must implement a compatible DTLS library.

Quick start

This section discusses how to send data-only messages to and receive Actions from ARTIK Cloud via DTLS CoAP endpoints. In addition, you can play with the ARTIK Cloud CoAP server using a command tool, dtlsclient, the DTLS CoAP client we have developed.

Download our DTLS client here.

In the next section, we will discuss how to implement this sample DTLS CoAP client. You can also build the dtlsclient tool using the source code there.

POST data-only messages

Data-only messages have type message. An ARTIK Cloud device can POST a CoAP message using the following path:

1
/v1.1/messages/<deviceToken>

The content of an CoAP message is the same as that of a message sent to ARTIK Cloud via REST or WebSockets except that sdid field is optional. If you provide the device ID for this field, make sure that the device ID corresponds to the device token in the path. Below is an example of a CoAP message:

1
2
3
4
5
{
  "ts": 1388179812427,
  "type": "message",
  "data": {"onFire":false,"temperature":50}
}           

Once ARTIK Cloud validates and accepts the message, it returns a message ID (mid) to the client.

1
2
3
4
5
6
7
8
9
10
11
$ java -jar dtlsclient-1.0.jar -X POST -d '{"type": "message", "data": {"onFire":false,"temperature":50}}' coaps://coaps-api.artik.cloud/v1.1/messages/1a201a1446fa48b
==[ CoAP Response ]============================================
MID    : 25173
Token  : 95d386
Type   : CON
Status : 2.01
Options: {"Content-Format":"application/json"}
Payload: 51 Bytes
---------------------------------------------------------------
{"data":{"mid":"91a8deb1d9814fc4a8da02462705a639"}}
===============================================================

When running the above command on a Windows machine, the single-quote must be removed or changed to a double-quote, and the double-quotes in the JSON appropriately escaped; for example:

1
java -jar dtlsclient-1.0.jar -X POST -d "{\"data\":{\"stepCount\":9620,\"calories\":908.0}}" coaps://coaps-api.artik.cloud/v1.1/messages/1a201a1446fa48b

Only messages with type message can be sent to ARTIK Cloud via CoAP.

GET (Observe) actions

The client establishes an "Observe" connection with the ARTIK Cloud CoAP server. With this connection, the client can receive Actions targeted to it. To start the connection, the client sends a GET (Observe) request at the following path:

1
/v1.1/actions/<deviceToken>

When another device or an application sends an Action to this client via REST or WebSocket, this client receives the Action as follows:

1
{"actions":[{"name":"setOn","parameters":{}}]}

The "Observe" connection will persist as long as the client continues to listen. Now let's receive Actions using the dtlsclient tool. Below is an example command and the output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$ java -jar dtlsclient-1.0.jar -t 500 -X GET coaps://coaps-api.artik.cloud/v1.1/actions/0cfba92aa46d4d

==[ CoAP Response ]============================================
MID    : 53417
Token  : 284f967f720905a0
Type   : ACK
Status : 2.03
Options: {"Observe":0}
Payload: 0 Bytes
===============================================================

==[ CoAP Response ]============================================
MID    : 25134
Token  : 284f967f720905a0
Type   : CON
Status : 2.05
Options: {"Observe":1, "Content-Format":"application/json"}
Payload: 47 Bytes
---------------------------------------------------------------
{"actions":[{"name":"setOff","parameters":{}}]}
===============================================================

==[ CoAP Response ]============================================
MID    : 25135
Token  : 284f967f720905a0
Type   : CON
Status : 2.05
Options: {"Observe":2, "Content-Format":"application/json"}
Payload: 46 Bytes
---------------------------------------------------------------
{"actions":[{"name":"setOn","parameters":{}}]}
===============================================================

In the above example, an option of -t 500 tells the client to wait for 500 seconds before disconnecting. The first response from the server is an ACK with "Observe" option. This means that the server has received the request and is observing (aka waiting for Actions for) the device. Subsequent responses from the server are the Actions received for the device.

A GET request without the "Observe" option specified by a CoAP client will fail.

Sample DTLS CoAP client

Download the source code at GitHub now. Follow the instructions in the README to build the client. The executable jar dtlsclient is created in the target directory. You have played with dtlsclient in Quick start.

The sample application teaches you how to implement the CoAP POST and GET (Observe) DTLS calls. The process is broken down into these steps:

  1. Create a DTLS endpoint with proper configuration.
  2. Create a CoAP client with request URI.
  3. Set the CoAP client endpoint to use the previously created DTLS endpoint.
  4. Call the request operation (POST/GET) on CoAP client.
  5. Retrieve the CoAP response.

Let's look at a few implementation details.

Create DTLS Handle

This loads a Java trust store, sets the client's identity, and finally creates Scandium's DTLSConnector. The trust store contains the certificate chain, which will be used to validate the server. Below is a code snippet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// load Java trust store
Certificate[] trustedCertificates = loadTrustStore();

// load client key store
KeyStore keyStore = KeyStore.getInstance("JKS");
InputStream in = DTLSClient.class.getClassLoader().getResourceAsStream(KEY_STORE_LOCATION);
keyStore.load(in, KEY_STORE_PASSWORD.toCharArray());

// Build DTLS config
DtlsConnectorConfig.Builder builder = new DtlsConnectorConfig.Builder(new InetSocketAddress(0));
builder.setIdentity((PrivateKey) keyStore.getKey(KEY_STORE_ALIAS, KEY_STORE_PASSWORD.toCharArray()),
        keyStore.getCertificateChain(KEY_STORE_ALIAS), false);
builder.setTrustStore(trustedCertificates);

// Create DTLS endpoint
dtlsConnector = new DTLSConnector(builder.build());

loadTrustStore() returns all certificates in a specified trust store (see the source code for full details). Initially, the trust store has a copy of $JAVA_HOME/jre/lib/security/cacerts. Then the Verisign intermediate certificate is inserted into the store. The Verisign certificate is used to verify the ARTIK Cloud server.

Lines 5-7 load the client key store, which is required by DtlsConnectorConfig. However, the values in this store are not used by the ARTIK Cloud server, since the server does not validate the client's identity.

Lines 10-13 create and configure the DTLS builder. The DTLS endpoint at the client binds to all IP addresses and the builder loads the certificates from the trust store.

Line 16 creates the DTLS endpoint. An exception will throw if there is any misconfiguration.

Make POST Call

With the Californium APIs, it is straightforward to make a CoAP POST call as follows:

1
2
3
4
5
6
7
8
9
10
11
12
CoapClient client = new CoapClient(uri);
client.setEndpoint(new CoapEndpoint(dtlsConnector, NetworkConfig.getStandard())).setTimeout(0).useCONs();
CoapResponse response = client.post(postJSON, MediaTypeRegistry.APPLICATION_JSON);

if (response != null) {
    // System.out.println(response.getCode());
    // System.out.println(response.getOptions());
    // System.out.println(response.getResponseText());
    System.out.println(Utils.prettyPrint(response));
} else {
    System.out.println("No response received.");
}

Line 1 creates a CoAP client with the request URI. Line 2 sets the CoAP endpoint with the DTLS endpoint previously created, and configures the endpoint as confirmable. Finally, line 3 makes the POST call with a JSON message payload.

Make GET (Observe) Call

It is also straightforward to make a CoAP GET (Observe) call as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
CoapClient client = new CoapClient(uri);
client.setEndpoint(new CoapEndpoint(dtlsConnector, NetworkConfig.getStandard())).setTimeout(0).useCONs();
CoapObserveRelation observeRelation = client.observe(
        new CoapHandler() {
            @Override
            public void onLoad(CoapResponse response) {
                System.out.println(Utils.prettyPrint(response));
            }

            @Override
            public void onError() {
                System.err.println("Observe GET Failed");
                System.exit(-1);
            }
        });

try {
    Thread.sleep(timeout * 1000);
} catch (InterruptedException e) {
    //
}

observeRelation.proactiveCancel();

Similar to the POST call, line 1-2 creates a CoAP client and sets the endpoint. Line 3 makes a GET (Observe) call by using the Californium observe API. At Line 18, the client waits for server responses for the specified number of seconds. Line 23 terminates the request.

Best practices

A CoAP client cannot send Actions to ARTIK Cloud. To support a use case where a CoAP client triggers Actions on another CoAP client, we suggest that you set up ARTIK Cloud Rules using the Rules UI in My ARTIK Cloud or by programmatically calling Rules APIs.

Let's illustrate the point with example CoAP source and destination clients. The source CoAP client is a fire detector. It sends Boolean data "onFire" to ARTIK Cloud. The destination CoAP client is a smart light that can receive on/off actions.

To send Actions from the fire detector to the light, you would create a pair of Rules in ARTIK Cloud. The "TURN ON" Rule turns on the smart light if the fire detector detects the flame (i.e., "onFire" is true). The "TURN OFF" rule does the opposite. Then the CoAP fire detector can trigger Actions on the CoAP light when sending a new piece of data.

If the source device is not limited to CoAP, you have more options. For example, the source device can send Actions directly to the destination CoAP client using REST or WebSockets.