govorox / SSLClient

SSLClient - generic secure client Arduino library using mbedtls
GNU General Public License v3.0
83 stars 39 forks source link

SIM7600G Unhandled: +CIPCLOSE: 0,0 (Error code -2) #103

Open AltayAtaman opened 1 month ago

AltayAtaman commented 1 month ago

Description: I'm trying to connect my SIM7600 to Azure IoT over cellular and secure connection is needed for establishing connection with Azure IoT. Because of this requirement I'm trying to use this library to add a secure layer. But I was not able to even make example code work with public broker provided in the example. I only changed the GSM initialization part to make it compatible with my SIM7600G but the code is not working. It's giving "Attempting MQTT connection...[147598] ### Unhandled: +CIPCLOSE: 0,0 failed, rc=-2...try again in 15 seconds" as error.

I have seen the other topic opened up which might have exactly the same issue but the GSM used in that project is different the mine and the solution provided (which is changing the certificate as far as I understood) didn't work for me.

Steps to Reproduce: Connect ESP32 to SIM7600 and upload the following code:

#include "SSLClient.h"
#include <PubSubClient.h>

#define TINY_GSM_DEBUG Serial

#include "ca_cert.h"

// SIM7600 defines added by me:
#define ESP32_TYPE 3
#define GSM_ENABLED 1
#define uS_TO_S_FACTOR      1000000ULL  /* Conversion factor for micro seconds to seconds *
#define TIME_TO_SLEEP       30          /* Time ESP32 will go to sleep (in seconds) */
#define UART_BAUD           115200
#define MODEM_TX            27
#define MODEM_RX            26
#define MODEM_PWRKEY        4
#define MODEM_DTR           32
#define MODEM_RI            33
#define MODEM_FLIGHT        25
#define MODEM_STATUS        34
#define LED_PIN             12
#define SerialMon Serial
#define SerialAT Serial1

// Configure TinyGSM library
#define TINY_GSM_MODEM_SIM7600  // Modem is SIM7600
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb

// Include after TinyGSM definitions
#include <TinyGsmClient.h>

const char apn[]      = "internet"; // Kullanilan servisin APN'i [Erişim Noktası Adı (Access Point Name)]
const char gprsUser[] = "vodafone"; // Kullanilan servis icin GPRS Kullanici adi
const char gprsPass[] = "vodafone"; // Kullanilan servis icin GPRS kullanici sifresi
const char simPIN[] = "";    // SIM card PIN code, if any

// MQTT Config
// EMQX Free Secure Broker for test https://www.emqx.io/mqtt/public-mqtt5-broker
// Check the website to find out more about the available options
// And obtain the current certificate
const char client_name[] = "MyEsp32";
const char mqtt_broker[] = "broker.emqx.io";
int secure_port = 8883; // TCP-TLS Port

// Layers stack
TinyGsm sim_modem(SerialAT);
TinyGsmClient gsm_transpor_layer(sim_modem);
SSLClient secure_presentation_layer(&gsm_transpor_layer);
PubSubClient client(secure_presentation_layer);

// For read the MQTT events
void callback(char *topic, uint8_t *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();
}

// To connect to the broker
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(client_name)) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "hello world");
      // ... and resubscribe
      client.subscribe("inTopic");
    }
    else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println("...try again in 15 seconds");
      delay(15000);
    }
  }
}

void turnModemOn() {
  digitalWrite(LED_PIN, LOW);

  pinMode(MODEM_PWRKEY, OUTPUT);
  digitalWrite(MODEM_PWRKEY, LOW);
  delay(1000); //Datasheet Ton mintues = 1S
  digitalWrite(MODEM_PWRKEY, HIGH);
}

void turnModemOff() {
  digitalWrite(MODEM_PWRKEY, LOW);
  delay(1500); //Datasheet Ton mintues = 1.2S
  digitalWrite(MODEM_PWRKEY, HIGH);

  digitalWrite(LED_PIN, LOW);
}

void setup() {
  SerialMon.begin(9600);
  delay(100);

  // Set SIM module baud rate and UART pins
  SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);

  //Add CA Certificate
  secure_presentation_layer.setCACert(root_ca);

  // SIM modem initial setup
  GSM_7600_Initialize(); // My 7600 initialization function

  // MQTT init
  client.setServer(mqtt_broker, secure_port);
  client.setCallback(callback);
}

void loop() {
  SerialMon.print("Initializing modem...");
  if (!sim_modem.init()) {
    SerialMon.print(" fail... restarting modem...");
    GSM_7600_Initialize();
    delay(5000);
    // Restart takes quite some time
    // Use modem.init() if you don't need the complete restart
    if (!sim_modem.restart())
    {
      SerialMon.println(" fail... even after restart");
      return;
    }
  }
  SerialMon.println(" OK");

  // General information
  String name = sim_modem.getModemName();
  Serial.println("Modem Name: " + name);
  delay(100);
  String modem_info = sim_modem.getModemInfo();
  Serial.println("Modem Info: " + modem_info);
  delay(100);
  sim_modem.setNetworkMode(2);
  delay(6000);

  // Wait for network availability
  SerialMon.print("Waiting for network...");
  if (!sim_modem.waitForNetwork()) {
    SerialMon.println(" fail");
    delay(10000);
    return;
  }
  SerialMon.println(" OK");
  delay(3000);

  // Connect to the GPRS network
  SerialMon.print("Connecting to network...");
  if (!sim_modem.isNetworkConnected()) {
    SerialMon.println(" fail");
    delay(10000);
    return;
  }
  SerialMon.println(" OK");
  delay(3000);

  // Connect to APN
  SerialMon.print("Connecting to APN: ");
  SerialMon.print(apn);
  if (!sim_modem.gprsConnect(apn, gprsUser, gprsPass)) {
    SerialMon.println(" fail");
    return;
  }
  digitalWrite(LED_PIN, HIGH);
  SerialMon.println(" OK");
  delay(3000);

  // More info..
  Serial.println("");
  String ccid = sim_modem.getSimCCID();
  Serial.println("CCID: " + ccid);
  delay(500);
  String imei = sim_modem.getIMEI();
  Serial.println("IMEI: " + imei);
  delay(500);
  String cop = sim_modem.getOperator();
  Serial.println("Operator: " + cop);
  delay(500);
  IPAddress local = sim_modem.localIP();
  Serial.println("Local IP: " + String(local));
  delay(500);
  int csq = sim_modem.getSignalQuality();
  Serial.println("Signal quality: " + String(csq));

  // MQTT Test loop
  // As long as we have connectivity
  while (sim_modem.isGprsConnected()) {
    Serial.println("Modem GPRS Check: TRUE");
    if (!client.connected()) {
      Serial.println("client.connected() FALSE");
      reconnect();
    }
    // We are listening to the events
    client.loop();
    delay(2500);
  }

  // Disconnect GPRS and PowerOff
  // Apparently the "gprsDisconnect()" method (TinyGSM) are not working well with the SIM7000...
  // ...you have to use additionally "poweroff()".
  // With that, the modem can be connected again in the next cycle of the loop.
  //sim_modem.gprsDisconnect();
  //sim_modem.poweroff();

  delay(15000);
}

// My 7600 initialization function
void GSM_7600_Initialize() {
  if (ESP32_TYPE == 3 && GSM_ENABLED) {
    String ret;
    bool res;

    SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
    delay(100);
    pinMode(LED_PIN, OUTPUT);
    digitalWrite(LED_PIN, HIGH);

    pinMode(MODEM_PWRKEY, OUTPUT);
    digitalWrite(MODEM_PWRKEY, HIGH);
    delay(300); //Need delay
    digitalWrite(MODEM_PWRKEY, LOW);

    pinMode(MODEM_FLIGHT, OUTPUT);
    digitalWrite(MODEM_FLIGHT, HIGH);

    Serial.println("Initializing modem...");
    while (!sim_modem.init()) {
      Serial.println("Failed to restart modem, delaying 3s and retrying");
      delay(3000);
    }
    Serial.println("Delaying 10s for modem boot.");
    delay(10000);

    ret = sim_modem.setNetworkMode(2);
    Serial.println("setNetworkMode:" + ret);
    delay(100);
    String name = sim_modem.getModemName();
    Serial.println("Modem Name:" + name);
    delay(100);
    String modemInfo = sim_modem.getModemInfo();
    Serial.println("Modem Info:" + modemInfo);
    delay(100);
    Serial.println("Waiting for network...");
    if (!sim_modem.waitForNetwork(600000L)) {
      Serial.println("WaitForNetwork fail.");
      light_sleep(10);
    }

    if (sim_modem.isNetworkConnected()) {
      Serial.println("Network connected");
    }
    delay(100);
    Serial.println("Connecting to" + String(apn));
    if (!sim_modem.gprsConnect(apn, gprsUser, gprsPass)) {
      light_sleep(10);
      return;
    }
    delay(100);
    res = sim_modem.isGprsConnected();
    Serial.println("GPRS status:" + String(res));

    String imei = sim_modem.getIMEI();
    Serial.println("IMEI:" + imei);
  }

  else {
    Serial.println("Skip: GSM_7600_Initialize");
  }
}

void light_sleep(uint32_t sec ) {
  esp_sleep_enable_timer_wakeup(sec * 1000000ULL);
  esp_light_sleep_start();
}

Expected Behavior: Establishing a secure connection to the broker.

Actual Behavior: Connection can't be achieved and following output is produced:

`Failed to restart modem, delaying 3s and retrying
[13726] ### TinyGSM Version: 0.11.7
[13726] ### TinyGSM Compiled Module:  TinyGsmClientSIM7600
[17979] ### Modem: SIMCOM SIM7600G
[17979] ### Modem: SIMCOM SIM7600G
Delaying 10s for modem boot.
setNetworkMode:1
[28139] ### Modem: SIMCOM SIM7600G
Modem Name:SIMCOM SIM7600G
Modem Info:Manufacturer: SIMCOM INCORPORATED Model: SIMCOM_SIM7600G Revision: SIM7600M21-A_V2.0.1 SVN: 01 IMEI: **************+GCAP: +CGSM
Waiting for network...
Network connected
Connecting tointernet
GPRS status:1
IMEI:**************
Initializing modem...[28940] ### TinyGSM Version: 0.11.7
[28940] ### TinyGSM Compiled Module:  TinyGsmClientSIM7600
[29112] ### Modem: SIMCOM SIM7600G
[29112] ### Modem: SIMCOM SIM7600G
 OK
[29165] ### Modem: SIMCOM SIM7600G
Modem Name: SIMCOM SIM7600G
Modem Info: Manufacturer: SIMCOM INCORPORATED Model: SIMCOM_SIM7600G Revision: SIM7600M21-A_V2.0.1 SVN: 01 IMEI: 868822041837392 +GCAP: +CGSM
Waiting for network... OK
Connecting to network... OK
Connecting to APN: internet OK
CCID: **************
IMEI: **************
Operator: vodafone 
Local IP: **************
Signal quality: 26
Modem GPRS Check: TRUE
client.connected() FALSE
Attempting MQTT connection...failed, rc=-2...try again in 15 seconds
Attempting MQTT connection...[63361] ### Unhandled: +CIPCLOSE: 0,0
failed, rc=-2...try again in 15 seconds
Attempting MQTT connection...[79702] ### Unhandled: +CIPCLOSE: 0,0
failed, rc=-2...try again in 15 seconds
Attempting MQTT connection...[96847] ### Unhandled: +CIPCLOSE: 0,0
failed, rc=-2...try again in 15 seconds

Environment, IDE: Arduino IDE 2.3.2 with esp32 3.0.0 package (switched to 3.0.0 to solve a problem)

Any help would be really appreciated, I'm stuck at connecting my SIM7600G to the Azure IoT for days. And if I manage to make this example work and then make Azure IoT work with this library a huge weight will be lifted on my back.

Note: Been changing the code to try many things so if you see minor "strange" things in the code it's probably a leftover from these tries.

github-actions[bot] commented 1 month ago

The following fields are missing: Description, Steps to Reproduce, Expected Behavior, Actual Behavior, Environment, IDE. Please update the issue with this information.

AltayAtaman commented 4 weeks ago

I also tried to make it work with AT commands. Connecting to public brokers did work with following commands:

RDY

+CPIN: READY

SMS DONE

PB DONE
AT+CMQTTSTART
+CMQTTSTART: 0

AT+CCERTDOWN="ca_cert.pem",1358
>-----BEGIN CERTIFICATE-----
<certificate here, multiple lines>
-----END CERTIFICATE-----
OK

AT+CSSLCFG="sslversion",0,4
OK
AT+CSSLCFG="authmode",0,1
OK
AT+CSSLCFG="cacert",0,"ca_cert.pem"
OK
AT+CMQTTSSLCFG=0,0
OK
AT+CMQTTREL=0
OK
AT+CMQTTACCQ=0,"Sim7600_fa7d2288",1
OK
AT+CMQTTCONNECT=0,"tcp://broker.emqx.io:8883",60,1
OK

+CMQTTCONNECT: 0,0

But when I try to connecting it to Azure IoT Hub via AT commands, it doesn't connect instead gives +CMQTTCONNECT: 0,32 which is "handshake fail" according to the SIM7600 AT Command Manual.


RDY

+CPIN: READY

SMS DONE

PB DONE
AT+CSSLCFG="sslversion",0,4
OK
AT+CSSLCFG="authmode",0,1
OK
AT+CSSLCFG="ignorelocaltime", 0, 1
OK
AT+CSSLCFG="ciphersuites", 0, 0xFFFF
OK
AT+CSSLCFG="cacert",0,"my_cert.pem"
OK
AT+CSSLCFG="enableSNI", 0, 1
OK
AT+CMQTTSTART
+CMQTTSTART: 0

OK
AT+CMQTTSSLCFG=0,0
OK
AT+CMQTTREL=0
OK
AT+CMQTTACCQ=0,"device_002",1
OK
AT+CMQTTCONNECT=0,"tcp://<my_broker>-devices.net:8883", 60, 1, "<my_broker>.azure-devices.net/device_002/?api-version=2021-04-12", "SharedAccessSignature sr=<my_broker>-devices.net%2Fdevices%2Fdevice_002&sig=********iS=********ZT=********Di********17246=********8"
OK

+CMQTTCONNECT: 0,32