diff -r 000000000000 -r 3553901f7fa8 telephonyserverplugins/simtsy/src/CSimMbmsPacketContext.cpp --- /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 +#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(KNumberofConfigs); + iSessionIdList = new (ELeave) CArrayFixFlat(1); + iMbmsSessionList = new CArrayPtrFlat(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;iItem(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 (accessBearer); + mbmsConfigParams.iServiceMode = reinterpret_cast (serviceMode); + mbmsConfigParams.iServicePriority = reinterpret_cast (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 + //>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("<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* configBase = (TPckg*)aConfig; + TPacketDataConfigBase& configBaseV1 = (*configBase)(); + iSetConfigRequestHandle = aTsyReqHandle; + TInt err = KErrCorrupt; + + if(configBaseV1.ExtensionId()==TPacketDataConfigBase::KConfigMBMS) + { + TPckg* configMBMSPckg = (TPckg*)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* configBase = (TPckg*)aConfig; + TPacketDataConfigBase& configBaseV1 = (*configBase)(); + + if(configBaseV1.ExtensionId()==TPacketDataConfigBase::KConfigMBMS) + { + + TPckg* configMBMSPckg = (TPckg*)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(iMbmsContextConfigParams->At(iMbmsContextConfigParamsIndex).iAccessBearer); + configMBMS.iMbmsServicePriority = reinterpret_cast(iMbmsContextConfigParams->At(iMbmsContextConfigParamsIndex).iServicePriority); + configMBMS.iMbmsServiceMode = reinterpret_cast(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* configBase = (TPckg*)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; iCount(); ++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; iCount(); ++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("<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); + }