locationcentre/lcservice/src/lcasyncoperation.cpp
branchRCL_3
changeset 16 4721bd00d3da
parent 14 3a25f69541ff
child 21 e15b7f06eba6
equal deleted inserted replaced
14:3a25f69541ff 16:4721bd00d3da
     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