Dependents:   TimeZoneDemo EthernetJackTestCode MMEx_Challenge ntp_mem ... more

Committer:
segundo
Date:
Sat Nov 27 23:23:43 2010 +0000
Revision:
5:fa27dde97304
Parent:
0:ac1725ba162c

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
segundo 0:ac1725ba162c 1
segundo 0:ac1725ba162c 2 /*
segundo 5:fa27dde97304 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) y Segundo Equipo
segundo 5:fa27dde97304 4
segundo 0:ac1725ba162c 5 Permission is hereby granted, free of charge, to any person obtaining a copy
segundo 0:ac1725ba162c 6 of this software and associated documentation files (the "Software"), to deal
segundo 0:ac1725ba162c 7 in the Software without restriction, including without limitation the rights
segundo 0:ac1725ba162c 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
segundo 0:ac1725ba162c 9 copies of the Software, and to permit persons to whom the Software is
segundo 0:ac1725ba162c 10 furnished to do so, subject to the following conditions:
segundo 5:fa27dde97304 11
segundo 0:ac1725ba162c 12 The above copyright notice and this permission notice shall be included in
segundo 0:ac1725ba162c 13 all copies or substantial portions of the Software.
segundo 5:fa27dde97304 14
segundo 0:ac1725ba162c 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
segundo 0:ac1725ba162c 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
segundo 0:ac1725ba162c 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
segundo 0:ac1725ba162c 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
segundo 0:ac1725ba162c 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
segundo 0:ac1725ba162c 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
segundo 0:ac1725ba162c 21 THE SOFTWARE.
segundo 0:ac1725ba162c 22 */
segundo 0:ac1725ba162c 23
segundo 5:fa27dde97304 24 /** \file
segundo 5:fa27dde97304 25 SMTP Client header file
segundo 5:fa27dde97304 26 */
segundo 5:fa27dde97304 27
segundo 0:ac1725ba162c 28 #ifndef SMTP_CLIENT_H
segundo 0:ac1725ba162c 29 #define SMTP_CLIENT_H
segundo 0:ac1725ba162c 30
segundo 0:ac1725ba162c 31 class EmailMessage;
segundo 0:ac1725ba162c 32
segundo 0:ac1725ba162c 33 #include "core/net.h"
segundo 0:ac1725ba162c 34 #include "api/TCPSocket.h"
segundo 5:fa27dde97304 35 #include "api/DNSRequest.h"
segundo 5:fa27dde97304 36 #include "EmailMessage.h"
segundo 0:ac1725ba162c 37 #include "mbed.h"
segundo 0:ac1725ba162c 38
segundo 5:fa27dde97304 39 ///SMTP client results
segundo 5:fa27dde97304 40 enum SMTPResult {
segundo 5:fa27dde97304 41 SMTP_OK, ///<Success
segundo 5:fa27dde97304 42 SMTP_PROCESSING, ///<Processing
segundo 5:fa27dde97304 43 SMTP_DNS, ///<Could not resolve name
segundo 5:fa27dde97304 44 SMTP_PRTCL, ///<Protocol error
segundo 5:fa27dde97304 45 SMTP_TIMEOUT, ///<Connection timeout
segundo 5:fa27dde97304 46 SMTP_DISC ///<Disconnected
segundo 0:ac1725ba162c 47 };
segundo 0:ac1725ba162c 48
segundo 5:fa27dde97304 49 ///SMTP authentication
segundo 5:fa27dde97304 50 enum SMTPAuth {
segundo 5:fa27dde97304 51 SMTP_AUTH_NONE, ///<No authentication
segundo 5:fa27dde97304 52 SMTP_AUTH_PLAIN ///<AUTH PLAIN authentication
segundo 5:fa27dde97304 53 };
segundo 5:fa27dde97304 54 #include "core/netservice.h"
segundo 5:fa27dde97304 55
segundo 5:fa27dde97304 56 ///A simple SMTP Client
segundo 5:fa27dde97304 57 /**
segundo 5:fa27dde97304 58 The SMTPClient is composed of:
segundo 5:fa27dde97304 59 - The actual client (SMTPClient)
segundo 5:fa27dde97304 60 - A class (EmailMessage) to hold the message addresses and content for sending
segundo 5:fa27dde97304 61 */
segundo 5:fa27dde97304 62 class SMTPClient : protected NetService {
segundo 0:ac1725ba162c 63 public:
segundo 5:fa27dde97304 64 ///Instantiates the SMTP client
segundo 5:fa27dde97304 65 SMTPClient();
segundo 5:fa27dde97304 66
segundo 5:fa27dde97304 67 ///Destructor for the SMTP client
segundo 5:fa27dde97304 68 virtual ~SMTPClient();
segundo 5:fa27dde97304 69
segundo 5:fa27dde97304 70 ///Full constructor for the SMTP client
segundo 5:fa27dde97304 71 /**
segundo 5:fa27dde97304 72 @param host : SMTP server host
segundo 5:fa27dde97304 73 @param heloDomain : domain name of client
segundo 5:fa27dde97304 74 @param user : username
segundo 5:fa27dde97304 75 @param password : password
segundo 5:fa27dde97304 76 @param auth : authentication type
segundo 5:fa27dde97304 77 */
segundo 5:fa27dde97304 78 SMTPClient(const Host& host, const char* heloDomain, const char* user, const char* password, SMTPAuth auth);
segundo 5:fa27dde97304 79
segundo 5:fa27dde97304 80 ///Set server host
segundo 5:fa27dde97304 81 /**
segundo 5:fa27dde97304 82 @param host : SMTP server host
segundo 5:fa27dde97304 83 */
segundo 5:fa27dde97304 84 void setServer(const Host& host);
segundo 5:fa27dde97304 85
segundo 5:fa27dde97304 86 ///Provides a plain authentication feature (Base64 encoded username and password)
segundo 5:fa27dde97304 87 /**
segundo 5:fa27dde97304 88 @param user : username
segundo 5:fa27dde97304 89 @param password : password
segundo 5:fa27dde97304 90 */
segundo 5:fa27dde97304 91 void setAuth(const char* user, const char* password); // Plain authentication
segundo 5:fa27dde97304 92
segundo 5:fa27dde97304 93 ///Turns off authentication
segundo 5:fa27dde97304 94 void clearAuth(); // Clear authentication
segundo 5:fa27dde97304 95
segundo 5:fa27dde97304 96 ///Set HELO domain (defaults to localhost if not set)
segundo 5:fa27dde97304 97 /**
segundo 5:fa27dde97304 98 @param heloDomain : domain name of client (strictly should be fully qualified domain name)
segundo 5:fa27dde97304 99 */
segundo 5:fa27dde97304 100 void setHeloDomain(const char* heloDomain);
segundo 5:fa27dde97304 101
segundo 5:fa27dde97304 102 //High Level setup functions
segundo 5:fa27dde97304 103 ///Sends the message (blocking)
segundo 5:fa27dde97304 104 /**
segundo 5:fa27dde97304 105 @param pMessage : pointer to a message
segundo 5:fa27dde97304 106
segundo 5:fa27dde97304 107 Blocks until completion
segundo 5:fa27dde97304 108 */
segundo 5:fa27dde97304 109 SMTPResult send(EmailMessage* pMessage); //Blocking
segundo 5:fa27dde97304 110
segundo 5:fa27dde97304 111 ///Sends the message (non blocking)
segundo 5:fa27dde97304 112 /**
segundo 5:fa27dde97304 113 @param pMessage : pointer to a message
segundo 5:fa27dde97304 114 @param pMethod : callback function
segundo 5:fa27dde97304 115
segundo 5:fa27dde97304 116 The function returns immediately and calls the callback on completion or error
segundo 5:fa27dde97304 117 */
segundo 5:fa27dde97304 118 SMTPResult send(EmailMessage* pMessage, void (*pMethod)(SMTPResult)); //Non blocking
segundo 5:fa27dde97304 119
segundo 5:fa27dde97304 120 ///Sends the message (non blocking)
segundo 5:fa27dde97304 121 /**
segundo 5:fa27dde97304 122 @param pMessage : pointer to a message
segundo 5:fa27dde97304 123 @param pItem : instance of class on which to execute the callback method
segundo 5:fa27dde97304 124 @param pMethod : callback method
segundo 5:fa27dde97304 125
segundo 5:fa27dde97304 126 The function returns immediately and calls the callback on completion or error
segundo 5:fa27dde97304 127 */
segundo 5:fa27dde97304 128 template<class T>
segundo 5:fa27dde97304 129 SMTPResult send(EmailMessage* pMessage, T* pItem, void (T::*pMethod)(SMTPResult)) { //Non blocking
segundo 5:fa27dde97304 130 setOnResult(pItem, pMethod);
segundo 5:fa27dde97304 131 doSend(pMessage);
segundo 5:fa27dde97304 132 return SMTP_PROCESSING;
segundo 5:fa27dde97304 133 }
segundo 5:fa27dde97304 134
segundo 5:fa27dde97304 135 ///Sends the message (non blocking)
segundo 5:fa27dde97304 136 /**
segundo 5:fa27dde97304 137 @param pMessage : pointer to a message
segundo 5:fa27dde97304 138
segundo 5:fa27dde97304 139 The function returns immediately and calls the previously set callback on completion or error
segundo 5:fa27dde97304 140 */
segundo 5:fa27dde97304 141 void doSend(EmailMessage* pMessage);
segundo 0:ac1725ba162c 142
segundo 5:fa27dde97304 143 ///Setup the result callback
segundo 5:fa27dde97304 144 /**
segundo 5:fa27dde97304 145 @param pMethod : callback function
segundo 5:fa27dde97304 146 */
segundo 5:fa27dde97304 147 void setOnResult( void (*pMethod)(SMTPResult) );
segundo 5:fa27dde97304 148
segundo 5:fa27dde97304 149 ///Setup the result callback
segundo 5:fa27dde97304 150 /**
segundo 5:fa27dde97304 151 @param pItem : instance of class on which to execute the callback method
segundo 5:fa27dde97304 152 @param pMethod : callback method
segundo 5:fa27dde97304 153 */
segundo 5:fa27dde97304 154 class CDummy;
segundo 5:fa27dde97304 155 template<class T>
segundo 5:fa27dde97304 156 void setOnResult( T* pItem, void (T::*pMethod)(SMTPResult) ) {
segundo 5:fa27dde97304 157 m_pCb = NULL;
segundo 5:fa27dde97304 158 m_pCbItem = (CDummy*) pItem;
segundo 5:fa27dde97304 159 m_pCbMeth = (void (CDummy::*)(SMTPResult)) pMethod;
segundo 5:fa27dde97304 160 }
segundo 0:ac1725ba162c 161
segundo 5:fa27dde97304 162 ///Setup timeout
segundo 5:fa27dde97304 163 /**
segundo 5:fa27dde97304 164 @param ms : time of connection inactivity in ms after which the request should timeout
segundo 5:fa27dde97304 165 */
segundo 5:fa27dde97304 166 void setTimeout(int ms);
segundo 5:fa27dde97304 167
segundo 5:fa27dde97304 168 ///Gets the last response from the server
segundo 5:fa27dde97304 169 string& getLastResponse();
segundo 5:fa27dde97304 170
segundo 5:fa27dde97304 171 virtual void poll(); //Called by NetServices
segundo 5:fa27dde97304 172
segundo 5:fa27dde97304 173 protected:
segundo 5:fa27dde97304 174 int rc(char* buf); //Return code
segundo 5:fa27dde97304 175 void process(bool writeable); //Main state-machine
segundo 5:fa27dde97304 176
segundo 5:fa27dde97304 177 void resetTimeout();
segundo 5:fa27dde97304 178
segundo 5:fa27dde97304 179 void init();
segundo 5:fa27dde97304 180 void close();
segundo 5:fa27dde97304 181
segundo 5:fa27dde97304 182 void setup(EmailMessage* pMessage); //Setup request, make DNS Req if necessary
segundo 5:fa27dde97304 183 void connect(); //Start Connection
segundo 5:fa27dde97304 184
segundo 5:fa27dde97304 185 int tryRead(); //Read data and try to feed output
segundo 5:fa27dde97304 186 void readData(); //Data has been read
segundo 5:fa27dde97304 187 void writeData(); //Data has been written & buf is free
segundo 0:ac1725ba162c 188
segundo 5:fa27dde97304 189 void onTCPSocketEvent(TCPSocketEvent e);
segundo 5:fa27dde97304 190 void onDNSReply(DNSReply r);
segundo 5:fa27dde97304 191 void onResult(SMTPResult r); //Called when exchange completed or on failure
segundo 5:fa27dde97304 192 void onTimeout(); //Connection has timed out
segundo 5:fa27dde97304 193
segundo 5:fa27dde97304 194 string encodePlainAuth(); // Encode plain authentication (username and password in based 64)
segundo 5:fa27dde97304 195 bool okPostAuthentication(int code); // True if server response is ok following authentication
segundo 5:fa27dde97304 196
segundo 5:fa27dde97304 197 private:
segundo 5:fa27dde97304 198 SMTPResult blockingProcess(); //Called in blocking mode, calls Net::poll() until return code is available
segundo 5:fa27dde97304 199
segundo 5:fa27dde97304 200 CDummy* m_pCbItem;
segundo 5:fa27dde97304 201 void (CDummy::*m_pCbMeth)(SMTPResult);
segundo 5:fa27dde97304 202 void (*m_pCb)(SMTPResult);
segundo 5:fa27dde97304 203
segundo 5:fa27dde97304 204 TCPSocket* m_pTCPSocket;
segundo 5:fa27dde97304 205
segundo 5:fa27dde97304 206 Timer m_watchdog;
segundo 5:fa27dde97304 207 int m_timeout;
segundo 5:fa27dde97304 208
segundo 5:fa27dde97304 209 DNSRequest* m_pDnsReq;
segundo 5:fa27dde97304 210 Host m_server;
segundo 5:fa27dde97304 211
segundo 5:fa27dde97304 212 bool m_closed;
segundo 0:ac1725ba162c 213
segundo 5:fa27dde97304 214 enum SMTPStep {
segundo 5:fa27dde97304 215 SMTP_HELLO,
segundo 5:fa27dde97304 216 SMTP_AUTH,
segundo 5:fa27dde97304 217 SMTP_FROM,
segundo 5:fa27dde97304 218 SMTP_TO,
segundo 5:fa27dde97304 219 SMTP_DATA,
segundo 5:fa27dde97304 220 SMTP_BODY,
segundo 5:fa27dde97304 221 SMTP_BODYMORE,
segundo 5:fa27dde97304 222 SMTP_EOF,
segundo 5:fa27dde97304 223 SMTP_BYE,
segundo 5:fa27dde97304 224 SMTP_CLOSED
segundo 5:fa27dde97304 225 };
segundo 5:fa27dde97304 226
segundo 5:fa27dde97304 227 SMTPStep m_state;
segundo 5:fa27dde97304 228
segundo 5:fa27dde97304 229 EmailMessage* m_pMessage;
segundo 5:fa27dde97304 230
segundo 5:fa27dde97304 231 int m_posInMsg;
segundo 5:fa27dde97304 232 int m_posInCRLF;
segundo 5:fa27dde97304 233
segundo 5:fa27dde97304 234 SMTPResult m_blockingResult; //Result if blocking mode
segundo 5:fa27dde97304 235 string m_response;
segundo 5:fa27dde97304 236 int m_responseCode;
segundo 5:fa27dde97304 237 string m_username;
segundo 5:fa27dde97304 238 string m_password;
segundo 5:fa27dde97304 239 SMTPAuth m_auth;
segundo 5:fa27dde97304 240 string m_heloDomain;
segundo 5:fa27dde97304 241
segundo 5:fa27dde97304 242 vector<string>::iterator m_To;
segundo 0:ac1725ba162c 243 };
segundo 0:ac1725ba162c 244
segundo 5:fa27dde97304 245 #endif // SMTP_CLIENT_H