EthernetInterface Libraryを使ったSimpleな SMTP ClientLibraryです. LOGIN認証を追加しました.(2014.4 Update) It is SMTPClient Library which is Simple using EthernetInterface Library.

Dependents:   SimpleSMTPClient_HelloWorld USBHost-MSD_Sensors_1 IOT-GPS-SMS IOT_HW_5_websockets ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SimpleSMTPClient.cpp Source File

SimpleSMTPClient.cpp

Go to the documentation of this file.
00001 /*
00002  *
00003  * mbed Simple SMTP Client
00004  * Copyright (c) 2012 Tadao Iida
00005  * Released under the MIT License: http://mbed.org/license/mit
00006  * 2015/12/1 Ver 1.5 Update 
00007  */ 
00008 
00009 //Debug is disabled by default
00010 #if 0
00011 //Enable debug
00012 #define __DEBUG__
00013 #include <cstdio>
00014 #define DBG(x, ...) std::printf("[DBG]"x"\r\n", ##__VA_ARGS__); 
00015 
00016 #else
00017 //Disable debug
00018 #define DBG(x, ...) 
00019 
00020 #endif
00021 
00022 /** @file
00023  * @brief Simple SMTP Client
00024  */
00025  
00026 #include "mbed.h"
00027 #include "EthernetInterface.h"
00028 #include "SimpleSMTPClient.h"
00029 
00030 SimpleSMTPClient::SimpleSMTPClient() : smtp()
00031 {
00032 
00033 
00034 }
00035 
00036 
00037 // Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
00038 int SimpleSMTPClient::base64enc(const char *input, unsigned int length, char *output, int outputlen) {
00039   static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00040   unsigned int c, c1, c2, c3;
00041  
00042   if (outputlen < (((length-1)/3)+1)<<2) return -1;
00043  
00044   for(unsigned int i = 0, j = 0; i<length; i+=3,j+=4) {
00045     c1 = ((((unsigned char)*((unsigned char *)&input[i]))));
00046     c2 = (length>i+1)?((((unsigned char)*((unsigned char *)&input[i+1])))):0;
00047     c3 = (length>i+2)?((((unsigned char)*((unsigned char *)&input[i+2])))):0;
00048  
00049     c = ((c1 & 0xFC) >> 2);
00050     output[j+0] = base64[c];
00051     c = ((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4);
00052     output[j+1] = base64[c];
00053     c = ((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6);
00054     output[j+2] = (length>i+1)?base64[c]:'=';
00055     c = (c3 & 0x3F);
00056     output[j+3] = (length>i+2)?base64[c]:'=';
00057   }
00058   output[(((length-1)/3)+1)<<2] = '\0';
00059   return 0;
00060 }
00061  
00062 // SMTP ReceiveMessage 
00063 int SimpleSMTPClient::receiveMessage(int code) {
00064     int i;
00065     char buf[1500];
00066  
00067     do{
00068         i = smtp.receive(buf, sizeof(buf));
00069         buf[i]='\0';
00070         printf("Recv>>%s[%d] \r\n",buf,i);    
00071     }while(atoi(buf) != code && i > 0 );
00072     
00073     // Check return code
00074     if (i < 0 )
00075         return -1; 
00076     
00077     return 0;
00078 }
00079  
00080 int SimpleSMTPClient::sendmail (char *host, char *user, char *pwd, char *domain,char *port,SMTPAuth auth) {
00081 
00082     int ret = -1;
00083     char ehlo[128];
00084     char tmp1[256];
00085  
00086     smtp.set_blocking(false, 1500); 
00087     smtp.connect(host, atoi(port)) ;
00088     if ( !smtp.is_connected() ){
00089         printf("Connection Error!\r\n");
00090         smtp.close();
00091         return -1; 
00092     }
00093     
00094     // send request
00095     wait_ms(100);
00096     sprintf(ehlo,"EHLO %s\r\n",domain);
00097     #ifdef __DEBUG__
00098         DBG("SEND %s(%d)", ehlo,strlen(ehlo));
00099     #endif    
00100     smtp.send(ehlo, strlen(ehlo));
00101     if (receiveMessage(250)) goto exit;
00102 
00103     if ( auth == SMTP_AUTH_PLAIN ){
00104         if ( user && pwd ) {
00105             // SMTP auth PLAIN
00106             char tmp[80], buf[100];
00107             int len;
00108             snprintf(tmp, sizeof(tmp), "%s%c%s%c%s",user, 0, user, 0, pwd);
00109             len = strlen(user)*2 + strlen(pwd) + 2;
00110             base64enc(tmp, len, buf, sizeof(buf));
00111             sprintf(tmp1,"AUTH PLAIN %s\r\n",buf);
00112             smtp.send(tmp1, strlen(tmp1));
00113             #ifdef __DEBUG__
00114               DBG("base64[%s]\r\n", buf);
00115             #endif            
00116             if (receiveMessage(235)){
00117                 smtp.send("QUIT\r\n", 6);
00118                 smtp.close();
00119             }
00120         }
00121     }else if ( auth == SMTP_AUTH_LOGIN) {
00122         if ( user && pwd ) {
00123             // SMTP auth
00124             char tmp[80], buf[100];
00125             int len;
00126 
00127             snprintf(tmp, sizeof(tmp), "%s",user);
00128             len = strlen(user) ;
00129             base64enc(tmp, len, buf, sizeof(buf));
00130             sprintf(tmp1,"AUTH LOGIN %s\r\n",buf);
00131             smtp.send(tmp1, strlen(tmp1));
00132   
00133             snprintf(tmp, sizeof(tmp), "%s",pwd);
00134             len = strlen(pwd) ;
00135             base64enc(tmp, len, buf, sizeof(buf));
00136             smtp.send(buf, strlen(buf));
00137             smtp.send("\r\n", 2);
00138 
00139             #ifdef __DEBUG__
00140               DBG("base64[%s]\r\n", buf);
00141             #endif            
00142             if (receiveMessage(235)){
00143                 smtp.send("QUIT\r\n", 6);
00144                 smtp.close();
00145             }     
00146         }   
00147     }        
00148     
00149     #ifdef __DEBUG__
00150       DBG("FromAddress[%s]\r\n", getFromAddress());
00151     #endif
00152     sprintf(tmp1,"MAIL FROM:<%s>\r\n",getFromAddress());
00153     smtp.send(tmp1, strlen(tmp1));
00154     if (receiveMessage(250)) goto exit;
00155            
00156     char tmp[128],addr[128];
00157     int i = 0;
00158     strcpy(tmp,getToAddress());
00159     
00160     while( tmp[i] != '\0' ){
00161         int j = 0;
00162         while( tmp[i] != ',' ){
00163             addr[j] = tmp[i];
00164 
00165             if( tmp[i] == '\0' ) break;
00166             j++;
00167             i++;
00168         }
00169         addr[j]='\0';
00170         
00171         #ifdef __DEBUG__
00172           DBG("ToAddress[%s]\r\n", addr);
00173         #endif
00174         
00175         sprintf(tmp1,"RCPT TO:<%s>\r\n",addr);
00176         smtp.send(tmp1, strlen(tmp1));
00177         if (receiveMessage(250)) goto exit;
00178 
00179         if(tmp[i]==',') i++;
00180         
00181     }
00182     ret = makeHeader();
00183     if ( ret == -1 ) {
00184         printf("The headers are less than 256 characters.\r\n");
00185         goto exit ;
00186     }
00187  
00188     // mail Body
00189     smtp.send("DATA\r\n", 6);
00190     if (receiveMessage(354)) goto exit; 
00191     sprintf(tmp1,"%s %s \r\n.\r\n",getHeader(),getMessage());
00192     smtp.send(tmp1, strlen(tmp1));    
00193     if (receiveMessage(250)) goto exit;
00194     #ifdef __DEBUG__
00195         DBG("Header %s\r\n", getHeader());
00196         DBG("Message %s\r\n", getMessage());
00197     #endif
00198 
00199     smtp.send("QUIT\r\n", 6);
00200     if (receiveMessage(221)) goto exit;
00201 
00202     ret = 0;
00203  
00204 exit:
00205     smtp.close();
00206 
00207     return ret;
00208 }
00209 
00210 int SimpleSMTPClient::setMessage(char *sub,char *msg)
00211 {
00212     int n;
00213     n = strlen(sub);
00214     if( n >= 64 )
00215         return -1;
00216     n = strlen(msg);
00217     if( n >= 1244 )
00218         return -1;    
00219     strcpy(subject,sub);        
00220     strcpy(message,msg);
00221     return 0;
00222 }
00223 
00224 int SimpleSMTPClient::addMessage(char *buf)
00225 {
00226     int n;
00227     n = strlen(message);
00228     n = n+strlen(buf);
00229     if( n >= 1244 )
00230         return -1;           
00231     strcat(message,buf);
00232     return 0;
00233 }
00234 
00235 int SimpleSMTPClient::setFromAddress(char *fromaddr)
00236 {
00237     int n;
00238     n = strlen(fromaddr);
00239     if( n <= 0 )
00240         return -1;
00241     strcpy(from,fromaddr);
00242 
00243     return n;
00244 }
00245 char* SimpleSMTPClient::getFromAddress()
00246 {
00247     return from;
00248 }
00249 int SimpleSMTPClient::setToAddress(char *toaddr)
00250 {
00251     int n;
00252     n = strlen(toaddr);
00253     if( n <= 0 && 128 <= n)
00254         return -1;    
00255     strcpy(to,toaddr);
00256 
00257     return n;
00258 }
00259 char* SimpleSMTPClient::getToAddress()
00260 {
00261     return to;
00262 }
00263 
00264 char* SimpleSMTPClient::getSubject()
00265 {
00266     return subject;
00267 }
00268 
00269 char* SimpleSMTPClient::getHeader()
00270 {
00271     return header;
00272 }
00273 
00274 char* SimpleSMTPClient::getMessage()
00275 {
00276     return message;
00277 }
00278 
00279 int SimpleSMTPClient::makeHeader(void)
00280 {
00281     strcpy(header, "From: ");
00282     strcat(header, getFromAddress());
00283     strcat(header, "\r\n");
00284     strcat(header, "To: " );
00285     strcat(header, getToAddress());
00286     strcat(header,  "\r\n");
00287     strcat(header, "Subject: ");
00288     strcat(header, getSubject());
00289     strcat(header, "\r\n\r\n") ;
00290     
00291     if ( strlen(header) > 256 )
00292         return -1;
00293     return 0;
00294 }
00295 
00296 void SimpleSMTPClient::clearMessage(void)
00297 {
00298     memset(message, 0, sizeof(message)); 
00299 }
00300 
00301 int SimpleSMTPClient::msgLength(void)
00302 {
00303     return strlen(message);
00304 }