--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/locationcentre/lcservice/src/lcasyncoperation.cpp Tue Feb 02 00:16:03 2010 +0200
@@ -0,0 +1,346 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Handles all the Asynchronous operations with the Location
+* Centre Client Session
+*
+*/
+
+
+// SYSTEM INCLUDES
+#include <s32mem.h>
+
+// USER INCLUDES
+#include "lcasyncoperation.h"
+#include "lcclientsession.h"
+#include "lcipcparams.h"
+#include "lcsyncoperation.h"
+
+// CONSTANT DEFINTIONS
+const TInt KLcLengthofInteger = 4;
+
+// ----- Member functions for TLcAppInfoContainer ----------------------------
+
+CLcAsyncOperation::TLcAppInfoContainer::TLcAppInfoContainer(
+ CLcLocationAppInfoArray*& aAppInfoArray )
+ :iAppInfoArray( aAppInfoArray )
+ {
+ }
+
+// ----- Member funtions for LcSyncOperation ---------------------------------
+
+// ---------------------------------------------------------------------------
+// CLcAsyncOperation::CLcAsyncOperation
+// ---------------------------------------------------------------------------
+//
+CLcAsyncOperation::CLcAsyncOperation( RLcClientSession& aSession,
+ MLcAsynOperationObserver& aObserver )
+ :CActive( EPriorityStandard ),
+ iClientSession( aSession ),
+ iObserver( aObserver ),
+ iBufferPtr( NULL, 0 )
+ {
+ CActiveScheduler::Add( this );
+ }
+
+// ---------------------------------------------------------------------------
+// CLcAsyncOperation::~CLcAsyncOperation
+// ---------------------------------------------------------------------------
+//
+CLcAsyncOperation::~CLcAsyncOperation()
+ {
+ // Cancel any outstanding request.
+ Cancel();
+
+ // Delete the filter
+ delete iFilterBuffer;
+
+ // Delete the Buffer pointer
+ delete iBuffer;
+
+ // Delete the App Info array container
+ delete iAppInfoArrayContainer;
+ }
+
+// ---------------------------------------------------------------------------
+// CLcAsyncOperation* CLcAsyncOperation::NewL
+// ---------------------------------------------------------------------------
+//
+CLcAsyncOperation* CLcAsyncOperation::NewL( RLcClientSession& aSession,
+ MLcAsynOperationObserver& aObserver )
+ {
+ CLcAsyncOperation* self = new ( ELeave ) CLcAsyncOperation( aSession, aObserver );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// void CLcAsyncOperation::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CLcAsyncOperation::ConstructL()
+ {
+ // Construct the Buffer structure used for exchanging information with the
+ // Location Centre Server.
+ iBuffer = CBufFlat::NewL( KLcLengthofInteger );
+ }
+
+// ---------------------------------------------------------------------------
+// void CLcAsyncOperation::GetLocationApplicationsL
+// ---------------------------------------------------------------------------
+//
+void CLcAsyncOperation::GetLocationApplicationsL(
+ const TLcLocationAppFilter& aLocationAppFilter,
+ CLcLocationAppInfoArray*& aAppInfoArray )
+ {
+ // Check if there was any request outstanding. Incase, there was any
+ // request then the request will leave with KErrInUse.
+ if ( IsActive())
+ {
+ User::Leave( KErrInUse );
+ }
+ // Copy the Filter parameters to the Filter member variable.
+ iAppFilter = aLocationAppFilter;
+
+ iFilterBuffer = new ( ELeave ) TPckg< TLcLocationAppFilter >( iAppFilter );
+
+ // Hold the Array pointer
+ iAppInfoArrayContainer = new ( ELeave )TLcAppInfoContainer( aAppInfoArray );
+
+ // Set the Operation to the Initial state and issue a new request.
+ GetLengthL();
+ }
+
+// ---------------------------------------------------------------------------
+// void CLcAsyncOperation::CancelGetLocationApplications
+// ---------------------------------------------------------------------------
+//
+void CLcAsyncOperation::CancelGetLocationApplications()
+ {
+ Cancel();
+ }
+
+// ---------------------------------------------------------------------------
+// void CLcAsyncOperation::ReIssueRequestL
+// ---------------------------------------------------------------------------
+//
+void CLcAsyncOperation::ReIssueRequestL()
+ {
+ // Check if there are any operation outstanding. This request will be valid
+ // only when there are no requests outstanding.
+ if ( ELcNoOperation != iOperation )
+ {
+ // Rest the State to the initial state and Issue a new request
+ GetLengthL();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// void CLcAsyncOperation::GetLengthL
+// ---------------------------------------------------------------------------
+//
+void CLcAsyncOperation::GetLengthL()
+ {
+ if ( !IsActive())
+ {
+
+ // Set the size of this buffer to 4. This is required because we dont
+ // actually fill this buffer but expect the server to fill it. In that case
+ // if we dont set the expected length, the server would fail with
+ // KrrBadDescriptor.
+ iBuffer->ResizeL( KLcLengthofInteger );
+
+ // Fill the IPC argument structure with the Length buffer, the server
+ // will write the data onto this buffer.
+
+ // By the IPC exchange parameter defintion, this must be the first
+ // argument to the IPC message.
+ iIpcArgs.Set( 0, iFilterBuffer );
+
+ // Set the buffer pointer to the start of the Length buffer
+ iBufferPtr.Set( const_cast< TUint8 *>( iBuffer->Ptr( 0 ).Ptr()),
+ KLcLengthofInteger,
+ KLcLengthofInteger );
+
+ // This will be the second argument passed to this IPC message.
+ iIpcArgs.Set( 1, &iBufferPtr);
+
+ // Send an asynchronous message to the server to obtain the length. On return the
+ // server is expected to pack the length of the Application information
+ // arrays in the LengthBuffer pointer.
+ iClientSession.SendReceive( ELcFilteredAppsBufferLength,
+ iIpcArgs,
+ iStatus );
+ iOperation = ELcGetAppLength;
+ SetActive();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// void CLcAsyncOperation::RunL
+// ---------------------------------------------------------------------------
+//
+void CLcAsyncOperation::RunL()
+ {
+ if( !iStatus.Int())
+ {
+ switch ( iOperation )
+ {
+ case ELcGetAppLength:
+ {
+ // The Server has passed the Length of the buffer that is needed to pack
+ // the Location Applications.
+
+ // If the server has not set the buffer then leave with KErrNotFound
+ if ( !iBufferPtr.Length())
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ // Obtain the length from the Length buffer;
+ RBufReadStream readStream( *iBuffer, 0 );
+ CleanupClosePushL( readStream );
+ TUint length = readStream.ReadInt32L();
+ CleanupStack::PopAndDestroy(); // readStream
+
+ // If the server has returned a length of 0, then there are no applications
+ // registered with Location Centre.
+ if ( !length )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ // Set the actual size to 'length' obtained in the previous IPC. This is required
+ // because we dont actually fill this buffer but expect the server to fill it.
+ // In that case if we dont set the expected length, the server would fail with
+ // KrrBadDescriptor.
+ iBuffer->ResizeL( length );
+
+ // Fill the IPC argument structure with the Application info buffer, the server
+ // will write the data onto this buffer.
+ TIpcArgs args;
+
+ // Pass the filter parameters to the Location Centre Server
+ // By the IPC exchange parameter defintion, this must be the first
+ // argument to the IPC message.
+ args.Set( 0, iFilterBuffer );
+
+ // Set the buffer pointer to the start of the Length buffer
+ iBufferPtr.Set( const_cast< TUint8 *>( iBuffer->Ptr( 0 ).Ptr()),
+ length,
+ length );
+
+ // This will be the second argument passed to this IPC message.
+ args.Set( 1, &iBufferPtr);
+
+ // Send an Asynchrnous message to the server to obtain the array of Applications.
+ iClientSession.SendReceive( ELcFilteredApps,
+ args,
+ iStatus );
+
+ iOperation = ELcGetApp;
+ SetActive();
+
+ break;
+ }
+ case ELcGetApp:
+ {
+ // The server has successfully returned the Location based Applications
+
+ // If the server has not set the buffer then leave with KErrNotFound
+ if ( !iBufferPtr.Length())
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ // Parse the Application information array to obtain the array
+ RBufReadStream appReadStream( *iBuffer, 0 );
+ CleanupClosePushL( appReadStream );
+
+ iAppInfoArrayContainer->iAppInfoArray =
+ LcSyncOperation::ParseLocAppBufferL( appReadStream );
+
+ // The App Info array container has been used. We can now free the
+ // memory for the same.
+ delete iAppInfoArrayContainer;
+ iAppInfoArrayContainer = NULL;
+
+ CleanupStack::PopAndDestroy(); // appReadStream
+
+ // The request has been successfully processed.
+ iObserver.OperationComplete( KErrNone );
+
+ break;
+ }
+ default:
+ {
+ // This condition should never occur
+ break;
+ }
+ }
+ }
+ else
+ {
+ // If the Retrieval function completes with KErrOverflow then there has been
+ // an update to the registry since the time we obtained the length. We need
+ // to re-issue the request to obtain the Length from the application
+ if( iOperation == ELcGetApp && KErrOverflow == iStatus.Int())
+ {
+ ReIssueRequestL();
+ }
+ else
+ {
+ // All other condtions terminate
+
+ // There is nothing to be done to the App Info buffer. Delete it
+ delete iAppInfoArrayContainer;
+ iAppInfoArrayContainer = NULL;
+
+ // There is an error from the Server side. Hence, complete the request
+ // to the Client Side.
+ iObserver.OperationComplete( iStatus.Int());
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// void CLcAsyncOperation::DoCancel
+// ---------------------------------------------------------------------------
+//
+void CLcAsyncOperation::DoCancel()
+ {
+ iClientSession.SendReceive( ELcCancelFilteredApps );
+
+ // Clear the App Info array container
+ delete iAppInfoArrayContainer;
+ iAppInfoArrayContainer = NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// TInt CLcAsyncOperation::RunError
+// ---------------------------------------------------------------------------
+//
+TInt CLcAsyncOperation::RunError( TInt aError )
+ {
+ // Clear the App Info array container
+ delete iAppInfoArrayContainer;
+ iAppInfoArrayContainer = NULL;
+
+ // The RunL has left with an Error, Notify the Client of the same
+ iObserver.OperationComplete( aError );
+ return KErrNone;
+ }
+
+// End of File