telephonyserverplugins/simtsy/src/CSimMbmsPacketContext.cpp
changeset 0 3553901f7fa8
child 10 4284d6390a82
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/telephonyserverplugins/simtsy/src/CSimMbmsPacketContext.cpp	Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,1586 @@
+// 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:
+// This file contains the implementation of the Similator TSY MBMS Packet Context functionality.  
+// 
+//
+
+/**
+ @file
+*/
+
+#include "Simlog.h"
+#include "CSimPhone.h"
+#include "CSimMbmsPacketContext.h"
+#include "CSimPacketQoS.h"
+#include "utils.h"
+#include <e32math.h>
+#include "CSimPacketService.h"
+#include "CSimContextHelper.h"
+
+CSimMbmsPacketContext* CSimMbmsPacketContext::NewL(CSimPhone* aPhone, CSimPacketService* aPacketService, const TDesC& aContextName)
+/**
+* Standard two phase constructor
+*
+* @param aPacketService Pointer to the Packet Service object (CSimPacketService)
+* @param aContextName name  for this packet context
+* @return CSimMbmsPacketContext pointer to the packet context object created.
+* @leave Leaves if no memory or object is not created for any reason.
+*/
+	{
+	CSimMbmsPacketContext* packetContext = new(ELeave) CSimMbmsPacketContext(aPhone, aPacketService, aContextName);
+	CleanupStack::PushL(packetContext);
+	packetContext->ConstructL();
+	CleanupStack::Pop();
+	return packetContext;
+	}
+
+CSimMbmsPacketContext::CSimMbmsPacketContext(CSimPhone* aPhone, CSimPacketService* aPacketService, const TName& aContextName)
+	:CSimPacketContext(aPhone,aPacketService,aContextName),iContextName(aContextName), iContextType(TPacketDataConfigBase::KConfigMBMS),
+	iPhone(aPhone),iPacketService(aPacketService)
+/**
+* Trivial Constructor.  Initialises all the data members
+*
+* @param aPacketService Pointer to the Packet Service object (CSimPacketService)
+* @param aContextName name  for this packet context
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext: Entered constructor");
+	iNotifyConfigMBMS.iNotifyPending = EFalse;
+	iNotifyStatusChange.iNotifyPending = EFalse;
+	}
+
+void CSimMbmsPacketContext::ConstructL()
+/**
+* Second phase of the 2-phase constructor.
+* Constructs all the member data and retrieves all the data from the config file specific to this class.
+*
+* @leave Leaves no memory or any data member does not construct for any reason.
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext: Entered constructL function");
+	CSimPacketContext::ConstructL();
+	
+	iMbmsSetConfigTimer = CSimTimer::NewL(iPhone);
+	iMbmsContextTimer = CSimTimer::NewL(iPhone);
+	iMbmsUpdateSessionTimer = CSimTimer::NewL(iPhone);
+	iMbmsContextInitTimer = CSimTimer::NewL(iPhone);
+	iMbmsGetSessionTimer = CSimTimer::NewL(iPhone);
+	
+	iMbmsContextConfigParams = new (ELeave) CArrayFixFlat<TMbmsConfigParams>(KNumberofConfigs);
+	iSessionIdList = new (ELeave) CArrayFixFlat<TUint>(1);
+	iMbmsSessionList = new CArrayPtrFlat<CPcktListReadAllAttempt>(1);
+		
+	const CTestConfigItem* item=NULL;
+	TInt ret=KErrNone;
+
+	/* Reading the MBMS Context configuration parameters */
+	TUint count=CfgFile()->ItemCount(KMBMSBroadcastMonitorList); //< Retrieves the Count of MBMS related information
+
+	for(TInt i=0;i<count;i++)
+		{
+		item = CfgFile()->Item(KMBMSBroadcastMonitorList,i); //< Retrieves the MBMS related information
+
+		TInt mnc =0; 
+		TInt mcc =0;
+		TInt serviceId =0;
+		TInt accessBearer=0;
+		TInt serviceMode =0;
+		TInt activateCode =0;
+		TInt servicePriority=0;
+		if(!item)
+			break;
+
+		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,mcc);
+		if(ret!=KErrNone)
+			{
+			break;
+			}
+
+		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,mnc);
+		if(ret!=KErrNone)
+			{
+			break;
+			}
+
+		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,serviceId);
+		if(ret!=KErrNone)
+			{
+			break;
+			}
+
+		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,4,accessBearer);
+		if(ret!=KErrNone)
+			{
+			break;
+			}
+
+		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,5,serviceMode);
+		if(ret!=KErrNone)
+			{
+			break;
+			}
+
+		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,7,activateCode);
+		if(ret!=KErrNone)
+			{
+			break;
+			}
+
+		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,8,servicePriority);
+		if(ret!=KErrNone)
+			{
+			break;
+			}
+
+		TMbmsConfigParams mbmsConfigParams;
+
+		mbmsConfigParams.iMCC = mcc;
+		mbmsConfigParams.iMNC = mnc;
+		mbmsConfigParams.iServiceId = serviceId;
+		mbmsConfigParams.iAccessBearer = reinterpret_cast<TMbmsScope&> (accessBearer);
+		mbmsConfigParams.iServiceMode = reinterpret_cast<TMbmsServiceMode&> (serviceMode);
+		mbmsConfigParams.iServicePriority = reinterpret_cast<TMbmsServicePriority&> (servicePriority);
+		mbmsConfigParams.iActivateCode = activateCode;
+
+		iMbmsContextConfigParams->AppendL(mbmsConfigParams);
+		}
+	
+	//iSessionIdList->AppendL(iNumOfSessionId);
+	iSessionIdList->InsertL(0,iNumOfSessionId);
+	
+	/* Reading the list of session ids mentioned in the configuration file*/
+	/*item = CfgFile()->Item(KMBMSSessionIdList,0); //< Retrieves the MBMS related information
+	
+	if(item != NULL)
+		{
+		TInt sessionId =0;
+		TInt numOfSessions =0;
+		
+		ret = CTestConfig::GetElement(item->Value(),KStdDelimiter,0,numOfSessions);
+		iSessionIdList->AppendL(numOfSessions);
+		
+		for(TInt j=1;j<=numOfSessions;j++)
+			{
+			ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,j,sessionId);
+			if(ret!=KErrNone)
+				{
+				break;
+				}
+			else
+				{
+				iSessionIdList->AppendL(sessionId);
+				}
+			}
+		}*/
+	}
+
+void CSimMbmsPacketContext::Init()
+/*
+ * Initialisation function; Not used in the CSimMbmsPacketContext class.
+ * but should be implemented as it is a pure virtual function of MTelObjectTSY. 
+ */
+	{}
+	
+CSimMbmsPacketContext::~CSimMbmsPacketContext()
+/**
+* Trivial Destructor
+* Closes all CObject type objects and destroys all other objects created in the ConstructL()
+*
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext: Entered destructor");
+
+	if (iMbmsSetConfigTimer != NULL)
+		{
+		delete iMbmsSetConfigTimer;
+		}
+
+	if(iMbmsContextTimer != NULL)
+		{
+		delete iMbmsContextTimer;
+		}
+
+	if(iMbmsUpdateSessionTimer != NULL)
+		{	
+		delete iMbmsUpdateSessionTimer;
+		}
+
+	if(iMbmsContextInitTimer)
+		{
+		delete iMbmsContextInitTimer;
+		}
+
+	if(iMbmsGetSessionTimer)
+		{
+		delete iMbmsGetSessionTimer;
+		}
+	
+	if(iMbmsContextConfigParams !=NULL)
+		{
+		iMbmsContextConfigParams->Delete(0,iMbmsContextConfigParams->Count());
+		delete iMbmsContextConfigParams;
+		}
+
+	if(iSessionIdList != NULL)
+		{
+		iSessionIdList->Delete(0,iSessionIdList->Count());
+		delete iSessionIdList;
+		}
+
+	if(iMbmsSessionList)
+		{
+		iMbmsSessionList->ResetAndDestroy();
+		}
+	delete iMbmsSessionList;
+
+	iPacketService->DecrementMbmsContextCount();
+	}
+
+CTelObject* CSimMbmsPacketContext::OpenNewObjectByNameL(const TDesC& /*aName*/)
+/**
+ * No Qos settings for the MBMS broadcast context 
+ * This is not supported and if called, will leave.
+ *
+ * @param aName name of the QoS object to be opened
+ * @leave Leaves with KErrNotSupported if the name is not as expected.
+ * @ return NULL.
+ */
+	{	
+	LOGPACKET1("Unexpected call to CSimMbmsPacketContext: OpenNewObjectByName");
+	User::Leave(KErrNotSupported);
+	return NULL;
+	}
+
+CTelObject* CSimMbmsPacketContext::OpenNewObjectL(TDes& /*aNewName*/)
+/**
+ * No Qos settings for the MBMS broadcast context 
+ * This is not supported and if called, will leave.
+ *
+ * @param aNewName new name of the object created
+ * @return NULL
+ * @leave Leaves if out of memory.
+ */
+	{
+	LOGPACKET1("Unexpected call to CSimMbmsPacketContext: OpenNewObjectL");
+	User::Leave(KErrNotSupported);
+	return NULL;
+	}
+
+CTelObject::TReqMode CSimMbmsPacketContext::ReqModeL(const TInt aIpc)
+/**
+* ReqModeL is called from the server's CTelObject::ReqAnalyserL
+* in order to check the type of request it has.
+* 
+* @param aIpc the ipc number that identifies the client request
+* @return CTelObject::TReqMode The request mode to be used for this request
+* @leave Leaves if not supported by this tsy 
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext: ReqModeL");
+	CTelObject::TReqMode ret=0;
+	switch (aIpc)
+		{
+		case EPacketContextGetConfig:
+		case EPacketContextSetConfig:
+		case EPacketContextActivate:
+		case EPacketContextDeactivate:
+		case EPacketContextDelete:
+		case EPacketContextGetStatus:
+		case EPacketContextUpdateMbmsSessionList:
+		case EPacketContextInitialiseContext:
+		case EPacketGetMbmsSessionListPhase1:
+		case EPacketGetMbmsSessionListPhase2:
+		case EPacketContextGetLastErrorCause:
+			break;
+						
+		case EPacketContextNotifyConfigChanged:
+		case EPacketContextNotifyStatusChange:
+		case EPacketContextNotifyDataTransferred:
+			ret=KReqModeMultipleCompletionEnabled | KReqModeRePostImmediately;
+			break;
+		default:
+			LOGPACKET1("CSimMbmsPacketContext: ReqModeL error, unknown IPC");
+			LOGPACKET1("CSimMbmsPacketContext: ReqModeL sending the request to CSimPacketContext");
+			ret = CSimPacketContext::ReqModeL(aIpc);
+			break;
+		}
+	return ret;
+	}
+
+TInt CSimMbmsPacketContext::RegisterNotification(const TInt aIpc)
+/**
+* RegisterNotification is called when the server recognises that this notification
+* is being posted for the first time on this sub-session object.
+* 
+* It enables the TSY to "turn on" any regular notification messages that it may receive 
+* from the phone
+*
+* @param aIpc the ipc number that identifies the client request
+* @return err KErrNone if fine
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext: RegisterNotification called");
+	switch (aIpc)
+		{
+		case EPacketContextNotifyConfigChanged:
+		case EPacketContextNotifyStatusChange:
+		case EPacketContextNotifyDataTransferred:
+			LOGPACKET1("CSimMbmsPacketContext: RegisterNotification");
+			return KErrNone;
+		default:
+			// Unknown or invalid IPC
+			LOGPACKET1("CSimMbmsPacketContext: Register error, unknown IPC");
+			LOGPACKET1("CSimMbmsPacketContext: Register sending the request to CSimPacketContext");
+			return CSimPacketContext::RegisterNotification(aIpc);
+		}
+	}
+
+TInt CSimMbmsPacketContext::DeregisterNotification(const TInt aIpc)
+/**
+* DeregisterNotification is called when the server recognises that this notification
+* will not be posted again because the last client to have a handle on this sub-session
+* object has just closed the handle.
+*
+* It enables the TSY to "turn off" any regular notification messages that it may 
+* receive from the phone
+*
+* @param aIpc the ipc number that identifies the client request
+* @return err KErrNone if fine
+*/
+	{	
+	LOGPACKET1("CSimMbmsPacketContext: DeregisterNotification called");
+	switch (aIpc)
+		{
+		case EPacketContextNotifyConfigChanged:
+		case EPacketContextNotifyStatusChange:
+		case EPacketContextNotifyDataTransferred:
+			LOGPACKET1("CSimMbmsPacketContext: DeregisterNotification");
+			return KErrNone;
+		default:
+			// Unknown or invalid IPC
+			LOGPACKET1("CSimMbmsPacketContext: Deregister error, unknown IPC");
+			LOGPACKET1("CSimMbmsPacketContext: Deregister sending the request to CSimPacketContext");
+			return CSimPacketContext::DeregisterNotification(aIpc);
+		}
+	}
+
+TInt CSimMbmsPacketContext::NumberOfSlotsL(const TInt aIpc)
+/**
+* NumberOfSlotsL is called by the server when it is registering a new notification
+* It enables the TSY to tell the server how many buffer slots to allocate for
+* "repost immediately" notifications that may trigger before clients collect them
+*
+* @param aIpc the ipc number that identifies the client request
+* @return err KErrNone if fine
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext: NumberOfSlotsL called");
+	TInt numberOfSlots=1;
+	switch (aIpc)
+		{
+		case EPacketContextNotifyConfigChanged:
+		case EPacketContextNotifyStatusChange:
+		case EPacketContextNotifyDataTransferred:
+			LOGPACKET1("CSimMbmsPacketContext: Registered with 5 slots");
+			numberOfSlots=5;
+			break;
+		default:
+			// Unknown or invalid IPC
+			LOGPACKET1("CSimMbmsPacketContext: Number of Slots error, unknown IPC");
+			LOGPACKET1("CSimMbmsPacketContext: Number of Slots: sending the request to CSimPacketContext");
+			return CSimPacketContext::NumberOfSlotsL(aIpc);
+		}  
+	return numberOfSlots;
+	}
+
+TInt CSimMbmsPacketContext::ExtFunc(const TTsyReqHandle aTsyReqHandle,const TInt aIpc,
+							  const TDataPackage& aPackage)
+/**
+* ExtFunc is called by the server when it has a "extended", i.e. non-core ETel request
+* for the TSY to process.
+* A request handle, request type and request data are passed to the TSY
+* 
+* @param aTsyReqHandle  The request handle for completing the request 
+* @param aIpc Ipc representing the request
+* @param aPackage any data associated with the request
+* @return err KErrNone if request completes ok
+*/
+	{
+	//< if this context has been deleted then the client can not do anything with it
+	//< if the client wants to use this class, the client must open a new object by 
+	//< name with the name for this context and this will reactivate the context.
+	if(iDeleted && (aIpc != EPacketContextGetStatus))  
+		{
+		ReqCompleted(aTsyReqHandle,KErrNotReady);
+		return KErrNone;
+		}
+	LOGPACKET1("CSimMbmsPacketContext: ExtFunc Called");
+	TAny* dataPtr=aPackage.Ptr1();
+	TAny* dataPtr2=aPackage.Ptr2();
+
+	switch (aIpc)
+		{
+		case EPacketContextGetConfig:
+			return GetConfig(aTsyReqHandle, aPackage.Des1n());
+		case EPacketContextGetConfigCancel:
+			return GetConfigCancel(aTsyReqHandle);
+		case EPacketContextSetConfig:
+			return SetConfig(aTsyReqHandle, aPackage.Des1n());
+		case EPacketContextSetConfigCancel:
+			return SetConfigCancel(aTsyReqHandle);
+		case EPacketContextActivate:
+			{	//< Ensures that theres only one context active as only one active context is 
+			//<permitted at any one time
+			if(iIsActive)
+				{
+				LOGPACKET1("Trying to activate an already activated context");
+				ReqCompleted(aTsyReqHandle,KErrEtelCallAlreadyActive);
+				return KErrNone;
+				}
+			else
+				return Activate(aTsyReqHandle);
+			}
+		case EPacketContextActivateCancel:
+			return ActivateCancel(aTsyReqHandle);
+		case EPacketContextDeactivate:
+			return Deactivate(aTsyReqHandle);
+		case EPacketContextDeactivateCancel:
+			return DeactivateCancel(aTsyReqHandle);
+		case EPacketContextDelete:
+			return Delete(aTsyReqHandle);
+		case EPacketContextDeleteCancel:
+			return DeleteCancel(aTsyReqHandle);
+		case EPacketContextGetLastErrorCause:
+			return GetLastErrorCause(aTsyReqHandle,
+			REINTERPRET_CAST(TInt*, dataPtr));
+		case EPacketContextNotifyConfigChanged:
+			return NotifyConfigChanged(aTsyReqHandle, aPackage.Des1n());
+		case EPacketContextNotifyConfigChangedCancel:
+			return NotifyConfigChangedCancel(aTsyReqHandle);
+		case EPacketContextNotifyStatusChange:
+			return NotifyStatusChange(aTsyReqHandle,
+					REINTERPRET_CAST(RPacketContext::TContextStatus*, dataPtr));
+		case EPacketContextNotifyStatusChangeCancel:
+			return NotifyStatusChangeCancel(aTsyReqHandle);
+		case EPacketContextGetStatus:
+			return GetStatus(aTsyReqHandle,
+					REINTERPRET_CAST(RPacketContext::TContextStatus*, dataPtr));
+		case EPacketContextUpdateMbmsSessionList:
+			return UpdateMbmsSessionListL(aTsyReqHandle,
+					REINTERPRET_CAST(TMbmsAction*, dataPtr),
+					REINTERPRET_CAST(TUint*, dataPtr2));	
+		case EPacketContextInitialiseContext:
+			return InitialiseContext(aTsyReqHandle, aPackage.Des1n());
+		case EPacketContextInitialiseContextCancel:
+			return InitialiseContextCancel(aTsyReqHandle);
+		case EPacketGetMbmsSessionListPhase1:
+			return GetMbmsSessionsPhase1(aTsyReqHandle, 
+			REINTERPRET_CAST(TClientId*, dataPtr), 
+			REINTERPRET_CAST(TInt*, dataPtr2));
+		case EPacketGetMbmsSessionListPhase2:
+			return GetMbmsSessionsPhase2(aTsyReqHandle, 
+			REINTERPRET_CAST(TClientId*, dataPtr), aPackage.Des2n());		
+		default:
+			LOGPACKET1("CSimMbmsPacketContext: ExtFunc Unknown IPC");
+			LOGPACKET1("CSimMbmsPacketContext: sending the request to CSimPacketContext::ExtFunc Unknown IPC");
+			return CSimPacketContext::ExtFunc(aTsyReqHandle,aIpc,aPackage);
+		}
+	}
+		
+TInt CSimMbmsPacketContext::CancelService(const TInt aIpc,const TTsyReqHandle aTsyReqHandle)
+/**
+* CancelService is called by the server when it is "cleaning-up" any still outstanding
+* asynchronous requests before closing a client's sub-session.
+* This will happen if a client closes its R-class handle without cancelling outstanding asynchronous requests.
+* 
+* @param aTsyReqHandle  The request handle for completing the request 
+* @param aIpc Ipc representing the request
+* @return err KErrNone if request completes ok
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext: - CancelService called");
+
+	switch (aIpc)
+		{
+		case EPacketContextSetConfig:
+			return SetConfigCancel(aTsyReqHandle);
+		case EPacketContextGetConfig:
+			return GetConfigCancel(aTsyReqHandle);
+		case EPacketContextActivate:
+			return ActivateCancel(aTsyReqHandle);
+		case EPacketContextDeactivate:
+			return DeactivateCancel(aTsyReqHandle);
+		case EPacketContextDeleteCancel:
+			return DeleteCancel(aTsyReqHandle);
+		case EPacketContextNotifyConfigChanged:
+			return NotifyConfigChangedCancel(aTsyReqHandle);
+		case EPacketContextNotifyStatusChange:
+			return NotifyStatusChangeCancel(aTsyReqHandle);
+		case EPacketContextInitialiseContext:
+			return InitialiseContextCancel(aTsyReqHandle);
+		case EPacketGetMbmsSessionListPhase1:
+		case EPacketGetMbmsSessionListPhase2:
+			return GetMbmsSessionsCancel(aTsyReqHandle);
+		default:
+			LOGPACKET1("CSimMbmsPacketContext: - CancelService unknown IPC called");
+			LOGPACKET1("CSimMbmsPacketContext: sending the request to CSimPacketContext::ExtFunc Unknown IPC");
+			return CSimPacketContext::CancelService(aIpc,aTsyReqHandle);
+		}
+	}
+
+void CSimMbmsPacketContext::TimerCallBack(TInt aId)
+/**
+* Timer callback function.  When the timer goes off, it will call back into this
+* function for further processing.
+* param - aId indicates which Timer Event has occured.
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext: - TimerCallBack(TInt aId) called");
+	switch(aId)
+		{
+		case ETimerIdMbmsPcktContextSetConfig:
+			LOGPACKET1("CSimMbmsPacketContext: - TimerCallBack SetConfig called");
+			if(iSetConfigValues.iErrorValue == KErrNone)
+				{
+				iMbmsContextConfigParamsIndex = iSetConfigValues.iIndex ;
+				}
+			ReqCompleted(iSetConfigRequestHandle,iSetConfigValues.iErrorValue);
+			break;
+		case ETimerIdMbmsUpdateSessionId:
+			LOGPACKET1("CSimMbmsPacketContext: - TimerCallBack UpdateSessionID called");
+			if(iUpdateSessionHandle != NULL)
+				{
+				ReqCompleted(iUpdateSessionHandle,KErrNone);
+				}
+			break;
+		case ETimerIdPcktContextInitContext:
+			DoInitialiseContext();
+			break;
+		case ETimerIdPcktContextCreateTft:
+			CSimPacketContext::TimerCallBack(aId);
+			break;
+		default:
+			{
+			LOGPACKET1(">>CSimMbmsPacketContext::TimerCallBack Default Case for Context Events");
+			switch(iCurrentEvent)
+				{
+				case EMbmsContextEventNone:
+					LOGPACKET1("TimerCallBack - iCurrentEvent = [EMbmsContextEventNone]");
+					break;
+				case EMbmsContextEventActivate:
+					LOGPACKET1("TimerCallBack - iCurrentEvent = [EMbmsContextEventActivate]");
+					if(iState==RPacketContext::EStatusActivating)
+						{
+						TInt activateValue = iMbmsContextConfigParams->At(iMbmsContextConfigParamsIndex).iActivateCode;
+						TInt ret;
+						if(activateValue != KErrNone) 
+							{ // Reject the Activation request.
+							ret=ChangeState(RPacketContext::EStatusInactive);
+							ReqCompleted(iActivateRequestHandle,KErrGprsActivationRejected);
+							iCurrentEvent=EMbmsContextEventNone;
+							}
+						else
+							{
+							ret=ChangeState(RPacketContext::EStatusActive);
+							ReqCompleted(iActivateRequestHandle,ret);
+							iCurrentEvent=EMbmsContextEventNone;
+							iIsActive = ETrue;
+							}
+						
+						// Check for and complete any pending notifications
+						if(iNotifyConfigMBMS.iNotifyPending)
+							{
+							TMbmsConfigParams thisConfig = iMbmsContextConfigParams->At(iMbmsContextConfigParamsIndex);
+							iNotifyConfigMBMS.iNotifyPending=EFalse;
+							RPacketMbmsContext::TContextConfigMbmsV1 *tempConfig = (RPacketMbmsContext::TContextConfigMbmsV1*)iNotifyConfigMBMS.iNotifyData;
+							tempConfig->iTmgi.SetServiceId(thisConfig.iServiceId);
+							tempConfig->iTmgi.SetMCC(thisConfig.iMCC);
+							tempConfig->iTmgi.SetMNC(thisConfig.iMNC);
+							tempConfig->iMbmsAccessBearer= thisConfig.iAccessBearer;
+							tempConfig->iMbmsServicePriority = thisConfig.iServicePriority;
+							tempConfig->iMbmsServiceMode = thisConfig.iServiceMode;
+							ReqCompleted(iNotifyConfigMBMS.iNotifyHandle,KErrNone);
+							}
+						}
+					else
+						{
+						LOGPACKET1("Unexpected iState for iCurrentEvent[EMbmsContextEventActivate]");
+						}
+					break;
+				case EMbmsContextEventDeactivate:
+					LOGPACKET1("TimerCallBack - iCurrentEvent = [EMbmsContextEventDeactivate]");
+					if(((iState == RPacketContext::EStatusInactive) || (iState == RPacketContext::EStatusDeactivating)) && 
+									(iCurrentEvent==EMbmsContextEventDeactivate))
+						{
+						TInt ret=ChangeState(RPacketContext::EStatusInactive);
+						ReqCompleted(iDeactivateRequestHandle,ret);
+						iCurrentEvent=EMbmsContextEventNone;
+						iIsActive = EFalse;
+						}
+					else
+						{
+						LOGPACKET1("Unexpected iState for iCurrentEvent[EMbmsContextEventActivate]");
+						}
+					break;
+				case EMbmsContextEventDelete:
+					LOGPACKET1("TimerCallBack - iCurrentEvent = [EMbmsContextEventDelete]");
+					if(iState == RPacketContext::EStatusInactive && !iIsActive )
+						{
+						TInt ret = ChangeState(RPacketContext::EStatusDeleted);
+						ReqCompleted(iDeleteRequestHandle,ret);
+						iCurrentEvent=EMbmsContextEventNone;
+						}
+					else
+						{
+						ReqCompleted(iDeleteRequestHandle,KErrCorrupt); // KErrCorrupt is sent to indicate that the 
+						//delete request is received when the context is Not inactive.
+						}
+					break;
+				default:
+					{
+					LOGPACKET1("CSimMbmsPacketContext::TimerCallBack");
+					LOGPACKET1("<<Unexpected iCurrentEvent @ TimerCallBack");
+					break;
+					}
+				}
+			}
+		}
+	}
+
+TName CSimMbmsPacketContext::ContextName() const 
+/**
+* Returns the context name to the requested client
+*
+* @return TName	Name of the MBMS context
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::ContextName called");
+	return iContextName; 
+	}
+
+const CTestConfigSection* CSimMbmsPacketContext::CfgFile()
+/**
+* Return a pointer to the Configuration File Section
+*
+* @return CTestConfigSection	pointer to the configuration file section
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::CfgFile called");
+	return iPacketService->CfgFile();
+	}
+
+TInt CSimMbmsPacketContext::SetConfig(const TTsyReqHandle aTsyReqHandle,const TDesC8* aConfig)
+/**
+* Sets the MBMS configuration parameters and notifies if
+* there is a pending notification for the config change.
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aConfig pointer containing the parameters to set to.
+* @return KErrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::SetConfig called");
+
+	TPckg<TPacketDataConfigBase>* configBase = (TPckg<TPacketDataConfigBase>*)aConfig;
+	TPacketDataConfigBase& configBaseV1 = (*configBase)();
+	iSetConfigRequestHandle = aTsyReqHandle;
+	TInt err = KErrCorrupt;
+
+	if(configBaseV1.ExtensionId()==TPacketDataConfigBase::KConfigMBMS)
+		{
+		TPckg<RPacketMbmsContext::TContextConfigMbmsV1>* configMBMSPckg = (TPckg<RPacketMbmsContext::TContextConfigMbmsV1>*)aConfig;
+		RPacketMbmsContext::TContextConfigMbmsV1& configMBMS = (*configMBMSPckg)();
+
+		TMbmsConfigParams mbmsConfigParams;
+
+		mbmsConfigParams.iMCC = configMBMS.iTmgi.GetMCC();
+		mbmsConfigParams.iMNC = configMBMS.iTmgi.GetMNC();
+		mbmsConfigParams.iServiceId = configMBMS.iTmgi.GetServiceId() ;
+		mbmsConfigParams.iAccessBearer = configMBMS.iMbmsAccessBearer;
+		mbmsConfigParams.iServiceMode = configMBMS.iMbmsServiceMode;
+		mbmsConfigParams.iServicePriority = configMBMS.iMbmsServicePriority;
+
+		TUint index;
+		for(index=0; index < iMbmsContextConfigParams->Count(); index++)
+			{
+			TMbmsConfigParams thisConfig = iMbmsContextConfigParams->At(index);
+
+			if ((mbmsConfigParams.iAccessBearer != thisConfig.iAccessBearer) ||
+					(mbmsConfigParams.iServiceMode != thisConfig.iServiceMode) ||
+					(mbmsConfigParams.iServicePriority != thisConfig.iServicePriority) ||
+					(mbmsConfigParams.iMCC != thisConfig.iMCC) ||
+					(mbmsConfigParams.iMNC != thisConfig.iMNC) ||
+					(mbmsConfigParams.iServiceId != thisConfig.iServiceId))
+				{
+				err = KErrCorrupt;
+				}
+			else
+				{
+				err = KErrNone;
+				//Check for and complete any pending notifications
+				if(iNotifyConfigMBMS.iNotifyPending)
+					{
+					iNotifyConfigMBMS.iNotifyPending=EFalse;
+					RPacketMbmsContext::TContextConfigMbmsV1 *tempConfig = (RPacketMbmsContext::TContextConfigMbmsV1*)iNotifyConfigMBMS.iNotifyData;
+					tempConfig->iTmgi.SetServiceId(thisConfig.iServiceId);
+					tempConfig->iTmgi.SetMCC(thisConfig.iMCC);
+					tempConfig->iTmgi.SetMNC(thisConfig.iMNC);
+					tempConfig->iMbmsAccessBearer= thisConfig.iAccessBearer;
+					tempConfig->iMbmsServicePriority = thisConfig.iServicePriority;
+					tempConfig->iMbmsServiceMode = thisConfig.iServiceMode;
+					ReqCompleted(iNotifyConfigMBMS.iNotifyHandle,KErrNone);
+					}
+				break;
+				}
+			}
+		iSetConfigValues.iErrorValue = err;
+		iSetConfigValues.iIndex = index;
+		}
+	else
+		{ // not expected to reach here in case of MBMS context
+		TUint index=0;
+		iSetConfigValues.iErrorValue = err;
+		iSetConfigValues.iIndex = index;
+		}
+	iMbmsSetConfigTimer->Start(RandTime(),this,ETimerIdMbmsPcktContextSetConfig);
+
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::SetConfigCancel(const TTsyReqHandle aTsyReqHandle)
+/**
+* Cancels the Setconfig request.
+* This method will do nothing in this version of SimTSY.
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @return err KErrNone 
+*/
+	{
+	iMbmsSetConfigTimer->Cancel();
+	ReqCompleted(aTsyReqHandle, KErrCancel);
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::GetConfig(const TTsyReqHandle aTsyReqHandle,TDes8* aConfig)
+/**
+* Retrieves and returns the MBMS context configuration
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aConfig pointer to the configuration params to retrieve
+* @return KErrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::GetConfig called");
+	TPckg<TPacketDataConfigBase>* configBase = (TPckg<TPacketDataConfigBase>*)aConfig;
+	TPacketDataConfigBase& configBaseV1 = (*configBase)();
+	
+	if(configBaseV1.ExtensionId()==TPacketDataConfigBase::KConfigMBMS)
+		{
+
+		TPckg<RPacketMbmsContext::TContextConfigMbmsV1>* configMBMSPckg = (TPckg<RPacketMbmsContext::TContextConfigMbmsV1>*)aConfig;
+		RPacketMbmsContext::TContextConfigMbmsV1& configMBMS = (*configMBMSPckg)();
+		
+		configMBMS.iTmgi.SetServiceId(iMbmsContextConfigParams->At(iMbmsContextConfigParamsIndex).iServiceId);
+		configMBMS.iTmgi.SetMCC(iMbmsContextConfigParams->At(iMbmsContextConfigParamsIndex).iMCC);
+		configMBMS.iTmgi.SetMNC(iMbmsContextConfigParams->At(iMbmsContextConfigParamsIndex).iMNC);
+		configMBMS.iMbmsAccessBearer = reinterpret_cast<TMbmsScope&>(iMbmsContextConfigParams->At(iMbmsContextConfigParamsIndex).iAccessBearer);
+		configMBMS.iMbmsServicePriority = reinterpret_cast<TMbmsServicePriority&>(iMbmsContextConfigParams->At(iMbmsContextConfigParamsIndex).iServicePriority);
+		configMBMS.iMbmsServiceMode = reinterpret_cast<TMbmsServiceMode&>(iMbmsContextConfigParams->At(iMbmsContextConfigParamsIndex).iServiceMode);
+
+		ReqCompleted(aTsyReqHandle,KErrNone);
+		}
+	else
+		{
+		ReqCompleted(aTsyReqHandle,KErrNotSupported);
+		}
+
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::GetConfigCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+* Cancels the Getconfig request.  
+* This method will do nothing in this version of SimTSY.
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @return err KErrNone 
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::GetConfigCancel called");
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::GetStatus(const TTsyReqHandle aTsyReqHandle,RPacketContext::TContextStatus* aContextStatus)
+/**
+* Retrieves and returns the current status of the MBMS context 
+* 
+* @param aTsyReqHandle Tsy Request handle for the client cancel request
+* @param aContextStatus pointer to the status of the mbms packet context.
+* @return KerrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::GetStatus called");
+	*aContextStatus = iState;
+	ReqCompleted(aTsyReqHandle,KErrNone);
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::Activate(const TTsyReqHandle aTsyReqHandle)
+/**
+* Client calls this method to try to Activate a mbms context.
+* In this method, we'll store the TsyReqHandle for later completion then call ActionEvent
+* state machine to handle the event which will kick off a timer.
+* The Actual Activation will take place in the TimerCallBack method.
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @return KErrNone
+*/
+	{
+	iActivateRequestHandle = aTsyReqHandle;
+	TInt ret;
+	ret = ActionEvent(EMbmsContextEventActivate);
+	return ret;
+	}
+
+TInt CSimMbmsPacketContext::ActivateCancel(const TTsyReqHandle aTsyReqHandle)
+/**
+* Client calls this method to try and cancel an Activate request.
+* This will only complete successfully if and only if the Activate request 
+* has not completed.i.e. if we haven't already activated the context.
+* Otherwise, the request will be completed with KErrNone
+*
+* @param aTsyReqHandle Tsy Request handle for the client cancel request
+* @return KErrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::ActivateCancel called");
+	iMbmsContextTimer->Cancel();
+	if(((iState == RPacketContext::EStatusInactive) || (iState == RPacketContext::EStatusActivating)) && 
+					(iCurrentEvent==EMbmsContextEventActivate))
+		{
+		iCurrentEvent= EMbmsContextEventNone;
+		TInt ret = ChangeState(RPacketContext::EStatusInactive);
+		if(ret!= KErrNone)
+			{
+			ReqCompleted(aTsyReqHandle,ret);
+			}
+		else
+			{
+			ReqCompleted(aTsyReqHandle,KErrCancel);
+			}
+		}
+	else if (iState == RPacketContext::EStatusDeleted)
+		{
+		ReqCompleted(aTsyReqHandle,KErrCancel);
+		}
+	else
+		{
+		ReqCompleted(aTsyReqHandle,KErrNone);
+		}
+
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::Deactivate(const TTsyReqHandle aTsyReqHandle)
+/**
+* Client calls this method to try to Deactivate an active context.
+* In this method, we'll store the TsyReqHandle for later completion then call ActionEvent
+* state machine to handle the event which will kick off a timer.
+* The Actual Deactivation will take place in the TimerCallBack method.
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @return KErrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::Deactivate called");
+	iDeactivateRequestHandle = aTsyReqHandle;
+	TInt ret = ActionEvent(EMbmsContextEventDeactivate);
+	return ret;
+	}
+
+TInt CSimMbmsPacketContext::DeactivateCancel(const TTsyReqHandle aTsyReqHandle)
+/**
+* Client calls this method to try and cancel a Deactivate request.
+* This will only complete successfully if and only if the Deactivate request has not completed.
+* i.e. if we haven't already deactivated the context.
+* Otherwise, the request will be completed with KErrNone.
+* 
+* @param aTsyReqHandle Tsy Request handle for the client cancel request
+* @return KErrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::DeactivateCancel called");
+	iMbmsContextTimer->Cancel();
+	if(((iState == RPacketContext::EStatusInactive) || (iState == RPacketContext::EStatusDeactivating)) && 
+					(iCurrentEvent==EMbmsContextEventDeactivate))
+		{
+		iCurrentEvent= EMbmsContextEventNone;
+		TInt ret = ChangeState(RPacketContext::EStatusActive);
+		if(ret!= KErrNone)
+			{
+			ReqCompleted(aTsyReqHandle,ret);
+			}
+		else
+			{
+			ReqCompleted(aTsyReqHandle,KErrCancel);
+			}
+		}
+	else
+		{
+		ReqCompleted(aTsyReqHandle,KErrNone);
+		}
+	
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::ReActivate(CSimPacketService* aPacketService, const TName& aContextName)
+/**
+* This method is called by the packet Service to Re-Initialise a Deleted context.
+* If the context is deleted then the client cannot retrieve any 
+* infomation or use the context in any way.
+* In order for the client to use the context again, the client must 
+* open an object by name passing the name of this context as a pararemter.
+*
+* @param aPacketService pointer to the parent class CSimPacketService.
+* @param aContextName Must be the same name as the name for this context.
+* @return KErrNone if no problem in re-initialising this context.
+*/
+	{
+	if(iContextName.Compare(aContextName) != KErrNone)
+		{
+		return KErrBadName;
+		}
+
+	iPacketService = aPacketService;
+
+	if(iDeleted)
+		{
+		TInt ret = ChangeState(RPacketContext::EStatusInactive);
+		if (ret != KErrNone)
+			{
+			return ret;
+			}
+
+		iDeleted = EFalse;
+		iMbmsContextConfigParamsIndex = 0;
+		iNotifyStatusChange.iNotifyPending = EFalse;
+		iNotifyConfigMBMS.iNotifyPending = EFalse;
+		}
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::Delete(const TTsyReqHandle aTsyReqHandle)
+/**
+* Client calls this method to try to Delete this context.
+* In this method, we'll store the TsyReqHandle for later completion then call ActionEvent
+* state machine to handle the event which will kick off a timer.
+* The Actual Delete will take place in the TimerCallBack method.
+*
+* This request will only succeed if the context already exist (had been created) and also not
+* previously deleted.
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @return KErrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::Delete called");
+	iDeleteRequestHandle = aTsyReqHandle;
+	TInt ret = ActionEvent(EMbmsContextEventDelete);
+	return ret;
+	}
+
+TInt CSimMbmsPacketContext::DeleteCancel(const TTsyReqHandle aTsyReqHandle)
+/**
+* Client calls this method to try and cancel a Delete context request.
+* This will only complete successfully if and only if the Delete request has not completed.
+* i.e. if we haven't already Deleted the context.
+*
+* @param aTsyReqHandle Tsy Request handle for the client cancel request
+* @return KErrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::DeleteCancel called");
+	iMbmsContextTimer->Cancel();
+	if((iState == RPacketContext::EStatusInactive) && (iCurrentEvent==EMbmsContextEventDelete))
+		{
+		iCurrentEvent= EMbmsContextEventNone;
+		ReqCompleted(aTsyReqHandle,KErrCancel);
+		}
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::GetLastErrorCause(const TTsyReqHandle aTsyReqHandle,TInt* /*aError*/)
+/**
+* This method is supported in only for the MBMS Packet Context
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aError pointer to the last error cause
+* @return KerrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::GetLastErrorCause called");
+	
+	ReqCompleted(aTsyReqHandle,iLastError);
+	return KErrNone;
+	}
+
+
+TInt CSimMbmsPacketContext::NotifyConfigChanged(const TTsyReqHandle aTsyReqHandle, TDes8* aConfig)
+/**
+* Records a client interest in being notified of a change in the Context Configuration.
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aConfig pointer to the context config to store the config info when the config changes.
+* @return KErrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::NotifyConfigChanged called");
+	TPckg<TPacketDataConfigBase>* configBase = (TPckg<TPacketDataConfigBase>*)aConfig;
+	TPacketDataConfigBase& configBaseV1 = (*configBase)();
+	
+	if(configBaseV1.ExtensionId() == TPacketDataConfigBase::KConfigMBMS)
+		{
+	    __ASSERT_ALWAYS(!iNotifyConfigMBMS.iNotifyPending,SimPanic(ENotificationAlreadyPending));
+
+	    iNotifyConfigMBMS.iNotifyPending = ETrue;
+	    iNotifyConfigMBMS.iNotifyHandle = aTsyReqHandle;
+	    iNotifyConfigMBMS.iNotifyData = &configBaseV1;
+		}
+	else
+		{
+		LOGPACKET1("CSimMbmsPacketContext::NotifyConfigChanged Unexpected config for MBMS context");
+		}
+
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::NotifyConfigChangedCancel(const TTsyReqHandle aTsyReqHandle)
+/**
+* Cancel a client's interest in being notified when the context configuration changes
+* This is acheived simply by resetting the flag that indicates a notification is pending.
+* 
+* @param aTsyReqHandle Tsy Request handle for the client cancel request
+* @return KErrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::NotifyConfigChangedCancel called");
+	if(iNotifyConfigMBMS.iNotifyPending &&
+		iNotifyConfigMBMS.iNotifyHandle == aTsyReqHandle)
+		{
+		iNotifyConfigMBMS.iNotifyPending=EFalse;
+		ReqCompleted(aTsyReqHandle,KErrCancel);
+		}
+	else
+		{
+		ReqCompleted(aTsyReqHandle,KErrNone);
+		}
+		
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::NotifyStatusChange(const TTsyReqHandle aTsyReqHandle,RPacketContext::TContextStatus* aContextStatus)
+/**
+* Record a client's interest in being notified of the state of the packet contexts.
+* First check that there isn't already a notification pending (the ETel Server should protect
+* against this) and then record the information necessary to complete the request later, when
+* the status does actually change.
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aContextStatus pointer to the packet context status
+* @return KErrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::NotifyStatusChange called");
+	__ASSERT_ALWAYS(!iNotifyStatusChange.iNotifyPending,SimPanic(ENotificationAlreadyPending));
+	iNotifyStatusChange.iNotifyPending = ETrue;
+	iNotifyStatusChange.iNotifyHandle = aTsyReqHandle;
+	iNotifyStatusChange.iNotifyData = aContextStatus;
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::NotifyStatusChangeCancel(const TTsyReqHandle aTsyReqHandle)
+/**
+* Cancel a client's interest in being notified when the packet context status changes.
+* This is acheived simply by resetting the flag that indicates a notification is pending.
+* 
+* @param aTsyReqHandle Tsy Request handle for the client cancel request
+* @return KErrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::NotifyStatusChangeCancel called");
+	if(iNotifyStatusChange.iNotifyPending)
+		{
+		iNotifyStatusChange.iNotifyPending=EFalse;
+		ReqCompleted(aTsyReqHandle,KErrCancel);
+		}
+	else
+		{
+		ReqCompleted(aTsyReqHandle,KErrNone);
+		}
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::UpdateMbmsSessionListL(const TTsyReqHandle aTsyReqHandle,TMbmsAction* aAction, TUint* aSessionId)
+/**
+* client's interest in updating the MBMS session's list.
+* This is achieved  by updating the list maintained internally by the context
+* 
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aAction TMbmsAction - ADD/ REMOVE / REMOVE_ALL
+* @param aSessionId sessoinID to be used for the updation.
+* @return KErrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::UpdateMbmsSessionListL called");
+
+	TInt error=KErrNone;
+	iUpdateSessionHandle = aTsyReqHandle;
+	TKeyArrayFix key(0, ECmpTUint);
+	TInt position =-1;
+
+	switch(*aAction)
+		{
+		case SIMTSY_PACKET_MBMS_ADD_ENTRIES:
+			LOGPACKET1("CSimMbmsPacketContext::UpdateMbmsSessionListL Action: ADD ");
+			TRAP(error,iSessionIdList->AppendL(*aSessionId));
+			if(error == KErrNone)
+				{
+				//iSessionIdList->At(0) = ++iNumOfSessionId;
+				iSessionIdList->Delete(0);
+				iSessionIdList->InsertL(0,++iNumOfSessionId);
+				iMbmsUpdateSessionTimer->Start(RandTime(),this,ETimerIdMbmsUpdateSessionId);
+				}
+			else
+				{
+				ReqCompleted(iUpdateSessionHandle,error);
+				}
+			break;
+
+		case SIMTSY_PACKET_MBMS_REM_ENTRIES:
+			LOGPACKET1("CSimMbmsPacketContext::UpdateMbmsSessionListL Action: REMOVE ");
+			iSessionIdList->Find(*aSessionId,key,position);
+			if(position != -1)
+				{
+				iSessionIdList->Delete(position);
+				//iSessionIdList->At(0) = --iNumOfSessionId;
+				iSessionIdList->InsertL(0,--iNumOfSessionId);
+				iMbmsUpdateSessionTimer->Start(RandTime(),this,ETimerIdMbmsUpdateSessionId);
+				}
+			else
+				{
+				error = KErrNotFound;
+				ReqCompleted(iUpdateSessionHandle,error);
+				}
+			break;
+
+		case SIMTSY_PACKET_MBMS_REM_ALL_ENTRIES:
+			LOGPACKET1("CSimMbmsPacketContext::UpdateMbmsSessionListL Action: REMOVE_ALL ");
+			iNumOfSessionId=0;
+			//iSessionIdList->At(0) = iNumOfSessionId;
+			iSessionIdList->InsertL(0,iNumOfSessionId);
+			iSessionIdList->Delete(1,iSessionIdList->Count()); // removing all session ids from the list
+			ReqCompleted(aTsyReqHandle, KErrNone);
+			break;
+
+		default:
+			LOGPACKET1("CSimMbmsPacketContext::UpdateMbmsSessionListL Action: Default ");
+			ReqCompleted(aTsyReqHandle,KErrNotFound);
+			break;
+		}
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::UpdateMbmsSessionListCancel(const TTsyReqHandle aTsyReqHandle)
+/**
+* client's interest in cancelling the updation the MBMS session's list.
+* 
+* @param aTsyReqHandle Tsy Request handle for the client cancel request
+* @return KErrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::UpdateMbmsSessionListCancel called");
+	iMbmsUpdateSessionTimer->Cancel();
+	if( iUpdateSessionHandle == aTsyReqHandle )
+		{
+		ReqCompleted(iUpdateSessionHandle,KErrCancel);
+		iUpdateSessionHandle=NULL;
+		}
+	else
+		{
+		ReqCompleted(iUpdateSessionHandle,KErrNone);
+		}
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::InitialiseContext(const TTsyReqHandle aTsyReqHandle, TDes8* aDataChannelV2Pckg)
+/**
+* client's interest in Initialising the context.
+* 
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aDataChannelV2Pckg the information to be filled once the initialisation is complete.
+* @return KErrNone
+*/
+	{
+	TCommSetupItem item = FindCommSettings();
+	iInitContextData.iTsyReqHandle = aTsyReqHandle;
+	iInitContextData.iChannel = aDataChannelV2Pckg;
+	iMbmsContextInitTimer->Start(RandTime(), this, ETimerIdPcktContextInitContext);
+
+	return KErrNone;
+	}
+	
+TInt CSimMbmsPacketContext::DoInitialiseContext()
+/* Function completes the request from the client for the initialisation of the context.
+ * Called when the timer event occurs after receiving the InitialiseContext request.
+ * returns KErrNone.
+ */
+	{
+	RPacketContext::TDataChannelV2Pckg* channel = (RPacketContext::TDataChannelV2Pckg*)iInitContextData.iChannel;
+	RPacketContext::TDataChannelV2& channelV2 = (*channel)();
+
+	// Check that the data structure is supported by the simulated TSY version
+	TInt err = iPhone->CheckSimTsyVersion(channelV2);
+	if(err != KErrNone)
+		{
+		ReqCompleted(iInitContextData.iTsyReqHandle, err);
+		return KErrNone;
+		}
+
+	TCommSetupItem item = FindCommSettings();
+	channelV2.iPort = item.iPortName;
+	channelV2.iCsy = item.iCsyName;
+	channelV2.iChannelId = item.iPortName;
+	
+	ReqCompleted(iInitContextData.iTsyReqHandle, KErrNone);
+
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::InitialiseContextCancel(const TTsyReqHandle aTsyReqHandle)
+/**
+* client's interest in cancelling the Initialisation of the MBMS Context.
+* 
+* @param aTsyReqHandle Tsy Request handle for the client cancel request
+* @return KErrNone
+*/
+	{
+	iMbmsContextInitTimer->Cancel();
+	ReqCompleted(aTsyReqHandle, KErrCancel);
+	
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::GetMbmsSessionsPhase1(const TTsyReqHandle aTsyReqHandle, TClientId* aClient, TInt* aBufSize)
+/**
+* client's interest in retrieving the MBMS Session information.
+* This is the phase1 retrieval
+* 
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aClient ClientId from which the request is sent
+* @param aBufSize  Size of the buffer to be allocated to retrieve the data in phase2.
+* @return KErrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::GetMbmsSessionsPhase1 called");
+	iGetMbmsSessionHandle = aTsyReqHandle;
+	TInt ret=KErrNone;
+	TInt leaveCode=KErrNone;
+	TRAP(leaveCode, ret=ProcessGetMbmsSessionsPhase1L(aTsyReqHandle, aClient, aBufSize););
+	if (leaveCode != KErrNone)
+		{
+		ReqCompleted(aTsyReqHandle,leaveCode);
+		}
+	return ret;
+	}	
+
+TInt CSimMbmsPacketContext::ProcessGetMbmsSessionsPhase1L(const TTsyReqHandle aTsyReqHandle, 
+													 TClientId* aClient, 
+													 TInt* aBufSize)
+/**
+* The Actual function which does the phase1 retrieval.
+* 
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aClient ClientId from which the request is sent
+* @param aBufSize  Size of the buffer to be allocated to retrieve the data in phase2.
+* @return KErrNone
+*/
+	{
+	// Retrieve MBMS session list,
+	// Store the sessions and then return the size of the buffer to the client
+	LOGPACKET1("CSimMbmsPacketContext::ProcessGetMbmsSessionsPhase1L called");
+	RPacketMbmsContext::CMbmsSession* mbmsSession=RPacketMbmsContext::CMbmsSession::NewL();
+	CleanupStack::PushL(mbmsSession);
+
+	for(TInt i=1;i<=iNumOfSessionId;i++)
+		{
+		mbmsSession->iSessionIdList.Append(iSessionIdList->At(i));
+		}
+
+	
+	// Store the streamed list and the client ID
+	CPcktListReadAllAttempt* read = CPcktListReadAllAttempt::NewL(*aClient,aTsyReqHandle);
+	CleanupStack::PushL(read);
+	
+	HBufC8* iBuff=NULL;
+	mbmsSession->ExternalizeL(iBuff);	
+	CleanupStack::PushL(iBuff);
+		
+	CBufFlat* buf=CBufFlat::NewL(iBuff->Length());
+	CleanupStack::PushL(buf);
+	buf->InsertL(0,*iBuff);	
+	
+	read->iListBuf = buf;
+	CleanupStack::Pop(buf);	
+	CleanupStack::PopAndDestroy(iBuff);
+	
+	iMbmsSessionList->AppendL(read);
+	CleanupStack::Pop(); // pop the CListReadAllAttempt
+	
+	// return the CBufBase’s size to client
+	*aBufSize=(read->iListBuf)->Size();
+	CleanupStack::PopAndDestroy(mbmsSession);
+	
+	// Complete first phase of list retrieval
+	ReqCompleted(aTsyReqHandle,KErrNone);
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::GetMbmsSessionsPhase2(const TTsyReqHandle aTsyReqHandle,TClientId* aClient, TDes8* aBuf)
+/**
+* client's interest in retrieving the MBMS Session information.
+* This is the phase2 retrieval
+* 
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aClient ClientId from which the request is sent
+* @param aBuf  Buffer allocated to retrieve the data.
+* @return KErrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::GetMbmsSessionsPhase2 called");
+	CPcktListReadAllAttempt* read=NULL;
+	// Find the get Mbms monitored services from this client
+	for (TInt i=0; i<iMbmsSessionList->Count(); ++i)
+		{
+		read = iMbmsSessionList->At(i);
+		if ((read->iClient.iSessionHandle==aClient->iSessionHandle) &&
+		    (read->iClient.iSubSessionHandle==aClient->iSubSessionHandle))
+			{
+			TPtr8 bufPtr((read->iListBuf)->Ptr(0));
+			// Copy the streamed list to the client
+			aBuf->Copy(bufPtr);
+			delete read;
+			iMbmsSessionList->Delete(i);
+			ReqCompleted(aTsyReqHandle,KErrNone);
+			return KErrNone;
+			}
+		}
+	// Should handle error case of not finding the matching client from read all phase 1
+	ReqCompleted(aTsyReqHandle,KErrBadHandle);
+	return KErrNone;
+	}
+	
+TInt CSimMbmsPacketContext::GetMbmsSessionsCancel(const TTsyReqHandle aTsyReqHandle)
+/**
+* client's interest in cancelling the MBMS Get session request.
+* 
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @return KErrNone
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::GetMbmsSessionsCancel called");
+	// Remove the MBMS sessions from iMbmsSessionList
+	
+	CPcktListReadAllAttempt* read=NULL;
+	for (TInt i=0; i<iMbmsSessionList->Count(); ++i)
+		{
+		read = iMbmsSessionList->At(i);
+		if (read->iReqHandle == aTsyReqHandle)
+			{
+			delete read;
+			iMbmsSessionList->Delete(i);
+			break;
+			}
+		}
+	ReqCompleted(aTsyReqHandle,KErrCancel);
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::ChangeState(RPacketContext::TContextStatus aNewState)
+/**
+* Attempt to change state.
+* First validate that the requested state change is ok.  If it is then proceed to change
+* the state and complete any pending state change notification.
+*
+* @param aNewState the new state to change to
+* @return Error indication if change of state is successful or not
+*/
+	{
+	LOGPACKET2("CSimMbmsPacketContext::ChangeState [newState=%d]", aNewState);
+	__ASSERT_ALWAYS(aNewState!=RPacketContext::EStatusUnknown,SimPanic(ECallStatusUnknownIllegal));
+
+	if(iState==aNewState)
+		return KErrNone;
+
+	TInt ret=KErrGeneral;
+	const struct TMbmsContextStateChangeValidity* stateChangePnt=KMbmsContextStateChangeValidity;
+	while(stateChangePnt->iOldState!=KMbmsContextStateTableTerminator)
+		{
+		if(stateChangePnt->iOldState == RPacketContext::EStatusReceiving && stateChangePnt->iNewState == RPacketContext::EStatusActive)
+			{
+			iLastError = KErrMbmsNotSupported;
+			}
+		else if(stateChangePnt->iOldState == RPacketContext::EStatusReceiving && stateChangePnt->iNewState == RPacketContext::EStatusSuspended)
+			{
+			iLastError = KErrMbmsServicePreempted;
+			}
+		else if(stateChangePnt->iOldState == RPacketContext::EStatusSuspended && stateChangePnt->iNewState == RPacketContext::EStatusActive)
+			{
+			iLastError = KErrMbmsServiceUnavailable;
+			}
+		if((stateChangePnt->iOldState==iState) && (stateChangePnt->iNewState==aNewState))
+			{
+			ret=stateChangePnt->iError;
+			break;
+			}
+		stateChangePnt++;
+		}
+
+	if(ret!=KErrNone)
+		return ret;
+
+	//Request permission from the phone to change the state of the packet connection
+	ret = iPacketService->ChangeState(ConvertToPacketServiceStatus(aNewState));
+	if(ret!=KErrNone)
+		return ret;
+
+	// Actually change the state.
+	iState=aNewState;
+
+	// Check for a pending line state notification.
+	if(iNotifyStatusChange.iNotifyPending)
+		{
+		iNotifyStatusChange.iNotifyPending = EFalse;
+		*(RPacketContext::TContextStatus*)iNotifyStatusChange.iNotifyData = iState;
+		ReqCompleted(iNotifyStatusChange.iNotifyHandle,KErrNone);
+		}
+
+	LOGPACKET1("<<CSimMbmsPacketContext::ChangeState Completed");
+	return KErrNone;
+	}
+
+TInt CSimMbmsPacketContext::ActionEvent(TMbmsContextEvent aEvent)
+/**
+* Entry point when an event has occured that may advance the state machine.
+* The aEvent parameter describes the event.
+*
+* This function contains the main state machine for the packet Context.  
+*
+* @param aEvent The Packet Context event to handle
+* @return value represents the error state caused by the attempted state machine jump.
+*/
+	{
+	LOGPACKET1("<<CSimMbmsPacketContext::ActionEvent Completed");
+	TInt ret=KErrNone;
+	__ASSERT_ALWAYS(iState!=RPacketContext::EStatusUnknown,SimPanic(ECallStatusUnknownIllegal));
+
+	switch(aEvent)
+		{
+		case EMbmsContextEventActivate:
+			LOGPACKET1("CSimMbmsPacketContext::ActionEvent = [EMbmsContextEventActivate]");
+			if(iState==RPacketContext::EStatusInactive)
+				{
+				iCurrentEvent=EMbmsContextEventActivate;
+				ret = ChangeState(RPacketContext::EStatusActivating);
+				iMbmsContextTimer->Start(RandTime(),this);  
+				}
+			else
+				{
+				ReqCompleted(iActivateRequestHandle, KErrGprsActivationRejected);
+				}
+			break;
+
+		case EMbmsContextEventDeactivate:
+			LOGPACKET1("CSimMbmsPacketContext::ActionEvent = [EMbmsContextEventDeactivate]");
+			if(iState==RPacketContext::EStatusActive || iState==RPacketContext::EStatusActivating)
+				{
+				iCurrentEvent=EMbmsContextEventDeactivate;
+				ret = ChangeState(RPacketContext::EStatusDeactivating);
+				iMbmsContextTimer->Start(RandTime(),this);
+				}
+			else
+				{
+				ReqCompleted(iDeactivateRequestHandle, KErrNone);
+				}
+			break;
+
+		case EMbmsContextEventDelete:
+			LOGPACKET1("CSimMbmsPacketContext::ActionEvent = [EMbmsContextEventDelete]");
+			iDeleted = ETrue;
+			if(iState==RPacketContext::EStatusInactive)
+				{
+				iCurrentEvent=EMbmsContextEventDelete;
+				iMbmsContextTimer->Start(RandTime(),this);
+				}
+			else
+				ReqCompleted(iDeleteRequestHandle, KErrInUse);
+			break;
+		default:
+			LOGPACKET1("CSimMbmsPacketContext::ActionEvent = [Default Case]");
+			break;
+		}
+	return ret;
+	}
+
+RPacketService::TStatus CSimMbmsPacketContext::ConvertToPacketServiceStatus(RPacketContext::TContextStatus aNewState)
+/**
+* Converts Packet Context Status (RPacketContext::TContextStatus) to 
+*          Packet Service Status (RPacketService::TStatus)
+*
+* @param aNewState the Context status to convert to packet service status
+* @return RPacketService::TStatus The packet service status conversion
+*/
+	{
+	LOGPACKET1("CSimMbmsPacketContext::ConvertToPacketServiceStatus called");
+	RPacketService::TStatus serviceStatus;
+	switch (aNewState)
+		{
+		case RPacketContext::EStatusInactive:
+		case RPacketContext::EStatusActivating:
+		case RPacketContext::EStatusDeleted:
+			serviceStatus = RPacketService::EStatusAttached;
+			break;
+		case RPacketContext::EStatusActive:
+		case RPacketContext::EStatusDeactivating:
+			serviceStatus = RPacketService::EStatusActive;
+			break;
+		case RPacketContext::EStatusSuspended:
+			serviceStatus = RPacketService::EStatusSuspended;
+			break;
+		default:
+			serviceStatus = RPacketService::EStatusUnattached;
+			break;
+		}
+	return serviceStatus;
+	}
+
+TInt CSimMbmsPacketContext::RandTime()
+/* 
+ * Function that generates time(in seconds) at random for the SimTSY 
+ * Maximum of four seconds; zero seconds also included just to simulate the 
+ * synchronous call scenario 
+ */
+	{
+	LOGPACKET1("CSimMbmsPacketContext::RandTime called");
+	TInt ranT= Math::Random()%4; 
+	return(ranT);
+	}