Dependents: SimpleLCDClock readCard2Twitter_http AnalogClock_StepperMotor_NTP ServoCamV1
Revision 0:a2dd0ba6cd2d, committed 2010-05-24
- Comitter:
- donatien
- Date:
- Mon May 24 10:24:38 2010 +0000
- Child:
- 1:7043cc0db03c
- Commit message:
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dbg/dbg.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,50 @@ +//#ifdef DBG_H +//#define DBG_H + +#ifdef __LWIP_DEBUG +#define __DEBUG +#endif + +#ifdef __DEBUG + +#ifndef __DEBUGSTREAM +#define __DEBUGSTREAM + + +class DebugStream +{ +public: +static void debug(const char* format, ...); +static void release(); +private: + +}; + +#undef DBG +#undef DBG_END +#define DBG DebugStream::debug +#define DBG_END DebugStream::release +#endif + +#else +#undef DBG +#undef DBG_END +#define DBG(...) +#define DBG_END() +#endif + +#ifdef __LWIP_DEBUG +#ifndef __SNPRINTF +#define __SNPRINTF +#include "mbed.h" + +//int snprintf(char *str, int size, const char *format, ...); +#endif +#endif + +#ifdef __LWIP_DEBUG +#undef __DEBUG +#endif + +//#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/e6be4cd80aad
Binary file services.ar has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/email/emailMessage.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,42 @@ +#ifndef EMAIL_MESSAGE_H +#define EMAIL_MESSAGE_H + +class SmtpClient; + +#include "smtp/smtpClient.h" + +#include <queue> +using std::queue; + +#include <string> +using std::string; + +class EmailMessage +{ +public: + EmailMessage(SmtpClient* pClient); + ~EmailMessage(); + + void setFrom(const char* from); + void addTo(const char* to); + int printf(const char* format, ... ); //Can be called multiple times to write the message + + void send(); + + //For now, only message sending is implemented + //int scanf(const char* format, ... ); + +private: + friend class SmtpClient; + queue<string> m_lTo; + string m_from; + + string m_content; + + SmtpClient* m_pClient; + +}; + + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/email/smtp/smtpClient.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,86 @@ +#ifndef SMTP_CLIENT_H +#define SMTP_CLIENT_H + +class EmailMessage; + +#include "if/net/net.h" +#include "api/TcpSocket.h" +#include "../emailMessage.h" + +#include "mbed.h" + +#define SMTP_REQUEST_TIMEOUT 5000 + +enum SmtpResult +{ + SMTP_OK, + SMTP_PRTCL, //Protocol error + SMTP_TIMEOUT, //Connection timeout + SMTP_DISC //Disconnected +}; + +class SmtpClient /*: public NetService*/ +{ +public: + SmtpClient(); + virtual ~SmtpClient(); + + void setHost(const Host& host); + void send(EmailMessage* pMessage); + + class CDummy; + template<class T> + //Linker bug : Must be defined here :( + void setOnResult( T* pItem, void (T::*pMethod)(SmtpResult) ) + { + m_pCbItem = (CDummy*) pItem; + m_pCbMeth = (void (CDummy::*)(SmtpResult)) pMethod; + } + + void init(); //Create and setup socket if needed + void close(); + +private: + int rc(char* buf); //Return code + void process(bool moreData); //Main state-machine + + void setTimeout(int ms); + void resetTimeout(); + + void onTimeout(); //Connection has timed out + void onTcpSocketEvent(TcpSocketEvent e); + void onResult(SmtpResult r); //Called when exchange completed or on failure + + EmailMessage* m_pMessage; + + TcpSocket* m_pTcpSocket; + + enum SmtpStep + { + SMTP_HELLO, + SMTP_FROM, + SMTP_TO, + SMTP_DATA, + SMTP_BODY, + SMTP_BODYMORE, + SMTP_EOF, + SMTP_BYE + }; + + SmtpStep m_nextState; + + CDummy* m_pCbItem; + void (CDummy::*m_pCbMeth)(SmtpResult); + + Timeout m_watchdog; + int m_timeout; + + int m_posInMsg; + + bool m_closed; + + Host m_host; + +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/http/client/HttpClient.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,180 @@ +#ifndef HTTP_CLIENT_H +#define HTTP_CLIENT_H + +class HttpData; + +#include "if/net/net.h" +#include "api/TcpSocket.h" +#include "api/DnsRequest.h" +#include "HttpData.h" +#include "mbed.h" + +#include <string> +using std::string; + +#include <map> +using std::map; + +#define HTTP_REQUEST_TIMEOUT 30000//15000 +#define HTTP_PORT 80 + +enum HttpResult +{ + HTTP_OK, + HTTP_PROCESSING, + HTTP_PARSE, //URI Parse error + HTTP_DNS, //Could not resolve name + HTTP_PRTCL, //Protocol error + HTTP_NOTFOUND, //404 Error + HTTP_REFUSED, //403 Error + HTTP_ERROR, //xxx error + HTTP_TIMEOUT, //Connection timeout + HTTP_CONN //Connection error +}; + + + +class HttpClient : protected NetService +{ +public: + HttpClient(); + virtual ~HttpClient(); + + void basicAuth(const char* user, const char* password); //Basic Authentification + + //High Level setup functions + HttpResult get(const char* uri, HttpData* pDataIn); //Blocking + HttpResult get(const char* uri, HttpData* pDataIn, void (*pMethod)(HttpResult)); //Non blocking + template<class T> + //Linker bug : Must be defined here :( + HttpResult get(const char* uri, HttpData* pDataIn, T* pItem, void (T::*pMethod)(HttpResult)) //Non blocking + { + setOnResult(pItem, pMethod); + doGet(uri, pDataIn); + return HTTP_PROCESSING; + } + + HttpResult post(const char* uri, const HttpData& dataOut, HttpData* pDataIn); //Blocking + HttpResult post(const char* uri, const HttpData& dataOut, HttpData* pDataIn, void (*pMethod)(HttpResult)); //Non blocking + template<class T> + //Linker bug : Must be defined here :( + HttpResult post(const char* uri, const HttpData& dataOut, HttpData* pDataIn, T* pItem, void (T::*pMethod)(HttpResult)) //Non blocking + { + setOnResult(pItem, pMethod); + doPost(uri, dataOut, pDataIn); + return HTTP_PROCESSING; + } + + void doGet(const char* uri, HttpData* pDataIn); + void doPost(const char* uri, const HttpData& dataOut, HttpData* pDataIn); + + void setOnResult( void (*pMethod)(HttpResult) ); + class CDummy; + template<class T> + //Linker bug : Must be defined here :( + void setOnResult( T* pItem, void (T::*pMethod)(HttpResult) ) + { + m_pCb = NULL; + m_pCbItem = (CDummy*) pItem; + m_pCbMeth = (void (CDummy::*)(HttpResult)) pMethod; + } + + void setTimeout(int ms); + + virtual void poll(); //Called by NetServices + + int getHttpResponseCode(); + void setRequestHeader(const string& header, const string& value); + string& getResponseHeader(const string& header); + void resetRequestHeaders(); + +protected: + void resetTimeout(); + + void init(); + void close(); + + void setup(const char* uri, HttpData* pDataOut, HttpData* pDataIn); //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(HttpResult r); //Called when exchange completed or on failure + void onTimeout(); //Connection has timed out + +private: + HttpResult blockingProcess(); //Called in blocking mode, calls Net::poll() until return code is available + + bool readHeaders(); //Called first when receiving data + bool writeHeaders(); //Called to create req + int readLine(char* str, int maxLen); + + enum HTTP_METH + { + HTTP_GET, + HTTP_POST, + HTTP_HEAD + }; + + HTTP_METH m_meth; + + CDummy* m_pCbItem; + void (CDummy::*m_pCbMeth)(HttpResult); + + void (*m_pCb)(HttpResult); + + TcpSocket* m_pTcpSocket; + map<string, string> m_reqHeaders; + map<string, string> m_respHeaders; + + Timer m_watchdog; + int m_timeout; + + DnsRequest* m_pDnsReq; + + Host m_server; + string m_path; + + bool m_closed; + + enum HttpStep + { + // HTTP_INIT, + HTTP_WRITE_HEADERS, + HTTP_WRITE_DATA, + HTTP_READ_HEADERS, + HTTP_READ_DATA, + HTTP_READ_DATA_INCOMPLETE, + HTTP_DONE, + HTTP_CLOSED + }; + + HttpStep m_state; + + HttpData* m_pDataOut; + HttpData* m_pDataIn; + + bool m_dataChunked; //Data is encoded as chunks + int m_dataPos; //Position in data + int m_dataLen; //Data length + char* m_buf; + char* m_pBufRemaining; //Remaining + int m_bufRemainingLen; //Data length in m_pBufRemaining + + int m_httpResponseCode; + + HttpResult m_blockingResult; //Result if blocking mode + +}; + +//Including data containers here for more convenience +#include "data/HttpFile.h" +#include "data/HttpStream.h" +#include "data/HttpText.h" +#include "data/HttpMap.h" + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/http/client/HttpData.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,33 @@ +#ifndef HTTP_DATA_H +#define HTTP_DATA_H + +#include "if/net/net.h" + +#include <string> +using std::string; + +class HttpData //This is a simple interface for Http data storage (impl examples are Key/Value Pairs, File, etc...) +{ +public: + HttpData(); + virtual ~HttpData(); + +protected: + friend class HttpClient; + virtual int read(char* buf, int len) = 0; + virtual int write(const char* buf, int len) = 0; + + virtual string getDataType() = 0; //Internet media type for Content-Type header + virtual void setDataType(const string& type) = 0; //Internet media type from Content-Type header + + virtual bool getIsChunked() = 0; //For Transfer-Encoding header + virtual void setIsChunked(bool chunked) = 0; //From Transfer-Encoding header + + virtual int getDataLen() = 0; //For Content-Length header + virtual void setDataLen(int len) = 0; //From Content-Length header, or if the transfer is chunked, next chunk length + +private: + +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/http/client/data/HttpFile.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,32 @@ +#ifndef HTTP_FILE_H +#define HTTP_FILE_H + +#include "../HttpData.h" +#include "mbed.h" + +class HttpFile : public HttpData //Read or Write data from a file +{ +public: + HttpFile(const char* path, const char* mode); //mode is "r", "w", "a", etc + virtual ~HttpFile(); + +protected: + virtual int read(char* buf, int len); + virtual int write(const char* buf, int len); + + virtual string getDataType(); //Internet media type for Content-Type header + virtual void setDataType(const string& type); //Internet media type from Content-Type header + + virtual bool getIsChunked(); //For Transfer-Encoding header + virtual void setIsChunked(bool chunked); //From Transfer-Encoding header virtual + + virtual int getDataLen(); //For Content-Length header + virtual void setDataLen(int len); //From Content-Length header + +private: + FILE* m_fp; + int m_len; + bool m_chunked; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/http/client/data/HttpMap.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,44 @@ +#ifndef HTTP_MAP_H +#define HTTP_MAP_H + +#include "../HttpData.h" +#include "mbed.h" + +#include <map> +using std::map; + +typedef map<string, string> Dictionary; + +class HttpMap : public HttpData, public Dictionary //Key/Value pairs +{ +public: + HttpMap(); + virtual ~HttpMap(); + + /* string& operator[](const string& key); + int count();*/ + + +protected: + virtual int read(char* buf, int len); + virtual int write(const char* buf, int len); + + virtual string getDataType(); //Internet media type for Content-Type header + virtual void setDataType(const string& type); //Internet media type from Content-Type header + + virtual bool getIsChunked(); //For Transfer-Encoding header + virtual void setIsChunked(bool chunked); //From Transfer-Encoding header + + virtual int getDataLen(); //For Content-Length header + virtual void setDataLen(int len); //From Content-Length header + +private: + void generateString(); + void parseString(); + //map<string, string> m_map; + string m_buf; + int m_len; + bool m_chunked; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/http/client/data/HttpStream.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,40 @@ +#ifndef HTTP_STREAM_H +#define HTTP_STREAM_H + +#include "../HttpData.h" +#include "mbed.h" + +typedef uint8_t byte; + +class HttpStream : public HttpData //Streaming buf +{ +public: + HttpStream(); + virtual ~HttpStream(); + + void readNext(byte* buf, int size); + + bool readable(); + + int readLen(); + +protected: + virtual int read(char* buf, int len); + virtual int write(const char* buf, int len); + + virtual string getDataType(); //Internet media type for Content-Type header + virtual void setDataType(const string& type); //Internet media type from Content-Type header + + virtual bool getIsChunked(); //For Transfer-Encoding header + virtual void setIsChunked(bool chunked); //From Transfer-Encoding header + + virtual int getDataLen(); //For Content-Length header + virtual void setDataLen(int len); //From Content-Length header, or if the transfer is chunked, next chunk length + +private: + byte* m_buf; + int m_size; //Capacity + int m_len; //Length +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/http/client/data/HttpText.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,37 @@ +#ifndef HTTP_TEXT_H +#define HTTP_TEXT_H + +#include "../HttpData.h" +#include "mbed.h" + +class HttpText : public HttpData //Simple Text I/O +{ +public: + HttpText(const string& encoding = "text/html"); + virtual ~HttpText(); + + const char* gets() const; + void puts(const char* str); + + string& get(); + void set(const string& str); + +protected: + virtual int read(char* buf, int len); + virtual int write(const char* buf, int len); + + virtual string getDataType(); //Internet media type for Content-Type header + virtual void setDataType(const string& type); //Internet media type from Content-Type header + + virtual bool getIsChunked(); //For Transfer-Encoding header + virtual void setIsChunked(bool chunked); //From Transfer-Encoding header + + virtual int getDataLen(); //For Content-Length header + virtual void setDataLen(int len); //From Content-Length header, or if the transfer is chunked, next chunk length + +private: + string m_buf; + string m_encoding; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/http/server/HttpRequestDispatcher.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,49 @@ +#ifndef HTTP_REQUEST_DISPATCHER_H +#define HTTP_REQUEST_DISPATCHER_H + +class HttpServer; + +#include "if/net/net.h" +#include "api/TcpSocket.h" +#include "HttpServer.h" + +#include "mbed.h" + +#define HTTP_REQUEST_TIMEOUT 5000 + +#include <string> +using std::string; + +class HttpRequestDispatcher : public NetService +{ +public: + HttpRequestDispatcher(HttpServer* pSvr, TcpSocket* pTcpSocket); + virtual ~HttpRequestDispatcher(); + +private: + + enum HTTP_METH + { + HTTP_GET, + HTTP_POST, + HTTP_HEAD + }; + + void dispatchRequest(); + + virtual void close(); //Close TcpSocket and destroy data + + void onTcpSocketEvent(TcpSocketEvent e); + + void onTimeout(); //Connection has timed out + + bool getRequest(string* rootPath, string* fullPath, string* meth); + + HttpServer* m_pSvr; + TcpSocket* m_pTcpSocket; + + Timeout m_watchdog; + bool m_closed; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/http/server/HttpRequestHandler.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,74 @@ +#ifndef HTTP_REQUEST_HANDLER_H +#define HTTP_REQUEST_HANDLER_H + +#include "if/net/net.h" +#include "api/TcpSocket.h" +//#include "HttpServer.h" + +#include "mbed.h" + +#define HTTP_REQUEST_TIMEOUT 5000 + +#include <string> +using std::string; + +#include <map> +using std::map; + +class HttpRequestHandler : public NetService +{ +public: + HttpRequestHandler(const char* rootPath, const char* path, TcpSocket* pTcpSocket); + virtual ~HttpRequestHandler(); + +//protected: + virtual void doGet() = 0; + virtual void doPost() = 0; + virtual void doHead() = 0; + + virtual void onReadable() = 0; //Data has been read + virtual void onWriteable() = 0; //Data has been written & buf is free + virtual void onTimeout(); //Connection has timed out + virtual void onClose() = 0; //Connection is closing + + virtual void close(); //Close socket and destroy data + +protected: + map<string, string>& reqHeaders() /*const*/; + string& path() /*const*/; + int dataLen() const; + int readData(char* buf, int len); + string& rootPath() /*const*/; + + void setErrCode(int errc); + void setContentLen(int len); + + map<string, string>& respHeaders(); + int writeData(const char* buf, int len); + + void setTimeout(int ms); + void resetTimeout(); + +private: + void readHeaders(); //Called at instanciation + void writeHeaders(); //Called at the first writeData call + void onTcpSocketEvent(TcpSocketEvent e); + + TcpSocket* m_pTcpSocket; + map<string, string> m_reqHeaders; + map<string, string> m_respHeaders; + string m_rootPath; + string m_path; + int m_errc; //Response code + + Timeout m_watchdog; + int m_timeout; + + bool m_closed; + bool m_headersSent; + + int readLine(char* str, int maxLen); + +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/http/server/HttpServer.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,44 @@ +#ifndef HTTP_SERVER_H +#define HTTP_SERVER_H + +class HttpRequestHandler; +class HttpRequestDispatcher; + +#include "if/net/net.h" +#include "HttpRequestHandler.h" +#include "HttpRequestDispatcher.h" + +#include <string> +using std::string; + +#include <map> +using std::map; + +class HttpServer +{ +public: + HttpServer(); + ~HttpServer(); + + template<typename T> + void addHandler(const char* path) //Template decl in header + { m_lpHandlers[path] = &T::inst; } + + void bind(int port = 80); + +private: + friend class HttpRequestDispatcher; + + void onTcpSocketEvent(TcpSocketEvent e); + + TcpSocket* m_pTcpSocket; + map< string, HttpRequestHandler*(*)(const char*, const char*, TcpSocket*) > m_lpHandlers; + +}; + +//Including handlers here for more convenience +#include "impl/RpcHandler.h" +#include "impl/FSHandler.h" +#include "impl/SimpleHandler.h" + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/http/server/impl/FSHandler.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,29 @@ +#ifndef FS_HANDLER_H +#define FS_HANDLER_H + +#include "../HttpRequestHandler.h" +#include "mbed.h" + +class FSHandler : public HttpRequestHandler +{ +public: + FSHandler(const char* rootPath, const char* path, TcpSocket* pTcpSocket); + virtual ~FSHandler(); + +//protected: + static inline HttpRequestHandler* inst(const char* rootPath, const char* path, TcpSocket* pTcpSocket) { return new FSHandler(rootPath, path, pTcpSocket); } //if we ever could do static virtual functions, this would be one + + virtual void doGet(); + virtual void doPost(); + virtual void doHead(); + + virtual void onReadable(); //Data has been read + virtual void onWriteable(); //Data has been written & buf is free + virtual void onClose(); //Connection is closing + +private: + FILE* m_fp; + bool m_err404; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/http/server/impl/RpcHandler.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,27 @@ +#ifndef RPC_HANDLER_H +#define RPC_HANDLER_H + +#include "../HttpRequestHandler.h" + +class RpcHandler : public HttpRequestHandler +{ +public: + RpcHandler(const char* rootPath, const char* path, TcpSocket* pTcpSocket); + virtual ~RpcHandler(); + +//protected: + static inline HttpRequestHandler* inst(const char* rootPath, const char* path, TcpSocket* pTcpSocket) { return new RpcHandler(rootPath, path, pTcpSocket); } //if we ever could do static virtual functions, this would be one + + virtual void doGet(); + virtual void doPost(); + virtual void doHead(); + + virtual void onReadable(); //Data has been read + virtual void onWriteable(); //Data has been written & buf is free + virtual void onClose(); //Connection is closing + +protected: + void cleanReq(char* data); +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/http/server/impl/SimpleHandler.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,24 @@ +#ifndef SIMPLE_HANDLER_H +#define SIMPLE_HANDLER_H + +#include "../HttpRequestHandler.h" + +class SimpleHandler : public HttpRequestHandler +{ +public: + SimpleHandler(const char* rootPath, const char* path, TcpSocket* pTcpSocket); + virtual ~SimpleHandler(); + +//protected: + static inline HttpRequestHandler* inst(const char* rootPath, const char* path, TcpSocket* pTcpSocket) { return new SimpleHandler(rootPath, path, pTcpSocket); } //if we ever could do static virtual functions, this would be one + + virtual void doGet(); + virtual void doPost(); + virtual void doHead(); + + virtual void onReadable(); //Data has been read + virtual void onWriteable(); //Data has been written & buf is free + virtual void onClose(); //Connection is closing +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/http/util/base64.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,34 @@ +#ifndef BASE64_H +#define BASE64_H + +#include <string> +using std::string; + +#ifdef __cplusplus +extern "C" { +#endif + +//Originaly from Rolf's iputil.h + +unsigned int base64enc_len(const char *str); + +void base64enc(const char *input, unsigned int length, char *output); + +#ifdef __cplusplus +} +#endif + +class Base64 +{ +public: + static string encode(const string& str) + { + char* out = new char[ base64enc_len(str.c_str()) ]; + base64enc(str.c_str(), str.length(), out); + string res(out); + delete[] out; + return res; + } +}; + +#endif /* LWIP_UTILS_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/http/util/url.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,65 @@ +#ifndef URL_H +#define URL_H + +#include "if/net/ipaddr.h" + +#include <string> +using std::string; + +#include "mbed.h" + +#ifdef __cplusplus +extern "C" { +#endif + +char *url_encode(char *str); +char *url_decode(char *str); + +#ifdef __cplusplus +} +#endif + +class Url +{ +public: + static string encode(const string& url) + { + char* c_res = url_encode( (char*) url.c_str() ); + string res(c_res); + free(c_res); //Alloc'ed in url_encode() + return res; + } + + static string decode(const string& url) + { + char* c_res = url_decode( (char*) url.c_str() ); + string res(c_res); + free(c_res); //Alloc'ed in url_decode() + return res; + } + + Url(); + + string getProtocol(); + string getHost(); + bool getHostIp(IpAddr* ip); //If host is in IP form, return true & proper object by ptr + uint16_t getPort(); + string getPath(); + + void setProtocol(string protocol); + void setHost(string host); + void setPort(uint16_t port); + void setPath(string path); + + void fromString(string str); + string toString(); + +private: + string m_protocol; + string m_host; + uint16_t m_port; + string m_path; + +}; + +#endif /* LWIP_UTILS_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/services/ntp/NtpClient.h Mon May 24 10:24:38 2010 +0000 @@ -0,0 +1,123 @@ +#ifndef SMTP_CLIENT_H +#define SMTP_CLIENT_H + +#include "if/net/net.h" +#include "api/UdpSocket.h" +#include "api/DnsRequest.h" +#include "mbed.h" + +#define NTP_PORT 123 +#define NTP_REQUEST_TIMEOUT 15000 +#define NTP_TIMESTAMP_DELTA 2208988800ull //Diff btw a UNIX timestamp (Starting Jan, 1st 1970) and a NTP timestamp (Starting Jan, 1st 1900) + +enum NtpResult +{ + NTP_OK, + NTP_PROCESSING, + NTP_PRTCL, //Protocol error + NTP_TIMEOUT, //Connection timeout + NTP_DNS //Could not resolve DNS Addr +}; + +class NtpClient +{ +public: + NtpClient(); + virtual ~NtpClient(); + + //High level setup functions + NtpResult setTime(const Host& host); //Blocking + NtpResult setTime(const Host& host, void (*pMethod)(NtpResult)); //Non blocking + template<class T> + //Linker bug : Must be defined here :( + NtpResult setTime(const Host& host, T* pItem, void (T::*pMethod)(NtpResult)) //Non blocking + { + setOnResult(pItem, pMethod); + doSetTime(host); + return NTP_PROCESSING; + } + + void doSetTime(const Host& host); + + void setOnResult( void (*pMethod)(NtpResult) ); + class CDummy; + template<class T> + //Linker bug : Must be defined here :( + void setOnResult( T* pItem, void (T::*pMethod)(NtpResult) ) + { + m_pCbItem = (CDummy*) pItem; + m_pCbMeth = (void (CDummy::*)(NtpResult)) pMethod; + } + + void init(); + void close(); + +private: + __packed struct NtpPacket //See RFC 4330 for Simple NTP + { + //WARN: We are in LE! Network is BE! + //LSb first + unsigned mode : 3; + unsigned vn : 3; + unsigned li : 2; + + uint8_t stratum; + uint8_t poll; + uint8_t precision; + //32 bits header + + uint32_t rootDelay; + uint32_t rootDispersion; + uint32_t refId; + + uint32_t refTm_s; + uint32_t refTm_f; + uint32_t origTm_s; + uint32_t origTm_f; + uint32_t rxTm_s; + uint32_t rxTm_f; + uint32_t txTm_s; + uint32_t txTm_f; + }; + + void process(); //Main state-machine + + void setTimeout(int ms); + void resetTimeout(); + + void onTimeout(); //Connection has timed out + void onDnsReply(DnsReply r); + void onUdpSocketEvent(UdpSocketEvent e); + void onResult(NtpResult r); //Called when exchange completed or on failure + + NtpResult blockingProcess(); //Called in blocking mode, calls Net::poll() until return code is available + + UdpSocket* m_pUdpSocket; + + enum NtpStep + { + NTP_PING, + NTP_PONG + }; + + NtpStep m_state; + + CDummy* m_pCbItem; + void (CDummy::*m_pCbMeth)(NtpResult); + + void (*m_pCb)(NtpResult); + + Timeout m_watchdog; + int m_timeout; + + bool m_closed; + + Host m_host; + + DnsRequest* m_pDnsReq; + + NtpResult m_blockingResult; //Result if blocking mode + +}; + +#endif