SimpleComponents / MQTT

82 views
Skip to first unread message

slos

unread,
Jun 29, 2022, 6:15:15 AMJun 29
to
Hello Dmitry,
I'm having fun playing with SimpleComponents MQTT implementation and I have some questions...

I'm on Debian Sid using :
GNAT Studio 23.0w (20220512) hosted on x86_64-pc-linux-gnu
GNAT 11.3.0 targeting x86_64-linux-gnu

GNAT Studio
(c) 2001-2022 AdaCore

Building the test application is fine using :
gprbuild -d -P/home/slos/Ada/SimpleComponents/components_4_62/test_components/components-connections_server-mqtt-test_mqtt.gpr -XObject_Dir=. -Xarch=x86_64 -XTarget_OS=Windows -XDevelopment=Debug -XLegacy=Ada2012 -XAtomic_Access=auto -XTasking=Multiple -XTraced_objects=Off /home/slos/Ada/SimpleComponents/components_4_62/test_components/test_mqtt_client.adb

Running using either "test.mosquitto.org" or local mosquitto gives an exception after some messages received :
Exception raised
raised GNAT.SOCKETS.SERVER.CONNECTION_ERROR : gnat-sockets-server.adb:1145

I don't recall having got exceptions with Gnat Community 2021 on Windows.
Could you please have a look on that behaviour ?

It should be possible to use user name and password but I haven't found how with your implementation.
Could you tell please ?

Of course, one should use TLS in this case. Is it feasible and how ?

Also, how to provide a timestamp ?

Thanks a lot for your kind support.

Best Regards,
Stéphane
https://www.ada4automation.org/

Dmitry A. Kazakov

unread,
Jun 29, 2022, 11:00:20 AMJun 29
to
On 2022-06-29 12:15, slos wrote:

> I'm having fun playing with SimpleComponents MQTT implementation and I have some questions...
>
> I'm on Debian Sid using :
> GNAT Studio 23.0w (20220512) hosted on x86_64-pc-linux-gnu
> GNAT 11.3.0 targeting x86_64-linux-gnu
>
> GNAT Studio
> (c) 2001-2022 AdaCore
>
> Building the test application is fine using :
> gprbuild -d -P/home/slos/Ada/SimpleComponents/components_4_62/test_components/components-connections_server-mqtt-test_mqtt.gpr -XObject_Dir=. -Xarch=x86_64 -XTarget_OS=Windows -XDevelopment=Debug -XLegacy=Ada2012 -XAtomic_Access=auto -XTasking=Multiple -XTraced_objects=Off /home/slos/Ada/SimpleComponents/components_4_62/test_components/test_mqtt_client.adb
>
> Running using either "test.mosquitto.org" or local mosquitto gives an exception after some messages received :
> Exception raised
> raised GNAT.SOCKETS.SERVER.CONNECTION_ERROR : gnat-sockets-server.adb:1145
>
> I don't recall having got exceptions with Gnat Community 2021 on Windows.
> Could you please have a look on that behaviour ?

It means that the other side (mosquitto) dropped the connection.

One possible case is when ping timeout (Keep_Alive) is set but the
client was silent for the period of time. You should send ping before
the timeout expires or reconnect.

> It should be possible to use user name and password but I haven't found how with your implementation.
> Could you tell please ?

User and password are set after TCP/IP connection established during
handshake (see Send_Connect).

> Of course, one should use TLS in this case. Is it feasible and how ?

Well, MQTT does not require SSL/TLS for user/password during the
handshake. But logically yes, without a secure layer (e.g. provided
GNUTLS or OpenSSL connection handlers) it makes little sense.

With SSL/TLS you could probably map users to certificates/keys and drop
user/password, but for the server side it is easier to have them in
order to maintain user access rights.

(In my opinion MQTT is a toy thing not be used for serious applications,
though I admit, it is hugely popular)

> Also, how to provide a timestamp ?

Hmm, where? MQTT is totally low-level. There are only string topic and
string messages, nothing else. Otherwise? if you want to send a time
stamp in a message use FILETIME or UNIX time epoch and pack 8 bytes UTC
offset to (low or big endian) in the corresponding resolution. MQTT
payload need not to be printable.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

slos

unread,
Jul 1, 2022, 4:51:30 AMJul 1
to
Le mercredi 29 juin 2022 à 17:00:20 UTC+2, Dmitry A. Kazakov a écrit :
> > Could you please have a look on that behaviour ?
> It means that the other side (mosquitto) dropped the connection.
>
> One possible case is when ping timeout (Keep_Alive) is set but the
> client was silent for the period of time. You should send ping before
> the timeout expires or reconnect.
Hello Dmitry,
Thanks for your answer.
I had set the "Keep_Alive" parameter :
Send_Connect (Client, "TestMQTTclient", Keep_Alive => 60.0);

If it is not set, one gets :
MQTT client test 1 started
MQTT client connected to test.mosquitto.org
Connect rejected identifier rejected

Indeed, I get exceptions because of this line :
GNAT.Exception_Traces.Trace_On (GNAT.Exception_Traces.Every_Raise);

I have played with mosquitto on localhost and wanted to see what would happen if the broker was shut down.
Problem is that I could not get an information or exception in this case.

So I had to add a check of the ping response in order to know if the broker is still there but maybe you have a better idea.

> > It should be possible to use user name and password but I haven't found how with your implementation.
> > Could you tell please ?
> User and password are set after TCP/IP connection established during
> handshake (see Send_Connect).
> > Of course, one should use TLS in this case. Is it feasible and how ?
> Well, MQTT does not require SSL/TLS for user/password during the
> handshake. But logically yes, without a secure layer (e.g. provided
> GNUTLS or OpenSSL connection handlers) it makes little sense.
>
> With SSL/TLS you could probably map users to certificates/keys and drop
> user/password, but for the server side it is easier to have them in
> order to maintain user access rights.
I use Gnoga as well and there are explanations on how to use SSL/TLS in Gnoga's documentation.
I wondered if such explanations where available to use with MQTT as well.

> (In my opinion MQTT is a toy thing not be used for serious applications,
> though I admit, it is hugely popular)
Well, there are many toy things used for serious applications ! ;-)
"Ada for Automation" being one of those... created by an Ada amateur...

> > Also, how to provide a timestamp ?
> Hmm, where? MQTT is totally low-level. There are only string topic and
> string messages, nothing else. Otherwise? if you want to send a time
> stamp in a message use FILETIME or UNIX time epoch and pack 8 bytes UTC
> offset to (low or big endian) in the corresponding resolution. MQTT
> payload need not to be printable.
You are right. I remember having played with nodes in Node-RED where there was something.
But from :
https://github.com/persan/mosquitto-ada
C.Publish (Mid => null, Topic => "test", Payload => "[" & GNAT.Time_Stamp.Current_Time & "] Hej", Qos => QOS_0, Retain => False);
or :
http://mosquitto.org/man/mosquitto_pub-1.html
Publish timestamp and temperature information to a remote host on a non-standard port and QoS 0:
mosquitto_pub -h 192.168.1.1 -p 1885 -t sensors/temperature -m "1266193804 32"
The timestamp is just part of the message string.

Unrelated, you have created your packages as childs of GNAT.Sockets.
Although it seems not a problem for using them, the applications can be built, that seems to be a problem for code navigation with GNAT Studio, even in latest version.
Is that a limitation of the tool or something I'm doing wrong ?

By the way, thanks to your MQTT implementation, this demo application is sending SIEMENS S7 PLC data to the mosquitto broker :
https://gitlab.com/ada-for-automation/ada-for-automation/-/tree/master/demo/142%20a4a_k0_S7

>
> --
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de

Dmitry A. Kazakov

unread,
Jul 1, 2022, 7:05:43 AMJul 1
to
On 2022-07-01 10:51, slos wrote:
> Le mercredi 29 juin 2022 à 17:00:20 UTC+2, Dmitry A. Kazakov a écrit :
>>> Could you please have a look on that behaviour ?
>> It means that the other side (mosquitto) dropped the connection.
>>
>> One possible case is when ping timeout (Keep_Alive) is set but the
>> client was silent for the period of time. You should send ping before
>> the timeout expires or reconnect.
> Hello Dmitry,
> Thanks for your answer.
> I had set the "Keep_Alive" parameter :
> Send_Connect (Client, "TestMQTTclient", Keep_Alive => 60.0);
>
> If it is not set, one gets :
> MQTT client test 1 started
> MQTT client connected to test.mosquitto.org
> Connect rejected identifier rejected

AFAIK it is a bug in mosquitto that it does not accept zero ping interval.

> Indeed, I get exceptions because of this line :
> GNAT.Exception_Traces.Trace_On (GNAT.Exception_Traces.Every_Raise);
>
> I have played with mosquitto on localhost and wanted to see what would happen if the broker was shut down.
> Problem is that I could not get an information or exception in this case.

It is unrelated to MQTT, just general TCP/IP behavior:

1. If one side (broker) shuts the socket down, the other side's (the
client) read ends with 0 payload.

2. If it crashes, the socket is closed and nothing happens until some
OS-specific timeout (might be seconds) and then the socket get shut down
and see above.

The second case could be improved by setting KEEP_ALIVE on the socket.
Not to confuse with MQTT's ping, which is rather a useless thing.

> So I had to add a check of the ping response in order to know if the broker is still there but maybe you have a better idea.

It is reverse. Ping is a sort of watchdog on the server side to drop off
sluggish clients.

If you want to speed up recognition that the broker had crashed use
TCP/IP KEEP_ALIVE option. Differently to ping it requires nothing from
you, being implemented transparently by the TCP/IP stack.

>> With SSL/TLS you could probably map users to certificates/keys and drop
>> user/password, but for the server side it is easier to have them in
>> order to maintain user access rights.
> I use Gnoga as well and there are explanations on how to use SSL/TLS in Gnoga's documentation.
> I wondered if such explanations where available to use with MQTT as well.

There is nothing specific to MQTT. All protocol implementations in
Simple Components (MQTT, HTTP, SMTP etc) use a connection server object.
If you take one like GNAT.Sockets.Server.Secure (GNUTLS) or
GNAT.Sockets.Server.OpenSSL (OpenSSL) with MQTT client/server and that
will give you MQTTS.

> Unrelated, you have created your packages as childs of GNAT.Sockets.

GNAT.Sockets.Server needs access to the private part of GNAT.Sockets.
That is the reason.

> Although it seems not a problem for using them, the applications can be built, that seems to be a problem for code navigation with GNAT Studio, even in latest version.
> Is that a limitation of the tool or something I'm doing wrong ?

It never worked well, if you mean "go to declaration" stuff. I know that
AdaCore is changing the cross-reference stuff. Maybe it will get better
at some point. (before getting worse first! (:-))

> By the way, thanks to your MQTT implementation, this demo application is sending SIEMENS S7 PLC data to the mosquitto broker :
> https://gitlab.com/ada-for-automation/ada-for-automation/-/tree/master/demo/142%20a4a_k0_S7

Nice.

P.S. In the proprietary code we rather use iTOT for SPS communication
which is far more efficient. Unfortunately it cannot be included into
the Simple Components.

slos

unread,
Jul 1, 2022, 9:22:36 AMJul 1
to
Hi Dmitry,

Thanks a lot for the provided information. Much appreciated !
Reply all
Reply to author
Forward
0 new messages