mbed Weather Platform firmware http://mbed.org/users/okini3939/notebook/mbed-weather-platform-firmware/
Dependencies: ChaNFSSD EthernetNetIf I2CLEDDisp Agentbed ChaNFSUSB ILinterpreter mbed BMP085 WeatherMeters ConfigFile ChaNFS I2CLCD
Revision 3:058292da2cee, committed 2011-09-07
- Comitter:
- okini3939
- Date:
- Wed Sep 07 16:03:54 2011 +0000
- Parent:
- 2:a3e5edf84f74
- Child:
- 4:46ad190e6328
- Commit message:
Changed in this revision
--- a/HTTPClient.lib Wed Aug 24 13:22:32 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/mamezu/code/HTTPClient/#62fac7f06c8d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TinyNet/TinyHTTP.cpp Wed Sep 07 16:03:54 2011 +0000 @@ -0,0 +1,240 @@ +/* + * mbed Tiny HTTP Client + * Copyright (c) 2011 Hiroshi Suga + * Released under the MIT License: http://mbed.org/license/mit + */ + +/** @file + * @brief Tiny HTTP Client + */ + +#include "mbed.h" +#include "EthernetNetIf.h" +#include "TCPSocket.h" +#include "DNSRequest.h" +#include "TinyHTTP.h" +#include <ctype.h> + + +static TCPSocket *http; +static volatile int tcp_ready, tcp_readable, tcp_writable; +static volatile int dns_status; + +// Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) +static int base64enc(const char *input, unsigned int length, char *output, int len) { + static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + unsigned int c, c1, c2, c3; + + if (len < ((((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; +} + +// Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) +int urlencode(char *str, char *buf, int len) { + static const char to_hex[] = "0123456789ABCDEF"; +// char *pstr = str, *buf = (char*)malloc(strlen(str) * 3 + 1), *pbuf = buf; + char *pstr = str, *pbuf = buf; + + if (len < (strlen(str) * 3 + 1)) return -1; + while (*pstr) { + if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') { + *pbuf++ = *pstr; + } else if (*pstr == ' ') { + *pbuf++ = '+'; + } else { + *pbuf++ = '%'; + *pbuf++ = to_hex[(*pstr >> 4) & 0x0f]; + *pbuf++ = to_hex[*pstr & 0x0f]; + } + pstr++; + } + *pbuf = '\0'; + return 0; +} + + +void isr_http (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; + } +} + +void createauth (char *user, char *pwd, char *buf, int len) { + char tmp[80]; + + strncpy(buf, "Authorization: Basic ", len); + snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd); + base64enc(tmp, strlen(tmp), &buf[strlen(buf)], len - strlen(buf)); + strncat(buf, "\r\n", len - strlen(buf)); +} + +static 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 httpRequest (int method, Host *host, char *uri, char *head, char *body) { + TCPSocketErr err; + Timer timeout; + char buf[1500]; + int i, ret = -1; + + http = new TCPSocket; + tcp_ready = 0; + tcp_readable = 0; + tcp_writable = 0; + + http->setOnEvent(isr_http); + + // connect + if (host->getIp().isNull()) { + // resolv + 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() < HTTP_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(HTTP_PORT); + } + err = http->connect(*host); + if (err != TCPSOCKET_OK) goto exit; + + // wait connect + timeout.reset(); + timeout.start(); + while (timeout.read_ms() < HTTP_TIMEOUT) { + if (tcp_ready) break; + Net::poll(); + } + timeout.stop(); + if (! tcp_ready) goto exit; + + // send request + if (method == METHOD_POST) { + http->send("POST ", 5); + } else { + http->send("GET ", 4); + } + http->send(uri, strlen(uri)); + http->send(" HTTP/1.1\r\nHost: ", 17); + http->send(host->getName(), strlen(host->getName())); + http->send("\r\n", 2); + http->send("Connection: close\r\n", 19); + if (head) { + http->send(head, strlen(head)); + } + if (method == METHOD_POST) { + sprintf(buf, "Content-Length: %d\r\n", strlen(body)); + http->send(buf, strlen(buf)); + } + http->send("\r\n", 2); + + // post method + if (method == METHOD_POST && body) { + http->send(body, strlen(body)); + } + + // wait responce + timeout.reset(); + timeout.start(); + while (timeout.read_ms() < HTTP_TIMEOUT) { + if (tcp_readable) break; + Net::poll(); + } + timeout.stop(); + if (! tcp_readable) goto exit; + + // recv responce + i = http->recv(buf, sizeof(buf) - 1); + buf[i] = 0; + if (i < sizeof(buf) - 1) tcp_readable = 0; + if (strncmp(buf, "HTTP/", 5) == 0) { + ret = atoi(&buf[9]); + } +#ifdef DEBUG + printf(buf); +#endif + + // recv dummy + timeout.reset(); + timeout.start(); + while (timeout.read_ms() < HTTP_TIMEOUT) { + if (tcp_readable) { + i = http->recv(buf, sizeof(buf) - 1); + buf[i] = 0; + if (i < sizeof(buf) - 1) tcp_readable = 0; +#ifdef DEBUG + printf(buf); +#endif + timeout.reset(); + } else + if (! tcp_ready) { + break; + } + Net::poll(); + } + timeout.stop(); + +exit: + http->resetOnEvent(); + http->close(); + delete http; + + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TinyNet/TinyHTTP.h Wed Sep 07 16:03:54 2011 +0000 @@ -0,0 +1,38 @@ +/* + * mbed Tiny HTTP Client + * Copyright (c) 2011 Hiroshi Suga + * Released under the MIT License: http://mbed.org/license/mit + */ + +/** @file + * @brief Tiny HTTP Client + */ + +#ifndef TinyHTTP_h +#define TinyHTTP_h + +//#define DEBUG + +#define HTTP_PORT 80 +#define HTTP_TIMEOUT 15000 // ms + +#define METHOD_GET 0 +#define METHOD_POST 1 + +/** send http request + * @param method METHOD_GET or METHOD_POST + * @param host http server + * @param uri URI + * @param head http header (CR+LF) (or NULL) + * @param body POST body (or NULL) + * @return http code, -1:failue + */ +int httpRequest (int method, Host *host, char *uri, char *head, char *body); + +void createauth (char *user, char *pwd, char *buf, int len); + +int base64enc(const char *input, unsigned int length, char *output, int len); + +int urlencode(char *str, char *buf, int len); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TinyNet/TinySMTP.cpp Wed Sep 07 16:03:54 2011 +0000 @@ -0,0 +1,217 @@ +/* + * 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) +static 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; +} + +static 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; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TinyNet/TinySMTP.h Wed Sep 07 16:03:54 2011 +0000 @@ -0,0 +1,31 @@ +/* + * 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
--- a/TinyNet/TinySNTP.cpp Wed Aug 24 13:22:32 2011 +0000 +++ b/TinyNet/TinySNTP.cpp Wed Sep 07 16:03:54 2011 +0000 @@ -91,7 +91,7 @@ } int ntpdate (const char* name, uint32_t *tim) { - UDPSocketErr err; +// UDPSocketErr err; Host sntphost; char buf[100]; int i, len;
--- a/email/EmailMessage.cpp Wed Aug 24 13:22:32 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ - -/* -Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) y Segundo Equipo - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#include "EmailMessage.h" - -#include <stdio.h> -#include <stdarg.h> - -#define BUF_SIZE 512 - -EmailMessage::EmailMessage() : m_from(), m_lTo(), m_content() { -} - -EmailMessage::~EmailMessage() { -} - -void EmailMessage::setFrom(const char* from) { - m_from = from; -} - -void EmailMessage::addTo(const char* to) { - m_lTo.push_back(to); -} - -void EmailMessage::clearTo() { - m_lTo.clear(); -} - -int EmailMessage::printf(const char* format, ... ) { // Can be called multiple times to write the message - - char buf[BUF_SIZE] = {0}; - int len = 0; - - va_list argp; - - va_start(argp, format); - len += vsnprintf(buf, BUF_SIZE, format, argp); - va_end(argp); - - if (len > 0) - m_content.append(buf); - - return len; -} - -void EmailMessage::clearContent() { - m_content.clear(); -} \ No newline at end of file
--- a/email/EmailMessage.h Wed Aug 24 13:22:32 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ - -/* -Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) y Segundo Equipo - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -/** \file -Email message header file -*/ - -#ifndef EMAIL_MESSAGE_H -#define EMAIL_MESSAGE_H - -#include <vector> -using std::vector; - -#include <string> -using std::string; - -///A simple email message -/** -A class to hold the message addresses and content for sending (with SMTPClient). -*/ -class EmailMessage { -public: - ///Instantiates the email message - EmailMessage(); - - ///Destructor for the email message - ~EmailMessage(); - - ///Set FROM address - /** - @param from : email from address - */ - void setFrom(const char* from); - - ///Add TO address to list of recipient addresses - /** - @param host : SMTP server host - */ - void addTo(const char* to); - - ///Clear TO addresses - void clearTo(); - - ///Append text to content of message using printf - /** - @param format : printf format followed by ... variables - - Can be called multiple times to write the message - */ - int printf(const char* format, ... ); - - ///Clear content previously appended by printf - void clearContent(); - -private: - friend class SMTPClient; - string m_from; - vector<string> m_lTo; - string m_content; - -}; - -#endif \ No newline at end of file
--- a/email/smtp/SMTPClient.cpp Wed Aug 24 13:22:32 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,453 +0,0 @@ - -/* -Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) y Segundo Equipo - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ -#include "netservice.h" -#include "SMTPClient.h" -#include "base64.h" - -#undef __DEBUG -#include "dbg/dbg.h" - -#define CHUNK_SIZE 256 //512 -#define BUF_SIZE (CHUNK_SIZE + 1) - -#define SMTP_REQUEST_TIMEOUT 15000 -#define SMTP_PORT 25 - -SMTPClient::SMTPClient() : NetService(false) /*Not owned by the pool*/, - m_pCbItem(NULL), m_pCbMeth(NULL), m_pCb(NULL), - m_watchdog(), m_timeout(SMTP_REQUEST_TIMEOUT), m_pDnsReq(NULL), m_server(), - m_closed(true), m_state(SMTP_CLOSED), m_pMessage(NULL), - m_posInMsg(0), m_blockingResult(SMTP_PROCESSING), - m_username(""), m_password(""), m_auth(SMTP_AUTH_NONE), - m_heloDomain("localhost") { - DBG("New SMTPClient %p\n", this); -} - -SMTPClient::SMTPClient(const Host& host, const char* heloDomain, const char* user, const char* password, SMTPAuth auth) : NetService(false), - m_pCbItem(NULL), m_pCbMeth(NULL), m_pCb(NULL), - m_watchdog(), m_timeout(SMTP_REQUEST_TIMEOUT), m_pDnsReq(NULL), m_server(host), - m_closed(true), m_state(SMTP_CLOSED), m_pMessage(NULL), - m_posInMsg(0), m_blockingResult(SMTP_PROCESSING), - m_username(string(user)), m_password(string(password)), m_auth(auth), - m_heloDomain(heloDomain) { - DBG("New SMTPClient %p\n", this); -} - -SMTPClient::~SMTPClient() { - close(); -} - -void SMTPClient::setAuth(const char* user, const char* password) { // Plain authentication - m_username = string(user); - m_password = string(password); - m_auth = SMTP_AUTH_PLAIN; -} - -void SMTPClient::clearAuth() { // Clear authentication - m_username = ""; - m_password = ""; - m_auth = SMTP_AUTH_NONE; -} - -string SMTPClient::encodePlainAuth() { - string decStr = m_username; - decStr += '\0'; - decStr += m_username; - decStr += '\0'; - decStr += m_password; - - string auth = "AUTH PLAIN "; - return auth.append(Base64::encode(decStr)); -} - -void SMTPClient::setHeloDomain(const char* heloDomain) { - m_heloDomain = string(heloDomain); -} - -SMTPResult SMTPClient::send(EmailMessage* pMessage) { //Blocking - doSend(pMessage); - return blockingProcess(); -} - -SMTPResult SMTPClient::send(EmailMessage* pMessage, void (*pMethod)(SMTPResult)) { //Non blocking - setOnResult(pMethod); - doSend(pMessage); - return SMTP_PROCESSING; -} - -void SMTPClient::doSend(EmailMessage* pMessage) { - setup(pMessage); -} - -void SMTPClient::setOnResult( void (*pMethod)(SMTPResult) ) { - m_pCb = pMethod; - m_pCbItem = NULL; - m_pCbMeth = NULL; -} - -void SMTPClient::setTimeout(int ms) { - m_timeout = ms; -} - -void SMTPClient::poll() { //Called by NetServices - if ( (!m_closed) && (m_watchdog.read_ms() >= m_timeout) ) { - onTimeout(); - } -} - -void SMTPClient::resetTimeout() { - m_watchdog.reset(); - m_watchdog.start(); -} - -void SMTPClient::init() { //Create and setup socket if needed - close(); //Remove previous elements - if (!m_closed) //Already opened - return; - m_state = SMTP_HELLO; - m_pTCPSocket = new TCPSocket; - m_pTCPSocket->setOnEvent(this, &SMTPClient::onTCPSocketEvent); - m_closed = false; - m_posInMsg = 0; - m_posInCRLF = 2; - m_response = ""; -} - -void SMTPClient::close() { - if (m_closed) - return; - m_state = SMTP_CLOSED; - m_closed = true; //Prevent recursive calling or calling on an object being destructed by someone else - m_watchdog.stop(); //Stop timeout - m_watchdog.reset(); - m_pTCPSocket->resetOnEvent(); - m_pTCPSocket->close(); - delete m_pTCPSocket; - m_pTCPSocket = NULL; - if ( m_pDnsReq ) { - m_pDnsReq->close(); - delete m_pDnsReq; - m_pDnsReq = NULL; - } -} - -void SMTPClient::setServer(const Host& host) { //Setup request, make DNS Req if necessary - m_server = host; -} - -void SMTPClient::setup(EmailMessage* pMessage) { //Setup request, make DNS Req if necessary - - init(); //Initialize client in known state, create socket - m_pMessage = pMessage; - resetTimeout(); - - m_To = m_pMessage->m_lTo.begin(); // Point to first to recipient in TO list - - //If port set to zero then use default port - if (!m_server.getPort()) { - m_server.setPort(SMTP_PORT); - DBG("Using default port %d\n", SMTP_PORT); - } - - if (m_server.getIp().isNull()) { - //DNS query required - m_pDnsReq = new DNSRequest(); - DBG("DNSRequest %p\r\n", m_pDnsReq); - m_pDnsReq->setOnReply(this, &SMTPClient::onDNSReply); - m_pDnsReq->resolve(&m_server); - return; - } else - connect(); - -} - -void SMTPClient::connect() { //Start Connection - resetTimeout(); - DBG("Connecting...\n"); - m_pTCPSocket->connect(m_server); -} - -void SMTPClient::onTCPSocketEvent(TCPSocketEvent e) { - - DBG("Event %d in SMTPClient::onTCPSocketEvent()\n", e); - - if (m_closed) { - DBG("WARN: Discarded\n"); - return; - } - - switch (e) { - case TCPSOCKET_READABLE: - resetTimeout(); - process(false); - break; - case TCPSOCKET_WRITEABLE: - resetTimeout(); - process(true); - break; - case TCPSOCKET_CONTIMEOUT: - case TCPSOCKET_CONRST: - case TCPSOCKET_CONABRT: - case TCPSOCKET_ERROR: - DBG("Connection error in SMTP Client.\n"); - close(); - onResult(SMTP_DISC); - break; - case TCPSOCKET_DISCONNECTED: - if (m_state != SMTP_BYE) { - DBG("Connection error in SMTP Client.\n"); - close(); - onResult(SMTP_DISC); - } - break; - } -} - -void SMTPClient::onDNSReply(DNSReply r) { - if (m_closed) { - DBG("WARN: Discarded\n"); - return; - } - - if ( r != DNS_FOUND ) { - DBG("Could not resolve hostname.\n"); - close(); - onResult(SMTP_DNS); - return; - } - - DBG("DNS Resolved to %d.%d.%d.%d\n", m_server.getIp()[0], m_server.getIp()[1], m_server.getIp()[2], m_server.getIp()[3]); - //If no error, m_server has been updated by m_pDnsReq so we're set to go ! - m_pDnsReq->close(); - delete m_pDnsReq; - m_pDnsReq = NULL; - connect(); -} - -void SMTPClient::onResult(SMTPResult r) { //Called when exchange completed or on failure - if (m_pCbItem && m_pCbMeth) - (m_pCbItem->*m_pCbMeth)(r); - else if (m_pCb) - m_pCb(r); - m_blockingResult = r; //Blocking mode -} - -void SMTPClient::onTimeout() { //Connection has timed out - DBG("Timed out.\n"); - close(); - onResult(SMTP_TIMEOUT); -} - -SMTPResult SMTPClient::blockingProcess() { //Called in blocking mode, calls Net::poll() until return code is available - //Disable callbacks - m_pCb = NULL; - m_pCbItem = NULL; - m_pCbMeth = NULL; - m_blockingResult = SMTP_PROCESSING; - do { - Net::poll(); - } while (m_blockingResult == SMTP_PROCESSING); - Net::poll(); //Necessary for cleanup - return m_blockingResult; -} - -int SMTPClient::rc(char* buf) { //Parse return code - int rc; - int len = sscanf(buf, "%d %*[^\r\n]\r\n", &rc); - if (len != 1) - return -1; - return rc; -} - -bool SMTPClient::okPostAuthentication(int code) { - return (code == 250) || (code == 235); -} - -void SMTPClient::process(bool writeable) { //Main state-machine - - DBG("In state %d, writeable %d\n", m_state, writeable); - - // If writeable but nothing to write then return - if (writeable && (m_state != SMTP_BODYMORE)) - return; - - // If not writeable then read - char buf[BUF_SIZE] = {0}; - int responseCode = -1; - if (!writeable) { - bool firstBuf = true; - int read; - do { // read until nothing left but only process the response from first buffer - read = m_pTCPSocket->recv(buf, BUF_SIZE - 1); - if (firstBuf) { - m_response = string(buf); - responseCode = rc(buf); - firstBuf = false; - DBG("Response %d %d | %s", read, responseCode, buf); - } - } while (read > 0); - } - - switch (m_state) { - case SMTP_HELLO: - if ( responseCode != 220 ) { - close(); - onResult(SMTP_PRTCL); - return; - } - char* helloCommand; - if (m_auth == SMTP_AUTH_NONE) { - helloCommand = "HELO"; - m_state = SMTP_FROM; - } else { - helloCommand = "EHLO"; - m_state = SMTP_AUTH; - } - snprintf(buf, BUF_SIZE, "%s %s\r\n", helloCommand, m_heloDomain.c_str()); - break; - case SMTP_AUTH: - if ( responseCode != 250 ) { - close(); - onResult(SMTP_PRTCL); - return; - } - snprintf(buf, BUF_SIZE, "%s\r\n", encodePlainAuth().c_str()); - m_state = SMTP_FROM; - break; - case SMTP_FROM: - if (!okPostAuthentication(responseCode)) { - close(); - onResult(SMTP_PRTCL); - return; - } - snprintf(buf, BUF_SIZE, "MAIL FROM:<%s>\r\n", m_pMessage->m_from.c_str()); - m_state = SMTP_TO; - break; - case SMTP_TO: - if ( responseCode != 250 ) { - close(); - onResult(SMTP_PRTCL); - return; - } - snprintf(buf, BUF_SIZE, "RCPT TO:<%s>\r\n", (m_To++)->c_str()); - if (m_To == m_pMessage->m_lTo.end()) - m_state = SMTP_DATA; - break; - case SMTP_DATA: - if ( responseCode != 250 ) { - close(); - onResult(SMTP_PRTCL); - return; - } - snprintf(buf, BUF_SIZE, "DATA\r\n"); - m_state = SMTP_BODY; - break; - case SMTP_BODY: - if ( responseCode != 354 ) { - close(); - onResult(SMTP_PRTCL); - return; - } - m_state = SMTP_BODYMORE; - buf[0] = '\0'; // clear buffer before carrying on into next state - case SMTP_BODYMORE: - if (strlen(buf) > 0) { // sending interrupted by a server response - close(); - onResult(SMTP_PRTCL); - return; - } - - if ( m_posInMsg < m_pMessage->m_content.length() ) { // if still something to send - int sendLen = 0; - while (sendLen < BUF_SIZE - 1) { // - 1 to allow room for extra dot or CR or LF - char c = m_pMessage->m_content.at(m_posInMsg++); - switch (c) { // thanks ExtraDotOutputStream.java (with extra check for naked CR) - case '.': - if (m_posInCRLF == 2) // add extra dot - buf[sendLen++] = '.'; - m_posInCRLF = 0; - break; - case '\r': - if (m_posInCRLF == 1) // two CR in a row, so insert an LF first - buf[sendLen++] = '\n'; - m_posInCRLF = 1; - break; - case '\n': - if (m_posInCRLF != 1) // convert naked LF to CRLF - buf[sendLen++] = '\r'; - m_posInCRLF = 2; - break; - default: - if (m_posInCRLF == 1) { // convert naked CR to CRLF - buf[sendLen++] = '\n'; - m_posInCRLF = 2; - } else - m_posInCRLF = 0; // we're no longer at the start of a line - break; - } - buf[sendLen++] = c; - if ( m_posInMsg == m_pMessage->m_content.length() ) - break; - } - m_pTCPSocket->send( buf, sendLen ); - DBG("Sending %d bytes of processed message content\n", sendLen); - } else { - if (m_posInCRLF == 0) - snprintf(buf, BUF_SIZE, "\r\n.\r\n"); - else if (m_posInCRLF == 1) - snprintf(buf, BUF_SIZE, "\n.\r\n"); - else - snprintf(buf, BUF_SIZE, ".\r\n"); - m_state = SMTP_EOF; - } - break; - case SMTP_EOF: - if ( responseCode != 250 ) { - close(); - onResult(SMTP_PRTCL); - return; - } - snprintf(buf, BUF_SIZE, "QUIT\r\n"); - m_state = SMTP_BYE; - break; - case SMTP_BYE: - if ( responseCode != 221 ) { - close(); - onResult(SMTP_PRTCL); - return; - } - close(); - onResult(SMTP_OK); - return; - } - - if ( m_state != SMTP_BODYMORE ) { - DBG("Sending | %s", buf); - m_pTCPSocket->send( buf, strlen(buf) ); - } - -} - -string& SMTPClient::getLastResponse() { // Return last response set on result - return m_response; -} \ No newline at end of file
--- a/email/smtp/SMTPClient.h Wed Aug 24 13:22:32 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,245 +0,0 @@ - -/* -Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) y Segundo Equipo - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -/** \file -SMTP Client header file -*/ - -#ifndef SMTP_CLIENT_H -#define SMTP_CLIENT_H - -class EmailMessage; - -#include "net.h" -#include "TCPSocket.h" -#include "DNSRequest.h" -#include "EmailMessage.h" -#include "mbed.h" - -///SMTP client results -enum SMTPResult { - SMTP_OK, ///<Success - SMTP_PROCESSING, ///<Processing - SMTP_DNS, ///<Could not resolve name - SMTP_PRTCL, ///<Protocol error - SMTP_TIMEOUT, ///<Connection timeout - SMTP_DISC ///<Disconnected -}; - -///SMTP authentication -enum SMTPAuth { - SMTP_AUTH_NONE, ///<No authentication - SMTP_AUTH_PLAIN ///<AUTH PLAIN authentication -}; -#include "core/netservice.h" - -///A simple SMTP Client -/** -The SMTPClient is composed of: -- The actual client (SMTPClient) -- A class (EmailMessage) to hold the message addresses and content for sending -*/ -class SMTPClient : protected NetService { -public: - ///Instantiates the SMTP client - SMTPClient(); - - ///Destructor for the SMTP client - virtual ~SMTPClient(); - - ///Full constructor for the SMTP client - /** - @param host : SMTP server host - @param heloDomain : domain name of client - @param user : username - @param password : password - @param auth : authentication type - */ - SMTPClient(const Host& host, const char* heloDomain, const char* user, const char* password, SMTPAuth auth); - - ///Set server host - /** - @param host : SMTP server host - */ - void setServer(const Host& host); - - ///Provides a plain authentication feature (Base64 encoded username and password) - /** - @param user : username - @param password : password - */ - void setAuth(const char* user, const char* password); // Plain authentication - - ///Turns off authentication - void clearAuth(); // Clear authentication - - ///Set HELO domain (defaults to localhost if not set) - /** - @param heloDomain : domain name of client (strictly should be fully qualified domain name) - */ - void setHeloDomain(const char* heloDomain); - - //High Level setup functions - ///Sends the message (blocking) - /** - @param pMessage : pointer to a message - - Blocks until completion - */ - SMTPResult send(EmailMessage* pMessage); //Blocking - - ///Sends the message (non blocking) - /** - @param pMessage : pointer to a message - @param pMethod : callback function - - The function returns immediately and calls the callback on completion or error - */ - SMTPResult send(EmailMessage* pMessage, void (*pMethod)(SMTPResult)); //Non blocking - - ///Sends the message (non blocking) - /** - @param pMessage : pointer to a message - @param pItem : instance of class on which to execute the callback method - @param pMethod : callback method - - The function returns immediately and calls the callback on completion or error - */ - template<class T> - SMTPResult send(EmailMessage* pMessage, T* pItem, void (T::*pMethod)(SMTPResult)) { //Non blocking - setOnResult(pItem, pMethod); - doSend(pMessage); - return SMTP_PROCESSING; - } - - ///Sends the message (non blocking) - /** - @param pMessage : pointer to a message - - The function returns immediately and calls the previously set callback on completion or error - */ - void doSend(EmailMessage* pMessage); - - ///Setup the result callback - /** - @param pMethod : callback function - */ - void setOnResult( void (*pMethod)(SMTPResult) ); - - ///Setup the result callback - /** - @param pItem : instance of class on which to execute the callback method - @param pMethod : callback method - */ - class CDummy; - template<class T> - void setOnResult( T* pItem, void (T::*pMethod)(SMTPResult) ) { - m_pCb = NULL; - m_pCbItem = (CDummy*) pItem; - m_pCbMeth = (void (CDummy::*)(SMTPResult)) pMethod; - } - - ///Setup timeout - /** - @param ms : time of connection inactivity in ms after which the request should timeout - */ - void setTimeout(int ms); - - ///Gets the last response from the server - string& getLastResponse(); - - virtual void poll(); //Called by NetServices - -protected: - int rc(char* buf); //Return code - void process(bool writeable); //Main state-machine - - void resetTimeout(); - - void init(); - void close(); - - void setup(EmailMessage* pMessage); //Setup request, make DNS Req if necessary - void connect(); //Start Connection - - int tryRead(); //Read data and try to feed output - void readData(); //Data has been read - void writeData(); //Data has been written & buf is free - - void onTCPSocketEvent(TCPSocketEvent e); - void onDNSReply(DNSReply r); - void onResult(SMTPResult r); //Called when exchange completed or on failure - void onTimeout(); //Connection has timed out - - string encodePlainAuth(); // Encode plain authentication (username and password in based 64) - bool okPostAuthentication(int code); // True if server response is ok following authentication - -private: - SMTPResult blockingProcess(); //Called in blocking mode, calls Net::poll() until return code is available - - CDummy* m_pCbItem; - void (CDummy::*m_pCbMeth)(SMTPResult); - void (*m_pCb)(SMTPResult); - - TCPSocket* m_pTCPSocket; - - Timer m_watchdog; - int m_timeout; - - DNSRequest* m_pDnsReq; - Host m_server; - - bool m_closed; - - enum SMTPStep { - SMTP_HELLO, - SMTP_AUTH, - SMTP_FROM, - SMTP_TO, - SMTP_DATA, - SMTP_BODY, - SMTP_BODYMORE, - SMTP_EOF, - SMTP_BYE, - SMTP_CLOSED - }; - - SMTPStep m_state; - - EmailMessage* m_pMessage; - - int m_posInMsg; - int m_posInCRLF; - - SMTPResult m_blockingResult; //Result if blocking mode - string m_response; - int m_responseCode; - string m_username; - string m_password; - SMTPAuth m_auth; - string m_heloDomain; - - vector<string>::iterator m_To; -}; - -#endif // SMTP_CLIENT_H \ No newline at end of file
--- a/net.cpp Wed Aug 24 13:22:32 2011 +0000 +++ b/net.cpp Wed Sep 07 16:03:54 2011 +0000 @@ -12,35 +12,26 @@ #include "weather.h" #include "EthernetNetIf.h" #ifdef USE_NTP -//#include "NTPClient.h" #include "TinySNTP.h" #endif #ifdef USE_HTTP -#include "HTTPClient.h" +#include "TinyHTTP.h" #endif #ifdef USE_EMAIL -#include "SMTPClient.h" +#include "TinySMTP.h" #endif - -#define STATIONS_URL "http://weather.sugakoubou.com/p" -#define TWITTER_URL "http://api.supertweet.net/1/statuses/update.xml" -#define PACHUBE_URL "http://api.pachube.com/v1/feeds/" +#include "TCPSocket.h" EthernetNetIf *eth; DigitalOut led_gayk(p24),led_gkya(p25), led_yk(p26); static DigitalIn eth_link(P1_25), eth_speed(P1_26); static volatile int ethernet_flg = 0; -#ifdef USE_HTTP -//static HTTPClient *http; -#endif -//static NTPClient *ntp; int weatherstations () { #ifdef USE_HTTP - char post_data[150]; - HTTPClient http; - HTTPResult ret; - HTTPText postContent("application/x-www-form-urlencoded"); + Host host; + char buf[FORMAT_STR_SIZE]; + char head[80]; if (! ethernet_flg) return 0; if (! conf.stations_id[0] || ! conf.stations_pin[0]) { @@ -48,39 +39,30 @@ } LED_NET_ACT_ON; - format_str("d0=%.2P&d1=%.2T&d2=%.2H&d3=%.2A&d4=%.2V&d5=%.2R&d6=%.2L&d7=%.2U&d8=%.2M&d9=%.2p", post_data, sizeof_1(post_data)); - strncat(post_data, "&fcd=", sizeof_len(post_data)); - strncat(post_data, conf.stations_id, sizeof_len(post_data)); - strncat(post_data, "&pin=", sizeof_len(post_data)); - strncat(post_data, conf.stations_pin, sizeof_len(post_data)); - postContent.puts(post_data); + + format_str("d0=%.2P&d1=%.2T&d2=%.2H&d3=%.2A&d4=%.2V&d5=%.2R&d6=%.2L&d7=%.2U&d8=%.2M&d9=%.2p", buf, sizeof_1(buf)); + snprintf(&buf[strlen(buf)], sizeof_len(buf), + "&fcd=%s&pin=%s", conf.stations_id, conf.stations_pin); #ifdef DEBUG - pc.printf("S: %s %s\r\n%s\r\n", conf.stations_id, conf.stations_pin, post_data); + pc.printf("S: %s %s\r\n%s\r\n", conf.stations_id, conf.stations_pin, buf); #endif // http->resetRequestHeaders(); // http->basicAuth(NULL, NULL); - http.setTimeout(NET_TIMEOUT); - ret = http.post(STATIONS_URL, postContent, NULL); + + strncpy(head, "Content-type: application/x-www-form-urlencoded\r\n", sizeof_1(head)); - if (ret != HTTP_OK && ret != HTTP_PROCESSING) { - pc.printf("Weather Statuons failure: %d\r\n", ret); - return -1; -#ifdef DEBUG - } else { - pc.printf("Weather Stations success: %d\r\n", ret); + host.setName("weather.sugakoubou.com"); + host.setPort(HTTP_PORT); + return httpRequest(METHOD_POST, &host, "/p", head, buf) == 200 ? 0 : -1; #endif - } -#endif - return 0; } int pachube () { #ifdef USE_HTTP - char buf[100], uri[100]; - HTTPClient http; - HTTPResult ret; - HTTPText csvContent("text/csv"); + Host host; + char buf[FORMAT_STR_SIZE]; + char uri[40], head[160]; if (! ethernet_flg) return 0; if (! conf.pachube_apikey[0] || ! conf.pachube_feedid[0]) { @@ -88,38 +70,28 @@ } LED_NET_ACT_ON; + // body format_str(conf.pachube_mesg, buf, sizeof_1(buf)); - csvContent.set(buf); - - snprintf(uri, sizeof(uri), PACHUBE_URL "%s.csv?_method=put", conf.pachube_feedid); - + // header + snprintf(head, sizeof(head), "Content-type: text/csv\r\nX-PachubeApiKey: %s\r\n", conf.pachube_apikey); + // uri + snprintf(uri, sizeof(uri), "/v1/feeds/%s.csv?_method=put", conf.pachube_feedid); #ifdef DEBUG pc.printf("P: %s %s %s\r\n", conf.pachube_apikey, conf.pachube_feedid, uri); #endif -// http->resetRequestHeaders(); -// http->basicAuth(NULL, NULL); - http.setTimeout(NET_TIMEOUT); - http.setRequestHeader("X-PachubeApiKey", conf.pachube_apikey); - ret = http.post(uri, csvContent, NULL); - if (ret != HTTP_OK && ret != HTTP_PROCESSING) { - pc.printf("Pachube failure: %d\r\n", ret); - return -1; -#ifdef DEBUG - } else { - pc.printf("Pachube success: %d\r\n", ret); + host.setName("api.pachube.com"); + host.setPort(HTTP_PORT); + return httpRequest(METHOD_POST, &host, uri, head, buf) == 200 ? 0 : -1; #endif - } -#endif - return 0; } int twitter (int num) { #ifdef USE_HTTP + Host host; char buf[FORMAT_STR_SIZE]; - HTTPClient http; - HTTPMap msg; - HTTPResult ret; + char msg[FORMAT_STR_SIZE]; + char head[160]; if (! ethernet_flg || num >= CF_TWITTER_NUM) return 0; if (! conf.twitter_user[0] || ! conf.twitter_pwd[0] || ! conf.twitter_mesg[num][0]) { @@ -127,36 +99,27 @@ } LED_NET_ACT_ON; - format_str(conf.twitter_mesg[num], buf, sizeof_1(buf)); - msg["status"] = buf; - + // header + createauth(conf.twitter_user, conf.twitter_pwd, head, sizeof(head)); + strncat(head, "Content-type: application/x-www-form-urlencoded\r\n", sizeof_len(head)); + // post data + format_str(conf.twitter_mesg[num], msg, sizeof_1(msg)); + strcpy(buf, "status="); + urlencode(msg, &buf[strlen(buf)], sizeof_len(buf)); #ifdef DEBUG pc.printf("T: %s %s %s\r\n%s\r\n", conf.twitter_user, conf.twitter_pwd, conf.twitter_mesg[num], buf); #endif -// http->resetRequestHeaders(); - http.setTimeout(NET_TIMEOUT); - http.basicAuth(conf.twitter_user, conf.twitter_pwd); - ret = http.post(TWITTER_URL, msg, NULL); - if (ret != HTTP_OK && ret != HTTP_PROCESSING) { - pc.printf("Twitter failure: %d\r\n", ret); - return -1; -#ifdef DEBUG - } else { - pc.printf("Twitter success: %d\r\n", ret); + host.setName("api.supertweet.net"); + host.setPort(HTTP_PORT); + return httpRequest(METHOD_POST, &host, "/1/statuses/update.xml", head, buf) == 200 ? 0 : -1; #endif - } -#endif - return 0; } int email (int num) { #ifdef USE_EMAIL + Host host; char buf[FORMAT_STR_SIZE]; - static SMTPClient smtp; - Host smtpserver; - EmailMessage msg; - SMTPResult ret; if (! ethernet_flg || num >= CF_MAIL_NUM) return 0; if (! conf.smtphost[0] || ! conf.mailfrom[0] || @@ -165,44 +128,17 @@ } LED_NET_ACT_ON; - smtpserver.setName(conf.smtphost); - smtpserver.setPort(conf.smtpport); - smtp.setServer(smtpserver); - smtp.setHeloDomain("mbed"); - if (conf.smtpuser[0] && conf.smtppwd[0]) { - // SMTP auth - smtp.setAuth(conf.smtpuser, conf.smtppwd); - } - msg.setFrom(conf.mailfrom); - msg.addTo(conf.mailto[num]); -/* - msg.printf("Content-Type: text/plain; charset=UTF-8\n"); - msg.printf("Content-Transfer-Encoding: 8bit\n"); - msg.printf("From: %s\n", conf.mailfrom); - msg.printf("To: %s\n", conf.mailto[num]); -*/ - msg.printf("Subject: Message from weather\n"); - format_str(conf.mailmesg[num], buf, sizeof_1(buf)); - msg.printf("\n%s\n", buf); - + snprintf(buf, sizeof(buf), "From: %s\nTo: %s\nSubject: Message from weather\n\n", conf.mailfrom, conf.mailto); + format_str(conf.mailmesg[num], &buf[strlen(buf)], sizeof_len(buf)); #ifdef DEBUG pc.printf("SMTP %s %s %s\r\n%s\r\n", conf.smtphost, conf.mailfrom, conf.mailto[num], buf); #endif - smtp.setTimeout(NET_TIMEOUT); - ret = smtp.send(&msg); - if (ret != HTTP_OK) { - pc.printf("Mail failure: %d\r\n", ret); - return -1; -#ifdef DEBUG - } else { - pc.printf("Mail success: %d\r\n", ret); - pc.printf("SMTP response %s", smtp.getLastResponse().c_str()); + host.setName(conf.smtphost); + host.setPort(conf.smtpport); + return sendmail(conf.mailfrom, conf.mailto[num], buf, &host, conf.smtpuser, conf.smtppwd); #endif - } -#endif - return 0; } int ntp (char *hostname) {
--- a/weather.h Wed Aug 24 13:22:32 2011 +0000 +++ b/weather.h Wed Sep 07 16:03:54 2011 +0000 @@ -13,7 +13,7 @@ #include "EthernetNetIf.h" #include "I2CLCD.h" -//#define DEBUG +#undef DEBUG #define PCB_LOT 0 // PCB version 0:i, 1:ro, 2:ha @@ -23,7 +23,7 @@ #define USE_HTTP // HTTP Client (Weather Stations, Pachube, Twitter) #define USE_NTP // NTP Client #undef USE_SNMP // SNMP Agent -#undef USE_EMAIL // send mail +#define USE_EMAIL // send mail #if PCB_LOT >= 1 #define USE_3LED // 3 leds level meter