.from: http://mbed.org/users/okini3939/programs/TinySMTP/lv1bdk
XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx TinySMTP.cpp XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx
/*
* mbed Tiny SMTP Client
* Copyright (c) 2011 Hiroshi Suga
* Released under the MIT License: http://mbed.org/license/mit
*/
/** @file
* @brief Tiny SMTP Client
*/
#include "mbed.h"
#include "EthernetNetIf.h"
#include "TCPSocket.h"
#include "DNSRequest.h"
#include "TinySMTP.h"
#define STATUS_NONE 0
#define STATUS_READABLE 1
#define STATUS_CONNECTED 2
#define STATUS_ERROR 3
#define STATUS_DISCONNECTED 4
static TCPSocket *smtp;
static volatile int tcp_ready, tcp_readable, tcp_writable;
static volatile int dns_status;
// Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
int base64enc(const char *input, unsigned int length, char *output, int outputlen) {
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned int c, c1, c2, c3;
if (outputlen < (((length-1)/3)+1)<<2) return -1;
for(unsigned int i = 0, j = 0; i<length; i+=3,j+=4) {
c1 = ((((unsigned char)*((unsigned char *)&input[i]))));
c2 = (length>i+1)?((((unsigned char)*((unsigned char *)&input[i+1])))):0;
c3 = (length>i+2)?((((unsigned char)*((unsigned char *)&input[i+2])))):0;
c = ((c1 & 0xFC) >> 2);
output[j+0] = base64[c];
c = ((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4);
output[j+1] = base64[c];
c = ((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6);
output[j+2] = (length>i+1)?base64[c]:'=';
c = (c3 & 0x3F);
output[j+3] = (length>i+2)?base64[c]:'=';
}
output[(((length-1)/3)+1)<<2] = '\0';
return 0;
}
void isr_smtp (TCPSocketEvent e) {
#ifdef DEBUG
printf("tcp(%d)\r\n", e);
#endif
switch(e) {
case TCPSOCKET_CONNECTED:
tcp_ready = 1;
break;
case TCPSOCKET_READABLE: //Incoming data
tcp_readable = 1;
break;
case TCPSOCKET_WRITEABLE: //We can send data
tcp_writable = 1;
break;
case TCPSOCKET_CONTIMEOUT:
case TCPSOCKET_CONRST:
case TCPSOCKET_CONABRT:
case TCPSOCKET_ERROR:
case TCPSOCKET_DISCONNECTED:
tcp_ready = 0;
break;
}
}
int wait_smtp (int code) {
Timer timeout;
int i;
char buf[1500];
// wait responce
timeout.reset();
timeout.start();
while (timeout.read_ms() < SMTP_TIMEOUT) {
if (tcp_readable) break;
Net::poll();
}
timeout.stop();
if (! tcp_readable) return -1;
// recv
i = smtp->recv(buf, sizeof(buf));
if (i < sizeof(buf) - 1) tcp_readable = 0;
buf[i] = 0;
#ifdef DEBUG
printf(buf);
#endif
// check return code
if (atoi(buf) == code) return 0;
return -1;
}
void isr_dns (DNSReply r) {
#ifdef DEBUG
printf("dns(%d)\r\n", r);
#endif
if (DNS_FOUND) {
dns_status = 1;
} else {
dns_status = -1;
}
}
int sendmail (char *to, char *from, char *data, Host *host, char *user, char *pwd) {
TCPSocketErr err;
Timer timeout;
int ret = -1;
smtp = new TCPSocket;
tcp_ready = 0;
tcp_readable = 0;
tcp_writable = 0;
smtp->setOnEvent(isr_smtp);
// connect
if (host->getIp().isNull()) {
DNSRequest dns;
dns_status = 0;
dns.setOnReply(isr_dns);
if (dns.resolve(host) != DNS_OK) goto exit;
timeout.reset();
timeout.start();
while (timeout.read_ms() < SMTP_TIMEOUT) {
if (dns_status) break;
Net::poll();
}
timeout.stop();
if (dns_status <= 0) goto exit;
#ifdef DEBUG
printf("%s [%d.%d.%d.%d]\r\n", host->getName(), (unsigned char)host->getIp()[0], (unsigned char)host->getIp()[1], (unsigned char)host->getIp()[2], (unsigned char)host->getIp()[3]);
#endif
}
if (! host->getPort()) {
host->setPort(SMTP_PORT);
}
err = smtp->connect(*host);
if (err != TCPSOCKET_OK) goto exit;
// wait connect
timeout.reset();
timeout.start();
while (timeout.read_ms() < SMTP_TIMEOUT) {
if (tcp_ready) break;
Net::poll();
}
timeout.stop();
if (! tcp_ready) goto exit;
if (wait_smtp(220)) goto exit;
// send request
wait_ms(100);
smtp->send("EHLO mbed\r\n", 11);
if (wait_smtp(250)) goto exit;
if (user && pwd) {
// smtp auth
char tmp[80], buf[100];
int len;
snprintf(tmp, sizeof(tmp), "%s%c%s%c%s", user, 0, user, 0, pwd);
len = strlen(user) * 2 + strlen(pwd) + 2;
base64enc(tmp, len, buf, sizeof(buf));
smtp->send("AUTH PLAIN ", 11);
smtp->send(buf, strlen(buf));
smtp->send("\r\n", 2);
if (wait_smtp(235)) goto quit;
}
smtp->send("MAIL FROM: ", 11);
smtp->send(from, strlen(from));
smtp->send("\r\n", 2);
if (wait_smtp(250)) goto quit;
smtp->send("RCPT TO: ", 9);
smtp->send(to, strlen(to));
smtp->send("\r\n", 2);
if (wait_smtp(250)) goto quit;
smtp->send("DATA\r\n", 6);
if (wait_smtp(354)) goto quit;
// mail data
smtp->send(data, strlen(data));
smtp->send("\r\n.\r\n", 5);
if (wait_smtp(250)) goto quit;
ret = 0;
quit:
smtp->send("QUIT\r\n", 6);
if (wait_smtp(221)) goto exit;
exit:
smtp->resetOnEvent();
smtp->close();
delete smtp;
return ret;
}
* mbed Tiny SMTP Client
* Copyright (c) 2011 Hiroshi Suga
* Released under the MIT License: http://mbed.org/license/mit
*/
/** @file
* @brief Tiny SMTP Client
*/
#include "mbed.h"
#include "EthernetNetIf.h"
#include "TCPSocket.h"
#include "DNSRequest.h"
#include "TinySMTP.h"
#define STATUS_NONE 0
#define STATUS_READABLE 1
#define STATUS_CONNECTED 2
#define STATUS_ERROR 3
#define STATUS_DISCONNECTED 4
static TCPSocket *smtp;
static volatile int tcp_ready, tcp_readable, tcp_writable;
static volatile int dns_status;
// Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
int base64enc(const char *input, unsigned int length, char *output, int outputlen) {
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned int c, c1, c2, c3;
if (outputlen < (((length-1)/3)+1)<<2) return -1;
for(unsigned int i = 0, j = 0; i<length; i+=3,j+=4) {
c1 = ((((unsigned char)*((unsigned char *)&input[i]))));
c2 = (length>i+1)?((((unsigned char)*((unsigned char *)&input[i+1])))):0;
c3 = (length>i+2)?((((unsigned char)*((unsigned char *)&input[i+2])))):0;
c = ((c1 & 0xFC) >> 2);
output[j+0] = base64[c];
c = ((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4);
output[j+1] = base64[c];
c = ((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6);
output[j+2] = (length>i+1)?base64[c]:'=';
c = (c3 & 0x3F);
output[j+3] = (length>i+2)?base64[c]:'=';
}
output[(((length-1)/3)+1)<<2] = '\0';
return 0;
}
void isr_smtp (TCPSocketEvent e) {
#ifdef DEBUG
printf("tcp(%d)\r\n", e);
#endif
switch(e) {
case TCPSOCKET_CONNECTED:
tcp_ready = 1;
break;
case TCPSOCKET_READABLE: //Incoming data
tcp_readable = 1;
break;
case TCPSOCKET_WRITEABLE: //We can send data
tcp_writable = 1;
break;
case TCPSOCKET_CONTIMEOUT:
case TCPSOCKET_CONRST:
case TCPSOCKET_CONABRT:
case TCPSOCKET_ERROR:
case TCPSOCKET_DISCONNECTED:
tcp_ready = 0;
break;
}
}
int wait_smtp (int code) {
Timer timeout;
int i;
char buf[1500];
// wait responce
timeout.reset();
timeout.start();
while (timeout.read_ms() < SMTP_TIMEOUT) {
if (tcp_readable) break;
Net::poll();
}
timeout.stop();
if (! tcp_readable) return -1;
// recv
i = smtp->recv(buf, sizeof(buf));
if (i < sizeof(buf) - 1) tcp_readable = 0;
buf[i] = 0;
#ifdef DEBUG
printf(buf);
#endif
// check return code
if (atoi(buf) == code) return 0;
return -1;
}
void isr_dns (DNSReply r) {
#ifdef DEBUG
printf("dns(%d)\r\n", r);
#endif
if (DNS_FOUND) {
dns_status = 1;
} else {
dns_status = -1;
}
}
int sendmail (char *to, char *from, char *data, Host *host, char *user, char *pwd) {
TCPSocketErr err;
Timer timeout;
int ret = -1;
smtp = new TCPSocket;
tcp_ready = 0;
tcp_readable = 0;
tcp_writable = 0;
smtp->setOnEvent(isr_smtp);
// connect
if (host->getIp().isNull()) {
DNSRequest dns;
dns_status = 0;
dns.setOnReply(isr_dns);
if (dns.resolve(host) != DNS_OK) goto exit;
timeout.reset();
timeout.start();
while (timeout.read_ms() < SMTP_TIMEOUT) {
if (dns_status) break;
Net::poll();
}
timeout.stop();
if (dns_status <= 0) goto exit;
#ifdef DEBUG
printf("%s [%d.%d.%d.%d]\r\n", host->getName(), (unsigned char)host->getIp()[0], (unsigned char)host->getIp()[1], (unsigned char)host->getIp()[2], (unsigned char)host->getIp()[3]);
#endif
}
if (! host->getPort()) {
host->setPort(SMTP_PORT);
}
err = smtp->connect(*host);
if (err != TCPSOCKET_OK) goto exit;
// wait connect
timeout.reset();
timeout.start();
while (timeout.read_ms() < SMTP_TIMEOUT) {
if (tcp_ready) break;
Net::poll();
}
timeout.stop();
if (! tcp_ready) goto exit;
if (wait_smtp(220)) goto exit;
// send request
wait_ms(100);
smtp->send("EHLO mbed\r\n", 11);
if (wait_smtp(250)) goto exit;
if (user && pwd) {
// smtp auth
char tmp[80], buf[100];
int len;
snprintf(tmp, sizeof(tmp), "%s%c%s%c%s", user, 0, user, 0, pwd);
len = strlen(user) * 2 + strlen(pwd) + 2;
base64enc(tmp, len, buf, sizeof(buf));
smtp->send("AUTH PLAIN ", 11);
smtp->send(buf, strlen(buf));
smtp->send("\r\n", 2);
if (wait_smtp(235)) goto quit;
}
smtp->send("MAIL FROM: ", 11);
smtp->send(from, strlen(from));
smtp->send("\r\n", 2);
if (wait_smtp(250)) goto quit;
smtp->send("RCPT TO: ", 9);
smtp->send(to, strlen(to));
smtp->send("\r\n", 2);
if (wait_smtp(250)) goto quit;
smtp->send("DATA\r\n", 6);
if (wait_smtp(354)) goto quit;
// mail data
smtp->send(data, strlen(data));
smtp->send("\r\n.\r\n", 5);
if (wait_smtp(250)) goto quit;
ret = 0;
quit:
smtp->send("QUIT\r\n", 6);
if (wait_smtp(221)) goto exit;
exit:
smtp->resetOnEvent();
smtp->close();
delete smtp;
return ret;
}
XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx TinySMTP.h XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx
/*
* mbed Tiny SMTP Client
* Copyright (c) 2011 Hiroshi Suga
* Released under the MIT License: http://mbed.org/license/mit
*/
/** @file
* @brief Tiny SMTP Client
*/
#ifndef TinySMTP_h
#define TinySMTP_h
#define DEBUG
#define SMTP_PORT 25
#define SMTP_TIMEOUT 15000 // ms
/** send mail
* @param to mail address
* @param from mail address
* @param data mail body
* @param host mail server
* @param data mail body
* @param user auth username (or NULL)
* @param pwd auth password (or NULL)
* @return 0:success, -1:failue
*/
int sendmail (char *to, char *from, char *data, Host *host, char *user, char *pwd);
#endif
* mbed Tiny SMTP Client
* Copyright (c) 2011 Hiroshi Suga
* Released under the MIT License: http://mbed.org/license/mit
*/
/** @file
* @brief Tiny SMTP Client
*/
#ifndef TinySMTP_h
#define TinySMTP_h
#define DEBUG
#define SMTP_PORT 25
#define SMTP_TIMEOUT 15000 // ms
/** send mail
* @param to mail address
* @param from mail address
* @param data mail body
* @param host mail server
* @param data mail body
* @param user auth username (or NULL)
* @param pwd auth password (or NULL)
* @return 0:success, -1:failue
*/
int sendmail (char *to, char *from, char *data, Host *host, char *user, char *pwd);
#endif
XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx main.cpp XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx
#include "mbed.h"
#include "EthernetNetIf.h"
#include "TCPSocket.h"
#include "TinySMTP.h"
#define SMTP "mail.domain.name"
#define PORT 587 // or 25
#define FROM "from@domain.name"
#define TO "to@domain.name"
#define USER "authuser"
#define PWD "password"
#define SUBJECT "mail test"
#define BODY "TEST TEST"
DigitalOut myled(LED1);
Serial pc(USBTX, USBRX);
EthernetNetIf eth;
int main () {
EthernetErr ethErr;
Host host;
int r;
char data[500];
myled = 1;
strcpy(data, "From: " FROM "\r\nTo: " TO "\r\n");
strcat(data, "Subject: " SUBJECT "\r\n\r\n" BODY "\r\n");
ethErr = eth.setup();
if(ethErr) {
return -1;
}
host.setName(SMTP);
host.setPort(PORT);
r = sendmail(FROM, TO, data, &host, USER, PWD);
if (r) {
printf("error\r\n");
} else {
printf("sent\r\n");
}
myled = 0;
return 0;
}
#include "EthernetNetIf.h"
#include "TCPSocket.h"
#include "TinySMTP.h"
#define SMTP "mail.domain.name"
#define PORT 587 // or 25
#define FROM "from@domain.name"
#define TO "to@domain.name"
#define USER "authuser"
#define PWD "password"
#define SUBJECT "mail test"
#define BODY "TEST TEST"
DigitalOut myled(LED1);
Serial pc(USBTX, USBRX);
EthernetNetIf eth;
int main () {
EthernetErr ethErr;
Host host;
int r;
char data[500];
myled = 1;
strcpy(data, "From: " FROM "\r\nTo: " TO "\r\n");
strcat(data, "Subject: " SUBJECT "\r\n\r\n" BODY "\r\n");
ethErr = eth.setup();
if(ethErr) {
return -1;
}
host.setName(SMTP);
host.setPort(PORT);
r = sendmail(FROM, TO, data, &host, USER, PWD);
if (r) {
printf("error\r\n");
} else {
printf("sent\r\n");
}
myled = 0;
return 0;
}
XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx EOF XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx
No comments:
Post a Comment