Dependents:   SimpleLCDClock readCard2Twitter_http AnalogClock_StepperMotor_NTP ServoCamV1

Revision:
0:a2dd0ba6cd2d
Child:
1:7043cc0db03c
--- /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