genericservices/activebackupclient/src/abachandler.cpp
changeset 0 e4d67989cc36
child 44 97b0fb8a2cc2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/genericservices/activebackupclient/src/abachandler.cpp	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,346 @@
+// Copyright (c) 2004-2009 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:
+// Implementation of CActiveBackupClient class.
+// 
+//
+
+/**
+ @file
+*/
+
+#include "abachandler.h"
+#include "abclientsession.h"
+#include "panic.h"
+
+namespace conn
+	{
+	CActiveBackupCallbackHandler* CActiveBackupCallbackHandler::NewL(MActiveBackupDataClient* aABDC,
+		RABClientSession& aClientSession)
+	/**
+	Symbian first phase constructor
+	@param aABDC pointer to the client's callback implementation
+	@param aClientSession reference to the client's session
+	@return Pointer to a created CActiveBackupCallbackHandler object
+	*/
+		{
+		CActiveBackupCallbackHandler* self = new (ELeave) CActiveBackupCallbackHandler(aABDC, aClientSession);
+		CleanupStack::PushL(self);
+		self->ConstructL();
+		CleanupStack::Pop(self);
+		return self;
+		}
+	
+	CActiveBackupCallbackHandler::CActiveBackupCallbackHandler(MActiveBackupDataClient* aABDC,
+		RABClientSession& aClientSession) : CActive(EPriorityNormal), iActiveBackupDataClient(aABDC), 
+		iClientSession(aClientSession), iTransferBuffer(NULL)
+	/**
+	C++ Constructor
+	@param aABDC pointer to the client's callback implementation
+	@param aClientSession reference to the client's session
+	@panic KErrArgument if the pointer aABDC is NULL
+	*/
+		{
+		__ASSERT_DEBUG(aABDC, Panic(KErrArgument));
+		}
+
+	CActiveBackupCallbackHandler::~CActiveBackupCallbackHandler()
+	/**
+	C++ Destructor
+	*/
+		{
+		// Cancel any outstanding Async requests (i.e. close down the callback interface)
+		Cancel();
+		delete iTransferBuffer;
+		}
+		
+	void CActiveBackupCallbackHandler::RunL()
+	/**
+	Handle messages "initiated" by the server. Because of IPC limitations, the client primes the 
+	server with a message containing modifiable package buffers that are filled with identifiers 
+	and arguments for the callback interface
+	*/
+		{
+		if (iStatus == KErrNone)
+			{
+			switch(iCallbackCommand())
+				{
+				case EABCallbackAllSnapshotsSupplied:
+					{
+  					iActiveBackupDataClient->AllSnapshotsSuppliedL();
+				
+					PrimeServerForCallbackL();
+					} break;
+				case EABCallbackReceiveSnapshotData:
+					{
+					TDriveNumber driveNum = EDriveC;		// Initialise to keep the compiler happy
+
+					HBufC8* pReceivedData = iClientSession.GetDataFromServerLC(iCallbackArg1(),
+						EABCallbackReceiveSnapshotData, driveNum);
+						
+					// Call the client method for handling receipt of the snapshot
+					iActiveBackupDataClient->ReceiveSnapshotDataL(driveNum, 
+						*pReceivedData, static_cast<TBool>(iCallbackArg2()));
+						
+					// Reprime the server
+					PrimeServerForCallbackL();
+					
+					CleanupStack::PopAndDestroy(pReceivedData);
+					} break;
+				case EABCallbackGetExpectedDataSize:
+					{
+					TUint dataSize = iActiveBackupDataClient->GetExpectedDataSize(static_cast<TDriveNumber>(iCallbackArg1()));
+					
+					// Reprime the server
+					PrimeServerForCallbackWithResponseL(dataSize);
+					} break;
+				case EABCallbackGetSnapshotData:
+					{
+					// Create an empty TPtr8 to point at the buffer to fill
+					TPtr8 bufferToSend(CreateFixedBufferL());
+					
+					TBool finished = ETrue;
+					
+					// Zero our descriptor so that it can be refilled
+					bufferToSend.Zero();
+					
+					// Callback the AB client to populate our descriptor
+					iActiveBackupDataClient->GetSnapshotDataL(static_cast<TDriveNumber>(iCallbackArg1()), 
+						bufferToSend, finished);
+					
+					// Send the length and some other info to the server to allow it to prepare for the actual transfer
+					iClientSession.SendDataLengthToServerL(bufferToSend, finished, EABCallbackGetSnapshotData);
+					
+					iTransferBuffer->Des().SetLength(bufferToSend.Length());
+					
+					// Send the actual data back to the server and prime for the next callback
+					PrimeServerForCallbackWithResponseL(*iTransferBuffer);
+					} break;
+				case EABCallbackInitialiseGetBackupData:
+					{
+					iActiveBackupDataClient->InitialiseGetBackupDataL(static_cast<TDriveNumber>(iCallbackArg1()));
+
+					// Reprime the server
+					PrimeServerForCallbackL();
+					} break;
+				case EABCallbackGetBackupDataSection:
+					{
+					// Create an empty TPtr8 to point at the buffer to fill
+					TPtr8 bufferToSend(CreateFixedBufferL());
+					
+					TBool finished = ETrue;
+
+					// Zero our descriptor so that it can be refilled
+					bufferToSend.Zero();
+					
+					// Callback the AB client to populate our descriptor
+					iActiveBackupDataClient->GetBackupDataSectionL(bufferToSend, finished);
+					
+					// Send the length and some other info to the server to allow it to prepare for the actual transfer
+					iClientSession.SendDataLengthToServerL(bufferToSend, finished, EABCallbackGetBackupDataSection);
+					
+					iTransferBuffer->Des().SetLength(bufferToSend.Length());
+					
+					// Send the actual data back to the server and prime for the next callback
+					PrimeServerForCallbackWithResponseL(*iTransferBuffer);
+					} break;
+				case EABCallbackInitialiseRestoreBaseDataSection:
+					{
+					iActiveBackupDataClient->InitialiseRestoreBaseDataL(static_cast<TDriveNumber>(iCallbackArg1()));
+
+					// Reprime the server
+					PrimeServerForCallbackL();
+					} break;
+				case EABCallbackRestoreBaseDataSection:
+					{
+					HBufC8* pReceivedData = iClientSession.GetDataFromServerLC(iCallbackArg1(),
+						EABCallbackRestoreBaseDataSection);
+					
+					// Call the client method for handling receipt of the snapshot
+					iActiveBackupDataClient->RestoreBaseDataSectionL(*pReceivedData, 
+						static_cast<TBool>(iCallbackArg2()));
+						
+					// Reprime the server
+					PrimeServerForCallbackL();
+					
+					CleanupStack::PopAndDestroy(pReceivedData);
+					} break;
+				case EABCallbackInitialiseRestoreIncrementData:
+					{
+					iActiveBackupDataClient->InitialiseRestoreIncrementDataL(static_cast<TDriveNumber>(iCallbackArg1()));
+
+					// Reprime the server
+					PrimeServerForCallbackL();
+					} break;
+				case EABCallbackRestoreIncrementDataSection:
+					{
+					HBufC8* pReceivedData = iClientSession.GetDataFromServerLC(iCallbackArg1(),
+						EABCallbackRestoreIncrementDataSection);
+					
+					// Call the client method for handling receipt of the snapshot
+					iActiveBackupDataClient->RestoreIncrementDataSectionL(*pReceivedData, 
+						static_cast<TBool>(iCallbackArg2()));
+						
+					// Reprime the server
+					PrimeServerForCallbackL();
+					
+					CleanupStack::PopAndDestroy(pReceivedData);
+					} break;
+				case EABCallbackRestoreComplete:
+					{
+					iActiveBackupDataClient->RestoreComplete(static_cast<TDriveNumber>(iCallbackArg1()));
+
+					// Reprime the server
+					PrimeServerForCallbackL();
+					} break;
+				case EABCallbackTerminateMultiStageOperation:
+					{
+					iActiveBackupDataClient->TerminateMultiStageOperation();
+
+					// Reprime the server
+					PrimeServerForCallbackL();
+					} break;
+				case EABCallbackGetDataChecksum:
+					{
+					iActiveBackupDataClient->GetDataChecksum(static_cast<TDriveNumber>(iCallbackArg1()));
+
+					// Reprime the server
+					PrimeServerForCallbackL();
+					} break;
+				case EABCallbackInitialiseGetProxyBackupData:
+					{
+					iActiveBackupDataClient->InitialiseGetProxyBackupDataL(static_cast<TSecureId>(iCallbackArg1()),
+						static_cast<TDriveNumber>(iCallbackArg2()));
+					
+					// Reprime the server
+					PrimeServerForCallbackL();
+					} break;
+				case EABCallbackInitialiseRestoreProxyBaseData:
+					{
+					iActiveBackupDataClient->InitialiseRestoreProxyBaseDataL(static_cast<TSecureId>(
+						iCallbackArg1()), static_cast<TDriveNumber>(iCallbackArg2()));
+
+					// Reprime the server				
+					PrimeServerForCallbackL();
+					} break;
+				default:
+					{
+					// Call the server to leave with KErrNotSupported
+					User::Leave(KErrNotSupported);
+					}
+				}
+				
+			// Set us up for another call
+			SetActive();
+
+			}
+		}
+		
+	void CActiveBackupCallbackHandler::PrimeServerForCallbackL()
+	/**
+	Reprime the server with a new IPC message to respond to
+	*/
+		{
+		iClientSession.PrimeServerForCallbackL(iCallbackCommand, iCallbackArg1, iCallbackArg2, iStatus);
+		}
+		
+	void CActiveBackupCallbackHandler::PrimeServerForCallbackWithResponseL(TInt aResponse)
+	/**
+	Reprime the server with a new IPC message to respond to, sending the result of the previous callback
+	
+	@param aResponse The response to send back to the server i.e. the result of the last callback made
+	*/
+		{
+		iClientSession.PrimeServerForCallbackWithResponseL(iCallbackCommand, iCallbackArg1, iCallbackArg2, aResponse, iStatus);
+		}
+
+	void CActiveBackupCallbackHandler::PrimeServerForCallbackWithResponseL(TDesC8& aResponse)
+	/**
+	Reprime the server with a new IPC message to respond to, sending the result of the previous callback
+	
+	@param aResponse The response to send back to the server i.e. the result of the last callback made
+	*/
+		{
+		iClientSession.PrimeServerForCallbackWithResponseL(iCallbackCommand, iCallbackArg1, iCallbackArg2, aResponse, iStatus);
+		}
+	
+	TInt CActiveBackupCallbackHandler::RunError(TInt aError)
+	/**
+	Handle any leaves that occur from within the RunL and hence from the callback methods. In order 
+	to propagate leaves over to the PC client, they must be sent to the backup engine to leave to the 
+	client
+	
+	@param aError The leave code that has been trapped from within the RunL. Propagate this code to the engine
+	@return Any unhandled leave code
+	*/
+		{
+		iClientSession.PropagateLeave(aError);
+		
+		PrimeServerForCallbackL();
+		SetActive();
+		
+		return KErrNone;	// Is this correct or do we return the error code even though it's been handled?
+		}
+		
+	void CActiveBackupCallbackHandler::DoCancel()
+	/**
+	Immediately cancel any outstanding calls to the backup engine
+	*/
+		{
+		// we can't do anything with the error code here
+		TRAP_IGNORE(iClientSession.CancelServerCallbackL());
+		}
+		
+	void CActiveBackupCallbackHandler::ConstructL()
+	/**
+	Add this object to the scheduler
+	
+	@panic KErrNotFound Debug only - If an ActiveScheduler is not installed
+	@leave Release only - If an ActiveScheduler is not installed
+	*/
+		{
+		if (!CActiveScheduler::Current())
+			{
+			__ASSERT_DEBUG(0, Panic(KErrNotFound));
+			}
+		
+		// Add this AO to the scheduler
+		CActiveScheduler::Add(this);
+		SetActive();
+		}
+		
+	void CActiveBackupCallbackHandler::StartListeningForServerMessagesL()
+	/**
+	Send an asynchronous IPC message to the server in order that it has a vehicle for "initiating" 
+	a callback on iActiveBackupDataClient. This should only be called once as it will start the 
+	active scheduler
+	*/
+		{
+		// Prime the server with the first prime for callback IPC message
+		PrimeServerForCallbackL();
+		}
+
+	TPtr8 CActiveBackupCallbackHandler::CreateFixedBufferL()
+	/**
+	Creates a buffer of the exact size.
+	*/
+		{
+		delete iTransferBuffer;
+		iTransferBuffer = NULL;
+					
+		iTransferBuffer = HBufC8::NewL(iCallbackArg1());
+		
+		return TPtr8(const_cast<TUint8*>(iTransferBuffer->Ptr()), iCallbackArg1());
+		}
+	}
+