How to connect to HiveMQ Cloud from ESP32 via GSM mobile network SSLClientESP32

Hi,

I can t get a connection via TinyGsm plus SSLClientESP32 from an ESP32 with a SIM800L GSM modem. I tried all sorts of certificates related to HiveMQ. mqttClient.connect() returns -2. I have no clue how to solve this. I basically will give up and try another MQTT broker. But, by chance, if anyone has tried that with success, I would be curious.

#define RX_GPS 34 // → connect to TX on GPS board, GPIOs 34 & 35
#define TX_GPS 35 //pins for SoftwareSerial connection to the GPS module
#define MQTT_MESSAGE_SIZE 300
// Configure TinyGSM library
#define TINY_GSM_MODEM_SIM800 // Modem is SIM800
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
#define SIM800L_IP5306_VERSION_20200811

#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h> //I2C
#include <WiFi.h>
#include <PubSubClient.h> //MQTT
#include <ArduinoJson.h> //build a dynamic or static JSON buffer in memory
#include <time.h>
#include <TinyGPSPlus.h> // Tiny GPS Plus Library
#include <TinyGsmClient.h>
#include “utilities.h” // belongs to TinyGsmClient.h
#include <SoftwareSerial.h> // uses actually ESPSoftwareSerial
#include “hivemq_realroot_ca.h”
#include <SSLClientESP32.h> //GitHub - alkonosst/SSLClientESP32: SSLClient - generic secure client Arduino library using mbedtls

char buffer[MQTT_MESSAGE_SIZE]; //MQTT sending buffer

// WiFi
const char *ssid = “fastnetap”; // Enter your WiFi name
const char *password = “1rede2RAP!”; // Enter WiFi password

// MQTT Broker
const int mqtt_port = 8883;
const char *mqtt_username = “blabla”;
const char *mqtt_password = “blabla”;
//this is the TLS URI
const char *mqtt_broker = “blabla.s2.eu.hivemq.cloud”;
const char *topic = “something”;
const char *client_id = “something”;
unsigned int count = 0;

// Your GPRS credentials (leave empty, if missing)
const char apn = “xxx”; // Your APN
const char gprsUser = “”; // User
const char gprsPass = “”; // Password
const char simPIN = “”; // SIM card PIN code, if any

//ToDo dont know what this WiFiClient is
//WiFiClient wifiClient;
TinyGsm modem(Serial1);
TinyGsmClient gsmClient(modem);
SSLClientESP32 sslClient(&gsmClient);
PubSubClient mqttClient(sslClient);

Adafruit_MPU6050 mpu;
TinyGPSPlus gps;
SoftwareSerial gpsSerial(RX_GPS, TX_GPS); //RX GPIO34 and TX…GPIO35

void setup() {
//SerialMonitor via Serial0 - USB. Also used for programming/flashing the ESP32
Serial.begin(115200);
delay(10);

// GSM
sslClient.setCACert(lastTry);

connectGSMModemToMobileNetwork();
delay(1000);
\

//time sync from GSM network time
setDateTime();
Serial.print("[INFO] local clock synched. The time is: ");
Serial.println(getLocalTimestampAsString());

//MQTT
//ToDo MQTT_MAX_PACKET_SIZE:256 Maximum packet size. Override with setBufferSize()
mqttClient.setServer(mqtt_broker, mqtt_port);
delay(100);
if (!mqttClient.setBufferSize(MQTT_MESSAGE_SIZE)){
Serial.println(“[WARNING] could not resize MQTT pubsub buffer”);
} //try to resize buffer from default value of 256, returns True or False
//mqttClient.setCallback(callback);
while (!mqttClient.connected()) {
//String client_id = “radlone”;
//client_id += String(WiFi.macAddress());
Serial.printf(“[INFO] The client %s connects to the public MQTT broker\n”, client_id);
//if (mqttClient.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
if (mqttClient.connect(client_id, mqtt_username, mqtt_password)) {
Serial.println(“[INFO] Hive MQTT broker connected”);
} else {
Serial.print("[INFO] failed connecting Hive MQTT. State: ");
Serial.println(mqttClient.state());
delay(200);
}
}
//END MQTT
}

Pls see here Connecting to private broker with ESP32 + SIM800L

I have the guts feeling that this SNI thing is causing my problem.

Hello @kgmuzungu

Welcome to HiveMQ Community! I’m not familiar with TinyGSM Plus library but I can try to help you.

When you receive a -2 return value from mqttClient.connect() , this typically indicates a connection failure, which can be due to various reasons ranging from network issues.

Is the SIM800L GSM modem an ESP32 Hat? Is it possible to remove it from the ESP32 device and test the basic code provided below?

#include <WiFi.h>  
#include <PubSubClient.h>
#include <WiFiClientSecure.h>

//---- WiFi settings
const char* ssid = "XXXXXXXXXX"; // replace with your WiFi SSID
const char* password = "XXXXXXXXXX"; // replace with your WiFi Password

//---- HiveMQ Cloud Broker settings
const char* mqtt_server = "XXXXXXXXXX"; // replace with your HiveMQ Cluster URL
const char* mqtt_username = "XXXXXXXXXX"; // replace with your Username
const char* mqtt_password = "XXXXXXXXXX"; // replace with your Password
const int mqtt_port = 8883;

WiFiClientSecure espClient;  
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (500)
char msg[MSG_BUFFER_SIZE];
int value = 0;

// HiveMQ Cloud Let's Encrypt CA certificate (hardcoded)
static const char *root_ca PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
)EOF";

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}


void reconnect() {
  // Loop until we’re reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection… ");
    // MQTT client ID
    String clientId = "ESP32Client";
    // Attempt to connect
    if (client.connect(clientId.c_str(), mqtt_username, mqtt_password)) {
      Serial.println("connected!");
      // Once connected, publish an announcement…
      client.publish("testTopic", "Hello World!");
      // … and resubscribe
      client.subscribe("testTopic");
    } else {
      Serial.print("failed, rc = ");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  delay(500);
  // When opening the Serial Monitor, select 9600 Baud
  Serial.begin(9600);
  delay(500);

  setup_wifi();

  espClient.setCACert(root_ca);
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  unsigned long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, MSG_BUFFER_SIZE, "Hello World! #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("testTopic", msg);
  }
}

Kind regards,
Diego from HiveMQ Team

Thank you very much already. I have got it working already before via WiFi. But I will try your code too. Meanwhile I ve found out that the SIM800L modem (only 2G) does not support any SNI settings for SSL/TLS. I guess this is why I get the -2 state when connecting. I have ordered actually a 4G modem now, LilyGO TTGO T-SIM-A7670E R2 ESP32 - ESP32-WROVER, actually a ESP32 with an SIM A7670E which is a 4G modem supporting SNI. I am curious. I will post my experience here.

1 Like

hello, were you able to get it working with the 4G module? Thanks

Hi @Solo

Can you confirm your device supports TLS SNI How do I test locally if my IoT device has TLS-SNI?

Let us know!

Best,
Dasha from The HiveMQ Team