|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "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". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: This class inherits the common functionalities for requests to the |
|
15 * Location Monitor from EPos_CPosLocMonitorReqHandlerBase.h and also |
|
16 * implements the functions specific to Last Known Position request. |
|
17 * |
|
18 */ |
|
19 |
|
20 |
|
21 |
|
22 #include "EPos_CPosLastKnownPosHandler.h" |
|
23 #include "EPos_CPosCallbackTimer.h" |
|
24 |
|
25 // ============================ CONSTANTS =========================================================== |
|
26 #ifdef _DEBUG |
|
27 _LIT(KTraceFileName, "EPos_CPosLastKnownPosHandler.cpp"); |
|
28 #endif |
|
29 |
|
30 // ============================== MEMBER FUNCTIONS =================================================== |
|
31 CPosLastKnownPosHandler* CPosLastKnownPosHandler::NewL() |
|
32 { |
|
33 CPosLastKnownPosHandler* self = new( ELeave ) CPosLastKnownPosHandler(); |
|
34 CleanupStack::PushL( self ); |
|
35 self->ConstructL(); |
|
36 CleanupStack::Pop( self ); |
|
37 return self; |
|
38 } |
|
39 |
|
40 CPosLastKnownPosHandler::CPosLastKnownPosHandler() |
|
41 { |
|
42 CActiveScheduler::Add(this); |
|
43 } |
|
44 |
|
45 void CPosLastKnownPosHandler::ConstructL() |
|
46 { |
|
47 TCallBack timeoutCallBack(HandleTimeOut, this); |
|
48 iTimeoutTimer = CPosCallbackTimer::NewL(timeoutCallBack); |
|
49 } |
|
50 |
|
51 CPosLastKnownPosHandler::~CPosLastKnownPosHandler() |
|
52 { |
|
53 |
|
54 if (iStatus==KRequestPending) |
|
55 { |
|
56 // Cancel the request sent to the location monitor |
|
57 Cancel(); |
|
58 } |
|
59 |
|
60 if (iLocMonPositioner.SubSessionHandle()) |
|
61 { |
|
62 iLocMonPositioner.Close(); |
|
63 } |
|
64 |
|
65 delete iTimeoutTimer; |
|
66 |
|
67 // The requests on the queue are completed by the base class destructor |
|
68 } |
|
69 |
|
70 /** |
|
71 * GetLastKnownPosL |
|
72 * >> Initiate a new request with the location monitor if the request queue is empty. |
|
73 * Otherwise, check if the session and subsession id of any request on the queue matches that of the |
|
74 * new request [ie. a duplicate request from the client]. If it matches panic the client. |
|
75 * If not add the new request to the queue. |
|
76 * |
|
77 * @param aLocMonSession - The handle to the session with the location monitor passed on from |
|
78 * CPosLocMonitorReqHandlerHub. |
|
79 * @param aMessage - The new request from the client |
|
80 */ |
|
81 void CPosLastKnownPosHandler::GetLastKnownPosL(RLbsLocMonitorSession& aLocMonSession, const RMessage2& aMessage) |
|
82 { |
|
83 DEBUG_TRACE("CPosLastKnownPosHandler::RequestPosL", __LINE__) |
|
84 |
|
85 if ( !(aLocMonSession.Handle()) ) |
|
86 { |
|
87 // Session with the location monitor is not found |
|
88 RequestComplete(aMessage, KErrCouldNotConnect); |
|
89 return; |
|
90 } |
|
91 |
|
92 if ( !(iLocMonPositioner.SubSessionHandle()) ) |
|
93 { |
|
94 iLocMonPositioner.OpenL(aLocMonSession); |
|
95 } |
|
96 |
|
97 CheckAndAddReqToQueueL(EReqOnSubSession, aMessage); |
|
98 |
|
99 if ((iLocMonitorReqQ.Count()>0) && !IsActive()) |
|
100 { |
|
101 // Initiate a new last known position request with the location monitor |
|
102 iLocMonPositioner.GetLastKnownPosition(iPositionInfo, iStatus); |
|
103 SetActive(); |
|
104 |
|
105 // Start timer if necessary |
|
106 if (KLastKnownPosTimeOut.Int64()>0) |
|
107 { |
|
108 DEBUG_TRACE("CPosLastKnownPosHandler::GetLastKnownPosL() Start Timeout Timer", __LINE__) |
|
109 iTimeoutTimer->StartTimer(KLastKnownPosTimeOut); |
|
110 } |
|
111 } |
|
112 |
|
113 } |
|
114 |
|
115 /** |
|
116 * CancelGetLastKnownPosL |
|
117 * >> Cancel the outstanding request with the location monitor if there is only one request on the queue. |
|
118 * >> Otherwise just complete the cancel request with KErrNone, remove the original request from the queue |
|
119 * and complete it with KErrCancel. |
|
120 * @param aMessage - The cancel request from the client |
|
121 */ |
|
122 void CPosLastKnownPosHandler::CancelGetLastKnownPosL(const RMessage2& aMessage) |
|
123 { |
|
124 DEBUG_TRACE("CPosLastKnownPosHandler::CancelGetLastKnownPosL", __LINE__) |
|
125 |
|
126 |
|
127 if ( iLocMonPositioner.SubSessionHandle() ) |
|
128 { |
|
129 // Call CancelRequest inherited from the baseclass |
|
130 CancelRequest(EReqOnSubSession, aMessage); |
|
131 } |
|
132 else |
|
133 { |
|
134 // The subsession with the location monitor is not found |
|
135 RequestComplete(aMessage, KErrCouldNotConnect); //TODO - KErrCouldNotConnect ? |
|
136 } |
|
137 } |
|
138 |
|
139 |
|
140 /** |
|
141 * RunL |
|
142 * >> Complete all the requests on the queue. |
|
143 */ |
|
144 void CPosLastKnownPosHandler::RunL() |
|
145 { |
|
146 |
|
147 // Cancel the timeout timer |
|
148 iTimeoutTimer->Cancel(); |
|
149 |
|
150 // Serving all the outstanding requests based on the current update |
|
151 // from the Location Monitor |
|
152 while (iLocMonitorReqQ.Count()>0) |
|
153 { |
|
154 // Retrieve the next request to be serviced |
|
155 TInt numReqs = iLocMonitorReqQ.Count()-1; |
|
156 |
|
157 if (iStatus.Int()==KErrNone) |
|
158 { |
|
159 // |TPositionClassTypeBase|TPositionInfoBase|TPositionInfo|... |
|
160 // No matter what the type of the class derived from TPositionInfo, the location monitor |
|
161 // just returns TPositionInfo and we write only the part |TPositionInfoBase|TPositionInfo| |
|
162 // skipping the TPositionClassTypeBase as it contains the position class type and size |
|
163 // that should not be corrupted. |
|
164 |
|
165 const TUint8* startAddress = reinterpret_cast <const TUint8*>(&iPositionInfo)+sizeof(TPositionClassTypeBase); |
|
166 TInt chunkSize = sizeof(TPositionInfo)-sizeof(TPositionClassTypeBase); |
|
167 TPtr8 copyFromDesc(const_cast<TUint8*>(startAddress),chunkSize,chunkSize); |
|
168 |
|
169 TInt err = iLocMonitorReqQ[numReqs].Write(0,copyFromDesc,sizeof(TPositionClassTypeBase)); |
|
170 RequestComplete(iLocMonitorReqQ[numReqs], err); |
|
171 |
|
172 } |
|
173 else |
|
174 { |
|
175 // Complete the client request with aReason |
|
176 RequestComplete(iLocMonitorReqQ[numReqs],iStatus.Int()); |
|
177 } |
|
178 |
|
179 // Remove the request that has just been serviced [last element] |
|
180 iLocMonitorReqQ.Remove(numReqs); |
|
181 } |
|
182 |
|
183 |
|
184 // Close the subsession with the location monitor when we receive the last known position from it |
|
185 iLocMonPositioner.Close(); |
|
186 } |
|
187 |
|
188 TInt CPosLastKnownPosHandler::RunError(TInt aError) |
|
189 { |
|
190 return aError; |
|
191 } |
|
192 |
|
193 |
|
194 /** |
|
195 * DoCancel |
|
196 * >> Cancel the active object. |
|
197 */ |
|
198 void CPosLastKnownPosHandler::DoCancel() |
|
199 { |
|
200 __ASSERT_DEBUG((iLocMonPositioner.SubSessionHandle())!=NULL, DebugPanic(EPosServerPanicPositionerNotInitialized)); |
|
201 |
|
202 // Cancel the timer as the request with the location monitor is going to be cancelled |
|
203 iTimeoutTimer->Cancel(); |
|
204 |
|
205 DEBUG_TRACE("calling RLbsAreaPositioner::CancelGetLastKnownPosition()", __LINE__) |
|
206 TInt err = iLocMonPositioner.CancelGetLastKnownPosition(); |
|
207 // As the cancel request is immediately completed, this return value |
|
208 // is not useful. |
|
209 } |
|
210 |
|
211 /** |
|
212 * NotifyOnEmptyLastKnownPosStoreReq |
|
213 * >> Cancel the outstanding get last known position area requests with KErrCancel |
|
214 * >> as an empty last known position store request has been issued. |
|
215 */ |
|
216 void CPosLastKnownPosHandler::NotifyOnEmptyLastKnownPosStoreReq() |
|
217 { |
|
218 // Complete all the requests on the queue with KErrCancel |
|
219 QRequestsComplete(KErrCancel); |
|
220 |
|
221 if (iStatus==KRequestPending) |
|
222 { |
|
223 Cancel(); |
|
224 } |
|
225 } |
|
226 |
|
227 /** |
|
228 * HandleTimeOut |
|
229 * >> Complete all the requests on the queue with KErrTimedOut. |
|
230 * @param aRequestHandler - self pointer used to call the appropriate timeout handling method |
|
231 */ |
|
232 TInt CPosLastKnownPosHandler::HandleTimeOut(TAny* aRequestHandler) |
|
233 { |
|
234 |
|
235 DEBUG_TRACE("CPosLastKnownPosHandler::HandleTimeOut()", __LINE__) |
|
236 |
|
237 CPosLastKnownPosHandler* self = reinterpret_cast<CPosLastKnownPosHandler*>(aRequestHandler); |
|
238 // The request with the location monitor has timed out. So complete all the outstanding |
|
239 // requests with KErrTimedOut |
|
240 self->QRequestsComplete(KErrTimedOut); |
|
241 // Cancel the pending request with the location monitor |
|
242 self->Cancel(); |
|
243 |
|
244 return KErrNone; |
|
245 |
|
246 } |
|
247 |
|
248 |