Having to run a piece of technology on a memory-constrained device changes everything. Web server technology is primarily meant to run on big servers, capable of serving a large number of concurrent clients, with complex data being transported over secure and/or reliable TCP sockets. HTTP is the de-facto protocol for interacting with such servers. Then there are embedded devices with RAM as low as 2kb.
Some ambitious people tried to turn constrained devices into HTTP servers in order to publish their sensor data to clients. It was obviously a bad idea, if you know what it takes to implement a full-fledged HTTP server. It gets worse if the "clients" are actually other constrained devices. It gets even worse if these devices are on a lossy network. Some of these people were smart enough to propose a replacement for HTTP for these kind of cases.
Enter, Constrained Application Protocol (CoAP). With CoAP, constrained devices can implement HTTP verbs, like GET, POST etc., and get away without implementing a full HTTP server. First, CoAP is designed to run on top of UDP, which considerably simplifies the network stack. There is support for TCP as well but lets forget it exists for now. Second, its message components are all binary, which means very low protocol bytes overhead and extremely simple-to-parse packets.
Lets compare a smallest possible HTTP GET vs a CoAP GET message:
GET / HTTP/1.1\r\nHost: hostaddress\r\n\r\n
0x51 0x01 0xab 0xcd 0xef
HTTP needs 27 bytes, excluding
hostaddress, versus 5 bytes for CoAP. It is already apparent that CoAP messages are not meant to be human-readable, unlike HTTP. It is harder to construct a CoAP message by hand. Your constrained devices, on the other hand, will happily encode/decode these messages. Here's a quick breakdown of the CoAP message.
0x51 : 01 | 01 | 0001 -------------------------------- ver. | NON msg type | token len. 0x01 : 000 | 00001 --------------- request | GET 0xabcd : message ID 0xef : token
For the curious, the full RFC is here.
Reliability over UDP
As mentioned earlier, CoAP uses UDP as the transport, so the missing reliability mechanism is built into CoAP itself. Looking at the above CoAP example message, the message type is
NON or non-confirmable.
NON messages are fire-and-forget kind of messages, where the sender doesn't expect an acknowledgement from the receiver. Any response sent back contains the token that was originally sent, so the sender still needs to keep the sent tokens temporarily to match with responses, if there are any. Another kind of message type is
CON or confirmable. These messages expect an
ACK type of message as response from the server, and are repeatedly sent until they get the acknowledgement. Message IDs are used to match the sent message with their
ACK responses, so the sender needs to keep IDs for
CON messages in memory.
Responses to requests of type
CON are normally
CON themselves. Which means the original requester needs to send back an
ACK after receiving a response.
NON responses are usually sent for
NON requests, but can be
A very neat feature of CoAP is the discovery of all services offered by a server. Anyone (or anything) can call
GET /.well-known/core to get a list of URIs that can be accessed. Here is an example resource discovery transaction.
GET /.well-known/core </sensors/temp>;rt="temperature-c";if="sensor", </sensors/light>;rt="light-lux";if="sensor"
This server offers two URIs. If the response parser knows how to interpret resources of types
light-lux, and knows what verbs are allowed on interface
sensor, it can fully interact with the server. This simple resource discovery allows machine-to-machine client/server communication model.
Simplicity comes at a cost. Before even being part of a system, all communicating entities have to agree upon and have full knowledge of all resource types and interfaces involved in the system, which is quite limiting. There's not much you can do to "filter" your resource discovery either. For example, you can't query "a list of all temperature sensors from floor 8" using standard methods. There is still a large room for improvement in CoAP's resource discovery process.
There is a whole RFC for resource discovery alone here
I am currently working on a better resource discovery process, which I'll be posting about here. Stay tuned!