Hono: MQTT Adapter: Handling of unsupported QoS levels during subscription to control endpoint by devices

Created on 17 Oct 2018  路  5Comments  路  Source: eclipse/hono

Hono Mqtt documentation states that Currently the MQTT adapter only supports publishing of command messages using QoS 0. and discards malformed messages that e.g. are published to an unsupported topic or use an unsupported QoS value.

When devices subscribe to control endpoint with QoS levels 1 and 2 (as shown in below example), there are no error messages, successfully getting subscribed and also these devices receive commands. On the other hand, validation of QoS is done when command response is being sent.

Example (With QoS 1):
$ mosquitto_sub -v -h 192.168.99.100 -u 'sensor1@DEFAULT_TENANT' -q 1 -P hono-secret -t control/+/+/req/#

control///req/101053c7df95-213d-4b95-91af-4b803330542c/test-qos-1 test qos 1

Example (With QoS 2):
$ mosquitto_sub -v -h 192.168.99.100 -u 'sensor1@DEFAULT_TENANT' -q 2 -P hono-secret -t control/+/+/req/#

control///req/1010d8016fad-48f0-4027-8fac-dcfcb2d3e13a/test-qos-2 test qos 2

MQTT Adapter enhancement

Most helpful comment

So your point is that we should deny a request to subscribe using QoS 2, right? I can live with that. Would you mind creating a PR?

All 5 comments

When devices subscribe to control endpoint with QoS levels 1 and 2 (as shown in below example), there are no error messages, successfully getting subscribed and also these devices receive commands.

It is true that the device can subscribe to the topic. However, the messages will still be published using QoS 0. You can see this if you add the -d switch to the command line:

$ mosquitto_sub -v -d -h hono.eclipse.org -u 'sensor1@DEFAULT_TENANT' -P hono-secret -t control/+/+/req/# -q 1
Client mosqsub|610-leia sending CONNECT
Client mosqsub|610-leia received CONNACK
Client mosqsub|610-leia sending SUBSCRIBE (Mid: 1, Topic: control/+/+/req/#, QoS: 1)
Client mosqsub|610-leia received SUBACK
Subscribed (mid: 1): 0

The last line shows the content of the SUBACK packet sent back to the device. The same happens when the client wants to subscribe using QoS 2.

When devices subscribe to control endpoint with QoS levels 1 and 2 (as shown in below example), there are no error messages, successfully getting subscribed and also these devices receive commands.

It is true that the device can subscribe to the topic. However, the messages will still be published using QoS 0. You can see this if you add the -d switch to the command line:

$ mosquitto_sub -v -d -h hono.eclipse.org -u 'sensor1@DEFAULT_TENANT' -P hono-secret -t control/+/+/req/# -q 1
Client mosqsub|610-leia sending CONNECT
Client mosqsub|610-leia received CONNACK
Connection Refused: broker unavailable.
Client mosqsub|610-leia sending CONNECT
Client mosqsub|610-leia received CONNACK
Client mosqsub|610-leia sending SUBSCRIBE (Mid: 1, Topic: control/+/+/req/#, QoS: 1)
Client mosqsub|610-leia received SUBACK
Subscribed (mid: 1): 0

The last line shows the content of the SUBACK packet sent back to the device. The same happens when the client wants to subscribe using QoS 2.

Me too used the same flag to check :) . But this rule is not applied when we send event, telemetry or command-response. When a device (tested using paho & mosquitto clients) sends an event, a telemetry or a response to a command with QoS level 2, then the Mqtt Adapter discards those messages and the mqtt client keeps retrying indefinitely(default timeout is -1 unless explicitly specified by a user), while there is no response from adapter. In this case the messages are not published using QoS 0.

$ mosquitto_pub -h 192.168.99.100 -u 'sensor1@DEFAULT_TENANT' -q 2 -P hono-secret -t telemetry -m "tesst" -d Client mosqpub/85317-wa3z008d- sending CONNECT Client mosqpub/85317-wa3z008d- received CONNACK Client mosqpub/85317-wa3z008d- sending PUBLISH (d0, q2, r0, m1, 'telemetry', ... (5 bytes)) Client mosqpub/85317-wa3z008d- sending PUBLISH (d1, q2, r0, m1, 'telemetry', ... (5 bytes)) Client mosqpub/85317-wa3z008d- sending PUBLISH (d1, q2, r0, m1, 'telemetry', ... (5 bytes)) Client mosqpub/85317-wa3z008d- sending PINGREQ Client mosqpub/85317-wa3z008d- received PINGRESP Client mosqpub/85317-wa3z008d- sending PUBLISH (d1, q2, r0, m1, 'telemetry', ... (5 bytes)) Client mosqpub/85317-wa3z008d- sending PUBLISH (d1, q2, r0, m1, 'telemetry', ... (5 bytes)) Client mosqpub/85317-wa3z008d- sending PUBLISH (d1, q2, r0, m1, 'telemetry', ... (5 bytes)) Client mosqpub/85317-wa3z008d- sending PINGREQ Client mosqpub/85317-wa3z008d- received PINGRESP Client mosqpub/85317-wa3z008d- sending PUBLISH (d1, q2, r0, m1, 'telemetry', ... (5 bytes)) Client mosqpub/85317-wa3z008d- sending PUBLISH (d1, q2, r0, m1, 'telemetry', ... (5 bytes)) Client mosqpub/85317-wa3z008d- sending PUBLISH (d1, q2, r0, m1, 'telemetry', ... (5 bytes)) Client mosqpub/85317-wa3z008d- sending PINGREQ Client mosqpub/85317-wa3z008d- received PINGRESP Client mosqpub/85317-wa3z008d- sending PUBLISH (d1, q2, r0, m1, 'telemetry', ... (5 bytes)) Client mosqpub/85317-wa3z008d- sending PUBLISH (d1, q2, r0, m1, 'telemetry', ... (5 bytes)) Client mosqpub/85317-wa3z008d- sending PINGREQ Client mosqpub/85317-wa3z008d- received PINGRESP Client mosqpub/85317-wa3z008d- sending PUBLISH (d1, q2, r0, m1, 'telemetry', ... (5 bytes)) Client mosqpub/85317-wa3z008d- sending PUBLISH (d1, q2, r0, m1, 'telemetry', ... (5 bytes)) Client mosqpub/85317-wa3z008d- sending PUBLISH (d1, q2, r0, m1, 'telemetry', ... (5 bytes)) Client mosqpub/85317-wa3z008d- sending PINGREQ Client mosqpub/85317-wa3z008d- received PINGRESP

Publishing takes place in two scenarios:

  1. A device publishes telemetry, events or command responses to the adapter. The supported QoS for these types of messages are documented in the MQTT adapter's user guide. For telemetry QoS 0 and 1 are supported, for events QoS 1 and for command responses QoS 0 and 1 are supported.
  2. The MQTT adapter publishes command messages to the device. The MQTT adapter's user guide defines QoS 0 as the only QoS supported in this case, i.e. commands are always published to devices using QoS 0.

When a device (tested using paho & mosquitto clients) sends an event, a telemetry or a response to a command with QoS level 2, then the Mqtt Adapter discards those messages and the mqtt client keeps retrying indefinitely(default timeout is -1 unless explicitly specified by an user), while there is no response from adapter.

This is the behavior defined by MQTT. There is no negative ACK defined in MQTT. The MQTT adapter can either ignore messages with an unsupported QoS level or it can decide to close the connection to the device. We chose to ignore such messages instead of closing the connection because a device that uses an unsupported QoS would most probably simply reconnect and send the same (erroneous) message again and again and again ...

Maybe we can improve the user guide to be (even) more explicit. But IMHO the adapter works as designed (and documented).

IMHO it is also important how consistently a system behaves in case of invalid inputs, which attributes to user friendliness. In case of command & control, a device can subscribe successfully with QoS 2 (system works fine) and the same device face issues when try to send a response to those command with QoS 2.

IMHO it is consistent, if hono doesn't let devices successfully subscribe with QoS 2 to a control endpoint. It is also ok, that we (even) more explicitly update the user guide.

So your point is that we should deny a request to subscribe using QoS 2, right? I can live with that. Would you mind creating a PR?

Was this page helpful?
0 / 5 - 0 ratings