techstudio-design / SimpleNB

A simple Arduino library for communication with NB-IoT/Cat-M1 modules
GNU Lesser General Public License v3.0
32 stars 4 forks source link

MQTT over secure connection to HiveMQ Cloud #8

Closed jftaylorMn closed 1 year ago

jftaylorMn commented 1 year ago

[ x] I have read the Troubleshooting section of the ReadMe

What type of issues is this?

[ ] Request to support a new module

[ ] Bug or problem compiling the library [ ] Bug or issue with library functionality (ie, sending data over TCP/IP) [ x] Question or request for help

What are you working with?

Modem: Sim7080G dev board from And-one Main processor board: ESP32 SimpleNB version: Latest Code:

Scenario, steps to reproduce

Expected result

I really want to use HiveMQ Cloud as my MQTT broker, which requires a secure connection. An alternative would be to find another "free" broker in the cloud that does not require SSL. In my work, I have been in discussions with security experts about TLS and certificates, understand the concepts at a vert high level, but that is not sufficient to make your example for MQTT work for me.

Before attempting this with the SIm7080G modem, I have plowed through code to make a PUBSUBClient work over wifi. Sample ino is below

#include <WiFi.h>  
#include <PubSubClient.h>
#include <WiFiClientSecure.h>
#include <SPI.h>
// ***ADD VARIABLE BELOW INITIAL CONFIG***
//---- WiFi settings
const char* ssid = "your ssid";
const char* password = "your password";
//---- MQTT Broker settings
const char* mqtt_server = "xxxxxxxxx.s2.eu.hivemq.cloud"; // replace with your broker url
const char* mqtt_username = "HiveMQUser"; // replace with your Credential
const char* mqtt_password = "HIveMQPassword";
const int mqtt_port = 8883;
//===========================
WiFiClientSecure espClient;
//espClient->setInsecure();  
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE  (50)
char msg[MSG_BUFFER_SIZE];
//============= Configure OUTPUT Here============================

const char* sensor1_topic= "topic1";

//============= Config Command Here==============================
//const char* command1_topic="command1";
//const char* command1_topic="command2";
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";
String topic;
String messageTemp;
String message;
void callback(char* topic, byte* payload, unsigned int length) {
  String incommingMessage = "";
  for (int i = 0; i < length; i++) incommingMessage+=(char)payload[i];
  Serial.println("Message arrived ["+String(topic)+"]"+incommingMessage);
  messageTemp = topic;
  Serial.print(messageTemp);
  //==============MESSAGE RECEPTION HERE (Uncomment to edit)====================
  /* if (messageTemp == "MESSAGE INPUT"){
    YOUR VARIABLE = incommingMessage.to**WHAT YOU NEED**();
  }*/
}
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    String clientId = "ESP32Client";   // Create a random client ID
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    Serial.print(clientId);
    if (client.connect(clientId.c_str(), mqtt_username, mqtt_password)) {
      Serial.println("connected");

      //SUBSCRIBE TO TOPIC HERE

     // client.subscribe("SUBSCRIBE NAME");

    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");   // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
//============================================ADD USER VARIABLE HERE====================================

void setup() {
//=========================NO TOUCHY==============================================================
  Serial.begin(115200);
  Serial.print("\nConnecting to ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  client.setCallback(callback);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  randomSeed(micros());
  Serial.println("\nWiFi connected\nIP address: ");
  Serial.println(WiFi.localIP());
  while (!Serial) delay(1);
  espClient.setCACert(root_ca);
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
  delay(1000);
//==================================ADD USER SETUP HERE===================================================

}

void loop() {
//============== NO TOUCHY=======================
   if (!client.connected()) reconnect();
      client.loop();
//============== ADD LOOP CODE HERE==============

//===============Publish MQTT MESSAGE=======================

//publishMessage(sensor1_topic,String("{ \"t\": 0, \"h\": 75}"),true); 

}

//======================================= publising as string
void publishMessage(const char* topic, String payload , boolean retained){
  if (client.publish(topic, payload.c_str(), true))
      Serial.println("Message publised ["+String(topic)+"]: "+payload);
}

From that exercise, I know that the URL, Port, login and password are needed. in addition there is a root cert/pem file/string that is required to establish the MQTTs session.

From your readme, it appears that secure MQTT can happen with a SIM7080G modem, but the example I see in the repository doesn't seem to go to that level.

I suspect that this is not what you want to see in an issue, but there is scant detail elsewhere. I have looked at gitter and see a few comments related to the modem in the tinyGSM room. Mostly, there are questions without answers. When I dive into the AT commands related to MQTTs for this modem series, there is reference to multiple certificates and or/keys that are pulled from files - (presumably on LittleFS?). I can likely get that detail from HiveMQ if I know what to ask for. Since the wifi version only requires the server level pem, I think the GSM version should not need more than that using AT commands.

Any advice /example code would be greatly appreciated.

Actual result

Debug and AT command log

techstudio-design commented 1 year ago

The httpsclient.ino provides the example of establishing a secure https connection. Whether using http or mqtt (which is TCP), the API and process of wrapping the TCP packet with secure layer is the same. Which is why we only show one example of using secure connection.

Anyway, I've updated the MqttClient.ino example so that it can be configure for both non-secure (port 1883) and secure (port 8883) connection. Other than adding the root CA cert or changing the broker url, all you need to do is to comment-in or comment-out a newly added macro:

#define USING_SECURE_MQTT

Please take a look of the code and try it out. I tested it on test.mosquitto.org broker on both port 1883 and 8883. Feel free to modify it for your broker configuration.

jftaylorMn commented 1 year ago

Sorry for the delay. I believe that your updated example code has resolved my issues. Appreciate the great support!!