Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added doc/SMTP API.pdf
Binary file not shown.
123 changes: 123 additions & 0 deletions examples/GSM_GPRSLibrary_SMTP_Client.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
This example shows how to send an encrypted mail
As each SMPT function basically returns true or false, depending on success,
the flow is simply a load of nested if () statements.

The SMTP class is capable of sending encrypted (SSL) or non-encrypted mail. Make sure you match the correct
server port with your choice.
Non-encrypted mail usually goes to port 25
Encrypted mail usually goes to port 465 but that may vary with the mail server.

The SIM900 can accept a mail body up to 4K bytes.
SMTP class supports messages in ASCII by default. UTF-8 is theoretically supported but not yet
tested.
*/
#include "SIM900.h"
#include <SoftwareSerial.h>
#include "smtp.h"
#include "inetGSM.h"

#define USESSL // comment out if not using SSL
//To change pins for Software Serial, use the two lines in GSM.cpp.

//GSM Shield for Arduino
//www.open-electronics.org
//this code is based on the example of Arduino Labs.

SMTPGSM smtp; // smtp object

int i=0;

// Edit the following for your own circumstances
char *Sender = "[email protected]";
char *ServerURL = "smtp.mail.yahoo.com";
char *Login = "[email protected]";
char *Password = "secret";

char *APN = ".....";
char *SenderNickName = "dave";
char *Recipient = "[email protected]";
char *RecipientNickName = "Fred";
char *Subject = "BLAH";
char *Body = "hello world";
int CID = 1;
#ifdef USESSL
int ServerPort = 465;
#else
int ServerPort = 25;
#endif

void setup()
{
//Serial connection.
Serial.begin(9600);
Serial.println("GSM Shield testing.");
//Start configuration of shield with baudrate.
if (gsm.begin(9600))
{
Serial.println("\nstatus=READY");
if (smtp.SmtpGprsIsOpen(CID))
smtp.SmtpCloseGprs(CID);
Serial.println("init passed");
}
else
Serial.println("\nstatus=IDLE");
}

void loop()
{
if (smtp.SmtpOpenGprs(CID,APN))
{
smtp.SmtpTimeout(60);
smtp.SmtpSetCS(smtp.ASCII);
Serial.println("open gprs passed");
#ifdef USESSL
smtp.SmtpSetSSL(true);
#else
smtp.SmtpSetSSL(false);
#endif
if (smtp.SmtpSetSender(Sender,SenderNickName))
{
Serial.println("set sender passed");
if (smtp.SmtpSetServer(ServerURL,ServerPort))
{
Serial.println("set server passed");
if (smtp.SmtpSetLogin(Login,Password))
{
Serial.println("set login passed");
if (smtp.SmtpSetRecipient(smtp.TO,0,Recipient,RecipientNickName))
{
Serial.println("set rcp passed");
if (smtp.SmtpSetSubject(Subject))
{
Serial.println("set subject passed");
if (smtp.SmtpSendBody(Body))
Serial.println("send body passed");
else
Serial.println("send body failed");
smtp.SmtpCloseGprs(CID);
while (true){}
}
else
Serial.println("set subject failed");
}
else
Serial.println("set rcp failed");
}
else
Serial.println("set sender failed");
}
else
Serial.println("set login failed");
}
else
Serial.println("set server failed");
}
else
{
Serial.println("open gprs failed");
if (smtp.SmtpCloseGprs(CID))
Serial.println("closed gprs");
}
}

258 changes: 258 additions & 0 deletions smtp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
#include "smtp.h"

/**********************************************************
Method sends SMTP


return:
All functions except SmtpBody return bool
true - success
false - failure

Note that none of the mail parameters (server, authentification, sender
recipients, subject) are persistent. Once a mail has been sent they must
all be reset for the next message.
Character set, timeout and SSL are persistent.
Maximum mail body size 4K. Up to you to keep track of what you are sending

an example of usage for encrypted mail:
SMTPGSM smtp;
int CID = 1; // can be 1,2 or 3 you must keep track of what is used
smtp.SmtpOpenGprs(CID,"myapn");
smtp.SmtpTimeout(60);
smtp.SmtpSetServer("mail.smtp.yahoo.com",465);
smtp.SmtpSetLogin("yourlogin","yourpassword");
smtp.SmtpSetSSL(true);
smtp.SmtpSetCS(smtp.ASCII);
smtp.SmtpSetSender("[email protected]","nickname");
smtp.SmtpSetRecipient(smtp.TO,0,"[email protected]");
smtp.SmtpSetRecipient(smtp.TO,1,"[email protected]");
smtp.SmtpSetRecipient(smtp.CC,0,"[email protected]");
smtp.SmtpSetRecipient(smtp.BCC,0,"[email protected]");
smtp.SmtpSetSubject("party tonight");
smtp.SmtpSendBody("dont be late");
smtp.SmtpCloseGprs(CID);
**********************************************************/
const char *OK = "OK";

bool writewithtimeout(char *buf,const char *response,unsigned long start,unsigned long interchar)
{
bool success = false;
byte status;
#ifdef SMTP_DEBUG_ON
Serial.println(buf);
#endif
gsm.SimpleWrite(buf);
// 1 sec. for initial comm tmout
// and max. 150 msec. for inter character timeout
gsm.RxInit(start, interchar);
// wait response is finished
do
{
if (gsm.IsStringReceived(response))
{
// perfect - we have some response, but what:
status = RX_FINISHED;
success = true;
break; // so finish receiving immediately and let's go to
// to check response
}
status = gsm.IsRxFinished();
} while (status == RX_NOT_FINISHED);
return success;
}

bool SMTPGSM::SmtpSetServer(char *server, int port)
{
bool success = false;
//pServer = server;
//Port = port;
sprintf(printbuf,"AT+SMTPSRV=\"%s\",%d\r\n",server,port);
#ifdef DEBUG_ON
Serial.println("DEBUG:SMTP SETSERV");
Serial.println(printbuf);
#endif
return writewithtimeout(printbuf,OK,4000,150);
}
bool SMTPGSM::SmtpSetLogin(char *login_str,char *password)
{
bool success = false;
//pLogin = login_str;
//pPassword = password;
sprintf(printbuf,"AT+SMTPAUTH=1,\"%s\",\"%s\"\r",login_str,password);
#ifdef DEBUG_ON
Serial.println("DEBUG:SMTP SETLOGIN");
Serial.println(printbuf);
#endif
return writewithtimeout(printbuf,OK,1000,150);
}
bool SMTPGSM::SmtpSetSender(char *address,char *name)
{
// pSenderAddress = address;
//pSenderName = name;
bool success = false;
sprintf(printbuf,"AT+SMTPFROM=\"%s\",\"%s\"\r",address,name);
#ifdef DEBUG_ON
Serial.println("DEBUG:SMTP SETSENDER");
Serial.println(printbuf);
#endif
return writewithtimeout(printbuf,OK,1000,150);
}
bool SMTPGSM::SmtpSetSSL(bool ssl)
{
if (ssl)
return writewithtimeout("AT+EMAILSSL=1\r",OK,1000,150);
else
return writewithtimeout("AT+EMAILSSL=0\r",OK,1000,150);
}
bool SMTPGSM::SmtpSetCS(eSMTPCS cs)
{
#if 0
bool success=false;
cset = cs;
if (cs == ASCII)
return writewithtimeout("AT+SMTPCS=\"ASCII\"\r",OK,1000,150);
else
return writewithtimeout("AT+SMTPCS=\"UTF-8\",\r",OK,1000,150);
#else
return writewithtimeout("AT+SMTPCS=\"ASCII\"\r",OK,1000,150);
#endif
}
bool SMTPGSM::SmtpSetRecipient(enum eSMTPRCPT type, int index, char *address,char *name)
{
bool success = false;
sprintf(printbuf,"AT+SMTPRCPT=%d,%d,\"%s\",\"%s\"\r",type,index,address,name);
#ifdef DEBUG_ON
Serial.println("DEBUG:SMTP SETRCPT");
Serial.println(printbuf);
#endif
return writewithtimeout(printbuf,OK,1000,150);
}

bool SMTPGSM::SmtpSendBody(char *body)
{
bool success = false;
if (writewithtimeout("AT+SMTPBODY\r",">",1000,150))
{
#ifdef DEBUG_ON
Serial.println("DEBUG:SMTP SETBODY");
Serial.println(body);
#endif
gsm.SimpleWrite(body);
sprintf(printbuf,"%c",26);
if (writewithtimeout(printbuf,OK,1000,150)) // add CTRL-Z end marker
{
delay(2000);
success = writewithtimeout("AT+SMTPSEND\r","+SMTPSEND: 1",1000,timeout*1000);
}
#ifdef SMTP_DEBUG_ON
Serial.println((char *)gsm.comm_buf);
#endif
}
return success;
}
bool SMTPGSM::SmtpTimeout(int to)
{
bool success = false;
timeout = (unsigned long)to;
sprintf(printbuf,"AT+EMAILTO=%d\r",to);
#ifdef DEBUG_ON
Serial.println("DEBUG:SMTP SETINIT");
Serial.println(printbuf);
#endif
return writewithtimeout(printbuf,OK,1000,150);
}

bool SMTPGSM::SmtpOpenGprs(int CID,char *apn)
{
bool success = false;
cid = CID;
sprintf(printbuf,"AT+SAPBR=3,%d,\"CONTYPE\",\"GPRS\"\r",cid);
if (writewithtimeout(printbuf,OK,5000,1000))
{
delay(2000);
sprintf(printbuf,"AT+SAPBR=3,%d,\"APN\",\"%s\"\r",cid,apn);
#ifdef DEBUG_ON
Serial.println("DEBUG:SMTP SETOPENGPRS");
Serial.println(printbuf);
#endif
if (writewithtimeout(printbuf,OK,1000,150))
{
delay(2000);
sprintf(printbuf,"AT+SAPBR=1,%d\r",cid);
if (writewithtimeout(printbuf,OK,1000,1000))
{
sprintf(printbuf,"AT+EMAILCID=%d\r",CID);
return writewithtimeout(printbuf,OK,1000,150);
}
}
}
return success;
}

bool SMTPGSM::SmtpQueryGprs(int CID)
{
sprintf(printbuf,"AT+SAPBR=2,%d\r",CID);
return writewithtimeout(printbuf,OK,1000,150);
}

bool SMTPGSM::SmtpCloseGprs(int CID)
{
sprintf(printbuf,"AT+SAPBR=0,%d\r",CID);
return writewithtimeout(printbuf,OK,1000,150);
}

bool SMTPGSM::SmtpSetSubject(char *sj)
{
bool success = false;
int i;
sprintf(printbuf,"AT+SMTPSUB=\"%s\"\r",sj);
#ifdef DEBUG_ON
Serial.println("DEBUG:SMTP SETSUB");
Serial.println(printbuf);
#endif
success= writewithtimeout(printbuf,OK,1000,150);
return success;
}

/*
Must call SmtpInit before calling this function;
*/
int SMTPGSM::SmtpGetBodySize()
{
char *ch;
Serial.println("bodysize");
if (writewithtimeout("AT+SMTPBODY=?\r",OK,5000,150))
{
ch = strstr((char *)gsm.comm_buf, "+SMTPBODY:");
if (ch == 0)
return -1;
else
{
ch += 10; // skip over compare string
return atoi(ch);
}
return 1;
}
else
return -1;
}

bool SMTPGSM::SmtpGprsIsOpen(int CID)
{
char *ch;
sprintf(printbuf,"AT+SAPBR=2,%d\r",CID);
if (writewithtimeout(printbuf,OK,5000,150))
{
ch = strstr((char *)gsm.comm_buf, "+SAPBR:1,");
if (ch == 0)
return false;
else
{
ch += 9; // skip over compare string
return *ch == '1';
}
}
else
return false;
}
Loading