--- a/telephonyserverplugins/simtsy/src/CSimCallWaiting.cpp Mon May 03 13:37:20 2010 +0300
+++ b/telephonyserverplugins/simtsy/src/CSimCallWaiting.cpp Thu May 06 15:10:38 2010 +0100
@@ -1,553 +1,553 @@
-// Copyright (c) 2001-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:
-// Implements the functionality required to provide clients with
-// CallWaiting status and registration information.
-//
-//
-
-/**
- @file
-*/
-
-#include <testconfigfileparser.h>
-#include "CSimCallWaiting.h"
-#include "CSimPhone.h"
-#include "Simlog.h"
-
-const TInt KMobServiceIndxStart = 1;
-const TInt KMobServiceIndxEnd = 5;
-
-
-CSimCallWaiting* CSimCallWaiting::NewL(CSimPhone* aPhone)
-/**
- * Standard two-phase constructor.
- * @param aPhone The parent phone object.
- * @return CSimCallWaiting The new call waiting class.
- */
- {
- CSimCallWaiting* self=new(ELeave) CSimCallWaiting(aPhone);
- CleanupStack::PushL(self);
- self->ConstructL();
- CleanupStack::Pop();
- return self;
- }
-
-CSimCallWaiting::CSimCallWaiting(CSimPhone* aPhone)
- : iPhone(aPhone)
-/**
- * Trivial first phase construction.
- * @param aPhone The parent phone object.
- */
- {
- }
-
-void CSimCallWaiting::ConstructL()
-/**
- Second phase of 2-Phase Constructor
- Retrieves all the Call waiting related tags from the config file
-*/
- {
- LOGCALL1("Starting to parse Call waiting config parameters...");
-
- iGetCWStatus = new(ELeave) CArrayPtrFlat<CListReadAllAttempt>(1);
- FindAndCreateCWListL();
- LOGCALL1("...Finished parsing Call waiting config parameters...");
- }
-
-void CSimCallWaiting::FindAndCreateCWListL()
-{
-/**
- Retrieves all the Call waiting tags that define the
- original status of Call waiting from the config file
-*/
- LOGCALL1("CSimPhone::FindAndCreateCWListL");
- RMobilePhone::TMobilePhoneCWInfoEntryV1 entry;
-
- iCWList = CMobilePhoneCWList::NewL();
- TInt count=CfgFile()->ItemCount(KCWList);
- const CTestConfigItem* item=NULL;
- TInt ret=KErrNone;
-
- LOGCALL1("Starting to Load and Parse CWList Config parameters");
- TInt i;
- for(i=0;i<count;i++)
- {
- item=CfgFile()->Item(KCWList,i);
- if(!item)
- break;
-
- TInt serviceGroup, status;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,serviceGroup);
- if(ret!=KErrNone)
- {
- LOGPARSERR("serviceGroup",ret,0,&KCWList);
- continue;
- }
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,status);
- if(ret!=KErrNone)
- {
- LOGPARSERR("status",ret,1,&KCWList);
- continue;
- }
-
- entry.iServiceGroup=(RMobilePhone::TMobileService)serviceGroup;
- entry.iStatus=(RMobilePhone::TMobilePhoneCWStatus)status;
-
- iCWList->AddEntryL(entry);
- }
- }
-
-CSimCallWaiting::~CSimCallWaiting()
- {
- delete iCWList;
- if (iGetCWStatus)
- iGetCWStatus->ResetAndDestroy();
- delete iGetCWStatus;
- }
-
-TInt CSimCallWaiting::ExtFuncL(const TTsyReqHandle aReqHandle,const TInt aIpc, const TDataPackage& aPckg)
- {
- /**
- Handles the phone based requests that apply to call waiting
- @param aReqHandle Handle to the request
- @param aIpc request identifier
- @param aPckg contains additional information for the requests
- */
-
- TAny* dataPtr = aPckg.Ptr1();
- TAny* dataPtr2 = aPckg.Ptr2();
- // The following requests can be completed even if the completion of another request is pending.
- switch(aIpc)
- {
- case EMobilePhoneSetCallWaitingStatus:
- return SetCallWaitingStatusL(aReqHandle,
- REINTERPRET_CAST(RMobilePhone::TMobileService*, dataPtr),
- REINTERPRET_CAST(RMobilePhone::TMobilePhoneServiceAction*,dataPtr2));
- case EMobilePhoneNotifyCallWaitingStatusChange:
- return NotifyCallWaitingStatusChange(aReqHandle, REINTERPRET_CAST(RMobilePhone::TMobilePhoneCWInfoEntryV1*, dataPtr));
- case EMobilePhoneGetWaitingStatusPhase1:
- return GetCallWaitingStatusPhase1(aReqHandle,
- REINTERPRET_CAST(CRetrieveMobilePhoneCWList::TGetCallWaitingRequest*, dataPtr),
- REINTERPRET_CAST(TInt*, dataPtr2));
- case EMobilePhoneGetWaitingStatusPhase2:
- return GetCallWaitingStatusPhase2(aReqHandle,
- REINTERPRET_CAST(RMobilePhone::TClientId*, dataPtr), aPckg.Des2n());
- default:
- break;
- }
- return KErrNotSupported;
- }
-
-TInt CSimCallWaiting::CancelService(const TInt aIpc, const TTsyReqHandle aReqHandle)
- {
- /**
- Cancels any phone based request regarding call waiting
- @param aIpc the IPC to cancel
- @param aReqHandle handle to the request
- */
- switch(aIpc)
- {
- case EMobilePhoneSetCallWaitingStatus:
- return SetCallWaitingStatusCancel(aReqHandle);
- case EMobilePhoneNotifyCallWaitingStatusChange:
- return NotifyCallWaitingStatusChangeCancel(aReqHandle);
- default:
- break;
- }
- return KErrNone;
- }
-
-TInt CSimCallWaiting::NotifyCallWaitingStatusChange(const TTsyReqHandle aReqHandle, RMobilePhone::TMobilePhoneCWInfoEntryV1* aCW)
- {
- /**
- Requests to be notified of change in the Call Waiting status
- @param aReqHandle Handle to the request
- @param aCW contains the service group and new status that has changed
- */
- __ASSERT_ALWAYS(!iCWNotification.iCWChangeInfoNotificationPending,SimPanic(ENotificationReqAlreadyOutstanding));
- iCWNotification.iCWChangeInfoNotificationPending=ETrue;
- iCWNotification.iCWChangeInfoReqHandle=aReqHandle;
- iCWNotification.iCWInfo=aCW;
- LOGCALL1("Finished CSimCallWaiting::NotifyCallWaitingStatusChange");
- return KErrNone;
- }
-
-TInt CSimCallWaiting::NotifyCallWaitingStatusChangeCancel(const TTsyReqHandle aReqHandle)
- {
- /**
- Cancels request to be notified of call Waiting status change
- @param aReqHandle Handle to the request
- */
- if(iCWNotification.iCWChangeInfoNotificationPending)
- {
- iCWNotification.iCWChangeInfoNotificationPending=EFalse;
- iPhone->ReqCompleted(aReqHandle,KErrCancel);
- }
- return KErrNone;
- }
-
-TInt CSimCallWaiting::SetCallWaitingStatusL(const TTsyReqHandle aReqHandle, RMobilePhone::TMobileService* aService, RMobilePhone::TMobilePhoneServiceAction* aAction)
- {
- /**
- Sets the status for call Waiting
- @param aReqHandle Handle to the request
- @param aCB condition for which the client whishes to set the call Waiting status
- @param aInfo additional parameters to set the call Waiting status
- */
-
- // make sure we know that the operation concluded sucessfully
- TRAPD(ret,UpdateCWListL(aService,aAction));
- if ( ret != KErrNone )
- {
- iPhone->ReqCompleted(aReqHandle,ret);
- }
-
- // otherwise proceed and notify all went well
- // Notify change
- if (iCWNotification.iCWChangeInfoNotificationPending)
- {
-
- (iCWNotification.iCWInfo->iServiceGroup)=*aService;
-
- switch (*aAction)
- {
- case RMobilePhone::EServiceActionRegister:
- case RMobilePhone::EServiceActionActivate:
- iCWNotification.iCWInfo->iStatus= RMobilePhone::ECallWaitingStatusActive;
- break;
- case RMobilePhone::EServiceActionDeactivate:
- case RMobilePhone::EServiceActionErase:
- iCWNotification.iCWInfo->iStatus= RMobilePhone::ECallWaitingStatusNotActive;
- break;
- case RMobilePhone::EServiceActionUnspecified:
- default:
- iCWNotification.iCWInfo->iStatus= RMobilePhone::ECallWaitingStatusUnknown;
- // no sense doing any further operation - leave
- User::Leave( KErrArgument );
- break;
- }
-
- iCWNotification.iCWChangeInfoNotificationPending=EFalse;
- iPhone->ReqCompleted(iCWNotification.iCWChangeInfoReqHandle,KErrNone);
- }
-
- iPhone->ReqCompleted(aReqHandle,KErrNone);
-
- return KErrNone;
- }
-
-TInt CSimCallWaiting::SetCallWaitingStatusCancel(const TTsyReqHandle aReqHandle)
- {
- /**
- Cancels the request to sets the status for call waiting
- @param aReqHandle Handle to the request
- */
-
- iPhone->ReqCompleted(aReqHandle,KErrCancel);
- return KErrNone;
- }
-
-
-
-const CTestConfigSection* CSimCallWaiting::CfgFile()
-/**
- * Returns a pointer to the current configuration file section.
- *
- * @return CTestConfigSection A pointer to the current configuration file data section.
- */
- {
- return iPhone->CfgFile();
- }
-
-TInt CSimCallWaiting::GetCallWaitingStatusPhase1(const TTsyReqHandle aTsyReqHandle,
- CRetrieveMobilePhoneCWList::TGetCallWaitingRequest* aReqData,
- TInt* aBufSize)
- {
- /**
- 1st phase retrieval of the the call waiting status list
- @param aReqHandle Handle to the request
- @param aReqData information about the request
- @param aBufSize Size of the buffer the client has to allocate for the 2nd pahase
- */
- LOGCALL1("CSimCallWaiting::GetCalWaitingStatusPhase1");
-
- TInt ret=KErrNone;
- TInt leaveCode=KErrNone;
- TRAP(leaveCode, ret=ProcessGetCallWaitingStatusPhase1L(aTsyReqHandle, aReqData, aBufSize););
- if (leaveCode != KErrNone)
- iPhone->ReqCompleted(aTsyReqHandle,leaveCode);
-
- LOGCALL1("CSimCallWaiting::GetCalWaitingStatusPhase1");
- return ret;
- }
-
-TInt CSimCallWaiting::ProcessGetCallWaitingStatusPhase1L(const TTsyReqHandle aTsyReqHandle,
- CRetrieveMobilePhoneCWList::TGetCallWaitingRequest* aReqData,
- TInt* aBufSize)
- {
- /** Retrieve call waiting status of each line from phone,
- store each CB status response as a list entry,
- stream the list and then return size of this buffer to client
- @param aReqHandle Handle to the request
- @param aReqData information about the request
- @param aBufSize Size of the buffer the client has to allocate for the 2nd pahase
- */
- LOGCALL1("CSimCallWaiting::ProcessGetCallWaitingStatusPhase1L");
-
- CMobilePhoneCWList* list=CMobilePhoneCWList::NewL();
- CleanupStack::PushL(list);
-
- TInt maxNum=iCWList->Enumerate();
- //if testing all CB are non-active
- // then we have to return a single entry EAllServices
- if ( maxNum )
- {
- for(TInt i=0;i<maxNum;i++)
- {
- list->AddEntryL(iCWList->GetEntryL(i));
- }
- }
- else
- {
- // if the list is empty and the querry general then we have to return general info
- RMobilePhone::TMobilePhoneCWInfoEntryV1 entry;
-
- // Check that the data structure is supported by the simulated TSY version
- TInt err = iPhone->CheckSimTsyVersion(entry);
- if(err != KErrNone)
- {
- iPhone->ReqCompleted(aTsyReqHandle, err);
- return KErrNone;
- }
-
- entry.iServiceGroup = RMobilePhone::EAllServices;
- entry.iStatus = RMobilePhone::ECallWaitingStatusNotActive;
- list->AddEntryL( entry );
- }
-
- // Store the streamed list and the client ID
- CListReadAllAttempt* read=CListReadAllAttempt::NewL(aReqData->iClient,aTsyReqHandle);
- CleanupStack::PushL(read);
-
- read->iListBuf = list->StoreLC();
- CleanupStack::Pop(); // pop the CBufBase allocated by StoreLC
-
- iGetCWStatus->AppendL(read);
- CleanupStack::Pop(read); // pop the CListReadAllAttempt
-
- // return the CBufBase’s size to client
- *aBufSize=(read->iListBuf)->Size();
-
- CleanupStack::PopAndDestroy(list); // pop&destroy list
-
- // Complete first phase of list retrieval
- iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
-
- LOGCALL1("CSimCallWaiting::ProcessGetCallWaitingStatusPhase1L");
- return KErrNone;
- }
-
-TInt CSimCallWaiting::GetCallWaitingStatusPhase2(const TTsyReqHandle aTsyReqHandle,
- RMobilePhone::TClientId* aClient, TDes8* aBuf)
- {
- /**
- 2nd phase retrieval of the the call waiting status list
- @param aReqHandle Handle to the request
- @param aClient Ponter to the client
- @param aBuf Buffer containiong the call waiting status list
- */
- LOGCALL1("CSimCallWaiting::GetCallWaitingStatusPhase2");
- CListReadAllAttempt* read=NULL;
- // Find the get detected network attempt from this client
- for (TInt i=0; i<iGetCWStatus->Count(); ++i)
- {
- read = iGetCWStatus->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;
- iGetCWStatus->Delete(i);
- iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
- }
- // Should handle error case of not finding the matching client from read all phase 1
- LOGCALL1("CSimCallWaiting::GetCallWaitingStatusPhase2");
- return KErrNotFound;
- }
-
-TInt CSimCallWaiting::GetCallWaitingStatusCancel(const TTsyReqHandle aTsyReqHandle)
- {
- /*
- Cancels a Request to retrieve the call waiting status list
- @param aReqHandle Handle to the request
- */
- LOGCALL1("CSimCallWaiting::GetCallWaitingStatusCancel");
- iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
- // Remove the read all attempt from iGetCBStatus
- CListReadAllAttempt* read=NULL;
- for (TInt i=0; i<iGetCWStatus->Count(); ++i)
- {
- read = iGetCWStatus->At(i);
- if (read->iReqHandle == aTsyReqHandle)
- {
- delete read;
- iGetCWStatus->Delete(i);
- break;
- }
- }
- iPhone->ReqCompleted(aTsyReqHandle,KErrCancel);
- LOGCALL1("CSimCallWaiting::GetCallWaitingStatusCancel");
- return KErrNone;
- }
-
-inline void SplitOneEntryIntoSeparateGroupsL(
- CMobilePhoneCWList* aCWList,
- RMobilePhone::TMobilePhoneCWInfoEntryV1 aOrigEntry,
- RMobilePhone::TMobileService aExceptServiceGroup
- )
- {
- /*
- Splits one entry valid for all basic service groups into individual entries
- and places them into a CMobilePhoneCBList. This excludes one service group.
- @param aCBList The list to which to store the entries
- @param aOrigEntry The original entry; details of which should be passed to individual group entries
- @param aExceptServiceGroup The group which has to be avoided
- */
- // we have to split the entry into entries
- // per group with the same condition; excluding the specified service group
- RMobilePhone::TMobilePhoneCWInfoEntryV1 anotherEntry = aOrigEntry;
-
- //anotherEntry.iCondition = aOrigEntry.iCondition;
- //anotherEntry.iStatus = RMobilePhone::ECallBarringStatusActive;
- RMobilePhone::TMobileService service;
-
- for (TInt i=KMobServiceIndxStart; i<=KMobServiceIndxEnd;i++)
- {
- service=static_cast<RMobilePhone::TMobileService>(i);
- if( service != aExceptServiceGroup )
- {
- anotherEntry.iServiceGroup=service;
- aCWList->AddEntryL(anotherEntry);
- }
- }//end for (another)
- }
-
-void CSimCallWaiting::UpdateCWListL(RMobilePhone::TMobileService* aServiceGroup, RMobilePhone::TMobilePhoneServiceAction* aAction )
- {
- /*
- Updates the status of call waiting.
- @param aServiceGroup service group to set
- @param aAction ation to be performed
- */
-
- // no sense processing if either condition or change info are NULLS
- User::LeaveIfNull(aServiceGroup);
- User::LeaveIfNull(aAction);
-
-
- //Lets do some work then
- RMobilePhone::TMobilePhoneCWInfoEntryV1 theNewEntry;
-
- theNewEntry.iServiceGroup = *aServiceGroup;
-
- switch (*aAction)
- {
- case RMobilePhone::EServiceActionRegister:
- case RMobilePhone::EServiceActionActivate:
- theNewEntry.iStatus= RMobilePhone::ECallWaitingStatusActive;
- break;
- case RMobilePhone::EServiceActionDeactivate:
- case RMobilePhone::EServiceActionErase:
- theNewEntry.iStatus= RMobilePhone::ECallWaitingStatusNotActive;
- break;
- case RMobilePhone::EServiceActionUnspecified:
- default:
- theNewEntry.iStatus= RMobilePhone::ECallWaitingStatusUnknown;
- // no sense doing any further operation - leave
- User::Leave( KErrArgument );
- break;
- }
-
- // retain prev version of the list in local variable and in Cleanup stack
- CMobilePhoneCWList* thePrevCWList = CMobilePhoneCWList::NewL();
- CleanupStack::PushL(thePrevCWList);
- // copy existing data into the temp storage
- for (TInt indx=0; indx<iCWList->Enumerate(); indx++)
- {
- thePrevCWList->AddEntryL(iCWList->GetEntryL(indx));
- }
- delete iCWList;
- iCWList = NULL;
-
- // create a new version and hold it in the class member
- iCWList = CMobilePhoneCWList::NewL();
- // get a hold of it in a local variable
- CMobilePhoneCWList* theNewCWList = iCWList;
- RMobilePhone::TMobilePhoneCWInfoEntryV1 entry;
-
- TInt count = thePrevCWList->Enumerate();
-
- if (theNewEntry.iStatus == RMobilePhone::ECallWaitingStatusActive)
- {
- if (theNewEntry.iServiceGroup==RMobilePhone::EAllServices)
- {
- theNewCWList->AddEntryL(theNewEntry);
- }
- else
- {
- for (TInt i = 0; i<count; i++)
- {
- entry = thePrevCWList->GetEntryL(i);
- if(entry.iServiceGroup!=theNewEntry.iServiceGroup
- && entry.iServiceGroup!=RMobilePhone::EAllServices)
- theNewCWList->AddEntryL(entry);
- }
- theNewCWList->AddEntryL(theNewEntry);
- }
- }
- else //deactivate
- {
- if (theNewEntry.iServiceGroup==RMobilePhone::EAllServices)
- {
- theNewCWList->AddEntryL(theNewEntry);
- }
- else
- {
- for (TInt i = 0; i<count; i++)
- {
- entry = thePrevCWList->GetEntryL(i);
- if(entry.iServiceGroup==RMobilePhone::EAllServices)
- {
- //add to the list active entries for all servive groups but the one to be deactivated
- SplitOneEntryIntoSeparateGroupsL(theNewCWList,entry, theNewEntry.iServiceGroup);
- continue;
- }
- if(entry.iServiceGroup!=theNewEntry.iServiceGroup)
- {
- theNewCWList->AddEntryL(entry);
- }
- }
- }
-
- }
- // now delete the old memory
- CleanupStack::PopAndDestroy(thePrevCWList);
- }
-
+// Copyright (c) 2001-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:
+// Implements the functionality required to provide clients with
+// CallWaiting status and registration information.
+//
+//
+
+/**
+ @file
+*/
+
+#include <testconfigfileparser.h>
+#include "CSimCallWaiting.h"
+#include "CSimPhone.h"
+#include "Simlog.h"
+
+const TInt KMobServiceIndxStart = 1;
+const TInt KMobServiceIndxEnd = 5;
+
+
+CSimCallWaiting* CSimCallWaiting::NewL(CSimPhone* aPhone)
+/**
+ * Standard two-phase constructor.
+ * @param aPhone The parent phone object.
+ * @return CSimCallWaiting The new call waiting class.
+ */
+ {
+ CSimCallWaiting* self=new(ELeave) CSimCallWaiting(aPhone);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+CSimCallWaiting::CSimCallWaiting(CSimPhone* aPhone)
+ : iPhone(aPhone)
+/**
+ * Trivial first phase construction.
+ * @param aPhone The parent phone object.
+ */
+ {
+ }
+
+void CSimCallWaiting::ConstructL()
+/**
+ Second phase of 2-Phase Constructor
+ Retrieves all the Call waiting related tags from the config file
+*/
+ {
+ LOGCALL1("Starting to parse Call waiting config parameters...");
+
+ iGetCWStatus = new(ELeave) CArrayPtrFlat<CListReadAllAttempt>(1);
+ FindAndCreateCWListL();
+ LOGCALL1("...Finished parsing Call waiting config parameters...");
+ }
+
+void CSimCallWaiting::FindAndCreateCWListL()
+{
+/**
+ Retrieves all the Call waiting tags that define the
+ original status of Call waiting from the config file
+*/
+ LOGCALL1("CSimPhone::FindAndCreateCWListL");
+ RMobilePhone::TMobilePhoneCWInfoEntryV1 entry;
+
+ iCWList = CMobilePhoneCWList::NewL();
+ TInt count=CfgFile()->ItemCount(KCWList);
+ const CTestConfigItem* item=NULL;
+ TInt ret=KErrNone;
+
+ LOGCALL1("Starting to Load and Parse CWList Config parameters");
+ TInt i;
+ for(i=0;i<count;i++)
+ {
+ item=CfgFile()->Item(KCWList,i);
+ if(!item)
+ break;
+
+ TInt serviceGroup, status;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,serviceGroup);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("serviceGroup",ret,0,&KCWList);
+ continue;
+ }
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,status);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("status",ret,1,&KCWList);
+ continue;
+ }
+
+ entry.iServiceGroup=(RMobilePhone::TMobileService)serviceGroup;
+ entry.iStatus=(RMobilePhone::TMobilePhoneCWStatus)status;
+
+ iCWList->AddEntryL(entry);
+ }
+ }
+
+CSimCallWaiting::~CSimCallWaiting()
+ {
+ delete iCWList;
+ if (iGetCWStatus)
+ iGetCWStatus->ResetAndDestroy();
+ delete iGetCWStatus;
+ }
+
+TInt CSimCallWaiting::ExtFuncL(const TTsyReqHandle aReqHandle,const TInt aIpc, const TDataPackage& aPckg)
+ {
+ /**
+ Handles the phone based requests that apply to call waiting
+ @param aReqHandle Handle to the request
+ @param aIpc request identifier
+ @param aPckg contains additional information for the requests
+ */
+
+ TAny* dataPtr = aPckg.Ptr1();
+ TAny* dataPtr2 = aPckg.Ptr2();
+ // The following requests can be completed even if the completion of another request is pending.
+ switch(aIpc)
+ {
+ case EMobilePhoneSetCallWaitingStatus:
+ return SetCallWaitingStatusL(aReqHandle,
+ REINTERPRET_CAST(RMobilePhone::TMobileService*, dataPtr),
+ REINTERPRET_CAST(RMobilePhone::TMobilePhoneServiceAction*,dataPtr2));
+ case EMobilePhoneNotifyCallWaitingStatusChange:
+ return NotifyCallWaitingStatusChange(aReqHandle, REINTERPRET_CAST(RMobilePhone::TMobilePhoneCWInfoEntryV1*, dataPtr));
+ case EMobilePhoneGetWaitingStatusPhase1:
+ return GetCallWaitingStatusPhase1(aReqHandle,
+ REINTERPRET_CAST(CRetrieveMobilePhoneCWList::TGetCallWaitingRequest*, dataPtr),
+ REINTERPRET_CAST(TInt*, dataPtr2));
+ case EMobilePhoneGetWaitingStatusPhase2:
+ return GetCallWaitingStatusPhase2(aReqHandle,
+ REINTERPRET_CAST(RMobilePhone::TClientId*, dataPtr), aPckg.Des2n());
+ default:
+ break;
+ }
+ return KErrNotSupported;
+ }
+
+TInt CSimCallWaiting::CancelService(const TInt aIpc, const TTsyReqHandle aReqHandle)
+ {
+ /**
+ Cancels any phone based request regarding call waiting
+ @param aIpc the IPC to cancel
+ @param aReqHandle handle to the request
+ */
+ switch(aIpc)
+ {
+ case EMobilePhoneSetCallWaitingStatus:
+ return SetCallWaitingStatusCancel(aReqHandle);
+ case EMobilePhoneNotifyCallWaitingStatusChange:
+ return NotifyCallWaitingStatusChangeCancel(aReqHandle);
+ default:
+ break;
+ }
+ return KErrNone;
+ }
+
+TInt CSimCallWaiting::NotifyCallWaitingStatusChange(const TTsyReqHandle aReqHandle, RMobilePhone::TMobilePhoneCWInfoEntryV1* aCW)
+ {
+ /**
+ Requests to be notified of change in the Call Waiting status
+ @param aReqHandle Handle to the request
+ @param aCW contains the service group and new status that has changed
+ */
+ __ASSERT_ALWAYS(!iCWNotification.iCWChangeInfoNotificationPending,SimPanic(ENotificationReqAlreadyOutstanding));
+ iCWNotification.iCWChangeInfoNotificationPending=ETrue;
+ iCWNotification.iCWChangeInfoReqHandle=aReqHandle;
+ iCWNotification.iCWInfo=aCW;
+ LOGCALL1("Finished CSimCallWaiting::NotifyCallWaitingStatusChange");
+ return KErrNone;
+ }
+
+TInt CSimCallWaiting::NotifyCallWaitingStatusChangeCancel(const TTsyReqHandle aReqHandle)
+ {
+ /**
+ Cancels request to be notified of call Waiting status change
+ @param aReqHandle Handle to the request
+ */
+ if(iCWNotification.iCWChangeInfoNotificationPending)
+ {
+ iCWNotification.iCWChangeInfoNotificationPending=EFalse;
+ iPhone->ReqCompleted(aReqHandle,KErrCancel);
+ }
+ return KErrNone;
+ }
+
+TInt CSimCallWaiting::SetCallWaitingStatusL(const TTsyReqHandle aReqHandle, RMobilePhone::TMobileService* aService, RMobilePhone::TMobilePhoneServiceAction* aAction)
+ {
+ /**
+ Sets the status for call Waiting
+ @param aReqHandle Handle to the request
+ @param aCB condition for which the client whishes to set the call Waiting status
+ @param aInfo additional parameters to set the call Waiting status
+ */
+
+ // make sure we know that the operation concluded sucessfully
+ TRAPD(ret,UpdateCWListL(aService,aAction));
+ if ( ret != KErrNone )
+ {
+ iPhone->ReqCompleted(aReqHandle,ret);
+ }
+
+ // otherwise proceed and notify all went well
+ // Notify change
+ if (iCWNotification.iCWChangeInfoNotificationPending)
+ {
+
+ (iCWNotification.iCWInfo->iServiceGroup)=*aService;
+
+ switch (*aAction)
+ {
+ case RMobilePhone::EServiceActionRegister:
+ case RMobilePhone::EServiceActionActivate:
+ iCWNotification.iCWInfo->iStatus= RMobilePhone::ECallWaitingStatusActive;
+ break;
+ case RMobilePhone::EServiceActionDeactivate:
+ case RMobilePhone::EServiceActionErase:
+ iCWNotification.iCWInfo->iStatus= RMobilePhone::ECallWaitingStatusNotActive;
+ break;
+ case RMobilePhone::EServiceActionUnspecified:
+ default:
+ iCWNotification.iCWInfo->iStatus= RMobilePhone::ECallWaitingStatusUnknown;
+ // no sense doing any further operation - leave
+ User::Leave( KErrArgument );
+ break;
+ }
+
+ iCWNotification.iCWChangeInfoNotificationPending=EFalse;
+ iPhone->ReqCompleted(iCWNotification.iCWChangeInfoReqHandle,KErrNone);
+ }
+
+ iPhone->ReqCompleted(aReqHandle,KErrNone);
+
+ return KErrNone;
+ }
+
+TInt CSimCallWaiting::SetCallWaitingStatusCancel(const TTsyReqHandle aReqHandle)
+ {
+ /**
+ Cancels the request to sets the status for call waiting
+ @param aReqHandle Handle to the request
+ */
+
+ iPhone->ReqCompleted(aReqHandle,KErrCancel);
+ return KErrNone;
+ }
+
+
+
+const CTestConfigSection* CSimCallWaiting::CfgFile()
+/**
+ * Returns a pointer to the current configuration file section.
+ *
+ * @return CTestConfigSection A pointer to the current configuration file data section.
+ */
+ {
+ return iPhone->CfgFile();
+ }
+
+TInt CSimCallWaiting::GetCallWaitingStatusPhase1(const TTsyReqHandle aTsyReqHandle,
+ CRetrieveMobilePhoneCWList::TGetCallWaitingRequest* aReqData,
+ TInt* aBufSize)
+ {
+ /**
+ 1st phase retrieval of the the call waiting status list
+ @param aReqHandle Handle to the request
+ @param aReqData information about the request
+ @param aBufSize Size of the buffer the client has to allocate for the 2nd pahase
+ */
+ LOGCALL1("CSimCallWaiting::GetCalWaitingStatusPhase1");
+
+ TInt ret=KErrNone;
+ TInt leaveCode=KErrNone;
+ TRAP(leaveCode, ret=ProcessGetCallWaitingStatusPhase1L(aTsyReqHandle, aReqData, aBufSize););
+ if (leaveCode != KErrNone)
+ iPhone->ReqCompleted(aTsyReqHandle,leaveCode);
+
+ LOGCALL1("CSimCallWaiting::GetCalWaitingStatusPhase1");
+ return ret;
+ }
+
+TInt CSimCallWaiting::ProcessGetCallWaitingStatusPhase1L(const TTsyReqHandle aTsyReqHandle,
+ CRetrieveMobilePhoneCWList::TGetCallWaitingRequest* aReqData,
+ TInt* aBufSize)
+ {
+ /** Retrieve call waiting status of each line from phone,
+ store each CB status response as a list entry,
+ stream the list and then return size of this buffer to client
+ @param aReqHandle Handle to the request
+ @param aReqData information about the request
+ @param aBufSize Size of the buffer the client has to allocate for the 2nd pahase
+ */
+ LOGCALL1("CSimCallWaiting::ProcessGetCallWaitingStatusPhase1L");
+
+ CMobilePhoneCWList* list=CMobilePhoneCWList::NewL();
+ CleanupStack::PushL(list);
+
+ TInt maxNum=iCWList->Enumerate();
+ //if testing all CB are non-active
+ // then we have to return a single entry EAllServices
+ if ( maxNum )
+ {
+ for(TInt i=0;i<maxNum;i++)
+ {
+ list->AddEntryL(iCWList->GetEntryL(i));
+ }
+ }
+ else
+ {
+ // if the list is empty and the querry general then we have to return general info
+ RMobilePhone::TMobilePhoneCWInfoEntryV1 entry;
+
+ // Check that the data structure is supported by the simulated TSY version
+ TInt err = iPhone->CheckSimTsyVersion(entry);
+ if(err != KErrNone)
+ {
+ iPhone->ReqCompleted(aTsyReqHandle, err);
+ return KErrNone;
+ }
+
+ entry.iServiceGroup = RMobilePhone::EAllServices;
+ entry.iStatus = RMobilePhone::ECallWaitingStatusNotActive;
+ list->AddEntryL( entry );
+ }
+
+ // Store the streamed list and the client ID
+ CListReadAllAttempt* read=CListReadAllAttempt::NewL(aReqData->iClient,aTsyReqHandle);
+ CleanupStack::PushL(read);
+
+ read->iListBuf = list->StoreLC();
+ CleanupStack::Pop(); // pop the CBufBase allocated by StoreLC
+
+ iGetCWStatus->AppendL(read);
+ CleanupStack::Pop(read); // pop the CListReadAllAttempt
+
+ // return the CBufBase’s size to client
+ *aBufSize=(read->iListBuf)->Size();
+
+ CleanupStack::PopAndDestroy(list); // pop&destroy list
+
+ // Complete first phase of list retrieval
+ iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
+
+ LOGCALL1("CSimCallWaiting::ProcessGetCallWaitingStatusPhase1L");
+ return KErrNone;
+ }
+
+TInt CSimCallWaiting::GetCallWaitingStatusPhase2(const TTsyReqHandle aTsyReqHandle,
+ RMobilePhone::TClientId* aClient, TDes8* aBuf)
+ {
+ /**
+ 2nd phase retrieval of the the call waiting status list
+ @param aReqHandle Handle to the request
+ @param aClient Ponter to the client
+ @param aBuf Buffer containiong the call waiting status list
+ */
+ LOGCALL1("CSimCallWaiting::GetCallWaitingStatusPhase2");
+ CListReadAllAttempt* read=NULL;
+ // Find the get detected network attempt from this client
+ for (TInt i=0; i<iGetCWStatus->Count(); ++i)
+ {
+ read = iGetCWStatus->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;
+ iGetCWStatus->Delete(i);
+ iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+ }
+ // Should handle error case of not finding the matching client from read all phase 1
+ LOGCALL1("CSimCallWaiting::GetCallWaitingStatusPhase2");
+ return KErrNotFound;
+ }
+
+TInt CSimCallWaiting::GetCallWaitingStatusCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ /*
+ Cancels a Request to retrieve the call waiting status list
+ @param aReqHandle Handle to the request
+ */
+ LOGCALL1("CSimCallWaiting::GetCallWaitingStatusCancel");
+ iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
+ // Remove the read all attempt from iGetCBStatus
+ CListReadAllAttempt* read=NULL;
+ for (TInt i=0; i<iGetCWStatus->Count(); ++i)
+ {
+ read = iGetCWStatus->At(i);
+ if (read->iReqHandle == aTsyReqHandle)
+ {
+ delete read;
+ iGetCWStatus->Delete(i);
+ break;
+ }
+ }
+ iPhone->ReqCompleted(aTsyReqHandle,KErrCancel);
+ LOGCALL1("CSimCallWaiting::GetCallWaitingStatusCancel");
+ return KErrNone;
+ }
+
+inline void SplitOneEntryIntoSeparateGroupsL(
+ CMobilePhoneCWList* aCWList,
+ RMobilePhone::TMobilePhoneCWInfoEntryV1 aOrigEntry,
+ RMobilePhone::TMobileService aExceptServiceGroup
+ )
+ {
+ /*
+ Splits one entry valid for all basic service groups into individual entries
+ and places them into a CMobilePhoneCBList. This excludes one service group.
+ @param aCBList The list to which to store the entries
+ @param aOrigEntry The original entry; details of which should be passed to individual group entries
+ @param aExceptServiceGroup The group which has to be avoided
+ */
+ // we have to split the entry into entries
+ // per group with the same condition; excluding the specified service group
+ RMobilePhone::TMobilePhoneCWInfoEntryV1 anotherEntry = aOrigEntry;
+
+ //anotherEntry.iCondition = aOrigEntry.iCondition;
+ //anotherEntry.iStatus = RMobilePhone::ECallBarringStatusActive;
+ RMobilePhone::TMobileService service;
+
+ for (TInt i=KMobServiceIndxStart; i<=KMobServiceIndxEnd;i++)
+ {
+ service=static_cast<RMobilePhone::TMobileService>(i);
+ if( service != aExceptServiceGroup )
+ {
+ anotherEntry.iServiceGroup=service;
+ aCWList->AddEntryL(anotherEntry);
+ }
+ }//end for (another)
+ }
+
+void CSimCallWaiting::UpdateCWListL(RMobilePhone::TMobileService* aServiceGroup, RMobilePhone::TMobilePhoneServiceAction* aAction )
+ {
+ /*
+ Updates the status of call waiting.
+ @param aServiceGroup service group to set
+ @param aAction ation to be performed
+ */
+
+ // no sense processing if either condition or change info are NULLS
+ User::LeaveIfNull(aServiceGroup);
+ User::LeaveIfNull(aAction);
+
+
+ //Lets do some work then
+ RMobilePhone::TMobilePhoneCWInfoEntryV1 theNewEntry;
+
+ theNewEntry.iServiceGroup = *aServiceGroup;
+
+ switch (*aAction)
+ {
+ case RMobilePhone::EServiceActionRegister:
+ case RMobilePhone::EServiceActionActivate:
+ theNewEntry.iStatus= RMobilePhone::ECallWaitingStatusActive;
+ break;
+ case RMobilePhone::EServiceActionDeactivate:
+ case RMobilePhone::EServiceActionErase:
+ theNewEntry.iStatus= RMobilePhone::ECallWaitingStatusNotActive;
+ break;
+ case RMobilePhone::EServiceActionUnspecified:
+ default:
+ theNewEntry.iStatus= RMobilePhone::ECallWaitingStatusUnknown;
+ // no sense doing any further operation - leave
+ User::Leave( KErrArgument );
+ break;
+ }
+
+ // retain prev version of the list in local variable and in Cleanup stack
+ CMobilePhoneCWList* thePrevCWList = CMobilePhoneCWList::NewL();
+ CleanupStack::PushL(thePrevCWList);
+ // copy existing data into the temp storage
+ for (TInt indx=0; indx<iCWList->Enumerate(); indx++)
+ {
+ thePrevCWList->AddEntryL(iCWList->GetEntryL(indx));
+ }
+ delete iCWList;
+ iCWList = NULL;
+
+ // create a new version and hold it in the class member
+ iCWList = CMobilePhoneCWList::NewL();
+ // get a hold of it in a local variable
+ CMobilePhoneCWList* theNewCWList = iCWList;
+ RMobilePhone::TMobilePhoneCWInfoEntryV1 entry;
+
+ TInt count = thePrevCWList->Enumerate();
+
+ if (theNewEntry.iStatus == RMobilePhone::ECallWaitingStatusActive)
+ {
+ if (theNewEntry.iServiceGroup==RMobilePhone::EAllServices)
+ {
+ theNewCWList->AddEntryL(theNewEntry);
+ }
+ else
+ {
+ for (TInt i = 0; i<count; i++)
+ {
+ entry = thePrevCWList->GetEntryL(i);
+ if(entry.iServiceGroup!=theNewEntry.iServiceGroup
+ && entry.iServiceGroup!=RMobilePhone::EAllServices)
+ theNewCWList->AddEntryL(entry);
+ }
+ theNewCWList->AddEntryL(theNewEntry);
+ }
+ }
+ else //deactivate
+ {
+ if (theNewEntry.iServiceGroup==RMobilePhone::EAllServices)
+ {
+ theNewCWList->AddEntryL(theNewEntry);
+ }
+ else
+ {
+ for (TInt i = 0; i<count; i++)
+ {
+ entry = thePrevCWList->GetEntryL(i);
+ if(entry.iServiceGroup==RMobilePhone::EAllServices)
+ {
+ //add to the list active entries for all servive groups but the one to be deactivated
+ SplitOneEntryIntoSeparateGroupsL(theNewCWList,entry, theNewEntry.iServiceGroup);
+ continue;
+ }
+ if(entry.iServiceGroup!=theNewEntry.iServiceGroup)
+ {
+ theNewCWList->AddEntryL(entry);
+ }
+ }
+ }
+
+ }
+ // now delete the old memory
+ CleanupStack::PopAndDestroy(thePrevCWList);
+ }
+