Search code examples
mqtttoit

Failing to connect to MQTT Broker when using physical device


Here is the code i'm trying to run:

import mqtt
import net
import tls
import net.x509
import device
import encoding.json


// Unique MQTT client ID to identify each client that connects to the MQTT broker.
CLIENT_ID ::= "$device.hardware_id"
// The publicly available Mosquitto MQTT server/broker is used in this example.
HOST      ::= "..."
// MQTT port 
PORT      ::= 8883
// MQTT topic name
TOPIC     ::= "..."

main:
  socket := net.open.tcp_connect HOST PORT
  tls_cert := tls.Certificate CLIENT_CERT PRIVATE_KEY
  tls_socket := tls.Socket.client socket
    --server_name=HOST
    --root_certificates=[SERVER_CERT]
    --certificate=tls_cert
    

  tls_socket.handshake

  client := mqtt.Client
    CLIENT_ID
    mqtt.TcpTransport tls_socket

  // Client is now connected.
  print "connected to $HOST"
  // Start subscribing to a topic.
  subscribe client  
  print "Subscribed to client"
  task:: my_task_1
  // Process subscribed messages.
  client.handle: | topic/string payload/ByteArray |
    decoded := json.decode payload
    print "Received message '$(decoded)' on '$topic'"

    // Stop after first message.
    //return

// Test task
my_task_1:
  while true:
    sleep --ms=5000
    print "task 1 is running"
 
subscribe client/mqtt.Client:
  // Subscripe to a topic
  client.subscribe TOPIC --qos=1
  print "Subscribed to topic '$TOPIC'"

It works perfectly well on a simulated device, but running it on an ESP32-­WROOM­-32UE it throws the following error:

EXCEPTION error. 
MALLOC_FAILED
  0: tls_handshake_            <sdk>/tls/session.toit:214:3
  1: Session.handshake.<block> <sdk>/tls/session.toit:99:9
  2: Session.handshake         <sdk>/tls/session.toit:79:3
  3: Socket.handshake          <sdk>/tls/socket.toit:53:5
  4: main                      /c:/.../MQTT/tls_connect.toit:29:14
  5: __entry__.<lambda>        <sdk>/core/entry.toit:46:20

I have tried multiple different devices of the same model, and all the other code I have uploaded to the devices have worked as expected.

I have removed certificates and personal paths from the code


Solution

  • When running MQTT over TLS concurrently with the primary connection to the Toit Cloud, the system have quite a few network buffers going on. That means the memory watermark is slightly higher than usually, pushing the system a bit further the previously.

    We're in the process of optimizing the memory usage in these scenarios, as well as better integrating out malloc implementation with the GC, to better handle these cases. I suspect 1.5 (scheduled to be released this month) will be a significant improvement here.