1 /* |
|
2 * Copyright (c) 2007 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: Handles all the Asynchronous operations with the Location |
|
15 * Centre Client Session |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 // SYSTEM INCLUDES |
|
21 #include <s32mem.h> |
|
22 |
|
23 // USER INCLUDES |
|
24 #include "lcasyncoperation.h" |
|
25 #include "lcclientsession.h" |
|
26 #include "lcipcparams.h" |
|
27 #include "lcsyncoperation.h" |
|
28 |
|
29 // CONSTANT DEFINTIONS |
|
30 const TInt KLcLengthofInteger = 4; |
|
31 |
|
32 // ----- Member functions for TLcAppInfoContainer ---------------------------- |
|
33 |
|
34 CLcAsyncOperation::TLcAppInfoContainer::TLcAppInfoContainer( |
|
35 CLcLocationAppInfoArray*& aAppInfoArray ) |
|
36 :iAppInfoArray( aAppInfoArray ) |
|
37 { |
|
38 } |
|
39 |
|
40 // ----- Member funtions for LcSyncOperation --------------------------------- |
|
41 |
|
42 // --------------------------------------------------------------------------- |
|
43 // CLcAsyncOperation::CLcAsyncOperation |
|
44 // --------------------------------------------------------------------------- |
|
45 // |
|
46 CLcAsyncOperation::CLcAsyncOperation( RLcClientSession& aSession, |
|
47 MLcAsynOperationObserver& aObserver ) |
|
48 :CActive( EPriorityStandard ), |
|
49 iClientSession( aSession ), |
|
50 iObserver( aObserver ), |
|
51 iBufferPtr( NULL, 0 ) |
|
52 { |
|
53 CActiveScheduler::Add( this ); |
|
54 } |
|
55 |
|
56 // --------------------------------------------------------------------------- |
|
57 // CLcAsyncOperation::~CLcAsyncOperation |
|
58 // --------------------------------------------------------------------------- |
|
59 // |
|
60 CLcAsyncOperation::~CLcAsyncOperation() |
|
61 { |
|
62 // Cancel any outstanding request. |
|
63 Cancel(); |
|
64 |
|
65 // Delete the filter |
|
66 delete iFilterBuffer; |
|
67 |
|
68 // Delete the Buffer pointer |
|
69 delete iBuffer; |
|
70 |
|
71 // Delete the App Info array container |
|
72 delete iAppInfoArrayContainer; |
|
73 } |
|
74 |
|
75 // --------------------------------------------------------------------------- |
|
76 // CLcAsyncOperation* CLcAsyncOperation::NewL |
|
77 // --------------------------------------------------------------------------- |
|
78 // |
|
79 CLcAsyncOperation* CLcAsyncOperation::NewL( RLcClientSession& aSession, |
|
80 MLcAsynOperationObserver& aObserver ) |
|
81 { |
|
82 CLcAsyncOperation* self = new ( ELeave ) CLcAsyncOperation( aSession, aObserver ); |
|
83 CleanupStack::PushL( self ); |
|
84 self->ConstructL(); |
|
85 CleanupStack::Pop( self ); |
|
86 return self; |
|
87 } |
|
88 |
|
89 // --------------------------------------------------------------------------- |
|
90 // void CLcAsyncOperation::ConstructL |
|
91 // --------------------------------------------------------------------------- |
|
92 // |
|
93 void CLcAsyncOperation::ConstructL() |
|
94 { |
|
95 // Construct the Buffer structure used for exchanging information with the |
|
96 // Location Centre Server. |
|
97 iBuffer = CBufFlat::NewL( KLcLengthofInteger ); |
|
98 } |
|
99 |
|
100 // --------------------------------------------------------------------------- |
|
101 // void CLcAsyncOperation::GetLocationApplicationsL |
|
102 // --------------------------------------------------------------------------- |
|
103 // |
|
104 void CLcAsyncOperation::GetLocationApplicationsL( |
|
105 const TLcLocationAppFilter& aLocationAppFilter, |
|
106 CLcLocationAppInfoArray*& aAppInfoArray ) |
|
107 { |
|
108 // Check if there was any request outstanding. Incase, there was any |
|
109 // request then the request will leave with KErrInUse. |
|
110 if ( IsActive()) |
|
111 { |
|
112 User::Leave( KErrInUse ); |
|
113 } |
|
114 // Copy the Filter parameters to the Filter member variable. |
|
115 iAppFilter = aLocationAppFilter; |
|
116 |
|
117 iFilterBuffer = new ( ELeave ) TPckg< TLcLocationAppFilter >( iAppFilter ); |
|
118 |
|
119 // Hold the Array pointer |
|
120 iAppInfoArrayContainer = new ( ELeave )TLcAppInfoContainer( aAppInfoArray ); |
|
121 |
|
122 // Set the Operation to the Initial state and issue a new request. |
|
123 GetLengthL(); |
|
124 } |
|
125 |
|
126 // --------------------------------------------------------------------------- |
|
127 // void CLcAsyncOperation::CancelGetLocationApplications |
|
128 // --------------------------------------------------------------------------- |
|
129 // |
|
130 void CLcAsyncOperation::CancelGetLocationApplications() |
|
131 { |
|
132 Cancel(); |
|
133 } |
|
134 |
|
135 // --------------------------------------------------------------------------- |
|
136 // void CLcAsyncOperation::ReIssueRequestL |
|
137 // --------------------------------------------------------------------------- |
|
138 // |
|
139 void CLcAsyncOperation::ReIssueRequestL() |
|
140 { |
|
141 // Check if there are any operation outstanding. This request will be valid |
|
142 // only when there are no requests outstanding. |
|
143 if ( ELcNoOperation != iOperation ) |
|
144 { |
|
145 // Rest the State to the initial state and Issue a new request |
|
146 GetLengthL(); |
|
147 } |
|
148 } |
|
149 |
|
150 // --------------------------------------------------------------------------- |
|
151 // void CLcAsyncOperation::GetLengthL |
|
152 // --------------------------------------------------------------------------- |
|
153 // |
|
154 void CLcAsyncOperation::GetLengthL() |
|
155 { |
|
156 if ( !IsActive()) |
|
157 { |
|
158 |
|
159 // Set the size of this buffer to 4. This is required because we dont |
|
160 // actually fill this buffer but expect the server to fill it. In that case |
|
161 // if we dont set the expected length, the server would fail with |
|
162 // KrrBadDescriptor. |
|
163 iBuffer->ResizeL( KLcLengthofInteger ); |
|
164 |
|
165 // Fill the IPC argument structure with the Length buffer, the server |
|
166 // will write the data onto this buffer. |
|
167 |
|
168 // By the IPC exchange parameter defintion, this must be the first |
|
169 // argument to the IPC message. |
|
170 iIpcArgs.Set( 0, iFilterBuffer ); |
|
171 |
|
172 // Set the buffer pointer to the start of the Length buffer |
|
173 iBufferPtr.Set( const_cast< TUint8 *>( iBuffer->Ptr( 0 ).Ptr()), |
|
174 KLcLengthofInteger, |
|
175 KLcLengthofInteger ); |
|
176 |
|
177 // This will be the second argument passed to this IPC message. |
|
178 iIpcArgs.Set( 1, &iBufferPtr); |
|
179 |
|
180 // Send an asynchronous message to the server to obtain the length. On return the |
|
181 // server is expected to pack the length of the Application information |
|
182 // arrays in the LengthBuffer pointer. |
|
183 iClientSession.SendReceive( ELcFilteredAppsBufferLength, |
|
184 iIpcArgs, |
|
185 iStatus ); |
|
186 iOperation = ELcGetAppLength; |
|
187 SetActive(); |
|
188 } |
|
189 } |
|
190 |
|
191 // --------------------------------------------------------------------------- |
|
192 // void CLcAsyncOperation::RunL |
|
193 // --------------------------------------------------------------------------- |
|
194 // |
|
195 void CLcAsyncOperation::RunL() |
|
196 { |
|
197 if( !iStatus.Int()) |
|
198 { |
|
199 switch ( iOperation ) |
|
200 { |
|
201 case ELcGetAppLength: |
|
202 { |
|
203 // The Server has passed the Length of the buffer that is needed to pack |
|
204 // the Location Applications. |
|
205 |
|
206 // If the server has not set the buffer then leave with KErrNotFound |
|
207 if ( !iBufferPtr.Length()) |
|
208 { |
|
209 User::Leave( KErrNotFound ); |
|
210 } |
|
211 |
|
212 // Obtain the length from the Length buffer; |
|
213 RBufReadStream readStream( *iBuffer, 0 ); |
|
214 CleanupClosePushL( readStream ); |
|
215 TUint length = readStream.ReadInt32L(); |
|
216 CleanupStack::PopAndDestroy(); // readStream |
|
217 |
|
218 // If the server has returned a length of 0, then there are no applications |
|
219 // registered with Location Centre. |
|
220 if ( !length ) |
|
221 { |
|
222 User::Leave( KErrNotFound ); |
|
223 } |
|
224 |
|
225 // Set the actual size to 'length' obtained in the previous IPC. This is required |
|
226 // because we dont actually fill this buffer but expect the server to fill it. |
|
227 // In that case if we dont set the expected length, the server would fail with |
|
228 // KrrBadDescriptor. |
|
229 iBuffer->ResizeL( length ); |
|
230 |
|
231 // Fill the IPC argument structure with the Application info buffer, the server |
|
232 // will write the data onto this buffer. |
|
233 TIpcArgs args; |
|
234 |
|
235 // Pass the filter parameters to the Location Centre Server |
|
236 // By the IPC exchange parameter defintion, this must be the first |
|
237 // argument to the IPC message. |
|
238 args.Set( 0, iFilterBuffer ); |
|
239 |
|
240 // Set the buffer pointer to the start of the Length buffer |
|
241 iBufferPtr.Set( const_cast< TUint8 *>( iBuffer->Ptr( 0 ).Ptr()), |
|
242 length, |
|
243 length ); |
|
244 |
|
245 // This will be the second argument passed to this IPC message. |
|
246 args.Set( 1, &iBufferPtr); |
|
247 |
|
248 // Send an Asynchrnous message to the server to obtain the array of Applications. |
|
249 iClientSession.SendReceive( ELcFilteredApps, |
|
250 args, |
|
251 iStatus ); |
|
252 |
|
253 iOperation = ELcGetApp; |
|
254 SetActive(); |
|
255 |
|
256 break; |
|
257 } |
|
258 case ELcGetApp: |
|
259 { |
|
260 // The server has successfully returned the Location based Applications |
|
261 |
|
262 // If the server has not set the buffer then leave with KErrNotFound |
|
263 if ( !iBufferPtr.Length()) |
|
264 { |
|
265 User::Leave( KErrNotFound ); |
|
266 } |
|
267 |
|
268 // Parse the Application information array to obtain the array |
|
269 RBufReadStream appReadStream( *iBuffer, 0 ); |
|
270 CleanupClosePushL( appReadStream ); |
|
271 |
|
272 iAppInfoArrayContainer->iAppInfoArray = |
|
273 LcSyncOperation::ParseLocAppBufferL( appReadStream ); |
|
274 |
|
275 // The App Info array container has been used. We can now free the |
|
276 // memory for the same. |
|
277 delete iAppInfoArrayContainer; |
|
278 iAppInfoArrayContainer = NULL; |
|
279 |
|
280 CleanupStack::PopAndDestroy(); // appReadStream |
|
281 |
|
282 // The request has been successfully processed. |
|
283 iObserver.OperationComplete( KErrNone ); |
|
284 |
|
285 break; |
|
286 } |
|
287 default: |
|
288 { |
|
289 // This condition should never occur |
|
290 break; |
|
291 } |
|
292 } |
|
293 } |
|
294 else |
|
295 { |
|
296 // If the Retrieval function completes with KErrOverflow then there has been |
|
297 // an update to the registry since the time we obtained the length. We need |
|
298 // to re-issue the request to obtain the Length from the application |
|
299 if( iOperation == ELcGetApp && KErrOverflow == iStatus.Int()) |
|
300 { |
|
301 ReIssueRequestL(); |
|
302 } |
|
303 else |
|
304 { |
|
305 // All other condtions terminate |
|
306 |
|
307 // There is nothing to be done to the App Info buffer. Delete it |
|
308 delete iAppInfoArrayContainer; |
|
309 iAppInfoArrayContainer = NULL; |
|
310 |
|
311 // There is an error from the Server side. Hence, complete the request |
|
312 // to the Client Side. |
|
313 iObserver.OperationComplete( iStatus.Int()); |
|
314 } |
|
315 } |
|
316 } |
|
317 |
|
318 // --------------------------------------------------------------------------- |
|
319 // void CLcAsyncOperation::DoCancel |
|
320 // --------------------------------------------------------------------------- |
|
321 // |
|
322 void CLcAsyncOperation::DoCancel() |
|
323 { |
|
324 iClientSession.SendReceive( ELcCancelFilteredApps ); |
|
325 |
|
326 // Clear the App Info array container |
|
327 delete iAppInfoArrayContainer; |
|
328 iAppInfoArrayContainer = NULL; |
|
329 } |
|
330 |
|
331 // --------------------------------------------------------------------------- |
|
332 // TInt CLcAsyncOperation::RunError |
|
333 // --------------------------------------------------------------------------- |
|
334 // |
|
335 TInt CLcAsyncOperation::RunError( TInt aError ) |
|
336 { |
|
337 // Clear the App Info array container |
|
338 delete iAppInfoArrayContainer; |
|
339 iAppInfoArrayContainer = NULL; |
|
340 |
|
341 // The RunL has left with an Error, Notify the Client of the same |
|
342 iObserver.OperationComplete( aError ); |
|
343 return KErrNone; |
|
344 } |
|
345 |
|
346 // End of File |
|