MQTT ESP SIM Port 8883

Need some basic advice on where I am going wrong.

Simply want to connect to xxx.s1.eu.hivemq.cloud 8883 have it working on 1883

Similar to this link

Code

boolean mqttConnect() //boolean true or false
{
  SerialMon.print("Connecting to ");
  SerialMon.println(broker);
  SerialMon.println("");  //add CR

  // Connect to MQTT Broker
  //boolean status = mqtt.connect("xxxx");                    //works 1883
  // Or, if you want to authenticate MQTT:
  // boolean status = mqtt.connect("xxxx", "xxxx", "xxxx");   //doesnt work 8883

  //List files in SPIFFS e.g., isrgrootx1.pem
  ListFilesSPIFFS(); //Only list when booting

  String serverAddress = "xxxx.s1.eu.hivemq.cloud";
  int serverPort = 8883;
  int keepAliveSeconds = 60;
  int cleanSession = 1;
  String username = "xxxx";
  String password = "xxxxx";
  
  // Set SSL version and authentication mode
  modem.sendAT("+CSSLCFG=\"sslversion\",0,4"); //ALL Set the SSL version of the first SSL context
  if (!modem.waitResponse(1000)) {
    Serial.println("CSSLCFG command failed");
    return false;
  }
  
  modem.sendAT("+CSSLCFG=\"authmode\",0,1"); //Server authentication. It needs the root CA of the serverSet the authentication mode(verify server) of the first SSL context
  if (!modem.waitResponse(1000)) {
    Serial.println("CSSLCFG command failed");
    return false;
  }

//  modem.sendAT("+CSSLCFG=\"ignoreltime\",0,1"); //1 – ignore time check for certification default is 1
//  if (!modem.waitResponse(1000)) {
//    Serial.println("CSSLCFG command failed");
//    return false;
//  }
  
  // Set server root CA
  modem.sendAT("+CSSLCFG=\"cacert\",0,\"isrgrootx1.pem\""); //Set the server root CA of the first SSL context
  if (!modem.waitResponse(1000)) {
    Serial.println("CSSLCFG command failed");
    return false;
  }
/*
  // Set client cert
  modem.sendAT("+CSSLCFG=\"clientcert\",0,\"clientcert.pem\""); //Set the client cert
  if (!modem.waitResponse(1000)) {
    Serial.println("CSSLCFG command failed");
    return false;
  }

  // Set client cert
  modem.sendAT("+CSSLCFG=\"clientkey\",0,\"clientkey.pem\""); //Set the clientkey
  if (!modem.waitResponse(1000)) {
    Serial.println("CSSLCFG command failed");
    return false;
  }
*/ 
  // Set client cert
  modem.sendAT("+CSSLCFG?"); 
  if (!modem.waitResponse(1000)) {
    Serial.println("CSSLCFG command failed");
    return false;
  }
 
  // Start MQTT service and activate PDP context
  modem.sendAT("+CMQTTSTART");
  if (!modem.waitResponse(1000)) {
    Serial.println("MQTT START command failed");
    return false;
  }
  
  // Acquire a client
  modem.sendAT("+CMQTTACCQ=0,\"client1\",1,4"); //1 MQTT server with SSL/TLS 4 MQTT version 3.1.1
  if (!modem.waitResponse(1000)) {
    Serial.println("MQTT ACCQ command failed");
    return false;
  }
  
  // Set the first SSL context to be used in the SSL connection
  modem.sendAT("+CMQTTSSLCFG=0,0");
  if (!modem.waitResponse(1000)) {
    Serial.println("MQTT SSLCFG command failed");
    return false;
  }
  
  // Connect to MQTT server
  //String mqttConnectCommand = "AT+CMQTTCONNECT=0,\"ssl://" + serverAddress + ":" + String(serverPort) + "\"," + String(keepAliveSeconds) + "," + String(cleanSession) + ",\"" + username + "\",\"" + password + "\"";
  String mqttConnectCommand = "AT+CMQTTCONNECT=0,\"tcp://" + serverAddress + ":" + String(serverPort) + "\"," + String(keepAliveSeconds) + "," + String(cleanSession) + ",\"" + username + "\",\"" + password + "\"";
  boolean status = SerialAT.print(mqttConnectCommand);
  
  if (status == false) {
    SerialMon.println("MQTT Connect fail");
    return false;
  }
  SerialMon.println("MQTT Connect success");

Logs

19:09:29.401 -> AT+NETOPEN?
19:09:29.401 -> 
19:09:29.401 -> +NETOPEN: 1
19:09:29.448 -> 
19:09:29.448 -> OK
19:09:29.448 -> AT+IPADDR
19:09:29.494 -> 
19:09:29.494 -> +IPADDR: xx.xx.xx.xx
19:09:29.541 -> 
19:09:29.541 -> OK
19:09:29.541 -> Connecting to xxxx.s1.eu.hivemq.cloud
19:09:29.541 -> 
19:09:29.728 -> File: /isrgrootx1.pem Size: 1939
19:09:29.774 -> AT+CSSLCFG="sslversion",0,4
19:09:29.774 -> 
19:09:29.774 -> OK
19:09:29.774 -> AT+CSSLCFG="authmode",0,1
19:09:29.774 -> 
19:09:29.821 -> OK
19:09:29.821 -> AT+CCERTLIST
19:09:29.821 -> 
19:09:29.821 -> OK
19:09:29.821 -> AT+CCERTDOWN="data/isrgrootx1.pem"1939
19:09:29.868 -> 
19:09:29.868 -> ERROR
19:09:29.868 -> AT+CSSLCFG="cacert",0,"isrgrootx1.pem"
19:09:29.868 -> 
19:09:29.868 -> ERROR
19:09:29.914 -> AT+CSSLCFG?
19:09:29.914 -> 
19:09:29.914 -> +CSSLCFG: 0,4,1,1,300,"","","",0,"",0x0
19:09:30.009 -> +CSSLCFG: 1,4,0,1,300,"","","",0,"",0x0
19:09:30.103 -> +CSSLCFG: 2,4,0,1,300,"","","",0,"",0x0
19:09:30.150 -> +CSSLCFG: 3,4,0,1,300,"","","",0,"",0x0
19:09:30.244 -> +CSSLCFG: 4,4,0,1,300,"","","",0,"",0x0
19:09:30.336 -> +CSSLCFG: 5,4,0,1,300,"","","",0,"",0x0
19:09:30.429 -> +CSSLCFG: 6,4,0,10,1,CSSLCFG command failed
19:09:30.989 -> AT+CGREG?
19:09:31.035 -> 
19:09:31.035 -> +CGREG: 0,1

So my questions are this

When compiling and writing the sketch to the ESP32/SIM7600 uploaded the /data/isrgrootx1.pem file which you can see listed as /isrgrootx1.pem in the logs confirming its located on SPIFFS. So to me I dont have the cert on the module? I know its located in SPIFFS can see it and the size.

Also used MQTT Explorer and set the same isrgrootx1.pem CERT with both validate cert and TLS enabled so I know the CERT works.

Revised code

Result error is +CMQTTCONNECT: 0,12 which ‘invalid parameter’

10:39:37.199 -> AT+IPADDR
10:39:37.199 -> 
10:39:37.199 -> +IPADDR: xx.xx.xx.xx
10:39:37.245 -> 
10:39:37.245 -> OK
10:39:37.245 -> 1
10:39:37.245 -> AT+NETOPEN?
10:39:37.292 -> 
10:39:37.292 -> +NETOPEN: 1
10:39:37.292 -> 
10:39:37.292 -> OK
10:39:37.339 -> AT+IPADDR
10:39:37.339 -> 
10:39:37.339 -> +IPADDR: xx.xx.xx.xx
10:39:37.385 -> 
10:39:37.385 -> OK
10:39:37.385 -> Connecting to xxx.s1.eu.hivemq.cloud
10:39:37.431 -> 
10:39:37.431 -> AT+CNSMOD
10:39:37.431 -> 
10:39:37.431 -> +CNSMOD: 0,8
10:39:37.431 -> AT+CSSLCFG="sslversion",0,4
10:39:37.431 -> 
10:39:37.431 -> OK
10:39:37.479 -> AT+CSSLCFG="authmode",0,1
10:39:37.479 -> 
10:39:37.479 -> OK
10:39:37.479 -> AT+CCERTLIST
10:39:37.479 -> 
10:39:37.526 -> +CCERTLIST: "isrgrootx1.pem"
10:39:37.573 -> 
10:39:37.573 -> OK
10:39:37.573 -> AT+CSSLCFG="cacert",0,"isrgrootx1.pem"
10:39:37.573 -> 
10:39:37.573 -> OK
10:39:37.619 -> AT+CMQTTREL=0
10:39:37.619 -> 
10:39:37.619 -> OK
10:39:37.619 -> AT+CMQTTSTOP
10:39:37.666 -> 
10:39:37.666 -> +CMQTTSTOP: 0
10:39:37.666 -> 
10:39:37.666 -> OK
10:39:37.712 -> AT+CMQTTSTART
10:39:37.712 -> 
10:39:37.712 -> +CMQTTSTART: 0
10:39:37.760 -> 
10:39:37.760 -> OK
10:39:37.760 -> AT+CMQTTACCQ=0,"Client1",1,4
10:39:37.760 -> 
10:39:37.760 -> OK
10:39:37.808 -> AT+CMQTTSSLCFG=0,0
10:39:37.808 -> 
10:39:37.808 -> OK
10:39:37.808 -> AT+CMQTTCONNECT=0,"tcp://xxx.s1.eu.hivemq.cloud",8883,60,1,"xxx","xxx"
10:39:38.789 -> MQTT Connect success
10:39:38.789 -> AT+NETOPEN?
10:39:38.836 -> 
10:39:38.836 -> +CMQTTCONNECT: 0,12
10:39:38.883 -> 
10:39:38.883 -> ERROR
10:39:38.883 -> AT+CIPRXGET=4,0
10:39:38.929 -> 
10:39:38.929 -> +CIPRXGET: 4,0,0
10:39:38.929 -> 
10:39:38.929 -> OK
10:39:38.976 -> AT+CIPCLOSE?
10:39:38.976 -> 
10:39:38.976 -> +CIPCLOSE: 0,0,0,0,0,0,0,0,0,0
10:39:39.023 -> 
10:39:39.023 -> OK
10:39:39.116 -> AT+CGREG?
10:39:39.162 -> 
10:39:39.162 -> +CGREG: 0,1
10:39:39.162 -> 
10:39:39.162 -> OK
10:39:39.162 -> MQTT NOT CONNECTED! 
10:39:39.162 -> Disconnecting from: xxx.s1.eu.hivemq.cloud
10:39:39.208 -> AT+CIPSEND=0,2

Q. Do I need to send a AT+CMQTTWILLTOPIC and then AT+CMQTTWILLMSG prior to the AT+CMQTTCONNECT?

Added

// Set the first SSL context to be used in the SSL connection
 modem.sendAT("+CMQTTSSLCFG=0,0");
 if (!modem.waitResponse(1000)) {
   Serial.println("CMQTTSTART SSLCFG command failed");
   return false;
 }

 // Send AT+CMQTTWILLTOPIC=0,20 test/temperature
 modem.sendAT("+CMQTTWILLTOPIC=0,28,\"test/temperature\"");
 if (!modem.waitResponse(1000)) {
   Serial.println("CMQTTWILLTOPIC command failed");
   return false;
 }

 // Send AT+CMQTTWILLMSG=0,17,1  
 modem.sendAT("+CMQTTWILLMSG=0,2,1");
 if (!modem.waitResponse(1000)) {
   Serial.println("CMQTTWILLMSG command failed");
   return false;
 }

Result

  // Send AT+CMQTTWILLTOPIC=0,20 test/temperature
  modem.sendAT("+CMQTTWILLTOPIC=0,28,\"test/temperature\"");
  if (!modem.waitResponse(1000)) {
    Serial.println("CMQTTWILLTOPIC command failed");
    return false;
  }

  // Send AT+CMQTTWILLMSG=0,17,1  
  modem.sendAT("+CMQTTWILLMSG=0,2,1");
  if (!modem.waitResponse(1000)) {
    Serial.println("CMQTTWILLMSG command failed");
    return false;
  }

Result

20:12:53.635 -> AT+CMQTTSTART
20:12:53.635 -> 
20:12:53.635 -> +CMQTTSTART: 0
20:12:53.682 -> 
20:12:53.682 -> OK
20:12:53.682 -> AT+CMQTTACCQ=0,"Client1",1,4
20:12:53.729 -> 
20:12:53.729 -> OK
20:12:53.729 -> AT+CMQTTSSLCFG=0,0
20:12:53.729 -> 
20:12:53.729 -> OK
20:12:53.729 -> AT+CMQTTWILLTOPIC=0,25
20:12:53.729 -> 1000#
20:12:53.777 -> 
20:12:53.777 -> >#test/temperature
20:12:54.759 -> #
20:12:57.748 -> AT+CMQTTWILLMSG=0,2,0
20:12:57.748 -> 1000#
20:12:57.748 -> 
20:12:57.748 -> OK
20:12:57.796 -> #29
20:12:57.796 -> #
20:13:00.762 -> AT+CMQTTCONNECT=0,"tcp://xxx.s1.eu.hivemq.cloud:8883",60,1,"xxx","xxx"
20:13:01.752 -> MQTT Connect success
20:13:01.752 -> AT+NETOPEN?
20:13:01.799 -> 
20:13:01.799 -> +CMQTTCONNECT: 0,12

My error is

20:12:53.729 -> AT+CMQTTWILLTOPIC=0,25
20:12:53.729 -> 1000#
20:12:53.777 -> 
20:12:53.777 -> >#test/temperature
20:12:54.759 -> #
20:12:57.748 -> AT+CMQTTWILLMSG=0,2,0
20:12:57.748 -> 1000#
20:12:57.748 -> 
20:12:57.748 -> OK

Added so whats wrong with the format/syntax? Documentation says...

AT+CMQTTWILLTOPIC=<client_index>,<req_length>

AT+CMQTTWILLTOPIC=0,10
>0123456789
Response
><
input data here>
OK
or
+CMQTTWILLTOPIC: <client_index>,<err>
ERROR
or
ERROR
  modem.sendAT("+CMQTTWILLTOPIC=0,25,\"test/temperature\"");
  if (!modem.waitResponse(1000)) {
    Serial.println("CMQTTWILLTOPIC command failed with /");
    return false;
  }
 
  delay(1000);

  // Send AT+CMQTTWILLMSG=0,25 test/temperature then 29
  modem.sendAT("+CMQTTWILLMSG=0,2,1,\"29\"");
  if (!modem.waitResponse(1000)) {
    Serial.println("CMQTTWILLMSG command failed");
    return false;
  }