sysstatemgmt/systemstatemgr/sus/src/sussimadaptation.cpp
changeset 0 4e1aa6a622a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysstatemgmt/systemstatemgr/sus/src/sussimadaptation.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,390 @@
+// Copyright (c) 2008-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:
+//
+
+#include "sussimadaptation.h"
+#include <e32debug.h>
+
+/**
+@internalComponent
+*/
+/*
+	//Add aMessage to the queue if AO is busy
+	//else
+	//Store the message in iCurrentMessage so that RunL can call aMessage::Complete()
+	//Unpack params 
+	//Submit request
+*/ 
+
+
+void CSimAdaptationRequests::SubmitOrQueueL(const RMessage2 &aMessage)
+	{
+	CAdaptationMessage *messageCopy = new(ELeave) CAdaptationMessage(aMessage);
+		
+	if(!IsActive())
+		{
+		Submit(messageCopy);
+		}
+	else 
+		{
+		CleanupStack::PushL(messageCopy);
+		DEBUGPRINT2A("CSimAdaptationRequests queuing request with function id: %d", aMessage.Function());
+		User::LeaveIfError(iPendingRequestsQueue.Queue(messageCopy));
+		CleanupStack::Pop(messageCopy);
+		}	
+	}
+
+void CSimAdaptationRequests::Submit(CAdaptationMessage*& aMessage)
+	{
+	DEBUGPRINT2A("CSimAdaptationRequests immediate submission of request with function id: %d", aMessage->Function());
+	iCurrentMessage = aMessage;
+	switch(aMessage->Function())
+		{
+		case EGetSimOwned :
+			{
+			iSimAdaptation.GetSimOwned(iSimOwnedPckg, iStatus);
+			break;	
+			}
+		default :
+			{
+			aMessage->Complete(KErrArgument);
+			return;
+			}
+		}
+	SetActive();
+	}
+
+/**
+CSimAdaptationRequests implements Sim Adaptation related functionality as part of CSsmAdaptationServer.
+CSsmAdaptationServer loads Sim Adaptation plugin and creates CSimAdaptationRequests using the NewL.
+From then the loaded Sim Adaptation plugin will be owned by CSimAdaptationRequests.
+
+@internalComponent
+*/
+CSimAdaptationRequests* CSimAdaptationRequests::NewL(MSimAdaptation& aAdaptation)
+	{
+	CSimAdaptationRequests* self = new(ELeave) CSimAdaptationRequests(aAdaptation);
+	return self;
+	}
+
+CSimAdaptationRequests::CSimAdaptationRequests(MSimAdaptation& aAdaptation) : CActive(EPriorityStandard), iSimAdaptation(aAdaptation)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CSimAdaptationRequests::~CSimAdaptationRequests()
+	{
+	iPendingRequestsQueue.NotifyAndRemoveAll();
+	Cancel();	// This call will delete iCurrentMessage if any
+	iPendingRequestsQueue.Close();
+	Release();
+	}
+
+void CSimAdaptationRequests::Release()
+	{
+	iSimAdaptation.Release();
+	}
+
+void CSimAdaptationRequests::DoGetSimOwnedL(const RMessage2& aMessage)
+	{
+	SubmitOrQueueL(aMessage);
+	}
+
+/*
+
+ALGO
+	If iCurrentMessage == aMessage
+	then call plugin's RequestCancel()
+	otherwise 
+	search the queue and complete the message with KErrCancel
+*/
+
+void CSimAdaptationRequests::DoGetSimCancel(const RMessage2& aMessage)
+	{
+	
+	if(iCurrentMessage != NULL)	
+		{
+		if(aMessage.Session() == iCurrentMessage->Session())
+			{
+			DEBUGPRINT1A("CSimAdaptationRequests cancelling current request as requested");
+			iSimAdaptation.GetCancel();
+			}
+		iPendingRequestsQueue.RemoveFromQueueAndComplete(aMessage);  	
+		aMessage.Complete(KErrNone);
+		}
+	else
+		{
+		DEBUGPRINT1A("CSimAdaptationRequests nothing to cancel, but cancel requested");
+		aMessage.Complete(KErrNone);				
+		}
+					
+	}
+
+/**
+ * Returns the SIM adaptation in use by this object
+ * 
+ * @internalComponent
+ */
+MSimAdaptation& CSimAdaptationRequests::Adaptation()
+	{
+	return iSimAdaptation;
+	}
+
+void CSimAdaptationRequests::RunL()
+	{
+	
+	WriteResponseDataToClientMessageL();
+
+	DEBUGPRINT2A("CSimAdaptationRequests processed the request with funtion id: %d", iCurrentMessage->Function());
+	iCurrentMessage->Complete(iStatus.Int());
+	delete iCurrentMessage;
+	iCurrentMessage = NULL;  
+
+	if( (iPendingRequestsQueue.IsEmpty()) == EFalse )
+		{
+		CAdaptationMessage *messageCopy = NULL;
+		iPendingRequestsQueue.Dequeue(messageCopy);
+		Submit(messageCopy);
+		} 
+	}
+
+void CSimAdaptationRequests::WriteResponseDataToClientMessageL()
+	{
+	switch(iCurrentMessage->Function())
+		{
+			case EGetSimOwned:
+				{
+				iCurrentMessage->WriteL(0,iSimOwnedPckg);
+				break;					
+				}
+			default:
+				{
+				break;					
+				}				
+		}			
+	}
+TInt CSimAdaptationRequests::RunError( TInt aError )
+	{
+
+	if(iCurrentMessage != NULL)	
+		{
+		iCurrentMessage->Complete(aError);
+		delete iCurrentMessage;
+		iCurrentMessage = NULL; 
+		}
+	
+	while( (iPendingRequestsQueue.IsEmpty()) == EFalse )
+		{
+		iPendingRequestsQueue.Dequeue(iCurrentMessage);
+		iCurrentMessage->Complete(aError);
+		delete iCurrentMessage;
+		iCurrentMessage = NULL;
+		}
+	
+	return KErrNone;
+	}
+
+void CSimAdaptationRequests::DoCancel()
+	{
+	if(iCurrentMessage != NULL)	
+		{
+		iCurrentMessage->Complete(KErrCancel);
+		delete iCurrentMessage;
+		iCurrentMessage = NULL;
+		}
+		
+	while( (iPendingRequestsQueue.IsEmpty()) == EFalse )
+		{
+		iPendingRequestsQueue.Dequeue(iCurrentMessage);
+		iCurrentMessage->Complete(KErrCancel);
+		delete iCurrentMessage;
+		iCurrentMessage = NULL;
+		}
+	
+	}
+
+// class CSimAdaptationObservers
+CSimAdaptationObservers* CSimAdaptationObservers::NewL(MSimAdaptation& aAdaptation)
+	{
+	CSimAdaptationObservers* self = new(ELeave) CSimAdaptationObservers(aAdaptation);
+
+	CleanupStack::PushL(self);
+	CleanupStack::Pop(); // self
+	return self;
+	}
+
+CSimAdaptationObservers::CSimAdaptationObservers(MSimAdaptation& aAdaptation) : CActive(EPriorityStandard), iSimAdaptation(aAdaptation)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CSimAdaptationObservers::~CSimAdaptationObservers()
+	{
+	Cancel();
+	iObserversList.Close();
+	}
+
+void CSimAdaptationObservers::DoGetLastSimEvent(const RMessage2& aMessage)
+	{
+	TRAPD(err,aMessage.WriteL(0, iEventPckg));
+	aMessage.Complete(err);	
+	}
+
+void CSimAdaptationObservers::DoNotifySimEventL(const RMessage2& aMessage)
+	{
+	if(iObserversList.Count() == 0)
+		{
+		// First observer so start notification
+		StartNotification();
+		}
+	CAdaptationMessage *newObserver = new(ELeave) CAdaptationMessage(aMessage);
+	CleanupStack::PushL(newObserver);
+	iObserversList.AddObserverL(newObserver);
+	CleanupStack::Pop();//newObserver
+	}
+
+void CSimAdaptationObservers::DoNotifySimEventCancelL(const RMessage2& aMessage)
+	{
+	iSimAdaptation.NotifyCancel();
+	CAdaptationMessage *newObserver = new(ELeave) CAdaptationMessage(aMessage);
+	iObserversList.RemoveObserver(newObserver);
+	aMessage.Complete(KErrNone); 
+	
+	if(iObserversList.Count() == 0)
+		{
+		// Last observer cancelled, stop notification
+		if(IsActive())
+			{
+			Cancel();
+			}
+		}
+	}
+
+void CSimAdaptationObservers::StartNotification()
+	{
+	DEBUGPRINT1A("CSimAdaptationObservers starting request for event notification");
+	iSimAdaptation.NotifySimEvent(iEventPckg,iStatus);
+
+	SetActive();	
+	}
+
+void CSimAdaptationObservers::RunL()
+	{
+	DEBUGPRINT1A("CSimAdaptationObservers received event notification");
+	iObserversList.NotifyAndRemoveAll(iEventPckg(),iStatus.Int());
+	}
+
+TInt CSimAdaptationObservers::RunError( TInt /*aError */)
+	{
+	iObserversList.Close();
+	return KErrNone;
+	}
+
+void CSimAdaptationObservers::DoCancel()
+	{
+	DEBUGPRINT1A("CSimAdaptationObservers cancelling request for event notification");
+	iSimAdaptation.NotifyCancel();
+	iObserversList.NotifyAndRemoveAll(iEventPckg(), KErrCancel);
+	}
+
+//Observer related functionality
+void RSimAdaptationObserversList::AddObserverL(CAdaptationMessage *aNotificationMessage)
+	{
+	//any error will cause a leave
+	iObservers.AppendL(aNotificationMessage);
+	}
+void RSimAdaptationObserversList::Close()
+	{
+	// Notify all clients first
+	NotifyAndRemoveAll(static_cast<TSsmSimEventType>(0), KErrCancel);
+	// Call RArray close()
+	iObservers.Close();
+	}
+
+TInt RSimAdaptationObserversList::Count()
+	{
+	return iObservers.Count();
+	}
+
+void RSimAdaptationObserversList::NotifyAndRemoveAll(TSsmSimEventType aEventType,TInt aCompleteCode)
+	{
+	TInt index,count = iObservers.Count();
+	
+	for(index =0;index < count ;index++)
+		{
+		TPckgBuf<TSsmSimEventType> pckgEvType(aEventType);
+		
+		// Complete the client with the requested code unless
+		// the descriptor write fails
+		TInt completeCode = aCompleteCode;
+		// Only copy across the event type if it was successful
+		if(aCompleteCode == KErrNone)
+			{
+			TRAPD(err,iObservers[index]->WriteL(0,pckgEvType));
+			if(err != KErrNone)
+				{
+				completeCode = err;
+				}
+			}
+		iObservers[index]->Complete(completeCode);
+		delete iObservers[index];
+		iObservers[index] = NULL;
+		}
+	iObservers.Reset();
+	}
+/*
+ALGO	
+	//parse TRequestStatus from each CAdaptationMessage and
+	//Find or FindL 
+	//Index will be returned
+	//then call Remove()  with Index in the array
+*/
+
+void RSimAdaptationObserversList::RemoveObserver(CAdaptationMessage *aCancelMessage)
+	{
+	if(aCancelMessage == NULL)
+		{
+		return;
+		}
+	TInt index,count = iObservers.Count();
+	CAdaptationMessage *notificationMessage;
+
+	for(index =0; index < count; index++)
+		{
+		notificationMessage = iObservers[index];
+		
+		// Compare on session pointers to check that the cancel only happens to notifications from the
+		// same session		
+		if( notificationMessage->Session() == aCancelMessage->Session())
+			{
+			CAdaptationMessage *message= iObservers[index];
+			iObservers[index]->Complete(KErrCancel);
+			iObservers.Remove(index);
+			delete message;
+			break;
+			}
+		}
+	delete aCancelMessage;
+	}
+
+
+
+
+
+
+
+
+
+
+