MQTT connection to AWS-IOT-CORE

Hi,

I’m working on a proof of concept at present that requires some simple feature extraction from an image captured with a Lepton sensor, and the key params of the features periodically returned from the camera to our core systems via MQTT, in this case through the Amazon AWS-IOT-Core MQTT broker.

We have the image capture and feature extraction running well on an H7 with the Lepton Breakout, and also have a Wifi Shield providing connectivity,

Additionally, on another platform, we have also successfully proven the MQTT configuration and functionality.

Unfortunately, we have hit a stumbling block in getting the H7 to make a successful MQTT connection to the AWS broker.

As the Amazon connection requires SSL / TLS the H7 has been updated to firmware 3.5.0 and the Wifi Shield to winc_19_6_1

Our code runs ok, connects to the wifi but then generates the exception below when trying to make the MQTT connection,

mbedtls_ssl_handshake error: -9

Traceback (most recent call last):
File “”, line 48, in
File “mqtt.py”, line 54, in connect
OSError: [Errno 5] EIO

The MQTT connection code which is pretty much verbatim from other Micropython AWS MQTT examples is as below :

KEY_PATH = "TestThing.private.key"
CERT_PATH = "TestThing.cert.pem"

with open(KEY_PATH, 'r') as f:
    key1 = f.read()

with open(CERT_PATH, 'r') as f:
    cert1 = f.read()

client = MQTTClient(client_id="basicPubSub",
                    server="a2708s3n9i3daw-ats.iot.eu-west-1.amazonaws.com",
                    port=8883,
                    keepalive=4000,
                    ssl=True,
                    ssl_params={ "key":key1, "cert":cert1, "server_side":False })



client.connect()

I’ve already burnt a fair amount of time trying to get to the bottom of it, so thought I’d check if its an issue anyone else has any experience of before I get stuck in for round 2 tomorrow

Thanks

Steve

You must be running one of the beta firmware images because I’ve just release v3.5.0 an hour ago. Anyway, line 54 is an empty line in the mqtt.py module ? are you using a different mqtt.py library ? If you update the firmware to 3.5.0 mqtt.py is now frozen (built-in) you should use that (and remove mqtt.py from the flash/sd if you still have it there). There’s no easy way for me to test this (unless you could provide steps, keys etc…).

Yes, I just realised it was a beta image, apologies, should have mentioned that in the original post, however, I have now updated to the 3.5.0 release and removed the mqtt.py from flash, basically getting the same error except at a different line number in mqtt.py eg

mbedtls_ssl_handshake error: -9

Traceback (most recent call last):
File “”, line 48, in
File “mqtt.py”, line 62, in connect
OSError: [Errno 5] EIO
MicroPython v1.11-omv OpenMV v3.5.0 2019-11-04; OPENMV4-STM32H743
Type “help()” for more information.

I’m going to be a bit busy on another project today but I’ll do some further tests later and if I still have no joy I could provide keys etc (as this is only a test system) to allow you to see if you can re-create the issue

Thanks again

Steve

Okay, btw when I was testing this I noticed it failed if server_hostname was not set (see the http_client_ssl.py example).

I got a bit delayed on some other projects but managed to back on this again today.

To be on the safe side I went back to basics and verified my code and key/cert on some other platforms, and one thing I did discover was that on an ESP8266 based MicroPython system I needed to format my certificate/key as binary DER in order to successfully connect, it occurred that perhaps this could be the issue here so I gave the binary files a try on OpenMV and it does now appear that I am no longer getting the ssl_handshake_error at 62 in mqtt.py

self.sock = ussl.wrap_socket(self.sock, **self.ssl_params)

This suggests to me that using the binary files is letting me establish a secure connection, but I’m now hitting a new error when trying to send data over this connection as I now get an exception at line 87 in mqtt.py

self.sock.send(premsg[0:i + 2])

eg

Traceback (most recent call last):
File “”, line 50, in
File “mqtt.py”, line 87, in connect
AttributeError: ‘ussl’ object has no attribute ‘send’
MicroPython v1.11-omv OpenMV v3.5.0 2019-11-04; OPENMV4-STM32H743

This confuses me a bit as looking at the ussl docs at ssl – SSL/TLS module — MicroPython latest documentation it says

In MicroPython, the returned object does not expose socket interface and methods like recv(), send()

Anyway, that’s about as far as I can get at present, so any help would be much appreciated if you had the time, accordingly, I’ll pm you the key/cert in both ASCII and binary format

Many Thanks Again

Steve

That’s right it doesn’t have send/recv you just need to use read/write instead.

Just a quick update,

I’ve created my own MQTT module that uses read / write when the socket is secure using ussl, and this works fine.

To summarise, in case anyone else is looking to use MQTT to connect to AWS (in my case from OpenMV v3.5.0) :

The cert and key files require to be in binary format

The built-in mqtt.py generates an exception when ussl is used to wrap the socket as it uses send / recv as opposed to write / read , but adding modified MQTT code to use write and read on the secure socket connection resolves the issue


Steve

That’s great to hear! I’ll modify the built-in MQTT lib to use read/write for SSL sockets.

Hi, I’ve just updated the mqtt library to use write/read instead of send/recv. For “regular” sockets, write/read call send/recv and for SSL sockets they call the stream write/read functions. This should be out in the next release (3.5.2)