adafruit/Adafruit_CircuitPython_MiniMQTT

Loop crashes after successful connecting to HiveMQ (tls)

Opened this issue · 7 comments

I used the sample code from "https://github.com/adafruit/Adafruit_CircuitPython_MiniMQTT/blob/main/examples/native_networking/minimqtt_adafruitio_native_networking.py" and modified it to connect to HiveMQ.

It requires tls, so besides changing wifi and mqtt credentials, I also added the is_ssl = True flag.

I can connect but after the loop is called once, the connection fails with an empty Exception:

Traceback (most recent call last):
File "", line 69, in
File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 1050, in loop
File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 1078, in _wait_for_msg
MMQTTException:

Digging deeper into it, and changing line 1078 to just "raise", gives a bit more insights:
Traceback (most recent call last):
File "", line 69, in
File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 1050, in loop
File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 1073, in _wait_for_msg
File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 1160, in _sock_exact_recv
OSError: -116

But not much more.

EDIT: I use RPi Pico WS, tested with CircuitPython 8 and 9, also the official release libraries and the most recent minimqtt code from here.
Connecting to a local broker without credentials works fine.

The full code of the test script is:

import os
import time
import ssl
import socketpool
import wifi
import adafruit_minimqtt.adafruit_minimqtt as MQTT
import adafruit_logging as logging

mqtt_username = "REMOVED"
mqtt_pw = "REMOVED"
brokerurl = "REMOVED"
wifi.radio.connect("REMOVED", "REMOVED")


print(f"Connected to wifi")
def connected(client, userdata, flags, rc):
    print(f"Connected")
    client.subscribe("#")
    print(f"subscribed")


def disconnected(client, userdata, rc):
    # This method is called when the client is disconnected
    print("Disconnected from Adafruit IO!")


def message(client, topic, message):
    # This method is called when a topic the client is subscribed to
    # has a new message.
    print(f"New message on topic {topic}: {message}")


# Create a socket pool
pool = socketpool.SocketPool(wifi.radio)
ssl_context = ssl.create_default_context()

# If you need to use certificate/key pair authentication (e.g. X.509), you can load them in the
# ssl context by uncommenting the lines below and adding the following keys to the "secrets"
# dictionary in your secrets.py file:
# "device_cert_path" - Path to the Device Certificate
# "device_key_path" - Path to the RSA Private Key
# ssl_context.load_cert_chain(
#     certfile=secrets["device_cert_path"], keyfile=secrets["device_key_path"]
# )

# Set up a MiniMQTT Client
mqtt_client = MQTT.MQTT(
    broker=brokerurl,
    port=8883,
    username=mqtt_username,
    password=mqtt_pw,
    socket_pool=pool,
    is_ssl=True,
    ssl_context=ssl_context,
)
mqtt_client.enable_logger(logging, 0)

# Setup the callback methods above
mqtt_client.on_connect = connected
mqtt_client.on_disconnect = disconnected
mqtt_client.on_message = message

# Connect the client to the MQTT broker.
print("Connecting to broker...")
mqtt_client.connect()

photocell_val = 0
while True:    
    mqtt_client.loop()
    time.sleep(0.1)

The log output is:

%Run -c $EDITOR_CONTENT
Connected to wifi
Connecting to broker...
2186.650: DEBUG - Attempting to connect to MQTT broker (attempt #0)
2186.653: DEBUG - Attempting to establish MQTT connection...
2186.658: INFO - Establishing a SECURE SSL connection to REMOVED
2188.582: DEBUG - Sending CONNECT to broker...
2188.586: DEBUG - Fixed Header: bytearray(b'\x10+')
2188.590: DEBUG - Variable Header: bytearray(b'\x00\x04MQTT\x04\xc2\x00<')
2188.600: DEBUG - Receiving CONNACK packet from broker
2189.115: DEBUG - Got message type: 0x20 pkt: 0x20
Connected
2189.122: DEBUG - Sending SUBSCRIBE to broker...
2189.126: DEBUG - Fixed Header: bytearray(b'\x82\x06')
2189.133: DEBUG - Variable Header: b'\x00\x01'
2189.139: DEBUG - SUBSCRIBING to topic # with QoS 0
2189.143: DEBUG - payload: b'\x00\x01#\x00'
2189.334: DEBUG - Got message type: 0x90 pkt: 0x90
subscribed
2189.340: DEBUG - Resetting reconnect backoff
2189.344: DEBUG - waiting for messages for 0 seconds
Traceback (most recent call last):
File "", line 69, in
File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 1050, in loop
File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 1073, in _wait_for_msg
File "/lib/adafruit_minimqtt/adafruit_minimqtt.py", line 1160, in _sock_exact_recv
OSError: -116


same problem
also talked about it here
but if i use a
adafruit_minimqtt
from 21.12.2022 OK,
?because it skips the CP's timing?

There is something about Pico W and the negative 116, see #177 (comment)

Not much of a contribution, but I just wanted to mention that I am also facing exactly this problem on a similar environment:

  • Raspi Pico W with CircuitPython 8.2.10
  • HiveMQ cloud broker (TLS)
  • CP lib bundle 8.x from 2024-03-07

Can you try with 9.0.0? This was caught in the 8->9 path that the Pico did errors differently.

Yes indeed. I have just tried to run it with CircuitPython 9.0.3 and it worked fine without the exception I faced with 8.2.10.
Thanks for the hint!

@philipphock are you willing to test in CP9? We should be able to close this out

I believe this should be moved to CP issues.