Skip to content

Instantly share code, notes, and snippets.

@gmag11
Last active February 26, 2024 10:13
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save gmag11/c565a18d361a46993039f8a515e67614 to your computer and use it in GitHub Desktop.
Save gmag11/c565a18d361a46993039f8a515e67614 to your computer and use it in GitHub Desktop.
Secure MQTT connection to broker with ESP32 and internal IDF mqtt client library
#include "Arduino.h"
#include <WiFi.h>
#include "esp_log.h"
#include "esp_system.h"
#include "esp_event.h"
#include "mqtt_client.h"
#define SECURE_MQTT // Comment this line if you are not using MQTT over SSL
#ifdef SECURE_MQTT
#include "esp_tls.h"
// Let's Encrypt CA certificate. Change with the one you need
static const unsigned char DSTroot_CA[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----
)EOF";
#endif // SECURE_MQTT
esp_mqtt_client_config_t mqtt_cfg;
esp_mqtt_client_handle_t client;
const char* WIFI_SSID = "Your_SSID";
const char* WIFI_PASSWD = "Your_password";
const char* MQTT_HOST = "Your_broker_address";
#ifdef SECURE_MQTT
const uint32_t MQTT_PORT = 8883;
#else
const uint32_t MQTT_PORT = 1883;
#endif // SECURE_MQTT
const char* MQTT_USER = "Username_in_broker";
const char* MQTT_PASSWD = "password";
static esp_err_t mqtt_event_handler (esp_mqtt_event_handle_t event) {
if (event->event_id == MQTT_EVENT_CONNECTED) {
ESP_LOGI ("TEST", "MQTT msgid= %d event: %d. MQTT_EVENT_CONNECTED", event->msg_id, event->event_id);
esp_mqtt_client_subscribe (client, "test/hello", 0);
esp_mqtt_client_publish (client, "test/status", "1", 1, 0, false);
}
else if (event->event_id == MQTT_EVENT_DISCONNECTED) {
ESP_LOGI ("TEST", "MQTT event: %d. MQTT_EVENT_DISCONNECTED", event->event_id);
//esp_mqtt_client_reconnect (event->client); //not needed if autoconnect is enabled
} else if (event->event_id == MQTT_EVENT_SUBSCRIBED) {
ESP_LOGI ("TEST", "MQTT msgid= %d event: %d. MQTT_EVENT_SUBSCRIBED", event->msg_id, event->event_id);
} else if (event->event_id == MQTT_EVENT_UNSUBSCRIBED) {
ESP_LOGI ("TEST", "MQTT msgid= %d event: %d. MQTT_EVENT_UNSUBSCRIBED", event->msg_id, event->event_id);
} else if (event->event_id == MQTT_EVENT_PUBLISHED) {
ESP_LOGI ("TEST", "MQTT event: %d. MQTT_EVENT_PUBLISHED", event->event_id);
} else if (event->event_id == MQTT_EVENT_DATA) {
ESP_LOGI ("TEST", "MQTT msgid= %d event: %d. MQTT_EVENT_DATA", event->msg_id, event->event_id);
ESP_LOGI ("TEST", "Topic length %d. Data length %d", event->topic_len, event->data_len);
ESP_LOGI ("TEST","Incoming data: %.*s %.*s\n", event->topic_len, event->topic, event->data_len, event->data);
} else if (event->event_id == MQTT_EVENT_BEFORE_CONNECT) {
ESP_LOGI ("TEST", "MQTT event: %d. MQTT_EVENT_BEFORE_CONNECT", event->event_id);
}
return ESP_OK;
}
void setup () {
mqtt_cfg.host = MQTT_HOST;
mqtt_cfg.port = MQTT_PORT;
mqtt_cfg.username = MQTT_USER;
mqtt_cfg.password = MQTT_PASSWD;
mqtt_cfg.keepalive = 15;
#ifdef SECURE_MQTT
mqtt_cfg.transport = MQTT_TRANSPORT_OVER_SSL;
#else
mqtt_cfg.transport = MQTT_TRANSPORT_OVER_TCP;
#endif // SECURE_MQTT
mqtt_cfg.event_handle = mqtt_event_handler;
mqtt_cfg.lwt_topic = "test/status";
mqtt_cfg.lwt_msg = "0";
mqtt_cfg.lwt_msg_len = 1;
Serial.begin (115200);
WiFi.mode (WIFI_MODE_STA);
WiFi.begin (WIFI_SSID, WIFI_PASSWD);
while (!WiFi.isConnected ()) {
Serial.print ('.');
delay (100);
}
Serial.println ();
#ifdef SECURE_MQTT
esp_err_t err = esp_tls_set_global_ca_store (DSTroot_CA, sizeof (DSTroot_CA));
ESP_LOGI ("TEST","CA store set. Error = %d %s", err, esp_err_to_name(err));
#endif // SECURE_MQTT
client = esp_mqtt_client_init (&mqtt_cfg);
//esp_mqtt_client_register_event (client, ESP_EVENT_ANY_ID, mqtt_event_handler, client); // not implemented in current Arduino core
err = esp_mqtt_client_start (client);
ESP_LOGI ("TEST", "Client connect. Error = %d %s", err, esp_err_to_name (err));
}
void loop () {
esp_mqtt_client_publish (client, "test/bye", "data", 4, 0, false);
delay (2000);
}
@r-sherwood
Copy link

I was having a headache try to debug the random crash issue when too many data received at once, the best way to handle it is to put a flag, and that the outer function catches it to do the rest of work.

@poky I'm facing the same issues and don't know how to solve it. Can you provide a sample how to deal with your recommended flaged incoming MQTT_EVENT_DATA and outer functions?

Thanks

@poky
Copy link

poky commented Nov 21, 2022

I was having a headache try to debug the random crash issue when too many data received at once, the best way to handle it is to put a flag, and that the outer function catches it to do the rest of work.

@poky I'm facing the same issues and don't know how to solve it. Can you provide a sample how to deal with your recommended flaged incoming MQTT_EVENT_DATA and outer functions?

Thanks

Add a function something like this...

void example_task()
{
if(flag)
{
// Some codes
flag = false;
}
}

add example_task() to the loop function to run.
Once the MQTT_EVENT_DATA event arrived, just make flag = true, so the function will run outside of the event handler.

@pprakash
Copy link

pprakash commented Jan 8, 2023

Hi, I tried to compile and run this on Platform IO. Compile was successful but was getting below error while running on ESP32-WROOM-32.
Any help on resolving this?

E (327) esp-tls-mbedtls: No server verification option set in esp_tls_cfg_t structure. Check esp_tls API reference E (328) esp-tls-mbedtls: Failed to set client configurations, returned [0x8017] (ESP_ERR_MBEDTLS_SSL_SETUP_FAILED) E (337) esp-tls: create_ssl_handle failed E (341) esp-tls: Failed to open new connection E (345) TRANSPORT_BASE: Failed to open a new connection E (352) MQTT_CLIENT: Error transport connect

Build Enviornment:
Visual Studio Code with Platform IO
PLATFORM: Espressif 32 (5.2.0)

  • framework-arduinoespressif32 @ 3.20005.220925 (2.0.5)
  • tool-esptoolpy @ 1.40201.0 (4.2.1)

@gmag11
Copy link
Author

gmag11 commented Jan 8, 2023

Maybe something has changed in IDF. I'll test it

@pprakash
Copy link

pprakash commented Jan 10, 2023

It works with Espresif 32 ( 3.2.1) core of Platform IO.

@gmag11
Copy link
Author

gmag11 commented Jan 21, 2023

Hi, I tried to compile and run this on Platform IO. Compile was successful but was getting below error while running on ESP32-WROOM-32. Any help on resolving this?

E (327) esp-tls-mbedtls: No server verification option set in esp_tls_cfg_t structure. Check esp_tls API reference E (328) esp-tls-mbedtls: Failed to set client configurations, returned [0x8017] (ESP_ERR_MBEDTLS_SSL_SETUP_FAILED) E (337) esp-tls: create_ssl_handle failed E (341) esp-tls: Failed to open new connection E (345) TRANSPORT_BASE: Failed to open a new connection E (352) MQTT_CLIENT: Error transport connect

Build Enviornment: Visual Studio Code with Platform IO PLATFORM: Espressif 32 (5.2.0)

  • framework-arduinoespressif32 @ 3.20005.220925 (2.0.5)
  • tool-esptoolpy @ 1.40201.0 (4.2.1)

I've compiled on latest Platformio ESP32 (6.0.0) and it compiles fine.

image

image

@MichMich
Copy link

Try adding the following:

mqtt_cfg.use_global_ca_store = true;

@russinnes
Copy link

mqtt_cfg.use_global_ca_store = true;

Required in arduino IDE 2.2 if you want TLS to work..

@JNRAY
Copy link

JNRAY commented Nov 18, 2023

Hello,
Could you tel me how do you generate the certificat ?

@bimalsatheesh
Copy link

Hello @gmag11, I have tested the code in esp32 Arduino platform and successfully published test messages to the given topic - test/bye. But I couldn't get any messages in the subscribed topic - test/hello. Couldn't find what is the issue. Please guide,
Thanks

@gmag11
Copy link
Author

gmag11 commented Nov 29, 2023

Hello, Could you tel me how do you generate the certificat ?

You can use OpenSSL utility. For instance http://www.steves-internet-guide.com/mosquitto-tls/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment