Merge branch 'development' of https://github.com/arendst/Sonoff-Tasmota into development

This commit is contained in:
Theo Arends 2019-10-20 11:58:02 +02:00
commit c362bae928
2 changed files with 125 additions and 81 deletions

View File

@ -3,37 +3,48 @@
#include "sendemail.h" #include "sendemail.h"
// enable serial debugging // enable serial debugging
//#define DEBUG_EMAIL_PORT Serial //#define DEBUG_EMAIL_PORT
//SendEmail(const String& host, const int port, const String& user, const String& passwd, const int timeout, const bool ssl); // sendmail works only with server port 465 SSL and doesnt support STARTTLS (not supported in Arduino)
//SendEmail::send(const String& from, const String& to, const String& subject, const String& msg) // only a couple of mailservers support this (e.g. gmail,gmx,yahoo,freenetmail)
// sendmail [server:port:user:passwd:from:to:subject] data // sendmail [server:port:user:passwd:from:to:subject] body
// sendmail [*:*:*:*:*:to:subject] data uses defines from user_config // sendmail [*:*:*:*:*:to:subject] data uses defines from user_config_overwrite
// sendmail currently only works with core 2.4.2 // #define EMAIL_USER "user"
// #define EMAIL_PASSWORD "passwd"
// #define EMAIL_FROM "<mr.x@gmail.com>"
// #define EMAIL_SERVER "smtp.gmail.com"
// #define EMAIL_PORT 465
// if email body consist of a single * and scripter is present
// and a section >m is found, the lines in this section (until #) are sent
// as email body
// sendmail works with pre2.6 using Light BearSSL
//HW Watchdog 8.44 sec. //HW Watchdog 8.44 sec.
//SW Watchdog 3.2 sec. //SW Watchdog 3.2 sec.
#ifndef SEND_MAIL_MINRAM
#define SEND_MAIL_MINRAM 12*1024 #define SEND_MAIL_MINRAM 12*1024
#endif
#define xPSTR(a) a
uint16_t SendMail(char *buffer) { uint16_t SendMail(char *buffer) {
uint16_t count;
char *params,*oparams; char *params,*oparams;
char *mserv; const char *mserv;
uint16_t port; uint16_t port;
char *user; const char *user;
char *pstr; const char *pstr;
char *passwd; const char *passwd;
char *from; const char *from;
char *to; const char *to;
char *subject; const char *subject;
char *cmd; const char *cmd;
char secure=0,auth=0; char auth=0;
uint16_t status=1; uint16_t status=1;
SendEmail *mail=0; SendEmail *mail=0;
uint16_t blen; uint16_t blen;
char *endcmd; char *endcmd;
//DebugFreeMem();
// return if not enough memory // return if not enough memory
uint16_t mem=ESP.getFreeHeap(); uint16_t mem=ESP.getFreeHeap();
@ -65,9 +76,7 @@ uint16_t SendMail(char *buffer) {
cmd=endcmd+1; cmd=endcmd+1;
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
SetSerialBaudrate(115200); AddLog_P2(LOG_LEVEL_INFO, PSTR("mailsize: %d"),blen);
DEBUG_EMAIL_PORT.print("mailsize: ");
DEBUG_EMAIL_PORT.println(blen);
#endif #endif
mserv=strtok(params,":"); mserv=strtok(params,":");
@ -119,43 +128,39 @@ uint16_t SendMail(char *buffer) {
#ifdef EMAIL_USER #ifdef EMAIL_USER
if (*user=='*') { if (*user=='*') {
user=(char*)EMAIL_USER; user=xPSTR(EMAIL_USER);
} }
#endif #endif
#ifdef EMAIL_PASSWORD #ifdef EMAIL_PASSWORD
if (*passwd=='*') { if (*passwd=='*') {
passwd=(char*)EMAIL_PASSWORD; passwd=xPSTR(EMAIL_PASSWORD);
} }
#endif #endif
#ifdef EMAIL_SERVER #ifdef EMAIL_SERVER
if (*mserv=='*') { if (*mserv=='*') {
mserv=(char*)EMAIL_SERVER; mserv=xPSTR(EMAIL_SERVER);
} }
#endif //USE_SENDMAIL #endif //USE_SENDMAIL
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(mserv); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s - %d - %s - %s"),mserv,port,user,passwd);
DEBUG_EMAIL_PORT.println(port);
DEBUG_EMAIL_PORT.println(user);
DEBUG_EMAIL_PORT.println(passwd);
#endif #endif
// 2 seconds timeout // 2 seconds timeout
#define MAIL_TIMEOUT 500 #ifndef MAIL_TIMEOUT
#define MAIL_TIMEOUT 2000
#endif
mail = new SendEmail(mserv,port,user,passwd, MAIL_TIMEOUT, auth); mail = new SendEmail(mserv,port,user,passwd, MAIL_TIMEOUT, auth);
#ifdef EMAIL_FROM #ifdef EMAIL_FROM
if (*from=='*') { if (*from=='*') {
from=(char*)EMAIL_FROM; from=xPSTR(EMAIL_FROM);
} }
#endif #endif
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(from); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s - %s - %s - %s"),from,to,subject,cmd);
DEBUG_EMAIL_PORT.println(to);
DEBUG_EMAIL_PORT.println(subject);
DEBUG_EMAIL_PORT.println(cmd);
#endif #endif
if (mail) { if (mail) {
@ -169,13 +174,11 @@ exit:
return status; return status;
} }
void script_send_email_body(BearSSL::WiFiClientSecure_light *client);
SendEmail::SendEmail(const String& host, const int port, const String& user, const String& passwd, const int timeout, const int auth_used) : SendEmail::SendEmail(const String& host, const int port, const String& user, const String& passwd, const int timeout, const int auth_used) :
host(host), port(port), user(user), passwd(passwd), timeout(timeout), ssl(ssl), auth_used(auth_used), client(new BearSSL::WiFiClientSecure_light(1024,1024)) host(host), port(port), user(user), passwd(passwd), timeout(timeout), ssl(ssl), auth_used(auth_used), client(new BearSSL::WiFiClientSecure_light(1024,1024)) {
{
} }
String SendEmail::readClient() { String SendEmail::readClient() {
@ -190,10 +193,7 @@ String SendEmail::readClient() {
return r; return r;
} }
//void SetSerialBaudrate(int baudrate); bool SendEmail::send(const String& from, const String& to, const String& subject, const char *msg) {
bool SendEmail::send(const String& from, const String& to, const String& subject, const char *msg)
{
bool status=false; bool status=false;
String buffer; String buffer;
@ -204,24 +204,19 @@ String buffer;
client->setTimeout(timeout); client->setTimeout(timeout);
// smtp connect // smtp connect
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
SetSerialBaudrate(115200); AddLog_P2(LOG_LEVEL_INFO, PSTR("Connecting: %s on port %d"),host.c_str(),port);
DEBUG_EMAIL_PORT.print("Connecting: ");
DEBUG_EMAIL_PORT.print(host);
DEBUG_EMAIL_PORT.print(":");
DEBUG_EMAIL_PORT.println(port);
#endif #endif
if (!client->connect(host.c_str(), port)) { if (!client->connect(host.c_str(), port)) {
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println("Connection failed: "); AddLog_P(LOG_LEVEL_INFO, PSTR("Connection failed"));
//DEBUG_EMAIL_PORT.println (client->getLastSSLError());
#endif #endif
goto exit; goto exit;
} }
buffer = readClient(); buffer = readClient();
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
if (!buffer.startsWith(F("220"))) { if (!buffer.startsWith(F("220"))) {
goto exit; goto exit;
@ -232,61 +227,52 @@ String buffer;
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
buffer = readClient(); buffer = readClient();
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
if (!buffer.startsWith(F("250"))) { if (!buffer.startsWith(F("250"))) {
goto exit; goto exit;
} }
if (user.length()>0 && passwd.length()>0 ) { if (user.length()>0 && passwd.length()>0 ) {
//buffer = F("STARTTLS");
//client->println(buffer);
buffer = F("AUTH LOGIN"); buffer = F("AUTH LOGIN");
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
buffer = readClient(); buffer = readClient();
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
if (!buffer.startsWith(F("334"))) if (!buffer.startsWith(F("334")))
{ {
goto exit; goto exit;
} }
base64 b; base64 b;
//buffer = user;
//buffer = b.encode(buffer);
buffer = b.encode(user); buffer = b.encode(user);
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
//DEBUG_EMAIL_PORT.println(user); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
DEBUG_EMAIL_PORT.println(buffer);
#endif #endif
buffer = readClient(); buffer = readClient();
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
if (!buffer.startsWith(F("334"))) { if (!buffer.startsWith(F("334"))) {
goto exit; goto exit;
} }
//buffer = this->passwd;
//buffer = b.encode(buffer);
buffer = b.encode(passwd); buffer = b.encode(passwd);
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
//DEBUG_EMAIL_PORT.println(passwd); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
DEBUG_EMAIL_PORT.println(buffer);
#endif #endif
buffer = readClient(); buffer = readClient();
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
if (!buffer.startsWith(F("235"))) { if (!buffer.startsWith(F("235"))) {
goto exit; goto exit;
@ -298,11 +284,11 @@ String buffer;
buffer += from; buffer += from;
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
buffer = readClient(); buffer = readClient();
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
if (!buffer.startsWith(F("250"))) { if (!buffer.startsWith(F("250"))) {
goto exit; goto exit;
@ -311,11 +297,11 @@ String buffer;
buffer += to; buffer += to;
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
buffer = readClient(); buffer = readClient();
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
if (!buffer.startsWith(F("250"))) { if (!buffer.startsWith(F("250"))) {
goto exit; goto exit;
@ -324,11 +310,11 @@ String buffer;
buffer = F("DATA"); buffer = F("DATA");
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
buffer = readClient(); buffer = readClient();
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
if (!buffer.startsWith(F("354"))) { if (!buffer.startsWith(F("354"))) {
goto exit; goto exit;
@ -337,32 +323,40 @@ String buffer;
buffer += from; buffer += from;
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
buffer = F("To: "); buffer = F("To: ");
buffer += to; buffer += to;
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
buffer = F("Subject: "); buffer = F("Subject: ");
buffer += subject; buffer += subject;
buffer += F("\r\n"); buffer += F("\r\n");
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
#ifdef USE_SCRIPT
if (*msg=='*' && *(msg+1)==0) {
script_send_email_body(client);
} else {
client->println(msg); client->println(msg);
}
#else
client->println(msg);
#endif
client->println('.'); client->println('.');
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(msg); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
buffer = F("QUIT"); buffer = F("QUIT");
client->println(buffer); client->println(buffer);
#ifdef DEBUG_EMAIL_PORT #ifdef DEBUG_EMAIL_PORT
DEBUG_EMAIL_PORT.println(buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR("%s"),buffer.c_str());
#endif #endif
status=true; status=true;

View File

@ -2100,6 +2100,7 @@ void Replace_Cmd_Vars(char *srcbuf,char *dstbuf,uint16_t dstsize) {
cp=srcbuf; cp=srcbuf;
struct T_INDEX ind; struct T_INDEX ind;
char string[SCRIPT_MAXSSIZE]; char string[SCRIPT_MAXSSIZE];
dstsize-=2;
for (count=0;count<dstsize;count++) { for (count=0;count<dstsize;count++) {
if (*cp=='%') { if (*cp=='%') {
cp++; cp++;
@ -2121,8 +2122,11 @@ void Replace_Cmd_Vars(char *srcbuf,char *dstbuf,uint16_t dstsize) {
} else { } else {
// string result // string result
} }
uint8_t slen=strlen(string);
if (count+slen<dstsize-1) {
strcpy(&dstbuf[count],string); strcpy(&dstbuf[count],string);
count+=strlen(string)-1; count+=slen-1;
}
cp++; cp++;
} else { } else {
strcpy(&dstbuf[count],"???"); strcpy(&dstbuf[count],"???");
@ -2158,6 +2162,7 @@ void Replace_Cmd_Vars(char *srcbuf,char *dstbuf,uint16_t dstsize) {
cp++; cp++;
} }
} }
dstbuf[count]=0;
} }
void toLog(const char *str) { void toLog(const char *str) {
@ -2621,7 +2626,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
if (cmdmem) { if (cmdmem) {
char *cmd=cmdmem; char *cmd=cmdmem;
uint16_t count; uint16_t count;
for (count=0; count<SCRIPT_CMDMEM/2-1; count++) { for (count=0; count<SCRIPT_CMDMEM/2-2; count++) {
//if (*lp=='\r' || *lp=='\n' || *lp=='}') { //if (*lp=='\r' || *lp=='\n' || *lp=='}') {
if (!*lp || *lp=='\r' || *lp=='\n') { if (!*lp || *lp=='\r' || *lp=='\n') {
cmd[count]=0; cmd[count]=0;
@ -4307,9 +4312,10 @@ String ScriptUnsubscribe(const char * data, int data_len)
} }
#endif // SUPPORT_MQTT_EVENT #endif // SUPPORT_MQTT_EVENT
#ifdef USE_SCRIPT_WEB_DISPLAY
#ifdef USE_SCRIPT_WEB_DISPLAY
void Script_Check_HTML_Setvars(void) { void Script_Check_HTML_Setvars(void) {
if (!HttpCheckPriviledgedAccess()) { return; } if (!HttpCheckPriviledgedAccess()) { return; }
@ -4596,6 +4602,50 @@ void ScriptWebShow(void) {
} }
#endif //USE_SCRIPT_WEB_DISPLAY #endif //USE_SCRIPT_WEB_DISPLAY
#ifdef USE_SENDMAIL
void script_send_email_body(BearSSL::WiFiClientSecure_light *client) {
uint8_t msect=Run_Scripter(">m",-2,0);
if (msect==99) {
char line[128];
char tmp[128];
char *lp=glob_script_mem.section_ptr+2;
while (lp) {
while (*lp==SCRIPT_EOL) {
lp++;
}
if (!*lp || *lp=='#' || *lp=='>') {
break;
}
if (*lp!=';') {
// send this line to smtp
memcpy(line,lp,sizeof(line));
line[sizeof(line)-1]=0;
char *cp=line;
for (uint32_t i=0; i<sizeof(line); i++) {
if (!*cp || *cp=='\n' || *cp=='\r') {
*cp=0;
break;
}
cp++;
}
Replace_Cmd_Vars(line,tmp,sizeof(tmp));
client->println(tmp);
}
if (*lp==SCRIPT_EOL) {
lp++;
} else {
lp = strchr(lp, SCRIPT_EOL);
if (!lp) break;
lp++;
}
}
} else {
client->println("*");
}
}
#endif
#ifdef USE_SCRIPT_JSON_EXPORT #ifdef USE_SCRIPT_JSON_EXPORT
void ScriptJsonAppend(void) { void ScriptJsonAppend(void) {
uint8_t web_script=Run_Scripter(">J",-2,0); uint8_t web_script=Run_Scripter(">J",-2,0);