- This topic has 14 replies, 2 voices, and was last updated 2 years ago by
Renzo Mischianti.
-
AuthorPosts
-
-
4 January 2023 at 21:41 #23777
It was working for the longest time, but has not been working again – likely for the past 2 weeks (Only noticed now)
When trying to run, I get the following outputs (Debug Print turned on, and some debug prints of my own)
EmailSendFrom=Test123@mydomain.com Test123@mydomain.com Server=exch6.mydomain.com exch6.mydomain.com Port=587 Send to Email=anyemail@adomain.com anyemail@adomain.com In email routine ONLY ONE RECIPIENTmiltiple destination and attachments Insecure client:0 exch6.mydomain.com 587 220 EXCH6.MYDOMAIN.COM Microsoft ESMTP MAIL Service ready at Wed, 4 Jan 2023 15:31:51 -0500 EHLO mischianti 501 5.5.4 Invalid domain name Sending status: 0 250 Identification error (501 5.5.4 Invalid domain name)
The code to send is the following
String str_ea = EWSetup.getSetupEmailAddr(); String str_ep = EWSetup.getSetupPassword(); String str_easf = EWSetup.getSetupEmailAddr(); String str_es = EWSetup.getExchServerIPFQDN(); String str_ste = EWSetup.getSendToEmail(); const char* ea = str_ea.c_str(); const char* ep = str_ep.c_str(); const char* easf = str_easf.c_str(); const char* es = str_es.c_str(); int smtpPort = EWSetup.getSetupSMTPPort(); const char* ste = str_ste.c_str(); SerDebug(F("EmailAddr=")); SerDebugln(EWSetup.getSetupEmailAddr()); SerDebugln(String(ea)); SerDebug(F("EmailPassword=")); SerDebugln(EWSetup.getSetupPassword()); SerDebugln(String(ep)); SerDebug(F("EmailSendFrom=")); SerDebugln(EWSetup.getSetupEmailAddr()); SerDebugln(String(easf)); SerDebug(F("Server=")); SerDebugln(EWSetup.getExchServerIPFQDN()); SerDebugln(String(es)); SerDebug(F("Port=")); SerDebugln(smtpPort); SerDebug(F("Send to Email=")); SerDebugln(EWSetup.getSendToEmail()); SerDebugln(String(ste)); EMailSender emailSend(ea, ep, easf, es, smtpPort); SerDebugln(F("In email routine")); emailSend.setEHLOCommand(true); EMailSender::EMailMessage msg; msg.subject = emailSubject; msg.message = emailMessage; EMailSender::Response resp = emailSend.send(ste, msg); SerDebugln(F("Sending status: ")); SerDebugln(resp.status); SerDebugln(resp.code); SerDebugln(resp.desc); return (resp.status);
Any ideas?
-
5 January 2023 at 15:44 #23785
Hi rs77can,
I think your email provider change something about EHLO message.
Try to contact your provider or check if there was some system updade.
Bye Renzo -
5 January 2023 at 17:51 #23789
I am using my own hosted exchange server, and have not changed anything (have not added any new cumulative updates etc).
I tried EHLO or HELO, and both don’t work, but both work if I execute them in a TELNET window. It seems from wireshark trace (I sent it to your info email) there is no appropriate response from EHLO or HELO when sent by the code, and the program just hangs there.
Did maybe something change in the dependency libraries?
-
5 January 2023 at 19:12 #23790
Hi rs77can,
no, nothing in particular, but you can try downloading an older library (in the Arduino IDE you can select all the previous version) to check if something is different.
Bye Renzo -
5 January 2023 at 20:29 #23791
Could the issue be that I am using the Async Ethernet libraries with my portenta STM32H747.
Looking at the code, I don’t think that is the default. What would be the best way to ensure that that is used. I see no global portenta or Async.
What is the recommended way to change the header file to force the use of the Async libraries
Thanks
-
5 January 2023 at 22:05 #23792
I am actually only using the Async libraries for the web Server.
The EMailSender routine is using the
#define EMAIL_NETWORK_CLASS EthernetClient
#define EMAIL_NETWORK_SERVER_CLASS EthernetServeron line 161 of the EMailSender.h – that seems like the appropriate settings – so nothing more to do there I don’t think.
-
6 January 2023 at 06:24 #23794
I have created a small test program that just outputs the data to exchange server, and this works. I am not checking for correct responses, just proceeding after the client.println, and getting a response when expected – just not analyzing it.
I have tested the same code with the delays removed, and other than beiung faster, it also works.
In my main code it is a multitasking envioronment, but I had tried to run between OSCritical enable/disable, and that had not made a difference.
Can you see anything you can suggest for me to try to resolve the issue. The actual library seems to hang after ehlo or helo commands, at which point I get the
Identification error (501 5.5.4 Invalid domain name)
I am able to send an email with no issues with the code attached below (just changed the actual emails, domain names and passwords):
/* * EMailSender library for Arduino, esp8266 and esp32 * Arduino Mega and UIPEthernet send example with Sendgrid provider * * Pay attention you must set in the library * #define DEFAULT_EMAIL_NETWORK_TYPE_ARDUINO NETWORK_ENC28J60 * for UIPEthernet * * #define DEFAULT_EMAIL_NETWORK_TYPE_ARDUINO NETWORK_W5100 * for standard Ethernet * * * http://mischianti.org/category/my-libraries/emailsender-send-email-with-attachments/ * */ #include "mbed.h" #include "rtos.h" #include <Portenta_Ethernet.h> #include <Ethernet.h> //#include <UIPEthernet.h> #include <EMailSender.h> // Enter a MAC address for your controller below. // Newer Ethernet shields have a MAC address printed on a sticker on the shield byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; void awaitSMTPResponse(EthernetClient &client) { uint32_t ts = millis(); while (!client.available()) { if (millis() > (ts + 5000)) { return; } } String _serverResponce = client.readStringUntil('\n'); Serial.println(_serverResponce); return; } EMailSender emailSend("Test123@mydomainmain.com", "mypasswd", "Test123@mydomainmain.com", "192.168.0.2", 587); void setup() { // Open serial communications and wait for port to open: Serial.begin(115200); // while (!Serial) {} delay(2000); Serial.println("Starting!"); // start the Ethernet connection: if (Ethernet.begin(mac) == 0) { Serial.println("Failed to configure Ethernet using DHCP"); while (1) ; } Serial.print("IP address "); Serial.println(Ethernet.localIP()); EMailSender::Response resp1; EthernetClient testCl; testCl.connect("192.168.0.2", 587); //resp1 = EMailSender::awaitSMTPResponse(testCl, "220", "Connection Error"); awaitSMTPResponse(testCl); testCl.println("helo 127.0.0.1"); awaitSMTPResponse(testCl); delay(2000); testCl.println("AUTH LOGIN"); awaitSMTPResponse(testCl); //EMailSender::awaitSMTPResponse(testCl); delay(2000); testCl.println("base64username"); awaitSMTPResponse(testCl); //EMailSender::awaitSMTPResponse(testCl); delay(2000); testCl.println("base64pwd"); awaitSMTPResponse(testCl); //EMailSender::awaitSMTPResponse(testCl); //EMailSender::awaitSMTPResponse(testCl); delay(2000); testCl.print(F("MAIL FROM: <")); testCl.print("Test123@mydomainmain.com"); testCl.println(F(">")); awaitSMTPResponse(testCl); //EMailSender::awaitSMTPResponse(testCl); delay(2000); testCl.print(F("RCPT TO: <")); testCl.print("rs@mydomain.com"); testCl.println(F(">")); //EMailSender::awaitSMTPRespo awaitSMTPResponse(testCl); delay(1000); testCl.println(F("DATA")); //EMailSender::awaitSMTPResponse(testCl); testCl.flush(); awaitSMTPResponse(testCl); delay(200); testCl.println(F("From: <Test123@mydomainmain.com>")); testCl.flush(); //delay(200); testCl.println(F("To: <rs@mydomain.com>")); testCl.flush(); //delay(200); testCl.print(F("Subject:")); testCl.println("This is the subject"); testCl.flush(); //delay(200); testCl.println(); testCl.flush(); //delay(200); testCl.println("this is my msg"); testCl.flush(); //delay(200); testCl.println("."); testCl.flush(); //delay(200); testCl.println(); testCl.flush(); //delay(200); awaitSMTPResponse(testCl); /* EMailSender::EMailMessage message; emailSend.setEHLOCommand(true); message.subject = "Soggetto"; message.message = "Ciao come stai<br>io bene.<br>www.mischianti.org"; EMailSender::Response resp = emailSend.send("rs@mydomain.com", message); Serial.println("Sending status: "); Serial.println(resp.status); Serial.println(resp.code); Serial.println(resp.desc); */ } void loop() { }
-
This reply was modified 1 year, 10 months ago by
Renzo Mischianti.
-
This reply was modified 1 year, 10 months ago by
-
6 January 2023 at 15:04 #23799
I made the following changes to the code, and it worked. Most of the changes are adding DEBUG_PRINTLN.
I added some client.flush() after the connect, and helo command, but they didn’t fix it.
It was only when I changed the ‘helo mischianti’ to helo + this->smtp_server that it worked.
Although the telnet connection did not care what was placed after the helo (I could even just send a helo all by itself), the exchange server was demanding a valid domain for the arduino, possibly because it is not a domain member IP address ???
Any way, here is the file
/* * EMail Sender Arduino, esp8266, stm32 and esp32 library to send email * * AUTHOR: Renzo Mischianti * VERSION: 3.0.6 * * http://mischianti.org/ * * The MIT License (MIT) * * Copyright (c) 2017 Renzo Mischianti www.mischianti.org All right reserved. * * You may copy, alter and reuse this code in any way you like, but please leave * reference to www.mischianti.org in your comments if you redistribute this code. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "EMailSender.h" #include <stdio.h> //#include <SPIFFS.h> //#include <LittleFS.h> //#define SD SPIFFS // BASE64 ----------------------------------------------------------- const char PROGMEM b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; #define encode64(arr) encode64_f(arr,strlen(arr)) inline void a3_to_a4(unsigned char * a4, unsigned char * a3) { a4[0] = (a3[0] & 0xfc) >> 2; a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4); a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6); a4[3] = (a3[2] & 0x3f); } int base64_encode(char *output, char *input, int inputLen) { int i = 0, j = 0; int encLen = 0; unsigned char a3[3]; unsigned char a4[4]; while (inputLen--) { a3[i++] = *(input++); if (i == 3) { a3_to_a4(a4, a3); for (i = 0; i < 4; i++) { output[encLen++] = pgm_read_byte(&b64_alphabet[a4[i]]); } i = 0; } } if (i) { for (j = i; j < 3; j++) { a3[j] = '\0'; } a3_to_a4(a4, a3); for (j = 0; j < i + 1; j++) { output[encLen++] = pgm_read_byte(&b64_alphabet[a4[j]]); } while ((i++ < 3)) { output[encLen++] = '='; } } output[encLen] = '\0'; return encLen; } int base64_enc_length(int plainLen) { int n = plainLen; return (n + 2 - ((n + 2) % 3)) / 3 * 4; } const char* encode64_f(char* input, uint8_t len) { // encoding DEBUG_PRINTLN(F("Encoding")); DEBUG_PRINTLN(input); DEBUG_PRINTLN(len); //int encodedLen = base64_enc_length(len); static char encoded[256]; // note input is consumed in this step: it will be empty afterwards base64_encode(encoded, input, len); return encoded; } // END BASE64 --------------------------------------------------------- EMailSender::EMailSender(const char* email_login, const char* email_password, const char* email_from, const char* name_from , const char* smtp_server, uint16_t smtp_port) { this->setEMailLogin(email_login); this->setEMailFrom(email_from); this->setEMailPassword(email_password); this->setSMTPServer(smtp_server); this->setSMTPPort(smtp_port); this->setNameFrom(name_from); // this->isSecure = isSecure; } EMailSender::EMailSender(const char* email_login, const char* email_password, const char* email_from, const char* smtp_server, uint16_t smtp_port) { this->setEMailLogin(email_login); this->setEMailFrom(email_from); this->setEMailPassword(email_password); this->setSMTPServer(smtp_server); this->setSMTPPort(smtp_port); // this->isSecure = isSecure; } EMailSender::EMailSender(const char* email_login, const char* email_password, const char* email_from, const char* name_from ) { this->setEMailLogin(email_login); this->setEMailFrom(email_from); this->setEMailPassword(email_password); this->setNameFrom(name_from); this->setNameFrom(name_from); // this->isSecure = isSecure; } EMailSender::EMailSender(const char* email_login, const char* email_password, const char* email_from) { this->setEMailLogin(email_login); this->setEMailFrom(email_from); this->setEMailPassword(email_password); // this->isSecure = isSecure; } EMailSender::EMailSender(const char* email_login, const char* email_password){ this->setEMailLogin(email_login); this->setEMailFrom(email_login); this->setEMailPassword(email_password); // this->isSecure = isSecure; } void EMailSender::setSMTPPort(uint16_t smtp_port){ this->smtp_port = smtp_port; }; void EMailSender::setSMTPServer(const char* smtp_server){ delete [] this->smtp_server; this->smtp_server = new char[strlen(smtp_server)+1]; strcpy(this->smtp_server, smtp_server); }; void EMailSender::setEMailLogin(const char* email_login){ delete [] this->email_login; this->email_login = new char[strlen(email_login)+1]; strcpy(this->email_login, email_login); }; void EMailSender::setEMailFrom(const char* email_from){ delete [] this->email_from; this->email_from = new char[strlen(email_from)+1]; strcpy(this->email_from, email_from); }; void EMailSender::setNameFrom(const char* name_from){ delete [] this->name_from; this->name_from = new char[strlen(name_from)+1]; strcpy(this->name_from, name_from); }; void EMailSender::setEMailPassword(const char* email_password){ delete [] this->email_password; this->email_password = new char[strlen(email_password)+1]; strcpy(this->email_password, email_password); }; void EMailSender::setIsSecure(bool isSecure) { this->isSecure = isSecure; } #ifdef SSLCLIENT_WRAPPER EMailSender::Response EMailSender::awaitSMTPResponse(SSLClient &client, const char* resp, const char* respDesc, uint16_t timeOut) { EMailSender::Response response; uint32_t ts = millis(); while (!client.available()) { if (millis() > (ts + timeOut)) { response.code = F("1"); response.desc = String(respDesc) + "! " + F("SMTP Response TIMEOUT!"); response.status = false; return response; } } _serverResponce = client.readStringUntil('\n'); DEBUG_PRINTLN(_serverResponce); if (resp && _serverResponce.indexOf(resp) == -1){ response.code = resp; response.desc = respDesc +String(" (") + _serverResponce + String(")"); response.status = false; return response; } response.status = true; return response; } #else EMailSender::Response EMailSender::awaitSMTPResponse(EMAIL_NETWORK_CLASS &client, const char* resp, const char* respDesc, uint16_t timeOut) { EMailSender::Response response; uint32_t ts = millis(); while (!client.available()) { if (millis() > (ts + timeOut)) { DEBUG_PRINTLN(F("In response - timeout")); response.code = F("1"); response.desc = String(respDesc) + "! " + F("SMTP Response TIMEOUT!"); response.status = false; return response; } } DEBUG_PRINTLN(F("In response")); _serverResponce = client.readStringUntil('\n'); DEBUG_PRINTLN(_serverResponce); if (resp && _serverResponce.indexOf(resp) == -1){ DEBUG_PRINTLN(F("In response - bad resp")); response.code = resp; response.desc = respDesc +String(" (") + _serverResponce + String(")"); response.status = false; return response; } response.status = true; return response; } #endif static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; void encodeblock(unsigned char in[3],unsigned char out[4],int len) { out[0]=cb64[in[0]>>2]; out[1]=cb64[((in[0]&0x03)<<4)|((in[1]&0xF0)>>4)]; out[2]=(unsigned char) (len>1 ? cb64[((in[1]&0x0F)<<2)|((in[2]&0xC0)>>6)] : '='); out[3]=(unsigned char) (len>2 ? cb64[in[2]&0x3F] : '='); } #ifdef ENABLE_ATTACHMENTS #ifdef STORAGE_EXTERNAL_ENABLED #if (defined(DIFFERENT_FILE_MANAGE) && defined(EMAIL_FILE_EX)) || !defined(STORAGE_INTERNAL_ENABLED) #ifdef SSLCLIENT_WRAPPER void encode(EMAIL_FILE_EX *file, SSLClient *client) { unsigned char in[3],out[4]; int i,len,blocksout=0; while (file->available()!=0) { len=0; for (i=0;i<3;i++){ in[i]=(unsigned char) file->read(); if (file->available()!=0) len++; else in[i]=0; } if (len){ encodeblock(in,out,len); // for(i=0;i<4;i++) client->write(out[i]); client->write(out, 4); blocksout++; } if (blocksout>=19||file->available()==0){ if (blocksout) { client->print("\r\n"); } blocksout=0; } } } #else void encode(EMAIL_FILE_EX *file, EMAIL_NETWORK_CLASS *client) { unsigned char in[3],out[4]; int i,len,blocksout=0; while (file->available()!=0) { len=0; for (i=0;i<3;i++){ in[i]=(unsigned char) file->read(); if (file->available()!=0) len++; else in[i]=0; } if (len){ encodeblock(in,out,len); // for(i=0;i<4;i++) client->write(out[i]); client->write(out, 4); blocksout++; } if (blocksout>=19||file->available()==0){ if (blocksout) { client->print("\r\n"); } blocksout=0; } } } #endif #endif #endif #ifdef STORAGE_INTERNAL_ENABLED #if defined(DIFFERENT_FILE_MANAGE) || (!defined(DIFFERENT_FILE_MANAGE) && defined(EMAIL_FILE)) || !defined(STORAGE_EXTERNAL_ENABLED) #ifdef SSLCLIENT_WRAPPER void encode(EMAIL_FILE *file, SSLClient *client) { unsigned char in[3],out[4]; int i,len,blocksout=0; while (file->available()!=0) { len=0; for (i=0;i<3;i++){ in[i]=(unsigned char) file->read(); if (file->available()!=0) len++; else in[i]=0; } if (len){ encodeblock(in,out,len); // for(i=0;i<4;i++) client->write(out[i]); client->write(out, 4); blocksout++; } if (blocksout>=19||file->available()==0){ if (blocksout) { client->print("\r\n"); } blocksout=0; } } } #else void encode(EMAIL_FILE *file, EMAIL_NETWORK_CLASS *client) { unsigned char in[3],out[4]; int i,len,blocksout=0; while (file->available()!=0) { len=0; for (i=0;i<3;i++){ in[i]=(unsigned char) file->read(); if (file->available()!=0) len++; else in[i]=0; } if (len){ encodeblock(in,out,len); // for(i=0;i<4;i++) client->write(out[i]); client->write(out, 4); blocksout++; } if (blocksout>=19||file->available()==0){ if (blocksout) { client->print("\r\n"); } blocksout=0; } } } #endif #endif #endif #endif const char** toCharArray(String arr[], int num) { // If we ever alloc with new with have to delete const char** buffer = new const char*[num]; for(int i = 0; i < num; i++) { buffer[i] = arr[i].c_str(); } return buffer; } const char** toCharArray(char* arr[], int num) { // If we ever alloc with new with have to delete const char** buffer = new const char*[num]; for(int i = 0; i < num; i++) { buffer[i] = arr[i]; } return buffer; } EMailSender::Response EMailSender::send(char* tos[], byte sizeOfTo, EMailMessage &email, Attachments attachments) { return send(toCharArray(tos, sizeOfTo), sizeOfTo, 0, 0, email, attachments); } EMailSender::Response EMailSender::send(char* tos[], byte sizeOfTo, byte sizeOfCc, EMailMessage &email, Attachments attachments) { return send(toCharArray(tos, sizeOfTo+sizeOfCc), sizeOfTo, sizeOfCc, 0, email, attachments); } EMailSender::Response EMailSender::send(char* tos[], byte sizeOfTo, byte sizeOfCc,byte sizeOfCCn, EMailMessage &email, Attachments attachments){ return send(toCharArray(tos, sizeOfTo+sizeOfCc+sizeOfCCn), sizeOfTo, sizeOfCc, sizeOfCCn, email, attachments); } EMailSender::Response EMailSender::send(String to, EMailMessage &email, Attachments attachments){ DEBUG_PRINT(F("ONLY ONE RECIPIENT")); const char* arrEmail[] = {to.c_str()}; return send(arrEmail, 1, email, attachments); } EMailSender::Response EMailSender::send(String tos[], byte sizeOfTo, EMailMessage &email, Attachments attachments) { return send(toCharArray(tos, sizeOfTo), sizeOfTo, 0, 0, email, attachments); } EMailSender::Response EMailSender::send(String tos[], byte sizeOfTo, byte sizeOfCc, EMailMessage &email, Attachments attachments) { return send(toCharArray(tos, sizeOfTo+sizeOfCc), sizeOfTo, sizeOfCc, 0, email, attachments); } EMailSender::Response EMailSender::send(String tos[], byte sizeOfTo, byte sizeOfCc,byte sizeOfCCn, EMailMessage &email, Attachments attachments){ return send(toCharArray(tos, sizeOfTo+sizeOfCc+sizeOfCCn), sizeOfTo, sizeOfCc, sizeOfCCn, email, attachments); } EMailSender::Response EMailSender::send(const char* to, EMailMessage &email, Attachments attachments){ DEBUG_PRINT(F("ONLY ONE RECIPIENT")); const char* arrEmail[] = {to}; return send(arrEmail, 1, email, attachments); } EMailSender::Response EMailSender::send(const char* to[], byte sizeOfTo, EMailMessage &email, Attachments attachments) { DEBUG_PRINTLN(F("miltiple destination and attachments")); return send(to, sizeOfTo, 0, email, attachments); } EMailSender::Response EMailSender::send(const char* to[], byte sizeOfTo, byte sizeOfCc, EMailMessage &email, Attachments attachments) { return send(to, sizeOfTo, sizeOfCc, 0, email, attachments); } #ifdef SSLCLIENT_WRAPPER #ifdef PUT_OUTSIDE_SCOPE_CLIENT_DECLARATION // Initialize the SSL client library // We input an EthernetClient, our trust anchors, and the analog pin EMAIL_NETWORK_CLASS base_client; SSLClient client(base_client, TAs, (size_t)TAs_NUM, ANALOG_PIN, 2); #else #error "You must put outside scope the client declaration if you want use SSLClient!" #endif #else #ifdef PUT_OUTSIDE_SCOPE_CLIENT_DECLARATION EMAIL_NETWORK_CLASS client; #endif #endif EMailSender::Response EMailSender::send(const char* to[], byte sizeOfTo, byte sizeOfCc,byte sizeOfCCn, EMailMessage &email, Attachments attachments) { #ifdef SSLCLIENT_WRAPPER DEBUG_PRINTLN(F("SSLClient active!")); #else #ifndef PUT_OUTSIDE_SCOPE_CLIENT_DECLARATION EMAIL_NETWORK_CLASS client; #endif DEBUG_PRINT(F("Insecure client:")); DEBUG_PRINTLN(this->isSecure); #ifndef FORCE_DISABLE_SSL #if (EMAIL_NETWORK_TYPE == NETWORK_ESP8266 || EMAIL_NETWORK_TYPE == NETWORK_ESP8266_242) #ifndef ARDUINO_ESP8266_RELEASE_2_4_2 if (this->isSecure == false){ client.setInsecure(); bool mfln = client.probeMaxFragmentLength(this->smtp_server, this->smtp_port, 512); DEBUG_PRINT("MFLN supported: "); DEBUG_PRINTLN(mfln?"yes":"no"); if (mfln) { client.setBufferSizes(512, 512); } } #endif #elif (EMAIL_NETWORK_TYPE == NETWORK_ESP32) // String coreVersion = String(ESP.getSdkVersion()); // uint8_t firstdot = coreVersion.indexOf('.'); // // DEBUG_PRINTLN(coreVersion.substring(1, coreVersion.indexOf('.', firstdot+1)).toFloat()); // DEBUG_PRINTLN(coreVersion.substring(1, coreVersion.indexOf('.', firstdot+1)).toFloat() >= 3.3f); // if (coreVersion.substring(1, coreVersion.indexOf('.', firstdot+1)).toFloat() >= 3.3f) { // client.setInsecure(); // } #include <core_version.h> #if ((!defined(ARDUINO_ESP32_RELEASE_1_0_4)) && (!defined(ARDUINO_ESP32_RELEASE_1_0_3)) && (!defined(ARDUINO_ESP32_RELEASE_1_0_2))) client.setInsecure(); #endif #endif #endif #endif EMailSender::Response response; DEBUG_PRINTLN(this->smtp_server); DEBUG_PRINTLN(this->smtp_port); if(!client.connect(this->smtp_server, this->smtp_port)) { response.desc = F("Could not connect to mail server"); response.code = F("2"); response.status = false; client.flush(); client.stop(); return response; } client.flush(); response = awaitSMTPResponse(client, "220", "Connection Error"); if (!response.status) { DEBUG_PRINTLN("Error: in response status after connect"); client.flush(); client.stop(); return response; } if (this->additionalResponseLineOnConnection > 0){ for (int i = 0; i<=this->additionalResponseLineOnConnection; i++) { response = awaitSMTPResponse(client, "220", "Connection response error ", 2500); if (!response.status && response.code == F("1")) { response.desc = F("Connection error! Reduce the HELO response line!"); client.flush(); client.stop(); return response; } } } String commandHELO = "HELO"; if (this->useEHLO == true) { commandHELO = "EHLO"; } String helo = commandHELO + " " + this->smtp_server; DEBUG_PRINTLN(helo); client.println(helo); client.flush(); response = awaitSMTPResponse(client, "250", "Identification error"); if (!response.status) { DEBUG_PRINTLN("Error: after HELO - in response status "); client.flush(); client.stop(); return response; } // if (this->useEHLO == true) { // for (int i = 0; i<=6; i++) awaitSMTPResponse(client); // } // // for (int i = 0; i <= 6; i++) { // response = awaitSMTPResponse(client, "250", "EHLO error", 2500); // if (!response.status && response.code == F("1")) { // DEBUG_PRINTLN(response.desc); // break; // } // } DEBUG_PRINTLN("Got to after send HELO"); if (this->useEHLO == true && this->additionalResponseLineOnHELO == 0) { DEBUG_PRINTLN("In use EHLO"); this->additionalResponseLineOnHELO = DEFAULT_EHLO_RESPONSE_COUNT; } if (this->additionalResponseLineOnHELO > 0){ for (int i = 0; i<=this->additionalResponseLineOnHELO; i++) { response = awaitSMTPResponse(client, "250", "EHLO error", 2500); if (!response.status && response.code == F("1")) { DEBUG_PRINTLN("Error: after HELO - timeout"); response.desc = F("Timeout! Reduce the HELO response line!"); client.flush(); client.stop(); return response; } } } DEBUG_PRINTLN("Got to Use Auth"); if (useAuth){ if (this->isSASLLogin == true){ int size = 1 + strlen(this->email_login)+ strlen(this->email_password)+2; char * logPass = (char *) malloc(size); // strcpy(logPass, " "); // strcat(logPass, this->email_login); // strcat(logPass, " "); // strcat(logPass, this->email_password); // String logPass; int maincont = 0; logPass[maincont++] = ' '; logPass[maincont++] = (char) 0; for (unsigned int i = 0;i<strlen(this->email_login);i++){ logPass[maincont++] = this->email_login[i]; } logPass[maincont++] = (char) 0; for (unsigned int i = 0;i<strlen(this->email_password);i++){ logPass[maincont++] = this->email_password[i]; } // strcpy(logPass, "\0"); // strcat(logPass, this->email_login); // strcat(logPass, "\0"); // strcat(logPass, this->email_password); String auth = "AUTH PLAIN "+String(encode64_f(logPass, size)); // String auth = "AUTH PLAIN "+String(encode64(logPass)); DEBUG_PRINTLN(auth); client.println(auth); }else{ DEBUG_PRINTLN(F("AUTH LOGIN:")); client.println(F("AUTH LOGIN")); awaitSMTPResponse(client); DEBUG_PRINTLN(encode64(this->email_login)); client.println(encode64(this->email_login)); awaitSMTPResponse(client); DEBUG_PRINTLN(encode64(this->email_password)); client.println(encode64(this->email_password)); } response = awaitSMTPResponse(client, "235", "SMTP AUTH error"); if (!response.status) { client.flush(); client.stop(); return response; } } DEBUG_PRINT(F("MAIL FROM: <")); DEBUG_PRINT(this->email_from); DEBUG_PRINTLN(F(">")); client.print(F("MAIL FROM: <")); client.print(this->email_from); client.println(F(">")); awaitSMTPResponse(client); // String rcpt = "RCPT TO: <" + String(to) + '>'; // // DEBUG_PRINTLN(rcpt); // client.println(rcpt); int cont; for (cont=0;cont<(sizeOfTo+sizeOfCc+sizeOfCCn);cont++){ DEBUG_PRINT(F("RCPT TO: <")); DEBUG_PRINT(to[cont]); DEBUG_PRINTLN(F(">")); client.print(F("RCPT TO: <")); client.print(to[cont]); client.println(F(">")); awaitSMTPResponse(client); } DEBUG_PRINTLN(F("DATA:")); client.println(F("DATA")); response = awaitSMTPResponse(client, "354", "SMTP DATA error"); if (!response.status) { client.flush(); client.stop(); return response; } // client.println("From: <" + String(this->email_from) + '>'); client.print(F("From: ")); if (this->name_from){ client.print(this->name_from); } client.print(F(" <")); client.print(this->email_from); client.println(F(">")); // client.println("To: <" + String(to) + '>'); client.print(F("To: ")); for (cont=0;cont<sizeOfTo;cont++){ client.print(F("<")); client.print(to[cont]); client.print(">"); if (cont!=sizeOfTo-1){ client.print(","); } } client.println(); if (sizeOfCc>0){ client.print(F("Cc: ")); for (;cont<sizeOfTo+sizeOfCc;cont++){ client.print(F("<")); client.print(to[cont]); client.print(">"); if (cont!=sizeOfCc-1){ client.print(","); } } client.println(); } if (sizeOfCCn>0){ client.print(F("CCn: ")); for (;cont<sizeOfTo+sizeOfCc+sizeOfCCn;cont++){ client.print(F("<")); client.print(to[cont]); client.print(">"); if (cont!=sizeOfCCn-1){ client.print(","); } } client.println(); } client.print(F("Subject: ")); client.println(email.subject); // client.println(F("Mime-Version: 1.0")); client.println(F("MIME-Version: 1.0")); client.println(F("Content-Type: Multipart/mixed; boundary=frontier")); client.println(F("--frontier")); client.print(F("Content-Type: ")); client.print(email.mime); client.println(F("; charset=\"UTF-8\"")); // client.println(F("Content-Type: text/html; charset=\"UTF-8\"")); client.println(F("Content-Transfer-Encoding: 7bit")); client.println(); if (email.mime==F("text/html")){ // String body = "<!DOCTYPE html><html lang=\"en\">" + String(email.message) + "</html>"; client.print(F("<!DOCTYPE html><html lang=\"en\">")); client.print(email.message); client.println(F("</html>")); // client.println(body); }else{ client.println(email.message); } client.println(); #ifdef STORAGE_INTERNAL_ENABLED bool spiffsActive = false; #endif #ifdef STORAGE_EXTERNAL_ENABLED bool sdActive = false; #endif #if defined(ENABLE_ATTACHMENTS) && (defined(STORAGE_EXTERNAL_ENABLED) || defined(STORAGE_INTERNAL_ENABLED)) // if ((sizeof(attachs) / sizeof(attachs[0]))>0){ if (sizeof(attachments)>0 && attachments.number>0){ DEBUG_PRINT(F("Array: ")); // for (int i = 0; i<(sizeof(attachs) / sizeof(attachs[0])); i++){ for (int i = 0; i<attachments.number; i++){ uint8_t tBuf[64]; if (attachments.fileDescriptor[i].url.length()==0){ EMailSender::Response response; response.code = F("400"); response.desc = "Error no filename specified for the file "+attachments.fileDescriptor[i].filename; response.status = false; client.flush(); client.stop(); return response; } if (attachments.fileDescriptor[i].mime.length()==0){ EMailSender::Response response; response.code = F("400"); response.desc = "Error no mime type specified for the file "+attachments.fileDescriptor[i].url; response.status = false; client.flush(); client.stop(); return response; } if (attachments.fileDescriptor[i].filename.length()==0){ EMailSender::Response response; response.code = F("400"); response.desc = "Error no filename specified for the file "+attachments.fileDescriptor[i].url; response.status = false; client.flush(); client.stop(); return response; } DEBUG_PRINTLN(attachments.fileDescriptor[i].filename); DEBUG_PRINTLN(F("--frontier")); client.println(F("--frontier")); DEBUG_PRINTLN(F("Content-Type: ")); client.print(F("Content-Type: ")); DEBUG_PRINTLN(attachments.fileDescriptor[i].mime); client.print(attachments.fileDescriptor[i].mime); DEBUG_PRINTLN(F("; charset=\"UTF-8\"")); client.println(F("; charset=\"UTF-8\"")); if (attachments.fileDescriptor[i].encode64){ client.println(F("Content-Transfer-Encoding: base64")); } client.print(F("Content-Disposition: attachment; filename=")); client.print(attachments.fileDescriptor[i].filename); client.println(F("\n")); DEBUG_PRINT(F("Readed filename: ")); DEBUG_PRINTLN(attachments.fileDescriptor[i].filename); DEBUG_PRINT(F("Check if exist: ")); //DEBUG_PRINTLN(INTERNAL_STORAGE_CLASS.exists(attachments.fileDescriptor[i].url.c_str())); int clientCount = 0; #ifdef STORAGE_INTERNAL_ENABLED if (attachments.fileDescriptor[i].storageType==EMAIL_STORAGE_TYPE_SPIFFS || attachments.fileDescriptor[i].storageType==EMAIL_STORAGE_TYPE_LITTLE_FS || attachments.fileDescriptor[i].storageType==EMAIL_STORAGE_TYPE_SPIFM || attachments.fileDescriptor[i].storageType==EMAIL_STORAGE_TYPE_FFAT){ #ifdef OPEN_CLOSE_INTERNAL if (!INTERNAL_STORAGE_CLASS.exists(attachments.fileDescriptor[i].url.c_str())){ DEBUG_PRINTLN(F("Begin internal storage!")); #if (INTERNAL_STORAGE == STORAGE_SPIFM) Adafruit_FlashTransport_SPI flashTransport(SPIFM_CS_PIN, SPI); // Set CS and SPI interface Adafruit_SPIFlash flash(&flashTransport); // Initialize flash library and check its chip ID. if (!flash.begin()) { EMailSender::Response response; response.code = F("500"); response.desc = F("Error, failed to initialize flash chip!"); response.status = false; client.flush(); client.stop(); return response; } // close flash.begin() if(!(INTERNAL_STORAGE_CLASS.begin(&flash))){ #else if(!(INTERNAL_STORAGE_CLASS.begin())){ #endif EMailSender::Response response; response.code = F("500"); response.desc = F("Error on startup filesystem!"); response.status = false; client.flush(); client.stop(); return response; } // Close INTERNAL_STORAGE_CLASS.begin spiffsActive = true; DEBUG_PRINTLN("SPIFFS BEGIN, ACTIVE"); } // Close INTERNAL_STORAGE_CLASS.exists } // Close storageType #endif DEBUG_PRINT(F("Try to open ")); DEBUG_PRINTLN(attachments.fileDescriptor[i].url); EMAIL_FILE myFile = INTERNAL_STORAGE_CLASS.open(attachments.fileDescriptor[i].url, EMAIL_FILE_READ); if(myFile) { DEBUG_PRINT(F("Filename -> ")); DEBUG_PRINTLN(myFile.name()); if (attachments.fileDescriptor[i].encode64){ encode(&myFile, &client); }else{ while(myFile.available()) { clientCount = myFile.read(tBuf,64); DEBUG_PRINTLN(clientCount); client.write((byte*)tBuf,clientCount); } } myFile.close(); client.println(); } // Else myfile else { EMailSender::Response response; response.code = F("404"); response.desc = "Error opening attachments file "+attachments.fileDescriptor[i].url; response.status = false; client.flush(); client.stop(); return response; } // Close myfile #endif #ifdef STORAGE_EXTERNAL_ENABLED if (attachments.fileDescriptor[i].storageType==EMAIL_STORAGE_TYPE_SD){ #ifdef OPEN_CLOSE_SD DEBUG_PRINTLN(F("SD Check")); if (!EXTERNAL_STORAGE_CLASS.exists(attachments.fileDescriptor[i].url.c_str())){ #if EXTERNAL_STORAGE == STORAGE_SD || EXTERNAL_STORAGE == STORAGE_SDFAT2 if(!EXTERNAL_STORAGE_CLASS.begin(SD_CS_PIN)){ response.code = F("500"); response.desc = F("Error on startup SD filesystem!"); response.status = false; client.flush(); client.stop(); return response; } // Close EXTERNAL_STORAGE_CLASS.begin #elif EXTERNAL_STORAGE == STORAGE_SPIFM Adafruit_FlashTransport_SPI flashTransport(SS, SPI); // Set CS and SPI interface Adafruit_SPIFlash flash(&flashTransport); if (!EXTERNAL_STORAGE_CLASS.begin(&flash)) { response.code = F("500"); response.desc = F("Error on startup SDFAT2 filesystem!"); response.status = false; client.flush(); client.stop(); return response; } #endif sdActive = true; } // Close EXTERNAL_STORAGE_CLASS.exists #endif DEBUG_PRINTLN(F("Open file: ")); EMAIL_FILE_EX myFile = EXTERNAL_STORAGE_CLASS.open(attachments.fileDescriptor[i].url.c_str()); if(myFile) { myFile.seek(0); DEBUG_PRINTLN(F("OK")); if (attachments.fileDescriptor[i].encode64){ DEBUG_PRINTLN(F("BASE 64")); encode(&myFile, &client); }else{ DEBUG_PRINTLN(F("NORMAL")); while(myFile.available()) { clientCount = myFile.read(tBuf,64); client.write((byte*)tBuf,clientCount); } } myFile.close(); client.println(); } // Else myfile else { response.code = F("404"); response.desc = "Error opening attachments file "+attachments.fileDescriptor[i].url; response.status = false; client.flush(); client.stop(); return response; } // Close myFile } // Close storageType==EMAIL_STORAGE_TYPE_SD #else if (attachments.fileDescriptor[i].storageType==EMAIL_STORAGE_TYPE_SD){ response.code = F("500"); response.desc = F("EMAIL_STORAGE_TYPE_SD not enabled on EMailSenderKey.h"); response.status = false; client.flush(); client.stop(); return response; } #endif } // Close attachment cycle client.println(); client.println(F("--frontier--")); #ifdef STORAGE_EXTERNAL_ENABLED #ifdef OPEN_CLOSE_SD if (sdActive){ DEBUG_PRINTLN(F("SD end")); #ifndef ARDUINO_ESP8266_RELEASE_2_4_2 EXTERNAL_STORAGE_CLASS.end(); #endif DEBUG_PRINTLN(F("SD end 2")); } #endif #endif #ifdef STORAGE_INTERNAL_ENABLED #ifdef OPEN_CLOSE_INTERNAL #if INTERNAL_STORAGE != STORAGE_SPIFM if (spiffsActive){ INTERNAL_STORAGE_CLASS.end(); DEBUG_PRINTLN(F("SPIFFS END")); } #endif #endif #endif } // Close attachement enable #endif DEBUG_PRINTLN(F("Message end")); client.println(F(".")); response = awaitSMTPResponse(client, "250", "Sending message error"); if (!response.status) { client.flush(); client.stop(); return response; } client.println(F("QUIT")); response = awaitSMTPResponse(client, "221", "SMTP QUIT error"); if (!response.status) { client.flush(); client.stop(); return response; } response.status = true; response.code = F("0"); response.desc = F("Message sent!"); client.flush(); client.stop(); return response; }
-
6 January 2023 at 15:26 #23800
Hi,
ok, your SMTP server needs the IP of your server in the helo message; you can use the library commandsetPublicIpDescriptor()
to change It from ‘mischianti’ to another value.
And update the library to the latest version.
Bye Renzo
-
6 January 2023 at 17:14 #23803
For whatever reason, that did not work, and I had to add the 2x clint.flush (after the connect, as well as after the helo).
Also, I removed the space after the PublicIPDescriptor.
Also in my case, I have to comment out the line
//DEBUG_PRINTLN(INTERNAL_STORAGE_CLASS.exists(attachments.fileDescriptor[i].url.c_str()));in the EMailSender.cpp program, in order to allow compile when DEBUGPRINT is on
I have attached the file below
Attachments:
You must be logged in to view attached files. -
6 January 2023 at 18:59 #23808
But with the flush and the space deletion work?
-
6 January 2023 at 21:09 #23817
Yes, with the changes as per the attached file, it works
-
7 January 2023 at 16:14 #23824
Hi rs77can,
to manage that situation I add 2 methods:emailSend.setAdditionalResponseLineOnConnection(1);
and
emailSend.setAdditionalResponseLineOnHELO(1);
these methods manage strange responses from the SMTP server, use that instead of adding
client.flush()
in the library.Can you confirm that the space after the PublicIPDescriptor generate another problem?
Thanks Renzo
-
8 January 2023 at 19:52 #23830
When it becomes available on the arduino library, I will update and add the lines above try.
Will let you know the results.
Thanks
-
13 May 2023 at 16:28 #25697
Just for the record.
I decided to finally update EmailSender to the latest version, and had the same issues as before.
I added the 2 lines as described above
... SerDebugln(F("In email routine")); //emailSend.setEHLOCommand(true); emailSend.setPublicIpDescriptor(es); emailSend.setAdditionalResponseLineOnConnection(1); emailSend.setAdditionalResponseLineOnHELO(1); EMailSender::EMailMessage msg; msg.subject = EMailData[i].emailSubject; msg.message = EMailData[i].emailMessage; EMailSender::Response resp = emailSend.send(ste, msg); ...
I ended up getting the following error
Connection error! Reduce the HELO response line!
I ended up removing them, and making the changes I had made before, and then it sends OK. The file with the mods is attached below
Attachments:
You must be logged in to view attached files. -
16 May 2023 at 09:16 #25744
Hi,
you can simply reduce this number.
-
-
AuthorPosts
- You must be logged in to reply to this topic.