ESP Crash on connection to SMTP Server

So I’ve been working on this for a few hours integrating the code into my sketch. Unfortunayley, it crashes.

The line that I figure it crashes on is “if (!clients.connect(smtp_server, smtp_port)) {” where smtp_server is a String and smtp_port is an int.

The function here:

bool Gsender_Send() {
  DEBUG_AM("Connecting to :");
  DEBUG_AM(smtp_server);
  if (!clients.connect(smtp_server, smtp_port)) {
    _error = "Could not connect to mail server";
    strcat(_error, csmtp_server);
    strcat(_error, ":");
    strcat(_error, csmtp_port);
   DEBUG_AM(_error);
    return false;
  }
  DEBUG_AM("220");
  if (!Gsender_AwaitSMTPResponse(clients, "220", smtpTimeOut)) {
    _error = "Connection Error";
     DEBUG_AM(_error);
    return false;
  }

  DEBUG_AM("HELO friend:");
  clients.println("HELO friend");
  if (!Gsender_AwaitSMTPResponse(clients, "250", smtpTimeOut)) {
    _error = "identification error";
     DEBUG_AM(_error);
    return false;
  }

  DEBUG_AM("AUTH LOGIN:");
  clients.println("AUTH LOGIN");
  Gsender_AwaitSMTPResponse(clients, "334", smtpTimeOut);

  DEBUG_AM("smtpUserID:");
  DEBUG_AM(smtpUserID);

  clients.println(encode64(csmtpUserID));
  Gsender_AwaitSMTPResponse(clients, "334", smtpTimeOut);

  DEBUG_AM("smtp_pass:");
  DEBUG_AM(smtp_pass);

  clients.println(encode64(csmtp_pass));
  if (!Gsender_AwaitSMTPResponse(clients, "235", smtpTimeOut)) {
    _error = "SMTP AUTH error";
    return false;
  }

  String mailFrom = "MAIL FROM: <" + String(smtpFrom) + '>';
  DEBUG_AM(smtpFrom);
  clients.println(smtpFrom);
  Gsender_AwaitSMTPResponse(clients, "250", smtpTimeOut);

  String rcpt = "RCPT TO: <" + smtpTo + '>';
  DEBUG_AM(smtpTo);
  clients.println(smtpTo);
  Gsender_AwaitSMTPResponse(clients, "250", smtpTimeOut);

  DEBUG_AM("DATA:");
  clients.println("DATA");
  if (!Gsender_AwaitSMTPResponse(clients, "354", smtpTimeOut)) {
    _error = "SMTP DATA error";
    return false;
  }

  clients.println("From: <" + smtpFrom + '>');
  clients.println("To: <" + smtpTo + '>');

  clients.print("Subject: ");
  clients.println(subject);
  clients.println("Mime-Version: 1.0");
  clients.println("Content-Type: text/html; charset=\"UTF-8\"");
  clients.println("Content-Transfer-Encoding: 7bit");
  clients.println();
  clients.println(body);
  clients.println(".");
  if (!Gsender_AwaitSMTPResponse(clients, "250", smtpTimeOut)) {
    _error = "Sending message error";
    return false;
  }
  clients.println("QUIT");
  if (!Gsender_AwaitSMTPResponse(clients, "221", smtpTimeOut)) {
    _error = "SMTP QUIT error";
    return false;
  }
  return true;
}

The Stack Decode:

Decoding stack results
0x40208f9c: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\matt\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266/HardwareSerial.h line 174
0x401008e1: realloc at C:\Users\matt\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266\umm_malloc\umm_malloc.c line 1504
0x402096c3: String::changeBuffer(unsigned int) at C:\Users\matt\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266\WString.cpp line 156
0x401008e1: realloc at C:\Users\matt\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266\umm_malloc\umm_malloc.c line 1504
0x402096c3: String::changeBuffer(unsigned int) at C:\Users\matt\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266\WString.cpp line 156
0x40100a44: free at C:\Users\matt\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266\umm_malloc\umm_malloc.c line 1760
0x40208f9c: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\matt\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266/HardwareSerial.h line 174
0x40209235: Print::write(char const*) at C:\Users\matt\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266/Print.h line 60
0x40100600: _umm_free at C:\Users\matt\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266\umm_malloc\umm_malloc.c line 1300
0x40100a44: free at C:\Users\matt\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266\umm_malloc\umm_malloc.c line 1760
0x40209680: String::invalidate() at C:\Users\matt\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266\WString.cpp line 141
0x4020398d: sendEmail(String, String) at C:\Users\matt\Documents\Arduino\node9-9/node9-9.ino line 176
0x40209758: String::copy(char const*, unsigned int) at C:\Users\matt\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266\WString.cpp line 182
0x40209844: String::operator=(String const&) at C:\Users\matt\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266\WString.cpp line 220
0x40204012: statusReport() at C:\Users\matt\Documents\Arduino\node9-9/node9-9.ino line 428
0x4020421f: setup() at C:\Users\matt\Documents\Arduino\node9-9/node9-9.ino line 141
0x4020a384: loop_wrapper() at C:\Users\matt\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266\core_esp8266_main.cpp line 122

Finally I attached the Whole Sketch.

node9-9.ino (21.9 KB)

  if (!clients.connect(smtp_server, smtp_port)) {
    _error = "Could not connect to mail server";
    strcat(_error, csmtp_server);
    strcat(_error, ":");
    strcat(_error, csmtp_port);
   DEBUG_AM(_error);
    return false;
  }

You set _error (a char *) to point to a c-string literal. Then you proceed to strcat a bunch of stuff on the end of that literal. That's trashing memory that you don't own.

gfvalvo:

  if (!clients.connect(smtp_server, smtp_port)) {

_error = “Could not connect to mail server”;
    strcat(_error, csmtp_server);
    strcat(_error, “:”);
    strcat(_error, csmtp_port);
  DEBUG_AM(_error);
    return false;
  }




You set _error (a char *) to point to a c-string literal. Then you proceed to strcat a bunch of stuff on the end of that literal. That's trashing memory that you don't own.

It’s gone a little further… now crashing with message “Abort Called”.

mattlogue:
It's gone a little further... now crashing with message "Abort Called".

The point is you shouldn't modify "_error". Everything after is irrelevant if you don't fix this first.

I took out modifications to error and it still crashes, but on second connection attempt. Stack decode suggests it stops in wificlientsecure.

mattlogue:
I took out modifications to error and it still crashes, but on second connection attempt. Stack decode suggests it stops in wificlientsecure.

Please post your modified code.

int sendEmail(String subject, String body) {
   return 0; //Suspended untill I figure out crashing...
  Serial.printf("\n STMP User ID: %s", smtpUserID.c_str());
  Serial.printf("\n To address: %s", smtpTo.c_str());
  Serial.printf("\n From address: %s", smtpFrom.c_str());
  Serial.printf("\n Subject: %s", subject.c_str());
  Serial.printf("\n Body: %s", body.c_str());
  //Flood control, only 3 messages per minute
  if (millis() - lastEmailMS > 60000) {
    emailsCount = 0;
  }
  if (emailsCount > 2) {
    Serial.printf("Flood control - email (%s) not sent!\n");
    return 460;
  }
  //If first of three emails, set time
  if (emailsCount == 0) lastEmailMS = millis();
  emailsCount++;
  //End of flood control
  String sendStatus;
  smtp_pass = ep("ATTPass");
  smtpUserID.toCharArray(csmtpUserID, 16);
  smtp_pass.toCharArray(csmtp_pass, 16);
  smtp_server.toCharArray(csmtp_server, 32);


  DEBUG_AM("Sending message to ");
  DEBUG_AM(smtpTo);
  DEBUG_AM(':');
  DEBUG_AM("SUBJECT: ");
  DEBUG_AM(subject);
  DEBUG_AM("   BODY: ");
  DEBUG_AM(body);


  if (Gsender_Send() == true) {
    DEBUG_AM("Message sent successfully.");
    sendStatus = "SENT";
    return 200;
  }
  else {
    DEBUG_AM("Message sending failed. (");
    DEBUG_AM(_error);
    DEBUG_AM(')');

    sendStatus = _error;
  }
  if (sendStatus != "SENT") {
    Serial.printf("Send error: %s", sendStatus.c_str());
    return 470;
  }
}
...
bool Gsender_Send() {
  DEBUG_AM("Connecting to :");
  DEBUG_AM(smtp_server);
  DEBUG_AM(smtp_port);
  clients.connect(smtp_server, smtp_port);

  do {
    DEBUG_AM("Awaiting connection");
    delay(100);
  }
  while (clients._clientConnectedState() < 100);

  long stmpTimeOut = 5000;
  char *response = "";
  String responseString = "";
  long doMS = millis();
  do {
    DEBUG_AM(clients.available());
    responseString = clients.readStringUntil('\n');
    responseString.toCharArray(response, 16);
    if (millis() - doMS > stmpTimeOut) {
      DEBUG_AM("Timed out");
      return false;
    }
    delay(100);
  }
  while (strlen(response) < 2);
  if (response == "220") {
    DEBUG_AM("220 OK");
  }
  else {
    DEBUG_AM(response); return false;
  }

  DEBUG_AM("HELO friend:");
  clients.println("HELO friend");
  doMS = millis();
  do {
    while (clients.available()) {
      responseString = clients.readStringUntil('\n');
      responseString.toCharArray(response, 16);
      if (millis() - doMS > stmpTimeOut) {
        DEBUG_AM("Timed out");
        return false;
      }
    }
  }
  while (strlen(response) < 2);
  if (response == "250") {
    DEBUG_AM("250 HELO OK");
  }
  else {
    DEBUG_AM(response); return false;
  }

  DEBUG_AM("AUTH LOGIN:");
  clients.println("AUTH LOGIN");
  doMS = millis();
  do  {
    while (clients.available()) {
      responseString = clients.readStringUntil('\n');
      responseString.toCharArray(response, 16);
      if (millis() - doMS > stmpTimeOut) {
        DEBUG_AM("Timed out");
        return false;
      }
    }
  }
  while (strlen(response) < 2);
  if (response == "334") {
    DEBUG_AM("334 AUTH OK");
  }
  else {
    DEBUG_AM(response); return false;
  }

  DEBUG_AM("smtpUserID:");
  DEBUG_AM(smtpUserID);

  clients.println(encode64(csmtpUserID));
  doMS = millis();
  do {
    while (clients.available()) {
      responseString = clients.readStringUntil('\n');
      responseString.toCharArray(response, 16);
      if (millis() - doMS > stmpTimeOut) {
        DEBUG_AM("Timed out");
        return false;
      }
    }
  }
  while (strlen(response) < 2);
  if (response == "334") {
    DEBUG_AM("334 USERID OK");
  }
  else {
    DEBUG_AM(response); return false;
  }
  DEBUG_AM("smtp_pass:");
  DEBUG_AM(smtp_pass);

  clients.println(encode64(csmtp_pass));

  doMS = millis();
  do {
    while (clients.available()) {
      responseString = clients.readStringUntil('\n');
      responseString.toCharArray(response, 16);
      if (millis() - doMS > stmpTimeOut) {
        DEBUG_AM("Timed out");
        return false;
      }
    }
  }
  while (strlen(response) < 2);
  if (response == "235") {
    DEBUG_AM("235 LOGGED IN OK");
  }
  else {
    DEBUG_AM(response); return false;
  }



  String mailFrom = "MAIL FROM: <" + String(smtpFrom) + '>';
  DEBUG_AM(smtpFrom);
  clients.println(smtpFrom);

  doMS = millis();
  do {
    while (clients.available()) {
      responseString = clients.readStringUntil('\n');
      responseString.toCharArray(response, 16);
      if (millis() - doMS > stmpTimeOut) {
        DEBUG_AM("Timed out");
        return false;
      }
    }
  }
  while (strlen(response) < 2);
  if (response == "250") {
    DEBUG_AM("250 MAIL FROM OK");
  }
  else {
    DEBUG_AM(response); return false;
  }
  String rcpt = "RCPT TO: <" + smtpTo + '>';
  DEBUG_AM(smtpTo);
  clients.println(smtpTo);
  doMS = millis();
  do {
    while (clients.available()) {
      responseString = clients.readStringUntil('\n');
      responseString.toCharArray(response, 16);
      if (millis() - doMS > stmpTimeOut) {
        DEBUG_AM("Timed out");
        return false;
      }
    }
  }
  while (strlen(response) < 2);
  if (response == "250") {
    DEBUG_AM("250 MAIL TO OK");
  }
  else {
    DEBUG_AM(response); return false;
  }

  DEBUG_AM("DATA:");
  clients.println("DATA");

  doMS = millis();
  do {
    while (clients.available()) {
      responseString = clients.readStringUntil('\n');
      responseString.toCharArray(response, 16);
      if (millis() - doMS > stmpTimeOut) {
        DEBUG_AM("Timed out");
        return false;
      }
    }
  }
  while (strlen(response) < 2);
  if (response == "354") {
    DEBUG_AM("354 DATA OK");
  }
  else {
    DEBUG_AM(response); return false;
  }

  clients.println("From: <" + smtpFrom + '>');
  clients.println("To: <" + smtpTo + '>');

  clients.print("Subject: ");
  clients.println(subject);
  clients.println("Mime-Version: 1.0");
  clients.println("Content-Type: text/html; charset=\"UTF-8\"");
  clients.println("Content-Transfer-Encoding: 7bit");
  clients.println();
  clients.println(body);
  clients.println(".");

  doMS = millis();
  do {
    while (clients.available()) {
      responseString = clients.readStringUntil('\n');
      responseString.toCharArray(response, 16);
      if (millis() - doMS > stmpTimeOut) {
        DEBUG_AM("Timed out");
        return false;
      }
    }
  }
  while (strlen(response) < 2);
  if (response == "250") {
    DEBUG_AM("250 MESSAGE SENT OK");
  }
  else {
    DEBUG_AM(response); return false;
  }

  clients.println("QUIT");
  return true;
}

Post (attach) the whole code. Really need to see how variables are defined, etc.

I will once I remove a bug I added, it crashes there now and having you help me with that would waste your time and embrass me...