12

We have at work an IoT scenario where the Thing/Constrained Device sends its GPS position in a regular interval to a given server. The constrained device is an Arduino-like board that is battery-powered and uses a GSM/SIM shield for connectivity. Those are our design goals:

  • Maximizing battery life
  • Minimizing data transfer

For testing purposes we have used HTTP resulting in messages around the 500 bytes, but it is time to use a more appropriated protocol for the data transmission. Some of the characteristics of the data transfer are these:

  • The payload is pretty small, normally less than 50 bytes (pretty far away from the typical MTUs, i.e. everything should fit in an IP package)
  • Data should be sent approximately once a minute. Some variance is not critical.
  • It is OK to lose some messages
  • Right now, the device does not need any kind of response from the server (however, this could change in the future). Nor the server has to start any conversation with the devices.

So far we have thought of these possibilities:

  • Custom protocol over TCP. This would get rid of the HTTP headers making the message 10 times smaller. This is our reliable/conservative approach.
  • Custom protocol over UDP. Since UDP has smaller headers and no overhead for reliability, we expect to be pretty efficient. As commented, losing one message here or there is not a concern... however, there might be other issues with the non-reliability that we are not aware of.
  • MQTT (standard over TCP): With almost no existing overhead in comparison to TCP, this could be an option as well... however, we don't have too much experience with the GSM/SIM technology, and don't know how a continuous MQTT connection would work this way, and whether the connection heartbeat bandwith is worth for such a low-frequency data transfer.
  • CoAP (standard over UDP): Seems promising as well. Just 4 bytes overhead for the headers and working over UDP. Unknown risks of UDP are there however.

Can anybody give any hint? Thanks in advance.

2
  • 1
    @RichardChambers in this scenario, the reliability is not that important. We can afford losing some packages here or there. Acking is not necessary. I think working on reliability on top of UDP does not make too much sense, that is what TCP is for.
    – bgusach
    Dec 20, 2017 at 9:19
  • 1
    I would not reinvent the wheel by designing a custom protocol. A google of CoAP vs. MQTT will give you more considerations. Do you need to future-proof your solution, ie. handle stricter requirements in the future (loss guarantees, response time, interoperability, etc)? Are the devices NAT'ed? Is there grouping of devices behind gateways? Many unknowns... Dec 21, 2017 at 20:43

6 Answers 6

6

A few thoughts on my experience with TCP, UDP, and MQTT as well as some additional resources to review.

With UDP I have run into the silent failure problem in which an application on one network node, the client, is seeing only some of the UDP messages that were sent. There are too many reasons why network traffic may go awry. The problem with UDP is that packets can be discarded pretty much whenever any of the nodes in the network path between producer of packets and consumer of packets warrants. See Wikipedia topic Packet loss.

The question is what is your loss rate under whatever the current network context. So if this is communication within a LAN or sub-network your loss rate may be low. On a WAN or across the internet your loss rate may be quite high. UDP packets are discarded for a number of reasons and routed however the network conditions allow with that hop count decrementing. Sending packets out into the great void with no accountability leaves open the possibility of silent failures.

It sounds like in your case just a simple ack with retransmit after a timeout without receiving an ack would suffice.

I have done XML messages over a maintained TCP connection and it worked great. I had a layer that delivered complete messages each in a buffer to the application layer to handle. I used XML to package the message with an XML starting tag for the beginning of the message and an XML ending tag to know when the entire message had been received.

TCP does have a few features such as sequential order of packets, no repeats, and being a connected transport mechanism means you know if the other end disappears or not though it may take a while to find out. Connecting and disconnecting can introduce delays but not burdensome under ordinary conditions though network conditions can cause TCP throughput to slow down.

MQTT is a protocol that is transported by a network transport layer, normally TCP. MQTT uses a publish/subscribe model so there is no message storing. So when a publisher publishes a message if the subscriber is not connected at the time then when it does connect, it will not see the message. MQTT is pretty much real time, I suppose that is what the telemetry part of the acronym is all about. I do like MQTT for small messages and have been doing some experiments with JSON payload through MQTT using Mosquitto. See this article Reliable message delivery with Mosquitto (MQTT) with an overview of MQTT and the quality of service. And see this brief article with links to resources including a sample application IoT – MQTT Publish and Subscriber C Code.

My experiments with MQTT using JSON text and an SQLite3 database in the subscriber to store messages is at https://github.com/RichardChambers/raspberrypi/tree/master/mqtt though the source is in C and is quite messy.

Here is a 13 minute video #144 Internet Protocols: CoAP vs MQTT, Network Sniffing, and preparation for IKEA Tradfri Hacking. This is an interesting article about CoAP, Constrained Application Protocol: CoAP is IoT's 'modern' protocol. There is this summation of CoAP:

Early adopters agree that the Constrained Application Protocol works extremely well for constrained networks and devices. Something not as well known: "On a very congested wireless network -- Wi-Fi or cellular -- CoAP can continue to work where a Transmission Control Protocol-based (TCP) protocol like MQTT can't even manage to complete a handshake," Vermillard said.

This is because unlike most other IoT protocols, CoAP is built upon UDP. In other words, it means no protocol handshakes or error correction as encountered with TCP. "CoAP may not be as reliable as HTTP or guarantee delivery of messages like MQTT, but it's extremely fast," Matthieu noted. "If you're okay with some messages not being received, you can send many more messages within the same timeframe."

There are a few others such as AMQP, STOMP, and CBOR you might look at as well. See the CBOR standard website as well as this thesis, Implementation and evaluation of the CBOR protocol. See this article, Choosing Your Messaging Protocol: AMQP, MQTT, or STOMP which compares and contrasts the AMQP, MQTT, and STOMP and ends with a note about the RabitMQ broker:

Hopefully, this can help many begin to navigate the protocol soup out there for each of your use cases. Since it is common for companies to have many applications with different needs, it is certainly possible you may need all three brokers across different applications. That’s where a solid multiprotocol, polyglot broker like RabbitMQ comes in—since it can send STOMP, MQTT, or AMQP in and get one of the other ones out. You don’t need to be locked-in by one of these protocols—all three are supported by the RabbitMQ broker, making it an ideal choice for interoperability between applications. The plugin architecture also enables RabbitMQ to evolve to support additional or updated versions of these protocols in the future.

This slide share package of some 60 slides does a compare and contrast between four different IoT protocols looking at the needs of two different IoT groups, Consumers and Industrial, which have differing needs for reliability and robustness. What's the Right Messaging Standard for the IoT?.

4

Sounds like a perfect application for UDP: client-server topology (pub/sub not required), tolerant to packet loss and big gaps between single packet transmissions mean out-of-order arrival is not an issue.

The savings in connection establishment and packet overhead will work well in your favour.

You just need to mitigate against the silent failure problem. Lots of ways to do this, but my suggestion would be to have the server respond every time it receives x (eg. 10) packets. That way the client knows how many of its packets are getting through, and if it's below a threshold it can up the frequency of transmissions to counter-act packet loss. If nothing is getting through then TCP ain't going to help anyway, so you're better off just putting the client in distress mode until the condition clears.

UDP packet loss over the internet is generally not high, and if it is it's usually a transitory phenomena. GSM provides some buffering and radio signal assessment so provides some tolerance to spurious noise anyway.

4

Are you externally constrained to use GSM/SIM?

An alternative may be to use a LoRa network which:

  • are highly optimised for small payloads
  • are designed for minimum energy use (and therefore max battery life)
  • are long range by design
  • have connection classes (always on, acknowledged, unacknowledged)
  • have scheduled download windows (e.g., for firmware updates or RX ACKs)

You can plug into existing community or commercial LoRa infrastructure in most countries, or you can deploy your own LoRa hubs if that were more appropriate.

There is active development globally and easy availability of prototyping shields (for example for Arduino).

4
  • 1
    Once a minute as mentioned in the question is far too frequent to fit recommended LoRa node transmission intervals. Feb 4, 2018 at 7:47
  • 1
    Agree 1 min is too often. Though @bgusach doesn't mention the application. If the payload can be binary encoded to reduce size and if a 3-5 min (or even 10min) interval is usable then it could be ideal. Anyway, just a suggestion as I note that it wasn't previously mentioned in the answers.
    – BrendanMcL
    Feb 4, 2018 at 8:21
  • 1
    Yes, if I'm reading it right, something like 50 bytes at four minute intervals might barely be a fit; but that needs verification, it could easily be off by at least a factor of two. Feb 4, 2018 at 8:33
  • 1
    Interesting, but we are GSM/SIM constrained (this is intended to be a consumer good, something that can be bought and used anywhere without any infrastructure but the phone network).
    – bgusach
    Feb 4, 2018 at 14:10
3

I'd prefer a minimum HTTP response with JSON data... a HTTP response can be far below 500 byte HTTP transfer, and you remain compatibility with many clients for RESTful web applications.

A minimum HTTP message (e.g. with JSON result) with aprox 130 bytes HTTP data looks like:

HTTP/1.1 200 OK
Server: ProprietaryAndroid
Connection: close
Content-Type: application/json
{
  "lat": "42.00000",
  "long": "10.00000"
}

if you just want to SEND data from your app to the server, you can simply use a HTTP GET where you set the lat/long as URL parameters. The request has even less data than the response.

GET /?lat=42.00000&long=10.0000 HTTP/1.1
Host: 192.168.0.2 
User-Agent: Proprietary
Accept: */* 
Connection: close
2
  • 7
    Thanks for your answer, but I don't see your point with the HTTP Response. We want to get rid of the whole HTTP Protocol to save data transfer. And on top of that, using GET to modify resources is the Wrong Thing™ to do
    – bgusach
    Dec 20, 2017 at 9:13
  • Agree with you from architectutal side that other verbs like POST (as the universal verb) are meanwhile more common in REST APIs. Depends on which maturity level you are developing your REST API. Just wanted to show how a HTTP can be minimized, while keeping benefit of easy impl and compatibility with existing frameworks (client and server), and at the same time keep human-readability. Answering with a response sample was confusing... If you want to SEND the data, of course you would use a POST or GET message - in case of a POST, wíth the json content which I showed in my first sample. Feb 16, 2019 at 17:29
3

There is no "best" protocol. Just a lot of trade-offs to consider:

  • Will your devices be on random networks with random ports blocked? If so, it might be better to use HTTPS.

  • If you send UDP, you can always send the last N measurements every time, so that small packet loss is ignored. You can also send an ACK packets, turning UDP into a reliable protocol. (Most protocols on top of UDP do this.)

  • Will your customers care if their data is exposed unencrypted? Will your customers care if hackers can inject bad data into those unencrypted connections? (If so, you may want encryption.)

  • What happens if someone sniffs your protocol and manipulates the data? Can you prevent one device from overwriting data for another?

  • How many devices will you have maximum? How you going to deal with all of those devices? How are you going to route the data to where it needs to go? How do you deal with maintenance and upgrades of your server infrastructure? If you don't have experience, you are probably over-estimating your ability to handle many simultaneous connections. It may be best to outsource to a vendor (and use their protocols, such as AWS IoT).

3

We have exact test comparing HTTP vs MQTT transmission rate, see test2, in your current scenario MQTT will bring you 50 times less traffic(and battery) then HTTP.

There is basically no difference between MQTT and plain TCP (in message size). I even would say that there is basically no difference between plain TCP and binary message and JSON in MQTT payload. In such way it is much more convenient to use MQTT+JSON and rely on this techs for data delivery and representation. Just name your keys more or less short.

Regarding UDP, if transmission is once per minute, then it is better to use TCP. If transmission is once per 10-20 minutes or more, then you may consider UDP as more traffic/battery effective solution. If you will try to develop own protocol with ACKs, I recommend you to use MQTT or TCP and just concentrate on your business case.

In general - the simpler you implement it the best results you can achieve in shortest time. If I were you, in that case I'd better test UDP+own binary format and MQTT+JSON and select one of them. Or even just started from MQTT+JSON and then think if it is OK for my case.

1
  • 1
    I will mention here few words against UDP. We maintaining large SaaS GPS fleet management system (more then 1 mln vehicles connected) having customers in more then 100 countries worldwide. And recently we discovered that U.S. based internet providers are blocking UDP packets going out of U.S. for some reason, even for M2M applications. It started few months ago, but it is very painful, so I recommend you to select TCP-based protocol (MQTT) and rely on global standards. Some day and in some countries you even will be forced to use MQTT over websockets to maintain connection. Just small advice.
    – shal
    Mar 19, 2018 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.