diff -r 000000000000 -r 4e1aa6a622a0 sysstatemgmt/systemstatemgr/sus/src/sussimadaptation.cpp --- /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 + +/** +@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(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 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; + } + + + + + + + + + + +