|
1 /* |
|
2 * Copyright (c) 2006-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 |
|
23 #include "testEPos_CPosLastKnownPosAreaHandler.h" |
|
24 #include "EPos_CPosCallbackTimer.h" |
|
25 |
|
26 |
|
27 // CONSTANTS |
|
28 #ifdef _DEBUG |
|
29 _LIT(KTraceFileName, "testEPos_CPosLastKnownPosAreaHandler.cpp"); |
|
30 #endif |
|
31 |
|
32 |
|
33 CPosLastKnownPosAreaHandler* CPosLastKnownPosAreaHandler::NewL() |
|
34 { |
|
35 CPosLastKnownPosAreaHandler* self = new( ELeave ) CPosLastKnownPosAreaHandler(); |
|
36 CleanupStack::PushL( self ); |
|
37 self->ConstructL(); |
|
38 CleanupStack::Pop( self ); |
|
39 return self; |
|
40 } |
|
41 |
|
42 CPosLastKnownPosAreaHandler::CPosLastKnownPosAreaHandler() |
|
43 { |
|
44 CActiveScheduler::Add(this); |
|
45 } |
|
46 |
|
47 void CPosLastKnownPosAreaHandler::ConstructL() |
|
48 { |
|
49 TCallBack timeoutCallBack(HandleTimeOut, this); |
|
50 iTimeoutTimer = CPosCallbackTimer::NewL(timeoutCallBack); |
|
51 } |
|
52 |
|
53 CPosLastKnownPosAreaHandler::~CPosLastKnownPosAreaHandler() |
|
54 { |
|
55 |
|
56 if (iStatus==KRequestPending) |
|
57 { |
|
58 // Cancel the request sent to the location monitor |
|
59 Cancel(); |
|
60 } |
|
61 |
|
62 if ( iLocMonAreaPositioner.SubSessionHandle() ) |
|
63 { |
|
64 iLocMonAreaPositioner.Close(); |
|
65 } |
|
66 |
|
67 delete iTimeoutTimer; |
|
68 |
|
69 // The requests on the queue are completed by the base class destructor |
|
70 } |
|
71 |
|
72 void CPosLastKnownPosAreaHandler::GetLastKnownPosAreaL(RLbsLocMonitorSession& aLocMonSession, const RMessage2& aMessage) |
|
73 { |
|
74 DEBUG_TRACE("CPosLastKnownPosAreaHandler::GetLastKnownPosAreaL", __LINE__) |
|
75 |
|
76 if ( !(aLocMonSession.Handle())) |
|
77 { |
|
78 // Session with the location monitor is not found |
|
79 RequestComplete(aMessage, KErrCouldNotConnect); |
|
80 return; |
|
81 } |
|
82 |
|
83 if (!(iLocMonAreaPositioner.SubSessionHandle())) |
|
84 { |
|
85 TInt err = iLocMonAreaPositioner.OpenL(aLocMonSession); |
|
86 if (err != KErrNone) |
|
87 { |
|
88 RequestComplete(aMessage, err); |
|
89 return; |
|
90 } |
|
91 } |
|
92 |
|
93 // Copy the buffers from the address space of the client |
|
94 HBufC8* lkposclientbuf = Global::CopyClientBuffer8LC(aMessage, KParamLKPAreaReqPos); |
|
95 HBufC8* lkposareaclientbuf = Global::CopyClientBuffer8LC(aMessage, KParamLKPAreaReqArea); |
|
96 |
|
97 TPositionInfoBase& posInfoBase = reinterpret_cast<TPositionInfoBase&> |
|
98 (const_cast<TUint8&>(*lkposclientbuf->Ptr())); |
|
99 TPositionAreaInfoBase& posAreaInfoBase = reinterpret_cast<TPositionAreaInfoBase&> |
|
100 (const_cast<TUint8&>(*lkposareaclientbuf->Ptr())); |
|
101 |
|
102 Global::ValidatePositionClassBufferL(posInfoBase, lkposclientbuf->Des()); |
|
103 Global::ValidatePositionClassTypeL(posInfoBase, EPositionInfoClass, KErrArgument); |
|
104 Global::ValidatePositionClassBufferL(posAreaInfoBase, lkposareaclientbuf->Des()); |
|
105 |
|
106 switch (posAreaInfoBase.PositionClassType()) |
|
107 { |
|
108 case EPositionAreaInfoClass: |
|
109 Global::ValidatePositionClassTypeL(posAreaInfoBase, EPositionAreaInfoClass, KErrArgument); |
|
110 break; |
|
111 case (EPositionAreaExtendedInfoClass+EPositionAreaInfoClass): //TODO Check LbsAreaInfo.cpp [constructor] |
|
112 Global::ValidatePositionClassTypeL(posAreaInfoBase, (EPositionAreaExtendedInfoClass+EPositionAreaInfoClass), KErrArgument); |
|
113 break; |
|
114 default: |
|
115 User::Leave(KErrArgument); //TODO - Check if this is correct ? |
|
116 break; |
|
117 } |
|
118 |
|
119 CleanupStack::PopAndDestroy(lkposareaclientbuf); |
|
120 CleanupStack::PopAndDestroy(lkposclientbuf); |
|
121 |
|
122 // Check the identity of the subsession and add the request to the queue |
|
123 CheckAndAddReqToQueueL(EReqOnSubSession, aMessage); |
|
124 |
|
125 if ((iLocMonitorReqQ.Count()>0) && !(this->iStatus==KRequestPending) ) |
|
126 { |
|
127 TPosAreaReqParams aParameters; |
|
128 // Always ask for extended information from the location monitor |
|
129 // as initiating a new request for clients that require extended information |
|
130 // is inefficient |
|
131 aParameters.iPositionAreaType = (EPositionAreaExtendedInfoClass+EPositionAreaInfoClass); |
|
132 |
|
133 // Initiate a new last known position request with the location monitor |
|
134 iLocMonAreaPositioner.GetLastKnownPositionArea(iPositionInfo, iPositionAreaInfo, aParameters, iStatus); |
|
135 SetActive(); |
|
136 |
|
137 // Start timer if necessary |
|
138 if (KLastKnownPosAreaTimeOut.Int64()>0) |
|
139 { |
|
140 DEBUG_TRACE("CPosLastKnownPosHandler::GetLastKnownPosAreaL() Start Timeout Timer", __LINE__) |
|
141 iTimeoutTimer->StartTimer(KLastKnownPosAreaTimeOut); |
|
142 } |
|
143 } |
|
144 |
|
145 } |
|
146 |
|
147 void CPosLastKnownPosAreaHandler::CancelGetLastKnownPosAreaL(const RMessage2& aMessage) |
|
148 { |
|
149 DEBUG_TRACE("CPosLastKnownPosAreaHandler::CancelGetLastKnownPosAreaL", __LINE__) |
|
150 |
|
151 // The subsession with the location monitor is not found |
|
152 if ( !(iLocMonAreaPositioner.SubSessionHandle()) ) |
|
153 { |
|
154 RequestComplete(aMessage, KErrCouldNotConnect); //TODO - KErrCouldNotConnect ? |
|
155 return; |
|
156 } |
|
157 |
|
158 // Call CancelRequest inherited from the baseclass |
|
159 CancelRequest(EReqOnSubSession, aMessage); |
|
160 |
|
161 } |
|
162 |
|
163 |
|
164 void CPosLastKnownPosAreaHandler::NotifyOnEmptyLastKnownPosStoreReq() |
|
165 { |
|
166 // Complete all the requests on the queue with KErrCancel |
|
167 QRequestsComplete(KErrCancel); |
|
168 |
|
169 if (iStatus==KRequestPending) |
|
170 { |
|
171 Cancel(); |
|
172 } |
|
173 } |
|
174 |
|
175 void CPosLastKnownPosAreaHandler::RunL() |
|
176 { |
|
177 |
|
178 // Cancel the timeout timer |
|
179 iTimeoutTimer->Cancel(); |
|
180 |
|
181 // Serving all the outstanding requests based on the current update |
|
182 // from the Location Monitor |
|
183 while (iLocMonitorReqQ.Count()>0) |
|
184 { |
|
185 TInt numReqs = iLocMonitorReqQ.Count()-1; |
|
186 // Retrieve the next request to be serviced [first element in the queue - FIFO] |
|
187 if (iStatus.Int()==KErrNone) |
|
188 { |
|
189 // Copy the buffers from the address space of the client |
|
190 const TUint8* startAddress = reinterpret_cast <const TUint8*>(&iPositionInfo)+sizeof(TPositionClassTypeBase); |
|
191 TInt chunkSize = sizeof(TPositionInfo)-sizeof(TPositionClassTypeBase); |
|
192 TPtr8 copyFromDesc(const_cast<TUint8*>(startAddress),chunkSize,chunkSize); |
|
193 |
|
194 TInt err = Global::Write(iLocMonitorReqQ[numReqs],KParamLKPAreaReqPos,copyFromDesc,sizeof(TPositionClassTypeBase)); |
|
195 //TInt err = iLocMonitorReqQ[numReqs].Write(KParamLKPAreaReqPos,copyFromDesc,sizeof(TPositionClassTypeBase)); |
|
196 |
|
197 // To identify the type of the request - last known position area / last known position area + extended info. |
|
198 HBufC8* lkposareaclientbuf = Global::CopyClientBuffer8LC(iLocMonitorReqQ[numReqs], KParamLKPAreaReqArea); |
|
199 TPositionAreaInfoBase& posAreaInfoBase = reinterpret_cast<TPositionAreaInfoBase&>(const_cast<TUint8&>(*lkposareaclientbuf->Ptr())); |
|
200 startAddress = reinterpret_cast <const TUint8*>(&iPositionAreaInfo)+sizeof(TPositionClassTypeBase); |
|
201 |
|
202 switch (posAreaInfoBase.PositionClassType()) |
|
203 { |
|
204 case EPositionAreaInfoClass: |
|
205 chunkSize = sizeof(TPositionAreaInfo)-sizeof(TPositionClassTypeBase); |
|
206 copyFromDesc.Set(const_cast<TUint8*>(startAddress),chunkSize,chunkSize); |
|
207 //err = iLocMonitorReqQ[numReqs].Write(KParamLKPAreaReqArea,copyFromDesc,sizeof(TPositionClassTypeBase)); |
|
208 err = Global::Write(iLocMonitorReqQ[numReqs],KParamLKPAreaReqArea,copyFromDesc,sizeof(TPositionClassTypeBase)); |
|
209 RequestComplete(iLocMonitorReqQ[numReqs], err); |
|
210 break; |
|
211 case (EPositionAreaExtendedInfoClass+EPositionAreaInfoClass): //TODO Check LbsAreaInfo.cpp [constructor] |
|
212 chunkSize = sizeof(TPositionAreaExtendedInfo)-sizeof(TPositionClassTypeBase); |
|
213 copyFromDesc.Set(const_cast<TUint8*>(startAddress),chunkSize,chunkSize); |
|
214 err = Global::Write(iLocMonitorReqQ[numReqs],KParamLKPAreaReqArea,copyFromDesc,sizeof(TPositionClassTypeBase)); |
|
215 //err = iLocMonitorReqQ[numReqs].Write(KParamLKPAreaReqArea,copyFromDesc,sizeof(TPositionClassTypeBase)); |
|
216 RequestComplete(iLocMonitorReqQ[numReqs], err); |
|
217 break; |
|
218 default: |
|
219 RequestComplete(iLocMonitorReqQ[numReqs], KErrArgument); //TODO - Check if this is correct ? |
|
220 break; |
|
221 } |
|
222 // Destroy the buffer used to hold the client's data |
|
223 CleanupStack::PopAndDestroy(lkposareaclientbuf); |
|
224 |
|
225 } |
|
226 else |
|
227 { |
|
228 // Complete the client request with aReason |
|
229 RequestComplete(iLocMonitorReqQ[numReqs],iStatus.Int()); |
|
230 } |
|
231 |
|
232 // Remove the request that has just been serviced [last element] |
|
233 iLocMonitorReqQ.Remove(numReqs); |
|
234 } |
|
235 |
|
236 // Close the subsession with the location monitor when we receive the last known position area from it |
|
237 iLocMonAreaPositioner.Close(); |
|
238 |
|
239 } |
|
240 |
|
241 TInt CPosLastKnownPosAreaHandler::RunError(TInt aError) |
|
242 { |
|
243 return aError; |
|
244 } |
|
245 |
|
246 void CPosLastKnownPosAreaHandler::DoCancel() |
|
247 { |
|
248 // Cancel the timer as the request with the location monitor is going to be cancelled |
|
249 iTimeoutTimer->Cancel(); |
|
250 |
|
251 DEBUG_TRACE("calling RLbsAreaPositioner::CancelGetLastKnownPosition()", __LINE__) |
|
252 __ASSERT_DEBUG((iLocMonAreaPositioner.SubSessionHandle())!=NULL, DebugPanic(EPosServerPanicPositionerNotInitialized)); |
|
253 |
|
254 TInt err = iLocMonAreaPositioner.CancelGetLastKnownPositionArea(); |
|
255 // As the cancel request is immediately completed, this return value |
|
256 // is not useful. |
|
257 } |
|
258 |
|
259 TInt CPosLastKnownPosAreaHandler::HandleTimeOut(TAny* aRequestHandler) |
|
260 { |
|
261 |
|
262 DEBUG_TRACE("CPosLastKnownPosAreaHandler::HandleTimeOut()", __LINE__) |
|
263 |
|
264 CPosLastKnownPosAreaHandler* self = reinterpret_cast<CPosLastKnownPosAreaHandler*>(aRequestHandler); |
|
265 // The request with the location monitor has timed out. So complete all the outstanding |
|
266 // requests with KErrTimedOut |
|
267 self->QRequestsComplete(KErrTimedOut); |
|
268 // Cancel the pending request with the location monitor |
|
269 self->Cancel(); |
|
270 |
|
271 return KErrNone; |
|
272 |
|
273 } |
|
274 |