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

Committer:
sunifu
Date:
Tue Dec 01 13:45:11 2015 +0000
Revision:
8:311b1f7cebb7
Parent:
7:0847fa2294a0
Update

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sunifu 0:3ea21ce21fe1 1 /*
sunifu 0:3ea21ce21fe1 2 *
sunifu 0:3ea21ce21fe1 3 * mbed Simple SMTP Client
sunifu 0:3ea21ce21fe1 4 * Copyright (c) 2012 Tadao Iida
sunifu 0:3ea21ce21fe1 5 * Released under the MIT License: http://mbed.org/license/mit
sunifu 8:311b1f7cebb7 6 * 2015/12/1 Ver 1.5 Update
sunifu 0:3ea21ce21fe1 7 */
sunifu 0:3ea21ce21fe1 8
sunifu 0:3ea21ce21fe1 9 //Debug is disabled by default
sunifu 0:3ea21ce21fe1 10 #if 0
sunifu 0:3ea21ce21fe1 11 //Enable debug
sunifu 0:3ea21ce21fe1 12 #define __DEBUG__
sunifu 0:3ea21ce21fe1 13 #include <cstdio>
sunifu 2:27053679f44b 14 #define DBG(x, ...) std::printf("[DBG]"x"\r\n", ##__VA_ARGS__);
sunifu 0:3ea21ce21fe1 15
sunifu 0:3ea21ce21fe1 16 #else
sunifu 0:3ea21ce21fe1 17 //Disable debug
sunifu 0:3ea21ce21fe1 18 #define DBG(x, ...)
sunifu 0:3ea21ce21fe1 19
sunifu 0:3ea21ce21fe1 20 #endif
sunifu 0:3ea21ce21fe1 21
sunifu 0:3ea21ce21fe1 22 /** @file
sunifu 0:3ea21ce21fe1 23 * @brief Simple SMTP Client
sunifu 0:3ea21ce21fe1 24 */
sunifu 0:3ea21ce21fe1 25
sunifu 0:3ea21ce21fe1 26 #include "mbed.h"
sunifu 0:3ea21ce21fe1 27 #include "EthernetInterface.h"
sunifu 0:3ea21ce21fe1 28 #include "SimpleSMTPClient.h"
sunifu 0:3ea21ce21fe1 29
sunifu 0:3ea21ce21fe1 30 SimpleSMTPClient::SimpleSMTPClient() : smtp()
sunifu 0:3ea21ce21fe1 31 {
sunifu 0:3ea21ce21fe1 32
sunifu 0:3ea21ce21fe1 33
sunifu 0:3ea21ce21fe1 34 }
sunifu 0:3ea21ce21fe1 35
sunifu 0:3ea21ce21fe1 36
sunifu 0:3ea21ce21fe1 37 // Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
sunifu 0:3ea21ce21fe1 38 int SimpleSMTPClient::base64enc(const char *input, unsigned int length, char *output, int outputlen) {
sunifu 0:3ea21ce21fe1 39 static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
sunifu 0:3ea21ce21fe1 40 unsigned int c, c1, c2, c3;
sunifu 0:3ea21ce21fe1 41
sunifu 0:3ea21ce21fe1 42 if (outputlen < (((length-1)/3)+1)<<2) return -1;
sunifu 0:3ea21ce21fe1 43
sunifu 0:3ea21ce21fe1 44 for(unsigned int i = 0, j = 0; i<length; i+=3,j+=4) {
sunifu 0:3ea21ce21fe1 45 c1 = ((((unsigned char)*((unsigned char *)&input[i]))));
sunifu 0:3ea21ce21fe1 46 c2 = (length>i+1)?((((unsigned char)*((unsigned char *)&input[i+1])))):0;
sunifu 0:3ea21ce21fe1 47 c3 = (length>i+2)?((((unsigned char)*((unsigned char *)&input[i+2])))):0;
sunifu 0:3ea21ce21fe1 48
sunifu 0:3ea21ce21fe1 49 c = ((c1 & 0xFC) >> 2);
sunifu 0:3ea21ce21fe1 50 output[j+0] = base64[c];
sunifu 0:3ea21ce21fe1 51 c = ((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4);
sunifu 0:3ea21ce21fe1 52 output[j+1] = base64[c];
sunifu 0:3ea21ce21fe1 53 c = ((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6);
sunifu 0:3ea21ce21fe1 54 output[j+2] = (length>i+1)?base64[c]:'=';
sunifu 0:3ea21ce21fe1 55 c = (c3 & 0x3F);
sunifu 0:3ea21ce21fe1 56 output[j+3] = (length>i+2)?base64[c]:'=';
sunifu 0:3ea21ce21fe1 57 }
sunifu 0:3ea21ce21fe1 58 output[(((length-1)/3)+1)<<2] = '\0';
sunifu 0:3ea21ce21fe1 59 return 0;
sunifu 0:3ea21ce21fe1 60 }
sunifu 0:3ea21ce21fe1 61
sunifu 0:3ea21ce21fe1 62 // SMTP ReceiveMessage
sunifu 0:3ea21ce21fe1 63 int SimpleSMTPClient::receiveMessage(int code) {
sunifu 0:3ea21ce21fe1 64 int i;
sunifu 0:3ea21ce21fe1 65 char buf[1500];
sunifu 0:3ea21ce21fe1 66
sunifu 0:3ea21ce21fe1 67 do{
sunifu 0:3ea21ce21fe1 68 i = smtp.receive(buf, sizeof(buf));
sunifu 0:3ea21ce21fe1 69 buf[i]='\0';
sunifu 0:3ea21ce21fe1 70 printf("Recv>>%s[%d] \r\n",buf,i);
sunifu 0:3ea21ce21fe1 71 }while(atoi(buf) != code && i > 0 );
sunifu 0:3ea21ce21fe1 72
sunifu 0:3ea21ce21fe1 73 // Check return code
sunifu 0:3ea21ce21fe1 74 if (i < 0 )
sunifu 0:3ea21ce21fe1 75 return -1;
sunifu 0:3ea21ce21fe1 76
sunifu 0:3ea21ce21fe1 77 return 0;
sunifu 0:3ea21ce21fe1 78 }
sunifu 0:3ea21ce21fe1 79
sunifu 2:27053679f44b 80 int SimpleSMTPClient::sendmail (char *host, char *user, char *pwd, char *domain,char *port,SMTPAuth auth) {
sunifu 0:3ea21ce21fe1 81
sunifu 0:3ea21ce21fe1 82 int ret = -1;
sunifu 2:27053679f44b 83 char ehlo[128];
sunifu 8:311b1f7cebb7 84 char tmp1[256];
sunifu 0:3ea21ce21fe1 85
sunifu 0:3ea21ce21fe1 86 smtp.set_blocking(false, 1500);
sunifu 0:3ea21ce21fe1 87 smtp.connect(host, atoi(port)) ;
sunifu 0:3ea21ce21fe1 88 if ( !smtp.is_connected() ){
sunifu 0:3ea21ce21fe1 89 printf("Connection Error!\r\n");
sunifu 0:3ea21ce21fe1 90 smtp.close();
sunifu 0:3ea21ce21fe1 91 return -1;
sunifu 0:3ea21ce21fe1 92 }
sunifu 0:3ea21ce21fe1 93
sunifu 0:3ea21ce21fe1 94 // send request
sunifu 0:3ea21ce21fe1 95 wait_ms(100);
sunifu 2:27053679f44b 96 sprintf(ehlo,"EHLO %s\r\n",domain);
sunifu 2:27053679f44b 97 #ifdef __DEBUG__
sunifu 2:27053679f44b 98 DBG("SEND %s(%d)", ehlo,strlen(ehlo));
sunifu 2:27053679f44b 99 #endif
sunifu 2:27053679f44b 100 smtp.send(ehlo, strlen(ehlo));
sunifu 8:311b1f7cebb7 101 if (receiveMessage(250)) goto exit;
sunifu 0:3ea21ce21fe1 102
sunifu 0:3ea21ce21fe1 103 if ( auth == SMTP_AUTH_PLAIN ){
sunifu 0:3ea21ce21fe1 104 if ( user && pwd ) {
sunifu 7:0847fa2294a0 105 // SMTP auth PLAIN
sunifu 0:3ea21ce21fe1 106 char tmp[80], buf[100];
sunifu 0:3ea21ce21fe1 107 int len;
sunifu 0:3ea21ce21fe1 108 snprintf(tmp, sizeof(tmp), "%s%c%s%c%s",user, 0, user, 0, pwd);
sunifu 0:3ea21ce21fe1 109 len = strlen(user)*2 + strlen(pwd) + 2;
sunifu 0:3ea21ce21fe1 110 base64enc(tmp, len, buf, sizeof(buf));
sunifu 8:311b1f7cebb7 111 sprintf(tmp1,"AUTH PLAIN %s\r\n",buf);
sunifu 8:311b1f7cebb7 112 smtp.send(tmp1, strlen(tmp1));
sunifu 0:3ea21ce21fe1 113 #ifdef __DEBUG__
sunifu 0:3ea21ce21fe1 114 DBG("base64[%s]\r\n", buf);
sunifu 0:3ea21ce21fe1 115 #endif
sunifu 0:3ea21ce21fe1 116 if (receiveMessage(235)){
sunifu 0:3ea21ce21fe1 117 smtp.send("QUIT\r\n", 6);
sunifu 0:3ea21ce21fe1 118 smtp.close();
sunifu 0:3ea21ce21fe1 119 }
sunifu 0:3ea21ce21fe1 120 }
sunifu 7:0847fa2294a0 121 }else if ( auth == SMTP_AUTH_LOGIN) {
sunifu 7:0847fa2294a0 122 if ( user && pwd ) {
sunifu 7:0847fa2294a0 123 // SMTP auth
sunifu 7:0847fa2294a0 124 char tmp[80], buf[100];
sunifu 7:0847fa2294a0 125 int len;
sunifu 7:0847fa2294a0 126
sunifu 7:0847fa2294a0 127 snprintf(tmp, sizeof(tmp), "%s",user);
sunifu 7:0847fa2294a0 128 len = strlen(user) ;
sunifu 7:0847fa2294a0 129 base64enc(tmp, len, buf, sizeof(buf));
sunifu 8:311b1f7cebb7 130 sprintf(tmp1,"AUTH LOGIN %s\r\n",buf);
sunifu 8:311b1f7cebb7 131 smtp.send(tmp1, strlen(tmp1));
sunifu 7:0847fa2294a0 132
sunifu 7:0847fa2294a0 133 snprintf(tmp, sizeof(tmp), "%s",pwd);
sunifu 7:0847fa2294a0 134 len = strlen(pwd) ;
sunifu 7:0847fa2294a0 135 base64enc(tmp, len, buf, sizeof(buf));
sunifu 7:0847fa2294a0 136 smtp.send(buf, strlen(buf));
sunifu 7:0847fa2294a0 137 smtp.send("\r\n", 2);
sunifu 7:0847fa2294a0 138
sunifu 7:0847fa2294a0 139 #ifdef __DEBUG__
sunifu 7:0847fa2294a0 140 DBG("base64[%s]\r\n", buf);
sunifu 7:0847fa2294a0 141 #endif
sunifu 7:0847fa2294a0 142 if (receiveMessage(235)){
sunifu 7:0847fa2294a0 143 smtp.send("QUIT\r\n", 6);
sunifu 7:0847fa2294a0 144 smtp.close();
sunifu 7:0847fa2294a0 145 }
sunifu 7:0847fa2294a0 146 }
sunifu 0:3ea21ce21fe1 147 }
sunifu 8:311b1f7cebb7 148
sunifu 8:311b1f7cebb7 149 #ifdef __DEBUG__
sunifu 8:311b1f7cebb7 150 DBG("FromAddress[%s]\r\n", getFromAddress());
sunifu 8:311b1f7cebb7 151 #endif
sunifu 8:311b1f7cebb7 152 sprintf(tmp1,"MAIL FROM:<%s>\r\n",getFromAddress());
sunifu 8:311b1f7cebb7 153 smtp.send(tmp1, strlen(tmp1));
sunifu 8:311b1f7cebb7 154 if (receiveMessage(250)) goto exit;
sunifu 7:0847fa2294a0 155
sunifu 0:3ea21ce21fe1 156 char tmp[128],addr[128];
sunifu 0:3ea21ce21fe1 157 int i = 0;
sunifu 0:3ea21ce21fe1 158 strcpy(tmp,getToAddress());
sunifu 0:3ea21ce21fe1 159
sunifu 0:3ea21ce21fe1 160 while( tmp[i] != '\0' ){
sunifu 0:3ea21ce21fe1 161 int j = 0;
sunifu 0:3ea21ce21fe1 162 while( tmp[i] != ',' ){
sunifu 0:3ea21ce21fe1 163 addr[j] = tmp[i];
sunifu 0:3ea21ce21fe1 164
sunifu 0:3ea21ce21fe1 165 if( tmp[i] == '\0' ) break;
sunifu 0:3ea21ce21fe1 166 j++;
sunifu 0:3ea21ce21fe1 167 i++;
sunifu 0:3ea21ce21fe1 168 }
sunifu 0:3ea21ce21fe1 169 addr[j]='\0';
sunifu 0:3ea21ce21fe1 170
sunifu 0:3ea21ce21fe1 171 #ifdef __DEBUG__
sunifu 0:3ea21ce21fe1 172 DBG("ToAddress[%s]\r\n", addr);
sunifu 0:3ea21ce21fe1 173 #endif
sunifu 0:3ea21ce21fe1 174
sunifu 8:311b1f7cebb7 175 sprintf(tmp1,"RCPT TO:<%s>\r\n",addr);
sunifu 8:311b1f7cebb7 176 smtp.send(tmp1, strlen(tmp1));
sunifu 8:311b1f7cebb7 177 if (receiveMessage(250)) goto exit;
sunifu 8:311b1f7cebb7 178
sunifu 0:3ea21ce21fe1 179 if(tmp[i]==',') i++;
sunifu 0:3ea21ce21fe1 180
sunifu 0:3ea21ce21fe1 181 }
sunifu 0:3ea21ce21fe1 182 ret = makeHeader();
sunifu 0:3ea21ce21fe1 183 if ( ret == -1 ) {
sunifu 0:3ea21ce21fe1 184 printf("The headers are less than 256 characters.\r\n");
sunifu 0:3ea21ce21fe1 185 goto exit ;
sunifu 0:3ea21ce21fe1 186 }
sunifu 0:3ea21ce21fe1 187
sunifu 0:3ea21ce21fe1 188 // mail Body
sunifu 0:3ea21ce21fe1 189 smtp.send("DATA\r\n", 6);
sunifu 6:f6efc3cc8d13 190 if (receiveMessage(354)) goto exit;
sunifu 8:311b1f7cebb7 191 sprintf(tmp1,"%s %s \r\n.\r\n",getHeader(),getMessage());
sunifu 8:311b1f7cebb7 192 smtp.send(tmp1, strlen(tmp1));
sunifu 0:3ea21ce21fe1 193 if (receiveMessage(250)) goto exit;
sunifu 0:3ea21ce21fe1 194 #ifdef __DEBUG__
sunifu 0:3ea21ce21fe1 195 DBG("Header %s\r\n", getHeader());
sunifu 0:3ea21ce21fe1 196 DBG("Message %s\r\n", getMessage());
sunifu 0:3ea21ce21fe1 197 #endif
sunifu 0:3ea21ce21fe1 198
sunifu 0:3ea21ce21fe1 199 smtp.send("QUIT\r\n", 6);
sunifu 0:3ea21ce21fe1 200 if (receiveMessage(221)) goto exit;
sunifu 8:311b1f7cebb7 201
sunifu 8:311b1f7cebb7 202 ret = 0;
sunifu 0:3ea21ce21fe1 203
sunifu 0:3ea21ce21fe1 204 exit:
sunifu 0:3ea21ce21fe1 205 smtp.close();
sunifu 0:3ea21ce21fe1 206
sunifu 0:3ea21ce21fe1 207 return ret;
sunifu 0:3ea21ce21fe1 208 }
sunifu 0:3ea21ce21fe1 209
sunifu 0:3ea21ce21fe1 210 int SimpleSMTPClient::setMessage(char *sub,char *msg)
sunifu 0:3ea21ce21fe1 211 {
sunifu 0:3ea21ce21fe1 212 int n;
sunifu 0:3ea21ce21fe1 213 n = strlen(sub);
sunifu 0:3ea21ce21fe1 214 if( n >= 64 )
sunifu 0:3ea21ce21fe1 215 return -1;
sunifu 0:3ea21ce21fe1 216 n = strlen(msg);
sunifu 0:3ea21ce21fe1 217 if( n >= 1244 )
sunifu 0:3ea21ce21fe1 218 return -1;
sunifu 0:3ea21ce21fe1 219 strcpy(subject,sub);
sunifu 0:3ea21ce21fe1 220 strcpy(message,msg);
sunifu 0:3ea21ce21fe1 221 return 0;
sunifu 0:3ea21ce21fe1 222 }
sunifu 0:3ea21ce21fe1 223
sunifu 0:3ea21ce21fe1 224 int SimpleSMTPClient::addMessage(char *buf)
sunifu 0:3ea21ce21fe1 225 {
sunifu 0:3ea21ce21fe1 226 int n;
sunifu 0:3ea21ce21fe1 227 n = strlen(message);
sunifu 0:3ea21ce21fe1 228 n = n+strlen(buf);
sunifu 0:3ea21ce21fe1 229 if( n >= 1244 )
sunifu 0:3ea21ce21fe1 230 return -1;
sunifu 0:3ea21ce21fe1 231 strcat(message,buf);
sunifu 0:3ea21ce21fe1 232 return 0;
sunifu 0:3ea21ce21fe1 233 }
sunifu 0:3ea21ce21fe1 234
sunifu 0:3ea21ce21fe1 235 int SimpleSMTPClient::setFromAddress(char *fromaddr)
sunifu 0:3ea21ce21fe1 236 {
sunifu 0:3ea21ce21fe1 237 int n;
sunifu 0:3ea21ce21fe1 238 n = strlen(fromaddr);
sunifu 0:3ea21ce21fe1 239 if( n <= 0 )
sunifu 0:3ea21ce21fe1 240 return -1;
sunifu 0:3ea21ce21fe1 241 strcpy(from,fromaddr);
sunifu 0:3ea21ce21fe1 242
sunifu 0:3ea21ce21fe1 243 return n;
sunifu 0:3ea21ce21fe1 244 }
sunifu 0:3ea21ce21fe1 245 char* SimpleSMTPClient::getFromAddress()
sunifu 0:3ea21ce21fe1 246 {
sunifu 0:3ea21ce21fe1 247 return from;
sunifu 0:3ea21ce21fe1 248 }
sunifu 0:3ea21ce21fe1 249 int SimpleSMTPClient::setToAddress(char *toaddr)
sunifu 0:3ea21ce21fe1 250 {
sunifu 0:3ea21ce21fe1 251 int n;
sunifu 0:3ea21ce21fe1 252 n = strlen(toaddr);
sunifu 0:3ea21ce21fe1 253 if( n <= 0 && 128 <= n)
sunifu 0:3ea21ce21fe1 254 return -1;
sunifu 0:3ea21ce21fe1 255 strcpy(to,toaddr);
sunifu 0:3ea21ce21fe1 256
sunifu 0:3ea21ce21fe1 257 return n;
sunifu 0:3ea21ce21fe1 258 }
sunifu 0:3ea21ce21fe1 259 char* SimpleSMTPClient::getToAddress()
sunifu 0:3ea21ce21fe1 260 {
sunifu 0:3ea21ce21fe1 261 return to;
sunifu 0:3ea21ce21fe1 262 }
sunifu 0:3ea21ce21fe1 263
sunifu 0:3ea21ce21fe1 264 char* SimpleSMTPClient::getSubject()
sunifu 0:3ea21ce21fe1 265 {
sunifu 0:3ea21ce21fe1 266 return subject;
sunifu 0:3ea21ce21fe1 267 }
sunifu 0:3ea21ce21fe1 268
sunifu 0:3ea21ce21fe1 269 char* SimpleSMTPClient::getHeader()
sunifu 0:3ea21ce21fe1 270 {
sunifu 0:3ea21ce21fe1 271 return header;
sunifu 0:3ea21ce21fe1 272 }
sunifu 0:3ea21ce21fe1 273
sunifu 0:3ea21ce21fe1 274 char* SimpleSMTPClient::getMessage()
sunifu 0:3ea21ce21fe1 275 {
sunifu 0:3ea21ce21fe1 276 return message;
sunifu 0:3ea21ce21fe1 277 }
sunifu 0:3ea21ce21fe1 278
sunifu 0:3ea21ce21fe1 279 int SimpleSMTPClient::makeHeader(void)
sunifu 0:3ea21ce21fe1 280 {
sunifu 0:3ea21ce21fe1 281 strcpy(header, "From: ");
sunifu 0:3ea21ce21fe1 282 strcat(header, getFromAddress());
sunifu 0:3ea21ce21fe1 283 strcat(header, "\r\n");
sunifu 0:3ea21ce21fe1 284 strcat(header, "To: " );
sunifu 0:3ea21ce21fe1 285 strcat(header, getToAddress());
sunifu 0:3ea21ce21fe1 286 strcat(header, "\r\n");
sunifu 0:3ea21ce21fe1 287 strcat(header, "Subject: ");
sunifu 0:3ea21ce21fe1 288 strcat(header, getSubject());
sunifu 0:3ea21ce21fe1 289 strcat(header, "\r\n\r\n") ;
sunifu 0:3ea21ce21fe1 290
sunifu 0:3ea21ce21fe1 291 if ( strlen(header) > 256 )
sunifu 0:3ea21ce21fe1 292 return -1;
sunifu 0:3ea21ce21fe1 293 return 0;
sunifu 4:7d16b08a1291 294 }
sunifu 4:7d16b08a1291 295
sunifu 4:7d16b08a1291 296 void SimpleSMTPClient::clearMessage(void)
sunifu 4:7d16b08a1291 297 {
sunifu 4:7d16b08a1291 298 memset(message, 0, sizeof(message));
sunifu 4:7d16b08a1291 299 }
sunifu 5:846af4db63c5 300
sunifu 5:846af4db63c5 301 int SimpleSMTPClient::msgLength(void)
sunifu 5:846af4db63c5 302 {
sunifu 5:846af4db63c5 303 return strlen(message);
sunifu 5:846af4db63c5 304 }