Update contrib.
2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
19 #include "sntpclientengine.h"
22 // 40 second timeout on operations
23 #define SNTP_ENGINE_TIMEOUT 40000000
27 #define SNTP_REMOTE_PORT 123
29 _LIT(KNTPEpochDate,"19000000:");
31 /* The simplest possible NTP request */
33 static const TUint8 sntpRequest[48] = {
34 0x23, 0x00, 0x00, 0x00,
35 0x00, 0x00, 0x00, 0x00,
36 0x00, 0x00, 0x00, 0x00,
37 0x00, 0x00, 0x00, 0x00,
38 0x00, 0x00, 0x00, 0x00,
39 0x00, 0x00, 0x00, 0x00,
40 0x00, 0x00, 0x00, 0x00,
41 0x00, 0x00, 0x00, 0x00,
42 0x00, 0x00, 0x00, 0x00,
43 0x00, 0x00, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x00 };
47 /* The main engine of the SNTP client */
49 CSNTPClient* CSNTPClient::NewL(TCommandLineArgs& aArgs)
51 CSNTPClient* self = CSNTPClient::NewLC(aArgs);
52 CleanupStack::Pop(self);
56 CSNTPClient* CSNTPClient::NewLC(TCommandLineArgs& aArgs)
58 CSNTPClient* self = new (ELeave) CSNTPClient(aArgs);
59 CleanupStack::PushL(self);
64 TSNTPClientState CSNTPClient::State()
69 void CSNTPClient::Start()
72 iState = EStateResolve;
73 iResolver.GetByName(*(iArgs.iServers[iServerIndex]), iNameEntry, iStatus);
75 iTimer->After(SNTP_ENGINE_TIMEOUT);
79 CSNTPClient::~CSNTPClient()
89 CSNTPClient::CSNTPClient(TCommandLineArgs& aArgs)
90 : CActive(EPriorityStandard), iArgs(aArgs)
94 void CSNTPClient::ConstructL()
96 User::LeaveIfError(iSockServ.Connect());
97 User::LeaveIfError(iSock.Open(iSockServ, KAfInet, KSockDatagram, KProtocolInetUdp));
98 User::LeaveIfError(iResolver.Open(iSockServ, KAfInet, KProtocolInetUdp));
100 iTimer = CTimeOutTimer::NewL(EPriorityHigh, *this);
101 CActiveScheduler::Add(this);
104 void CSNTPClient::RunL()
107 if (iStatus.Int() < 0)
109 User::Leave(iStatus.Int());
118 iBuffer.Append(sntpRequest, 48);
120 // set the port on the address
121 iNameEntry().iAddr.SetPort(SNTP_REMOTE_PORT);
123 iState = EStateWrite;
124 iSock.SendTo(iBuffer, iNameEntry().iAddr, 0, iStatus);
126 iTimer->After(SNTP_ENGINE_TIMEOUT);
133 iSock.RecvFrom(iBuffer, iNameEntry().iAddr, 0, iStatus);
135 iTimer->After(SNTP_ENGINE_TIMEOUT);
142 iStatus = KRequestPending;
143 iState = EStateComplete;
144 TRequestStatus* status = &iStatus;
146 User::RequestComplete(status, KErrNone);
151 CActiveScheduler::Stop();
157 User::Leave(KErrArgument);
164 void CSNTPClient::DoCancel()
185 TInt CSNTPClient::RunError(TInt /* aError */)
187 // The current server didn't work, lets try the next if available.
190 if (++iServerIndex < iArgs.iServers.Count())
196 iState = EStateFailed;
197 CActiveScheduler::Stop();
202 void CSNTPClient::TimerExpired()
206 // The current server didn't work, lets try the next if available.
208 if (++iServerIndex < iArgs.iServers.Count())
214 iState = EStateAborted;
215 CActiveScheduler::Stop();
219 void CSNTPClient::SetTimeL()
222 TUint32 timestamp(0);
224 /* Use the seconds from the transmit time field
228 for (TInt i = 40; i < 44; ++i)
230 timestamp = (timestamp << 8) + iBuffer[i];
233 // Obtain the time, including the specified timezone offset
235 TTimeIntervalMinutes mins(timestamp / 60);
236 TTimeIntervalSeconds secs(timestamp % 60);
239 User::LeaveIfError(ntpTime.Set(KNTPEpochDate));
243 // Apply offset and (possibly) daylight savings time
245 TTimeIntervalHours hours;
247 if (iArgs.iApplyDaylightSavings && Util::DaylightSavingsAppliesL(ntpTime))
249 hours = iArgs.iOffset + 1;
253 hours = iArgs.iOffset;
258 User::LeaveIfError(User::SetHomeTime(ntpTime));
263 /* Timeout handler for read/write operations */
265 CTimeOutTimer::CTimeOutTimer(const TInt aPriority)
270 CTimeOutTimer::~CTimeOutTimer()
275 CTimeOutTimer* CTimeOutTimer::NewL(const TInt aPriority, MTimeOutNotify& aTimeOutNotify)
277 CTimeOutTimer *p = new (ELeave) CTimeOutTimer(aPriority);
278 CleanupStack::PushL(p);
279 p->ConstructL(aTimeOutNotify);
284 void CTimeOutTimer::ConstructL(MTimeOutNotify &aTimeOutNotify)
286 iNotify=&aTimeOutNotify;
287 CTimer::ConstructL();
288 CActiveScheduler::Add(this);
291 void CTimeOutTimer::RunL()
292 // Timer request has completed, so notify the timer's owner
294 iNotify->TimerExpired();