sysstatemgmt/systemstatemgr/sus/src/sussimadaptation.cpp
changeset 0 4e1aa6a622a0
equal deleted inserted replaced
-1:000000000000 0:4e1aa6a622a0
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "sussimadaptation.h"
       
    17 #include <e32debug.h>
       
    18 
       
    19 /**
       
    20 @internalComponent
       
    21 */
       
    22 /*
       
    23 	//Add aMessage to the queue if AO is busy
       
    24 	//else
       
    25 	//Store the message in iCurrentMessage so that RunL can call aMessage::Complete()
       
    26 	//Unpack params 
       
    27 	//Submit request
       
    28 */ 
       
    29 
       
    30 
       
    31 void CSimAdaptationRequests::SubmitOrQueueL(const RMessage2 &aMessage)
       
    32 	{
       
    33 	CAdaptationMessage *messageCopy = new(ELeave) CAdaptationMessage(aMessage);
       
    34 		
       
    35 	if(!IsActive())
       
    36 		{
       
    37 		Submit(messageCopy);
       
    38 		}
       
    39 	else 
       
    40 		{
       
    41 		CleanupStack::PushL(messageCopy);
       
    42 		DEBUGPRINT2A("CSimAdaptationRequests queuing request with function id: %d", aMessage.Function());
       
    43 		User::LeaveIfError(iPendingRequestsQueue.Queue(messageCopy));
       
    44 		CleanupStack::Pop(messageCopy);
       
    45 		}	
       
    46 	}
       
    47 
       
    48 void CSimAdaptationRequests::Submit(CAdaptationMessage*& aMessage)
       
    49 	{
       
    50 	DEBUGPRINT2A("CSimAdaptationRequests immediate submission of request with function id: %d", aMessage->Function());
       
    51 	iCurrentMessage = aMessage;
       
    52 	switch(aMessage->Function())
       
    53 		{
       
    54 		case EGetSimOwned :
       
    55 			{
       
    56 			iSimAdaptation.GetSimOwned(iSimOwnedPckg, iStatus);
       
    57 			break;	
       
    58 			}
       
    59 		default :
       
    60 			{
       
    61 			aMessage->Complete(KErrArgument);
       
    62 			return;
       
    63 			}
       
    64 		}
       
    65 	SetActive();
       
    66 	}
       
    67 
       
    68 /**
       
    69 CSimAdaptationRequests implements Sim Adaptation related functionality as part of CSsmAdaptationServer.
       
    70 CSsmAdaptationServer loads Sim Adaptation plugin and creates CSimAdaptationRequests using the NewL.
       
    71 From then the loaded Sim Adaptation plugin will be owned by CSimAdaptationRequests.
       
    72 
       
    73 @internalComponent
       
    74 */
       
    75 CSimAdaptationRequests* CSimAdaptationRequests::NewL(MSimAdaptation& aAdaptation)
       
    76 	{
       
    77 	CSimAdaptationRequests* self = new(ELeave) CSimAdaptationRequests(aAdaptation);
       
    78 	return self;
       
    79 	}
       
    80 
       
    81 CSimAdaptationRequests::CSimAdaptationRequests(MSimAdaptation& aAdaptation) : CActive(EPriorityStandard), iSimAdaptation(aAdaptation)
       
    82 	{
       
    83 	CActiveScheduler::Add(this);
       
    84 	}
       
    85 
       
    86 CSimAdaptationRequests::~CSimAdaptationRequests()
       
    87 	{
       
    88 	iPendingRequestsQueue.NotifyAndRemoveAll();
       
    89 	Cancel();	// This call will delete iCurrentMessage if any
       
    90 	iPendingRequestsQueue.Close();
       
    91 	Release();
       
    92 	}
       
    93 
       
    94 void CSimAdaptationRequests::Release()
       
    95 	{
       
    96 	iSimAdaptation.Release();
       
    97 	}
       
    98 
       
    99 void CSimAdaptationRequests::DoGetSimOwnedL(const RMessage2& aMessage)
       
   100 	{
       
   101 	SubmitOrQueueL(aMessage);
       
   102 	}
       
   103 
       
   104 /*
       
   105 
       
   106 ALGO
       
   107 	If iCurrentMessage == aMessage
       
   108 	then call plugin's RequestCancel()
       
   109 	otherwise 
       
   110 	search the queue and complete the message with KErrCancel
       
   111 */
       
   112 
       
   113 void CSimAdaptationRequests::DoGetSimCancel(const RMessage2& aMessage)
       
   114 	{
       
   115 	
       
   116 	if(iCurrentMessage != NULL)	
       
   117 		{
       
   118 		if(aMessage.Session() == iCurrentMessage->Session())
       
   119 			{
       
   120 			DEBUGPRINT1A("CSimAdaptationRequests cancelling current request as requested");
       
   121 			iSimAdaptation.GetCancel();
       
   122 			}
       
   123 		iPendingRequestsQueue.RemoveFromQueueAndComplete(aMessage);  	
       
   124 		aMessage.Complete(KErrNone);
       
   125 		}
       
   126 	else
       
   127 		{
       
   128 		DEBUGPRINT1A("CSimAdaptationRequests nothing to cancel, but cancel requested");
       
   129 		aMessage.Complete(KErrNone);				
       
   130 		}
       
   131 					
       
   132 	}
       
   133 
       
   134 /**
       
   135  * Returns the SIM adaptation in use by this object
       
   136  * 
       
   137  * @internalComponent
       
   138  */
       
   139 MSimAdaptation& CSimAdaptationRequests::Adaptation()
       
   140 	{
       
   141 	return iSimAdaptation;
       
   142 	}
       
   143 
       
   144 void CSimAdaptationRequests::RunL()
       
   145 	{
       
   146 	
       
   147 	WriteResponseDataToClientMessageL();
       
   148 
       
   149 	DEBUGPRINT2A("CSimAdaptationRequests processed the request with funtion id: %d", iCurrentMessage->Function());
       
   150 	iCurrentMessage->Complete(iStatus.Int());
       
   151 	delete iCurrentMessage;
       
   152 	iCurrentMessage = NULL;  
       
   153 
       
   154 	if( (iPendingRequestsQueue.IsEmpty()) == EFalse )
       
   155 		{
       
   156 		CAdaptationMessage *messageCopy = NULL;
       
   157 		iPendingRequestsQueue.Dequeue(messageCopy);
       
   158 		Submit(messageCopy);
       
   159 		} 
       
   160 	}
       
   161 
       
   162 void CSimAdaptationRequests::WriteResponseDataToClientMessageL()
       
   163 	{
       
   164 	switch(iCurrentMessage->Function())
       
   165 		{
       
   166 			case EGetSimOwned:
       
   167 				{
       
   168 				iCurrentMessage->WriteL(0,iSimOwnedPckg);
       
   169 				break;					
       
   170 				}
       
   171 			default:
       
   172 				{
       
   173 				break;					
       
   174 				}				
       
   175 		}			
       
   176 	}
       
   177 TInt CSimAdaptationRequests::RunError( TInt aError )
       
   178 	{
       
   179 
       
   180 	if(iCurrentMessage != NULL)	
       
   181 		{
       
   182 		iCurrentMessage->Complete(aError);
       
   183 		delete iCurrentMessage;
       
   184 		iCurrentMessage = NULL; 
       
   185 		}
       
   186 	
       
   187 	while( (iPendingRequestsQueue.IsEmpty()) == EFalse )
       
   188 		{
       
   189 		iPendingRequestsQueue.Dequeue(iCurrentMessage);
       
   190 		iCurrentMessage->Complete(aError);
       
   191 		delete iCurrentMessage;
       
   192 		iCurrentMessage = NULL;
       
   193 		}
       
   194 	
       
   195 	return KErrNone;
       
   196 	}
       
   197 
       
   198 void CSimAdaptationRequests::DoCancel()
       
   199 	{
       
   200 	if(iCurrentMessage != NULL)	
       
   201 		{
       
   202 		iCurrentMessage->Complete(KErrCancel);
       
   203 		delete iCurrentMessage;
       
   204 		iCurrentMessage = NULL;
       
   205 		}
       
   206 		
       
   207 	while( (iPendingRequestsQueue.IsEmpty()) == EFalse )
       
   208 		{
       
   209 		iPendingRequestsQueue.Dequeue(iCurrentMessage);
       
   210 		iCurrentMessage->Complete(KErrCancel);
       
   211 		delete iCurrentMessage;
       
   212 		iCurrentMessage = NULL;
       
   213 		}
       
   214 	
       
   215 	}
       
   216 
       
   217 // class CSimAdaptationObservers
       
   218 CSimAdaptationObservers* CSimAdaptationObservers::NewL(MSimAdaptation& aAdaptation)
       
   219 	{
       
   220 	CSimAdaptationObservers* self = new(ELeave) CSimAdaptationObservers(aAdaptation);
       
   221 
       
   222 	CleanupStack::PushL(self);
       
   223 	CleanupStack::Pop(); // self
       
   224 	return self;
       
   225 	}
       
   226 
       
   227 CSimAdaptationObservers::CSimAdaptationObservers(MSimAdaptation& aAdaptation) : CActive(EPriorityStandard), iSimAdaptation(aAdaptation)
       
   228 	{
       
   229 	CActiveScheduler::Add(this);
       
   230 	}
       
   231 
       
   232 CSimAdaptationObservers::~CSimAdaptationObservers()
       
   233 	{
       
   234 	Cancel();
       
   235 	iObserversList.Close();
       
   236 	}
       
   237 
       
   238 void CSimAdaptationObservers::DoGetLastSimEvent(const RMessage2& aMessage)
       
   239 	{
       
   240 	TRAPD(err,aMessage.WriteL(0, iEventPckg));
       
   241 	aMessage.Complete(err);	
       
   242 	}
       
   243 
       
   244 void CSimAdaptationObservers::DoNotifySimEventL(const RMessage2& aMessage)
       
   245 	{
       
   246 	if(iObserversList.Count() == 0)
       
   247 		{
       
   248 		// First observer so start notification
       
   249 		StartNotification();
       
   250 		}
       
   251 	CAdaptationMessage *newObserver = new(ELeave) CAdaptationMessage(aMessage);
       
   252 	CleanupStack::PushL(newObserver);
       
   253 	iObserversList.AddObserverL(newObserver);
       
   254 	CleanupStack::Pop();//newObserver
       
   255 	}
       
   256 
       
   257 void CSimAdaptationObservers::DoNotifySimEventCancelL(const RMessage2& aMessage)
       
   258 	{
       
   259 	iSimAdaptation.NotifyCancel();
       
   260 	CAdaptationMessage *newObserver = new(ELeave) CAdaptationMessage(aMessage);
       
   261 	iObserversList.RemoveObserver(newObserver);
       
   262 	aMessage.Complete(KErrNone); 
       
   263 	
       
   264 	if(iObserversList.Count() == 0)
       
   265 		{
       
   266 		// Last observer cancelled, stop notification
       
   267 		if(IsActive())
       
   268 			{
       
   269 			Cancel();
       
   270 			}
       
   271 		}
       
   272 	}
       
   273 
       
   274 void CSimAdaptationObservers::StartNotification()
       
   275 	{
       
   276 	DEBUGPRINT1A("CSimAdaptationObservers starting request for event notification");
       
   277 	iSimAdaptation.NotifySimEvent(iEventPckg,iStatus);
       
   278 
       
   279 	SetActive();	
       
   280 	}
       
   281 
       
   282 void CSimAdaptationObservers::RunL()
       
   283 	{
       
   284 	DEBUGPRINT1A("CSimAdaptationObservers received event notification");
       
   285 	iObserversList.NotifyAndRemoveAll(iEventPckg(),iStatus.Int());
       
   286 	}
       
   287 
       
   288 TInt CSimAdaptationObservers::RunError( TInt /*aError */)
       
   289 	{
       
   290 	iObserversList.Close();
       
   291 	return KErrNone;
       
   292 	}
       
   293 
       
   294 void CSimAdaptationObservers::DoCancel()
       
   295 	{
       
   296 	DEBUGPRINT1A("CSimAdaptationObservers cancelling request for event notification");
       
   297 	iSimAdaptation.NotifyCancel();
       
   298 	iObserversList.NotifyAndRemoveAll(iEventPckg(), KErrCancel);
       
   299 	}
       
   300 
       
   301 //Observer related functionality
       
   302 void RSimAdaptationObserversList::AddObserverL(CAdaptationMessage *aNotificationMessage)
       
   303 	{
       
   304 	//any error will cause a leave
       
   305 	iObservers.AppendL(aNotificationMessage);
       
   306 	}
       
   307 void RSimAdaptationObserversList::Close()
       
   308 	{
       
   309 	// Notify all clients first
       
   310 	NotifyAndRemoveAll(static_cast<TSsmSimEventType>(0), KErrCancel);
       
   311 	// Call RArray close()
       
   312 	iObservers.Close();
       
   313 	}
       
   314 
       
   315 TInt RSimAdaptationObserversList::Count()
       
   316 	{
       
   317 	return iObservers.Count();
       
   318 	}
       
   319 
       
   320 void RSimAdaptationObserversList::NotifyAndRemoveAll(TSsmSimEventType aEventType,TInt aCompleteCode)
       
   321 	{
       
   322 	TInt index,count = iObservers.Count();
       
   323 	
       
   324 	for(index =0;index < count ;index++)
       
   325 		{
       
   326 		TPckgBuf<TSsmSimEventType> pckgEvType(aEventType);
       
   327 		
       
   328 		// Complete the client with the requested code unless
       
   329 		// the descriptor write fails
       
   330 		TInt completeCode = aCompleteCode;
       
   331 		// Only copy across the event type if it was successful
       
   332 		if(aCompleteCode == KErrNone)
       
   333 			{
       
   334 			TRAPD(err,iObservers[index]->WriteL(0,pckgEvType));
       
   335 			if(err != KErrNone)
       
   336 				{
       
   337 				completeCode = err;
       
   338 				}
       
   339 			}
       
   340 		iObservers[index]->Complete(completeCode);
       
   341 		delete iObservers[index];
       
   342 		iObservers[index] = NULL;
       
   343 		}
       
   344 	iObservers.Reset();
       
   345 	}
       
   346 /*
       
   347 ALGO	
       
   348 	//parse TRequestStatus from each CAdaptationMessage and
       
   349 	//Find or FindL 
       
   350 	//Index will be returned
       
   351 	//then call Remove()  with Index in the array
       
   352 */
       
   353 
       
   354 void RSimAdaptationObserversList::RemoveObserver(CAdaptationMessage *aCancelMessage)
       
   355 	{
       
   356 	if(aCancelMessage == NULL)
       
   357 		{
       
   358 		return;
       
   359 		}
       
   360 	TInt index,count = iObservers.Count();
       
   361 	CAdaptationMessage *notificationMessage;
       
   362 
       
   363 	for(index =0; index < count; index++)
       
   364 		{
       
   365 		notificationMessage = iObservers[index];
       
   366 		
       
   367 		// Compare on session pointers to check that the cancel only happens to notifications from the
       
   368 		// same session		
       
   369 		if( notificationMessage->Session() == aCancelMessage->Session())
       
   370 			{
       
   371 			CAdaptationMessage *message= iObservers[index];
       
   372 			iObservers[index]->Complete(KErrCancel);
       
   373 			iObservers.Remove(index);
       
   374 			delete message;
       
   375 			break;
       
   376 			}
       
   377 		}
       
   378 	delete aCancelMessage;
       
   379 	}
       
   380 
       
   381 
       
   382 
       
   383 
       
   384 
       
   385 
       
   386 
       
   387 
       
   388 
       
   389 
       
   390