MQTT PSK Implementation

I have a Mosquitto MQTT Broker set up using TLS via Pre-Shared Key. I’ve tested it by running a mosquitto client remotely and the broker itself is functioning properly. I’ve also tested MQTT on a Flexy with standard unencrypted MQTT on port 1883, based on the example BASIC code found here:
https://tools.ewonsupport.biz/mqtt/program.txt

So, what I am attempting to do now is modify the BASIC code from the example to change the port to 8883 and include the proper PSK information.

Below is what I have at the moment (only pasting in the portions of code that I’m modifying):
//######## CONFIG ###############
MQTTBrokerURL$ = “public IP address”
MQTTPort$ = “8883”
MQTTpsk_identity$ = “PSK Hint”
MQTTpsk$ = “hexadecimal PSK”
TopicToPublishOn$ = “/topic/flexy/” + SerNum$ + “/data”
TopicToSubscribe$ = “/topic/flexy/” + SerNum$ + “/command”
MsgToPublish$ = "Hello From Flexy " + SerNum$

//Uncomment the below line if you want to send your Tag values in a json format
SendTagValues% = 1

//######## END CONFIG ###############

Last_ConnStatus% = 0
//Configure MQTT Connection parameters

CONNECTMQTT:
MQTT “OPEN”, SerNum$ , MQTTBrokerURL$
MQTT “SETPARAM”, “PORT”, MQTTPort$
MQTT “SETPARAM”, “PSK”, MQTTpsk$
MQTT “SETPARAM”, “PSK-IDENTITY”, MQTTpsk_identity$
MQTT “SETPARAM”, “KEEPALIVE”, “30”
MQTT “SUBSCRIBE”,TopicToSubscribe$,1
//Launch the MQTT process in the background
SETSYS PRG,“RESUMENEXT”,1 //Continue in case of error at MQTT “CONNECT”
MQTT “CONNECT”
//If an error is raised --> Log a message
ErrorReturned% = GETSYS PRG,“LSTERR”
IF ErrorReturned% = 28 THEN @Log("[MQTT SCRIPT] WAN interface not yet ready")
SETSYS PRG,“RESUMENEXT”,0
//When receiving a message from Broker, “GOTO MQTTRECEIVEMSG”
ONMQTT “GOTO MQTTRECEIVEMSG”
ONTIMER 1, “GOTO SENDDATA”
TSET 1,30 //publish every 30 seconds
END

When I run this, I receive the error:
Operation failed (28) 38: MQTT “SETPARAM”, “PSK”, MQTTpsk$

So, my assumption is that “PSK” isn’t the proper parameter name to use here, but I haven’t been able to find any documentation about implementing TLS-PSK in BASIC. Any help would be awesome!

TLS-PSK is not supported on the Ewon so you’ll have to use certificate for TLS. I’ve found that working with certificates can be intimidating at first, but once you have set it up a few times, it will be very easy. Let me know if you have any questions about the process and I can try to help.

Here is an example of setting up MQTT over TLS:

https://techforum.ewon.biz/thread-786.html

The example uses Azure. I’m not sure how you are planning on creating your certificates, but you will want to consider this post also if you are creating certificates using openssll :

https://techforum.ewon.biz/thread-985.html

No problem, I’m sure I can noodle my way through it!

Out of curiosity (keep in mind, I’m no software programmer), what is the limitation for supporting TLS-PSK, or any other type of feature, for that matter? Is it something that isn’t supported by BASIC as a whole, or something that eWon would need to develop the function internally and it would be included somewhere in the background? In the sample code, I see that there is a command called MQTT and then you pass different parameters to it. Is the function running in the background that defines the MQTT command something that eWon developed?

The only reason I ask is I was having trouble finding anything regarding TLS-PSK implementation with BASIC in general…though it’s very difficult to Google “BASIC” and find results pertaining to the programming language!

I honestly am not sure why it’s not supported, but I would guess that the Flexy has a minimal build of openssl and TLS-PSK wasn’t included because there wasn’t a demand at the time. I will try to find out. I don’t think it has anything to do with BASIC. The MQTT functionality is built into the Flexy with APIs for BASIC and JAVA. Here is the documentation for the BASIC commands. We have a page you should check out if you haven’t already:

We don’t have a great tutorial for setting up the Flexy with a Mosquitto Broker and creating the certificates. I think I’m going to try to create one when I have a chance!

Thanks Kyle, that is all great information! I’ll comb through it when I can find some time! Appreciate all the help!

1 Like

Good Morning, thought I’d just continue this thread instead of creating a new one.

I have my certs setup on my mosquitto broker on our remote server and have tested connection with a local client via the domain name. All is well there. But, I’m not able to connect from the eWon…I’m sure I’m missing something pretty basic.

CLS
SETSYS INF, “LOAD”
SerNum$ = “20192063”
SendTagValues% = 0
//######## CONFIG ###############
MQTTBrokerURL$ = “my.domain.com
MQTTPort$ = “8884”
MQTTCaCert$ = “/usr/mqtt/certs/ca.crt”
MQTTClientCert$ = “/usr/mqtt/certs/client.crt”
MQTTkey$ = “/usr/mqtt/certs/server.key”
TopicToPublishOn$ = “/topic/flexy/” + SerNum$ + “/data”
TopicToSubscribe$ = “/topic/flexy/” + SerNum$ + “/command”
MsgToPublish$ = “Hello From Flexy " + SerNum$
//Uncomment the below line if you want to send your Tag values in a json format
SendTagValues% = 1
//######## END CONFIG ###############
Last_ConnStatus% = 0
//Configure MQTT Connection parameters
CONNECTMQTT:
MQTT “OPEN”, SerNum$ , MQTTBrokerURL$
MQTT “SETPARAM”, “PORT”, MQTTPort$
MQTT “SETPARAM”, “KEEPALIVE”, “30”
MQTT “SETPARAM”, “cafile”, MQTTCaCert$
MQTT “SETPARAM”, “certfile”, MQTTClientCert$
MQTT “SETPARAM”, “keyfile”, MQTTkey$
MQTT “SUBSCRIBE”,TopicToSubscribe$,1
//Launch the MQTT process in the background
SETSYS PRG,“RESUMENEXT”,1 //Continue in case of error at MQTT “CONNECT”
MQTT “CONNECT”
//If an error is raised --> Log a message
ErrorReturned% = GETSYS PRG,“LSTERR”
IF ErrorReturned% = 28 THEN @Log(”[MQTT SCRIPT] WAN interface not yet ready")
SETSYS PRG,“RESUMENEXT”,0

The first thing about our setup is that we’re using port 8884 instead of 8883 because I left our listener for TLS-PSK intact. If eWon doesn’t support a connection on Port 8884, then I can easily change this.

Also, I have the broker set up so that it doesn’t require username / password. It simply needs the cert files in order to encrypt traffic. Maybe my logic is flawed, but I wouldn’t think the username/password auth would be necessary since the CA cert is required and that wouldn’t be able to be obtained any easier than a username/password?

Using the MQTT.fx utility, I’m able to connect with the following configuration:
image

I’m also able to connect with this connection scheme:

The BASIC IDE console is report this error:
image

Any pointers is greatly appreciated!

Did you use a password when creating the certs?

Does your broker support just TLSv1.1 or 1.2 also?

Ah, yes, it did prompt for a password when creating the cert.

It supports 1.2, I just happen to have it set at v1.1 for now. I can also get that bumped up if need be.

You should be able to create the cert without a password and it will work. I haven’t done it in a while, but I know that is an option.

I was able to get the cert setup without a password and confirmed functionality with the MQTT.fx client:

I’m also no longer getting the “Operation failed (28) 46: MQTT “CONNECT”” error. Instead, when I run the script, I get nothing in the console for 10 seconds and then I get the following:
image

Afterwhich, the “Flexy not connected” line repeats every 10 seconds.

I’ve copied my BASIC init section below, apologies for how long it is…just wanted to make everything was in there in case I messed something up along the way.

CLS
SETSYS INF, “LOAD”
SerNum$ = “20192063”
SendTagValues% = 1
//######## CONFIG ###############
MQTTBrokerURL$ = “my.domain”
MQTTPort$ = “8884”
TopicToPublishOn$ = “/topic/flexy/” + SerNum$ + “/data”
TopicToSubscribe$ = “/topic/flexy/” + SerNum$ + “/command”
MsgToPublish$ = “Hello From Flexy " + SerNum$
//Uncomment the below line if you want to send your Tag values in a json format
SendTagValues% = 1
//######## END CONFIG ###############
Last_ConnStatus% = 0
//Configure MQTT Connection parameters
CONNECTMQTT:
MQTT “OPEN”, SerNum$ , MQTTBrokerURL$
MQTT “SETPARAM”, “PORT”, MQTTPort$
MQTT “SETPARAM”, “KEEPALIVE”, “30”
MQTT “SETPARAM”, “CAFILE”, “/usr/mqtt/certs/ca.crt”
MQTT “SETPARAM”, “CERTFILE”, “/usr/mqtt/certs/client.crt”
MQTT “SETPARAM”, “KEYFILE”, “/usr/mqtt/certs/client.key”
MQTT “SETPARAM”, “PROTOCOLVERSION”, “3.1.1”
MQTT “SETPARAM”, “TLSVERSION”, “tlsv1.2”
MQTT “SUBSCRIBE”,TopicToSubscribe$,1
//Launch the MQTT process in the background
SETSYS PRG,“RESUMENEXT”,1 //Continue in case of error at MQTT “CONNECT”
MQTT “CONNECT”
//If an error is raised --> Log a message
ErrorReturned% = GETSYS PRG,“LSTERR”
IF ErrorReturned% = 28 THEN @Log(”[MQTT SCRIPT] WAN interface not yet ready")
SETSYS PRG,“RESUMENEXT”,0
//When receiving a message from Broker, “GOTO MQTTRECEIVEMSG”
ONMQTT “GOTO MQTTRECEIVEMSG”
ONTIMER 1, “GOTO SENDDATA”
TSET 1,10 //publish every 10 seconds
END
SENDDATA:
//Read MQTT Connection Status (5 = Connected, other values = Not connected)
ConnStatus% = MQTT “STATUS”
IF Last_ConnStatus% <> ConnStatus% THEN
IF ConnStatus% = 5 THEN //Connection is back online
@Log("[MQTT SCRIPT] Flexy connected to Broker")
ELSE
@Log("[MQTT SCRIPT] Flexy disconnected from Broker")
ENDIF
Last_ConnStatus% = ConnStatus%
ENDIF
//IF Connected --> Publish messages
IF ConnStatus% = 5 THEN //If connected --> Publish
IF SendTagValues% = 1 THEN
NB% = GETSYS PRG,“NBTAGS”
MsgToPublish$ = “[”
FOR i% = 0 TO NB%-1
SETSYS Tag, “load”,-i%
TagName$ = GETSYS Tag, “Name”
TagValue$ = GETSYS Tag, “TagValue”
IF i% = 0 THEN
MsgToPublish$ = MsgToPublish$ + ‘{“tag”:"’ + TagName$ + ‘",“value”:’ + TagValue$ + ‘,“time”:"’ + @GetTime$() + ‘"}’
ELSE
MsgToPublish$ = MsgToPublish$ + ‘,{“tag”:"’ + TagName$ + ‘",“value”:’ + TagValue$ + ‘,“time”:"’ + @GetTime$() + ‘"}’
ENDIF
NEXT i%
MsgToPublish$ = MsgToPublish$ + “]”
ENDIF
MQTT “PUBLISH”, TopicToPublishOn$ , MsgToPublish$, 0,0
PRINT “[MQTT SCRIPT] Message '” + MsgToPublish$ + “’ sent on topic : " + TopicToPublishOn$
ELSE //If not connected --> Save message in file
@Log(”[MQTT SCRIPT] Flexy not connected")
ENDIF
END
MQTTRECEIVEMSG:
//Executed when receiving messages from Broker
MessageQty%=Mqtt “READ” //Return the number of pending messages
IF (MessageQty%>0) Then
MsgTopic$= MQTT “MSGTOPIC”
MsgData$ = MQTT “MSGDATA”
@Log("[MQTT SCRIPT] Message ‘"+ MsgData$ + "’ received on topic " +MsgTopic$)
GOTO MQTTRECEIVEMSG
ENDIF
END
FUNCTION Log($Msg$)
LOGEVENT $Msg$ ,100
PRINT $Msg$
ENDFN
Function GetTime$()
$a$ = Time$
$GetTime$ = $a$(7 To 10) + “-” + $a$(4 To 5) + “-” + $a$(1 To 2) + " " + $a$(12 To 13)+":"+$a$(15 To 16)+":"+$a$(18 To 19)
EndFn

I’m having a hard time finding the reason why ConnStatus isn’t 5 here. You are no longer getting the BASIC error upon connection.

Can you create a full backup with eBuddy and include the Support Files so that I can see all of the logs?

That seemed strange to me as well. Backup w/ Support Files attached. Thanks!

MOVED TO STAFF NOTE (1.2 MB)

Did you test this with your Mosquitto server? Is it a local server or hosted on the internet?

Hi Kyle, yes I used the MQTT.fx client on my local machine and was able to connect to the mosquitto server. It is hosted remotely on one of our servers and I’m accessing it over the internet via domain name.

I think this is your problem:

https://techforum.ewon.biz/thread-985-post-4218.html#pid4218

The SAN “Subject Alternative Name” field on the cert does not match the domain name that the Flexy needs to connect to.

Hi Kyle, everything seems to be up and running! All I really need to do now is play around with the format of the data being sent and I’ll be good to go! Thanks for all the help!

1 Like

Awesome! Thank you for the update!

Let me know if there is anything else that we can do-