--- a/telephonyserverplugins/simtsy/src/CSimCallBarring.cpp Mon May 03 13:37:20 2010 +0300
+++ b/telephonyserverplugins/simtsy/src/CSimCallBarring.cpp Thu May 06 15:10:38 2010 +0100
@@ -1,700 +1,700 @@
-// 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
-// callBarring status and registration information.
-//
-//
-
-/**
- @file
-*/
-
-#include <testconfigfileparser.h>
-#include "CSimCallBarring.h"
-#include "CSimPhone.h"
-#include "Simlog.h"
-
-// The Mobile Basic Service Groups used - originally were magic numbers from 1 to 6 incl;
-const TInt KMobServiceIndxStart = 1;
-const TInt KMobServiceIndxEnd = 6;
-
-
-CSimCallBarring* CSimCallBarring::NewL(CSimPhone* aPhone)
-/**
- * Standard two-phase constructor.
- * @param aPhone The parent phone object.
- * @return CSimNetworkStatus The new network status class.
- */
- {
- CSimCallBarring* self=new(ELeave) CSimCallBarring(aPhone);
- CleanupStack::PushL(self);
- self->ConstructL();
- CleanupStack::Pop();
- return self;
- }
-
-CSimCallBarring::CSimCallBarring(CSimPhone* aPhone)
- : iPhone(aPhone)
-/**
- * Trivial first phase construction.
- * @param aPhone The parent phone object.
- */
- {
- }
-
-void CSimCallBarring::ConstructL()
-/**
- Second phase of 2-Phase Constructor
- Retrieves all the Call Barring related tags from the config file
-*/
- {
- LOGCALL1("Starting to parse Call Barring config parameters...");
-
- iPassword.Copy(CfgFile()->ItemValue(KCBPassword,KCBDefaultPassword));
-
- iGetCBStatus = new(ELeave) CArrayPtrFlat<CListReadAllAttempt>(1);
- FindAndCreateCBListL();
- LOGCALL1("...Finished parsing Call Barring config parameters...");
- }
-
-void CSimCallBarring::FindAndCreateCBListL()
-{
-/**
- Retrieves all the Call barring tags that define the
- original status of Call barring from the config file
-*/
- LOGCALL1("CSimPhone::FindAndCreateCBListL");
- RMobilePhone::TMobilePhoneCBInfoEntryV1 entry;
-
- iCBList = CMobilePhoneCBList::NewL();
- TInt count=CfgFile()->ItemCount(KCBList);
- const CTestConfigItem* item=NULL;
- TInt ret=KErrNone;
-
- LOGCALL1("Starting to Load and Parse CBList Config parameters");
- TInt i;
- for(i=0;i<count;i++)
- {
- item=CfgFile()->Item(KCBList,i);
- if(!item)
- break;
-
- TInt condition, serviceGroup, status;
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,condition);
- if(ret!=KErrNone)
- {
- LOGPARSERR("condition",ret,0,&KCBList);
- continue;
- }
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,serviceGroup);
- if(ret!=KErrNone)
- {
- LOGPARSERR("serviceGroup",ret,1,&KCBList);
- continue;
- }
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,status);
- if(ret!=KErrNone)
- {
- LOGPARSERR("status",ret,2,&KCBList);
- continue;
- }
-
- entry.iCondition=(RMobilePhone::TMobilePhoneCBCondition)condition;
- entry.iServiceGroup=(RMobilePhone::TMobileService)serviceGroup;
- entry.iStatus=(RMobilePhone::TMobilePhoneCBStatus)status;
-
- iCBList->AddEntryL(entry);
- }
- }
-
-CSimCallBarring::~CSimCallBarring()
- {
- delete iCBList;
- if (iGetCBStatus)
- iGetCBStatus->ResetAndDestroy();
- delete iGetCBStatus;
- }
-
-TInt CSimCallBarring::ExtFunc(const TTsyReqHandle aReqHandle,const TInt aIpc, const TDataPackage& aPckg)
- {
- /**
- Handles the phone based requests that apply to call barring
- @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 EMobilePhoneSetCallBarringStatus:
- return SetCallBarringStatus(aReqHandle,
- reinterpret_cast<RMobilePhone::TMobilePhoneCBCondition*>(dataPtr),
- reinterpret_cast<RMobilePhone::TMobilePhoneCBChangeV1*>(dataPtr2));
- case EMobilePhoneSetCallBarringPassword:
- return SetCallBarringPassword(aReqHandle,reinterpret_cast<RMobilePhone::TMobilePhonePasswordChangeV1*>(dataPtr));
- case EMobilePhoneNotifyCallBarringStatusChange:
- return NotifyCallBarringStatusChange(aReqHandle, reinterpret_cast<RMobilePhone::TMobilePhoneCBCondition*>(dataPtr));
- case EMobilePhoneGetBarringStatusPhase1:
- return GetCallBarringStatusPhase1(aReqHandle,
- REINTERPRET_CAST(CRetrieveMobilePhoneCBList::TGetCallBarringRequest*, dataPtr),
- REINTERPRET_CAST(TInt*, dataPtr2));
- case EMobilePhoneGetBarringStatusPhase2:
- return GetCallBarringStatusPhase2(aReqHandle,
- REINTERPRET_CAST(RMobilePhone::TClientId*, dataPtr), aPckg.Des2n());
- default:
- break;
- }
- return KErrNotSupported;
- }
-
-TInt CSimCallBarring::CancelService(const TInt aIpc, const TTsyReqHandle aReqHandle)
- {
- /**
- Cancels any phone based request regarding call barring
- @param aIpc the IPC to cancel
- @param aReqHandle handle to the request
- */
- switch(aIpc)
- {
- case EMobilePhoneSetCallBarringStatus:
- return SetCallBarringStatusCancel(aReqHandle);
- case EMobilePhoneSetCallBarringPassword:
- return SetCallBarringPasswordCancel(aReqHandle);
- case EMobilePhoneNotifyCallBarringStatusChange:
- return NotifyCallBarringStatusChangeCancel(aReqHandle);
- default:
- break;
- }
- return KErrNone;
- }
-
-TInt CSimCallBarring::NotifyCallBarringStatusChange(const TTsyReqHandle aReqHandle, RMobilePhone::TMobilePhoneCBCondition* aCB)
- {
- /**
- Requests to be notified of change in the Call baring status
- @param aReqHandle Handle to the request
- @param aCB condition for which the client is interested in being notified
- */
- __ASSERT_ALWAYS(!iCBNotification.iCBChangeInfoNotificationPending,SimPanic(ENotificationReqAlreadyOutstanding));
- iCBNotification.iCBChangeInfoNotificationPending=ETrue;
- iCBNotification.iCBChangeInfoReqHandle=aReqHandle;
- iCBNotification.iCurrentCBCondition=aCB;
- LOGCALL1("Finished CSimCallBarring::NotifyCallBarringStatusChange");
- return KErrNone;
- }
-
-TInt CSimCallBarring::NotifyCallBarringStatusChangeCancel(const TTsyReqHandle aReqHandle)
- {
- /**
- Cancels request to be notified of call barring status change
- @param aReqHandle Handle to the request
- */
- if(iCBNotification.iCBChangeInfoNotificationPending)
- {
- iCBNotification.iCBChangeInfoNotificationPending=EFalse;
- iPhone->ReqCompleted(aReqHandle,KErrCancel);
- }
- return KErrNone;
- }
-
-TInt CSimCallBarring::SetCallBarringStatus(const TTsyReqHandle aReqHandle, RMobilePhone::TMobilePhoneCBCondition* aCB, RMobilePhone::TMobilePhoneCBChangeV1* aInfo)
- {
- /**
- Sets the status for call barring
- @param aReqHandle Handle to the request
- @param aCB condition for which the client whishes to set the call barring status
- @param aInfo additional parameters to set the call barring status
- */
- //Password does not correspond, return KErrAccessDenied .. is that right ? Not specified in SDK!
- if (iPassword != aInfo->iPassword)
- {
- iPhone->ReqCompleted(aReqHandle,KErrAccessDenied);
- return KErrNone;
- }
-
- // make sure we know that the operation concluded sucessfully
- TRAPD(ret,UpdateCBListL(aCB,aInfo));
- if ( ret != KErrNone )
- {
- iPhone->ReqCompleted(aReqHandle,ret);
- return KErrNone;
- }
-
- // otherwise proceed and notify all went well
- // Notify change
- if (iCBNotification.iCBChangeInfoNotificationPending)
- {
- *(iCBNotification.iCurrentCBCondition)=*aCB;
- iCBNotification.iCBChangeInfoNotificationPending=EFalse;
- iPhone->ReqCompleted(iCBNotification.iCBChangeInfoReqHandle,KErrNone);
- }
-
- iPhone->ReqCompleted(aReqHandle,KErrNone);
-
- return KErrNone;
- }
-
-TInt CSimCallBarring::SetCallBarringStatusCancel(const TTsyReqHandle aReqHandle)
- {
- /**
- Cancels the request to sets the status for call barring
- @param aReqHandle Handle to the request
- */
-
- iPhone->ReqCompleted(aReqHandle,KErrCancel);
- return KErrNone;
- }
-
-TInt CSimCallBarring::SetCallBarringPassword(const TTsyReqHandle aReqHandle, RMobilePhone::TMobilePhonePasswordChangeV1* aInfo)
- {
- /**
- Sets the password that prevents the call barring status to be modified
- @param aReqHandle Handle to the request
- @param aInfo The old and new password
- */
- if (iPassword == aInfo->iOldPassword)
- {
- iPassword = aInfo->iNewPassword;
- iPhone->ReqCompleted(aReqHandle,KErrNone);
- }
- else
- {
- iPhone->ReqCompleted(aReqHandle,KErrAccessDenied);
- }
- return KErrNone;
- }
-
-TInt CSimCallBarring::SetCallBarringPasswordCancel(const TTsyReqHandle aReqHandle)
- {
- /**
- cancels a request to set the password that prevents the call barring status to be modified
- @param aReqHandle Handle to the request
- */
- iPhone->ReqCompleted(aReqHandle,KErrCancel);
- return KErrNone;
- }
-
-
-const CTestConfigSection* CSimCallBarring::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 CSimCallBarring::GetCallBarringStatusPhase1(const TTsyReqHandle aTsyReqHandle,
- CRetrieveMobilePhoneCBList::TGetCallBarringRequest* aReqData,
- TInt* aBufSize)
- {
- /**
- 1st phase retrieval of the the call barring 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("CSimPhone::GetCallBarringStatusPhase1");
-
- TInt ret=KErrNone;
- TInt leaveCode=KErrNone;
- TRAP(leaveCode, ret=ProcessGetCallBarringStatusPhase1L(aTsyReqHandle, aReqData, aBufSize););
- if (leaveCode != KErrNone)
- iPhone->ReqCompleted(aTsyReqHandle,leaveCode);
-
- LOGCALL1("CSimPhone::GetCallBarringStatusPhase1");
- return ret;
- }
-
-TInt CSimCallBarring::ProcessGetCallBarringStatusPhase1L(const TTsyReqHandle aTsyReqHandle,
- CRetrieveMobilePhoneCBList::TGetCallBarringRequest* aReqData,
- TInt* aBufSize)
- {
- /** Retrieve call barring 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("CSimCallBarring::ProcessGetCallBarringStatusPhase1L");
-
- CMobilePhoneCBList* list=CMobilePhoneCBList::NewL();
- CleanupStack::PushL(list);
-
-
- TInt cnt=0;//Only interested by entries with a particular condition
- TInt maxNum=iCBList->Enumerate();
- //if testing all conditions and all CB are non-active
- // then we have to return a single entry EBarAllCases and EAllServices
- if ( maxNum )
- {
- for(TInt i=0;i<maxNum;i++)
- {
- if((iCBList->GetEntryL(i).iCondition == aReqData->iCondition)
- ||(aReqData->iCondition==RMobilePhone::EBarUnspecified))
- {
- list->AddEntryL(iCBList->GetEntryL(i));
- cnt++;
- }
- }
- }
- else
- {
- // if the list is empty and the querry general then we have to return general info
- if ( aReqData->iCondition == RMobilePhone::EBarUnspecified )
- {
- RMobilePhone::TMobilePhoneCBInfoEntryV1 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.iCondition = RMobilePhone::EBarAllCases;
- entry.iServiceGroup = RMobilePhone::EAllServices;
- entry.iStatus = RMobilePhone::ECallBarringStatusNotActive;
- 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
-
- iGetCBStatus->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("CSimCallBarring::ProcessGetCallBarringStatusPhase1L");
- return KErrNone;
- }
-
-TInt CSimCallBarring::GetCallBarringStatusPhase2(const TTsyReqHandle aTsyReqHandle,
- RMobilePhone::TClientId* aClient, TDes8* aBuf)
- {
- /**
- 2nd phase retrieval of the the call barring status list
- @param aReqHandle Handle to the request
- @param aClient Ponter to the client
- @param aBuf Buffer containiong the call barring status list
- */
- LOGCALL1("CSimCallBarring::GetCallBarringStatusPhase2");
- CListReadAllAttempt* read=NULL;
- // Find the get detected network attempt from this client
- for (TInt i=0; i<iGetCBStatus->Count(); ++i)
- {
- read = iGetCBStatus->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;
- iGetCBStatus->Delete(i);
- iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
- return KErrNone;
- }
- }
- // Should handle error case of not finding the matching client from read all phase 1
- LOGCALL1("CSimCallBarring::GetCallBarringStatusPhase2");
- return KErrNotFound;
- }
-
-TInt CSimCallBarring::GetCallBarringStatusCancel(const TTsyReqHandle aTsyReqHandle)
- {
- /*
- Cancels a Request to retrieve the call barring status list
- @param aReqHandle Handle to the request
- */
- LOGCALL1("CSimCallBarring::GetCallBarringStatusCancel");
- iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
- // Remove the read all attempt from iGetCBStatus
- CListReadAllAttempt* read=NULL;
- for (TInt i=0; i<iGetCBStatus->Count(); ++i)
- {
- read = iGetCBStatus->At(i);
- if (read->iReqHandle == aTsyReqHandle)
- {
- delete read;
- iGetCBStatus->Delete(i);
- break;
- }
- }
- iPhone->ReqCompleted(aTsyReqHandle,KErrCancel);
- LOGCALL1("CSimCallBarring::GetCallBarringStatusCancel");
- return KErrNone;
- }
-
-// some useful functions for checking the type of conditions
-inline TBool IsOutgoingCondition( RMobilePhone::TMobilePhoneCBCondition aCondition )
- {
- return ( (aCondition)==RMobilePhone::EBarAllOutgoing ||
- (aCondition)==RMobilePhone::EBarOutgoingInternational ||
- (aCondition)==RMobilePhone::EBarOutgoingInternationalExHC );
- }
-
-inline TBool IsIncomingCondition( RMobilePhone::TMobilePhoneCBCondition aCondition )
- {
- return ( (aCondition)==RMobilePhone::EBarAllIncoming ||
- (aCondition)==RMobilePhone::EBarIncomingRoaming );
- }
-
-inline TBool IsDeactivationConditionOnly( RMobilePhone::TMobilePhoneCBCondition aCondition )
- {
- return ( (aCondition)==RMobilePhone::EBarAllCases ||
- (aCondition)==RMobilePhone::EBarAllOutgoingServices ||
- (aCondition)==RMobilePhone::EBarAllIncomingServices );
- }
-
-inline void SplitOneEntryIntoSeparateGroupsL(
- CMobilePhoneCBList* aCBList,
- RMobilePhone::TMobilePhoneCBInfoEntryV1 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::TMobilePhoneCBInfoEntryV1 anotherEntry = aOrigEntry;
-
- // NOTE: A call to CheckSimTsyVersion must be inserted here if there is a
- // change to the version of the structure declared above
-
- //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;
- aCBList->AddEntryL(anotherEntry);
- }
- }//end for (another)
- }
-
-void CSimCallBarring::UpdateCBListL(RMobilePhone::TMobilePhoneCBCondition* aCB, RMobilePhone::TMobilePhoneCBChangeV1* aCBInfo )
- {
- /*
- Updates the status of call barring.
- @param aCB condition to set
- @param aCBInfo details of the call barring status to set
- */
- // no sense processing if either condition or change info are NULLS
- User::LeaveIfNull(aCBInfo);
- User::LeaveIfNull(aCB);
-
- // check for more conditions as some of the combinations really do not make sense
- // and no need to do processing in this case
- if (*aCB == RMobilePhone::EBarUnspecified)
- User::Leave(KErrArgument);
- if ( IsDeactivationConditionOnly(*aCB)
- && ( !( (aCBInfo->iAction == RMobilePhone::EServiceActionDeactivate )
- || (aCBInfo->iAction == RMobilePhone::EServiceActionErase ))))
- User::Leave(KErrArgument);
-
- //Lets do some work then
- RMobilePhone::TMobilePhoneCBInfoEntryV1 theNewEntry;
-
- theNewEntry.iCondition = *aCB;
- theNewEntry.iServiceGroup = aCBInfo->iServiceGroup;
- switch (aCBInfo->iAction)
- {
- case RMobilePhone::EServiceActionRegister:
- case RMobilePhone::EServiceActionActivate:
- theNewEntry.iStatus= RMobilePhone::ECallBarringStatusActive;
- break;
- case RMobilePhone::EServiceActionDeactivate:
- case RMobilePhone::EServiceActionErase:
- theNewEntry.iStatus= RMobilePhone::ECallBarringStatusNotActive;
- break;
- case RMobilePhone::EServiceActionUnspecified:
- default:
- // no sense doing any further operation - leave
- User::Leave(KErrArgument);
- break;
- }
-
- // retain prev version of the list in local variable and in Cleanup stack
- CMobilePhoneCBList* thePrevCBList = CMobilePhoneCBList::NewL();
- CleanupStack::PushL(thePrevCBList);
- // copy existing data into the temp storage
- for (TInt indx=0; indx<iCBList->Enumerate(); indx++)
- {
- thePrevCBList->AddEntryL(iCBList->GetEntryL(indx));
- }
- delete iCBList;
- iCBList = NULL;
- // get a hold of it in a local variable
- iCBList = CMobilePhoneCBList::NewL();
- // get a hold of it in a local variable
- CMobilePhoneCBList* theNewCBList = iCBList;
- RMobilePhone::TMobilePhoneCBInfoEntryV1 entry;
-
- TInt count = thePrevCBList->Enumerate();
-
- if (theNewEntry.iStatus == RMobilePhone::ECallBarringStatusActive)
- {
- if (theNewEntry.iServiceGroup==RMobilePhone::EAllServices)
- {
- //Activate all conds
- //action is to ActivateAllServices with a particular condition;
- //Only copy entries with a different condition
- for (TInt i = 0; i<count; i++)
- {
- entry = thePrevCBList->GetEntryL(i);
- //check if the new entry will encompass conditions already defined
- // if it does the existing entry is not needed
- if (!(
- theNewEntry.iCondition==entry.iCondition
- ||
- ( IsOutgoingCondition(entry.iCondition) && IsOutgoingCondition(theNewEntry.iCondition))
- ||
- ( IsIncomingCondition(entry.iCondition) && IsIncomingCondition(theNewEntry.iCondition))
- ))
- theNewCBList->AddEntryL(entry);
- }//end for
- theNewCBList->AddEntryL(theNewEntry);
- }
- else
- {
- //ActivateOne;
- // working under the assumption that if EBarOutgoingInternational is enabled
- // for EAllServices then setting the fax group, for example to EBarOutgoingInternational
- // specifically, will be ignored due to inclusion. Also setting the same condition
- // for the same service group(s) again will be ignored.
- TBool addNewElem = TRUE;
-
- for (TInt i = 0; i<count; i++)
- {
- entry = thePrevCBList->GetEntryL(i);
- // are in the same direction?
- if ( (IsOutgoingCondition(theNewEntry.iCondition) && IsOutgoingCondition(entry.iCondition))
- || (IsIncomingCondition(theNewEntry.iCondition) && IsIncomingCondition(entry.iCondition)))
- {
- // they are in the same direction
- // is the current entry specific to a group or not ?
- if (entry.iServiceGroup != RMobilePhone::EAllServices)
- {
- if (theNewEntry.iServiceGroup != entry.iServiceGroup)
- theNewCBList->AddEntryL(entry);
- }
- else
- {
- // the entry is for all groups
- if (theNewEntry.iCondition == entry.iCondition)
- {
- // the group already precludes this condition;
- // just add the existing
- theNewCBList->AddEntryL(entry);
- addNewElem = FALSE;
- }
- else
- {
- // we have to split the entry into entries
- // per group with the same condition
- SplitOneEntryIntoSeparateGroupsL(
- theNewCBList, entry, theNewEntry.iServiceGroup
- );
- }// end split entry
- }
- }
- else
- {
- // they are in different directions
- // no need to check further; just add it
- theNewCBList->AddEntryL(entry);
- }//end are in the same direction?
- }// for loop
- if (addNewElem)
- {
- theNewCBList->AddEntryL(theNewEntry);
- }
- }//end else
- }
- else //deactivate
- {
- if (
- (theNewEntry.iServiceGroup==RMobilePhone::EAllServices)
- &&(theNewEntry.iCondition==RMobilePhone::EBarAllCases)
- )
- ;//Deactivate all conditions: do nothing, list is empty.
- else
- {
- for (TInt i = 0; i<count; i++)
- {
- entry = thePrevCBList->GetEntryL(i);
-
- if (theNewEntry.iCondition == RMobilePhone::EBarAllCases
- ||
- (( theNewEntry.iCondition == RMobilePhone::EBarAllOutgoingServices || IsOutgoingCondition(theNewEntry.iCondition))
- && IsOutgoingCondition(entry.iCondition))
- ||
- ((theNewEntry.iCondition == RMobilePhone::EBarAllIncomingServices || IsIncomingCondition(theNewEntry.iCondition))
- && IsIncomingCondition(entry.iCondition)))
- {
- if(theNewEntry.iServiceGroup!=RMobilePhone::EAllServices
- && entry.iServiceGroup==RMobilePhone::EAllServices)
- {
- SplitOneEntryIntoSeparateGroupsL(
- theNewCBList, entry, theNewEntry.iServiceGroup
- );
- }//end if(create others)
- else
- {//action applies to different service group
- if((theNewEntry.iServiceGroup!=RMobilePhone::EAllServices )
- && (theNewEntry.iServiceGroup!=entry.iServiceGroup))
- theNewCBList->AddEntryL(entry);
- }
-
- }//end if
- else
- {//action applies to different condition
- theNewCBList->AddEntryL(entry);
- }//end else
- }//end for (entries)
- }//end else(all)
- }//end else(deactivate)
-
- //destroy the previous version, the local theNewCBList will be destroyed
- CleanupStack::PopAndDestroy(thePrevCBList);
- }
+// 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
+// callBarring status and registration information.
+//
+//
+
+/**
+ @file
+*/
+
+#include <testconfigfileparser.h>
+#include "CSimCallBarring.h"
+#include "CSimPhone.h"
+#include "Simlog.h"
+
+// The Mobile Basic Service Groups used - originally were magic numbers from 1 to 6 incl;
+const TInt KMobServiceIndxStart = 1;
+const TInt KMobServiceIndxEnd = 6;
+
+
+CSimCallBarring* CSimCallBarring::NewL(CSimPhone* aPhone)
+/**
+ * Standard two-phase constructor.
+ * @param aPhone The parent phone object.
+ * @return CSimNetworkStatus The new network status class.
+ */
+ {
+ CSimCallBarring* self=new(ELeave) CSimCallBarring(aPhone);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+CSimCallBarring::CSimCallBarring(CSimPhone* aPhone)
+ : iPhone(aPhone)
+/**
+ * Trivial first phase construction.
+ * @param aPhone The parent phone object.
+ */
+ {
+ }
+
+void CSimCallBarring::ConstructL()
+/**
+ Second phase of 2-Phase Constructor
+ Retrieves all the Call Barring related tags from the config file
+*/
+ {
+ LOGCALL1("Starting to parse Call Barring config parameters...");
+
+ iPassword.Copy(CfgFile()->ItemValue(KCBPassword,KCBDefaultPassword));
+
+ iGetCBStatus = new(ELeave) CArrayPtrFlat<CListReadAllAttempt>(1);
+ FindAndCreateCBListL();
+ LOGCALL1("...Finished parsing Call Barring config parameters...");
+ }
+
+void CSimCallBarring::FindAndCreateCBListL()
+{
+/**
+ Retrieves all the Call barring tags that define the
+ original status of Call barring from the config file
+*/
+ LOGCALL1("CSimPhone::FindAndCreateCBListL");
+ RMobilePhone::TMobilePhoneCBInfoEntryV1 entry;
+
+ iCBList = CMobilePhoneCBList::NewL();
+ TInt count=CfgFile()->ItemCount(KCBList);
+ const CTestConfigItem* item=NULL;
+ TInt ret=KErrNone;
+
+ LOGCALL1("Starting to Load and Parse CBList Config parameters");
+ TInt i;
+ for(i=0;i<count;i++)
+ {
+ item=CfgFile()->Item(KCBList,i);
+ if(!item)
+ break;
+
+ TInt condition, serviceGroup, status;
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,condition);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("condition",ret,0,&KCBList);
+ continue;
+ }
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,serviceGroup);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("serviceGroup",ret,1,&KCBList);
+ continue;
+ }
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,status);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("status",ret,2,&KCBList);
+ continue;
+ }
+
+ entry.iCondition=(RMobilePhone::TMobilePhoneCBCondition)condition;
+ entry.iServiceGroup=(RMobilePhone::TMobileService)serviceGroup;
+ entry.iStatus=(RMobilePhone::TMobilePhoneCBStatus)status;
+
+ iCBList->AddEntryL(entry);
+ }
+ }
+
+CSimCallBarring::~CSimCallBarring()
+ {
+ delete iCBList;
+ if (iGetCBStatus)
+ iGetCBStatus->ResetAndDestroy();
+ delete iGetCBStatus;
+ }
+
+TInt CSimCallBarring::ExtFunc(const TTsyReqHandle aReqHandle,const TInt aIpc, const TDataPackage& aPckg)
+ {
+ /**
+ Handles the phone based requests that apply to call barring
+ @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 EMobilePhoneSetCallBarringStatus:
+ return SetCallBarringStatus(aReqHandle,
+ reinterpret_cast<RMobilePhone::TMobilePhoneCBCondition*>(dataPtr),
+ reinterpret_cast<RMobilePhone::TMobilePhoneCBChangeV1*>(dataPtr2));
+ case EMobilePhoneSetCallBarringPassword:
+ return SetCallBarringPassword(aReqHandle,reinterpret_cast<RMobilePhone::TMobilePhonePasswordChangeV1*>(dataPtr));
+ case EMobilePhoneNotifyCallBarringStatusChange:
+ return NotifyCallBarringStatusChange(aReqHandle, reinterpret_cast<RMobilePhone::TMobilePhoneCBCondition*>(dataPtr));
+ case EMobilePhoneGetBarringStatusPhase1:
+ return GetCallBarringStatusPhase1(aReqHandle,
+ REINTERPRET_CAST(CRetrieveMobilePhoneCBList::TGetCallBarringRequest*, dataPtr),
+ REINTERPRET_CAST(TInt*, dataPtr2));
+ case EMobilePhoneGetBarringStatusPhase2:
+ return GetCallBarringStatusPhase2(aReqHandle,
+ REINTERPRET_CAST(RMobilePhone::TClientId*, dataPtr), aPckg.Des2n());
+ default:
+ break;
+ }
+ return KErrNotSupported;
+ }
+
+TInt CSimCallBarring::CancelService(const TInt aIpc, const TTsyReqHandle aReqHandle)
+ {
+ /**
+ Cancels any phone based request regarding call barring
+ @param aIpc the IPC to cancel
+ @param aReqHandle handle to the request
+ */
+ switch(aIpc)
+ {
+ case EMobilePhoneSetCallBarringStatus:
+ return SetCallBarringStatusCancel(aReqHandle);
+ case EMobilePhoneSetCallBarringPassword:
+ return SetCallBarringPasswordCancel(aReqHandle);
+ case EMobilePhoneNotifyCallBarringStatusChange:
+ return NotifyCallBarringStatusChangeCancel(aReqHandle);
+ default:
+ break;
+ }
+ return KErrNone;
+ }
+
+TInt CSimCallBarring::NotifyCallBarringStatusChange(const TTsyReqHandle aReqHandle, RMobilePhone::TMobilePhoneCBCondition* aCB)
+ {
+ /**
+ Requests to be notified of change in the Call baring status
+ @param aReqHandle Handle to the request
+ @param aCB condition for which the client is interested in being notified
+ */
+ __ASSERT_ALWAYS(!iCBNotification.iCBChangeInfoNotificationPending,SimPanic(ENotificationReqAlreadyOutstanding));
+ iCBNotification.iCBChangeInfoNotificationPending=ETrue;
+ iCBNotification.iCBChangeInfoReqHandle=aReqHandle;
+ iCBNotification.iCurrentCBCondition=aCB;
+ LOGCALL1("Finished CSimCallBarring::NotifyCallBarringStatusChange");
+ return KErrNone;
+ }
+
+TInt CSimCallBarring::NotifyCallBarringStatusChangeCancel(const TTsyReqHandle aReqHandle)
+ {
+ /**
+ Cancels request to be notified of call barring status change
+ @param aReqHandle Handle to the request
+ */
+ if(iCBNotification.iCBChangeInfoNotificationPending)
+ {
+ iCBNotification.iCBChangeInfoNotificationPending=EFalse;
+ iPhone->ReqCompleted(aReqHandle,KErrCancel);
+ }
+ return KErrNone;
+ }
+
+TInt CSimCallBarring::SetCallBarringStatus(const TTsyReqHandle aReqHandle, RMobilePhone::TMobilePhoneCBCondition* aCB, RMobilePhone::TMobilePhoneCBChangeV1* aInfo)
+ {
+ /**
+ Sets the status for call barring
+ @param aReqHandle Handle to the request
+ @param aCB condition for which the client whishes to set the call barring status
+ @param aInfo additional parameters to set the call barring status
+ */
+ //Password does not correspond, return KErrAccessDenied .. is that right ? Not specified in SDK!
+ if (iPassword != aInfo->iPassword)
+ {
+ iPhone->ReqCompleted(aReqHandle,KErrAccessDenied);
+ return KErrNone;
+ }
+
+ // make sure we know that the operation concluded sucessfully
+ TRAPD(ret,UpdateCBListL(aCB,aInfo));
+ if ( ret != KErrNone )
+ {
+ iPhone->ReqCompleted(aReqHandle,ret);
+ return KErrNone;
+ }
+
+ // otherwise proceed and notify all went well
+ // Notify change
+ if (iCBNotification.iCBChangeInfoNotificationPending)
+ {
+ *(iCBNotification.iCurrentCBCondition)=*aCB;
+ iCBNotification.iCBChangeInfoNotificationPending=EFalse;
+ iPhone->ReqCompleted(iCBNotification.iCBChangeInfoReqHandle,KErrNone);
+ }
+
+ iPhone->ReqCompleted(aReqHandle,KErrNone);
+
+ return KErrNone;
+ }
+
+TInt CSimCallBarring::SetCallBarringStatusCancel(const TTsyReqHandle aReqHandle)
+ {
+ /**
+ Cancels the request to sets the status for call barring
+ @param aReqHandle Handle to the request
+ */
+
+ iPhone->ReqCompleted(aReqHandle,KErrCancel);
+ return KErrNone;
+ }
+
+TInt CSimCallBarring::SetCallBarringPassword(const TTsyReqHandle aReqHandle, RMobilePhone::TMobilePhonePasswordChangeV1* aInfo)
+ {
+ /**
+ Sets the password that prevents the call barring status to be modified
+ @param aReqHandle Handle to the request
+ @param aInfo The old and new password
+ */
+ if (iPassword == aInfo->iOldPassword)
+ {
+ iPassword = aInfo->iNewPassword;
+ iPhone->ReqCompleted(aReqHandle,KErrNone);
+ }
+ else
+ {
+ iPhone->ReqCompleted(aReqHandle,KErrAccessDenied);
+ }
+ return KErrNone;
+ }
+
+TInt CSimCallBarring::SetCallBarringPasswordCancel(const TTsyReqHandle aReqHandle)
+ {
+ /**
+ cancels a request to set the password that prevents the call barring status to be modified
+ @param aReqHandle Handle to the request
+ */
+ iPhone->ReqCompleted(aReqHandle,KErrCancel);
+ return KErrNone;
+ }
+
+
+const CTestConfigSection* CSimCallBarring::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 CSimCallBarring::GetCallBarringStatusPhase1(const TTsyReqHandle aTsyReqHandle,
+ CRetrieveMobilePhoneCBList::TGetCallBarringRequest* aReqData,
+ TInt* aBufSize)
+ {
+ /**
+ 1st phase retrieval of the the call barring 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("CSimPhone::GetCallBarringStatusPhase1");
+
+ TInt ret=KErrNone;
+ TInt leaveCode=KErrNone;
+ TRAP(leaveCode, ret=ProcessGetCallBarringStatusPhase1L(aTsyReqHandle, aReqData, aBufSize););
+ if (leaveCode != KErrNone)
+ iPhone->ReqCompleted(aTsyReqHandle,leaveCode);
+
+ LOGCALL1("CSimPhone::GetCallBarringStatusPhase1");
+ return ret;
+ }
+
+TInt CSimCallBarring::ProcessGetCallBarringStatusPhase1L(const TTsyReqHandle aTsyReqHandle,
+ CRetrieveMobilePhoneCBList::TGetCallBarringRequest* aReqData,
+ TInt* aBufSize)
+ {
+ /** Retrieve call barring 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("CSimCallBarring::ProcessGetCallBarringStatusPhase1L");
+
+ CMobilePhoneCBList* list=CMobilePhoneCBList::NewL();
+ CleanupStack::PushL(list);
+
+
+ TInt cnt=0;//Only interested by entries with a particular condition
+ TInt maxNum=iCBList->Enumerate();
+ //if testing all conditions and all CB are non-active
+ // then we have to return a single entry EBarAllCases and EAllServices
+ if ( maxNum )
+ {
+ for(TInt i=0;i<maxNum;i++)
+ {
+ if((iCBList->GetEntryL(i).iCondition == aReqData->iCondition)
+ ||(aReqData->iCondition==RMobilePhone::EBarUnspecified))
+ {
+ list->AddEntryL(iCBList->GetEntryL(i));
+ cnt++;
+ }
+ }
+ }
+ else
+ {
+ // if the list is empty and the querry general then we have to return general info
+ if ( aReqData->iCondition == RMobilePhone::EBarUnspecified )
+ {
+ RMobilePhone::TMobilePhoneCBInfoEntryV1 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.iCondition = RMobilePhone::EBarAllCases;
+ entry.iServiceGroup = RMobilePhone::EAllServices;
+ entry.iStatus = RMobilePhone::ECallBarringStatusNotActive;
+ 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
+
+ iGetCBStatus->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("CSimCallBarring::ProcessGetCallBarringStatusPhase1L");
+ return KErrNone;
+ }
+
+TInt CSimCallBarring::GetCallBarringStatusPhase2(const TTsyReqHandle aTsyReqHandle,
+ RMobilePhone::TClientId* aClient, TDes8* aBuf)
+ {
+ /**
+ 2nd phase retrieval of the the call barring status list
+ @param aReqHandle Handle to the request
+ @param aClient Ponter to the client
+ @param aBuf Buffer containiong the call barring status list
+ */
+ LOGCALL1("CSimCallBarring::GetCallBarringStatusPhase2");
+ CListReadAllAttempt* read=NULL;
+ // Find the get detected network attempt from this client
+ for (TInt i=0; i<iGetCBStatus->Count(); ++i)
+ {
+ read = iGetCBStatus->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;
+ iGetCBStatus->Delete(i);
+ iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
+ return KErrNone;
+ }
+ }
+ // Should handle error case of not finding the matching client from read all phase 1
+ LOGCALL1("CSimCallBarring::GetCallBarringStatusPhase2");
+ return KErrNotFound;
+ }
+
+TInt CSimCallBarring::GetCallBarringStatusCancel(const TTsyReqHandle aTsyReqHandle)
+ {
+ /*
+ Cancels a Request to retrieve the call barring status list
+ @param aReqHandle Handle to the request
+ */
+ LOGCALL1("CSimCallBarring::GetCallBarringStatusCancel");
+ iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
+ // Remove the read all attempt from iGetCBStatus
+ CListReadAllAttempt* read=NULL;
+ for (TInt i=0; i<iGetCBStatus->Count(); ++i)
+ {
+ read = iGetCBStatus->At(i);
+ if (read->iReqHandle == aTsyReqHandle)
+ {
+ delete read;
+ iGetCBStatus->Delete(i);
+ break;
+ }
+ }
+ iPhone->ReqCompleted(aTsyReqHandle,KErrCancel);
+ LOGCALL1("CSimCallBarring::GetCallBarringStatusCancel");
+ return KErrNone;
+ }
+
+// some useful functions for checking the type of conditions
+inline TBool IsOutgoingCondition( RMobilePhone::TMobilePhoneCBCondition aCondition )
+ {
+ return ( (aCondition)==RMobilePhone::EBarAllOutgoing ||
+ (aCondition)==RMobilePhone::EBarOutgoingInternational ||
+ (aCondition)==RMobilePhone::EBarOutgoingInternationalExHC );
+ }
+
+inline TBool IsIncomingCondition( RMobilePhone::TMobilePhoneCBCondition aCondition )
+ {
+ return ( (aCondition)==RMobilePhone::EBarAllIncoming ||
+ (aCondition)==RMobilePhone::EBarIncomingRoaming );
+ }
+
+inline TBool IsDeactivationConditionOnly( RMobilePhone::TMobilePhoneCBCondition aCondition )
+ {
+ return ( (aCondition)==RMobilePhone::EBarAllCases ||
+ (aCondition)==RMobilePhone::EBarAllOutgoingServices ||
+ (aCondition)==RMobilePhone::EBarAllIncomingServices );
+ }
+
+inline void SplitOneEntryIntoSeparateGroupsL(
+ CMobilePhoneCBList* aCBList,
+ RMobilePhone::TMobilePhoneCBInfoEntryV1 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::TMobilePhoneCBInfoEntryV1 anotherEntry = aOrigEntry;
+
+ // NOTE: A call to CheckSimTsyVersion must be inserted here if there is a
+ // change to the version of the structure declared above
+
+ //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;
+ aCBList->AddEntryL(anotherEntry);
+ }
+ }//end for (another)
+ }
+
+void CSimCallBarring::UpdateCBListL(RMobilePhone::TMobilePhoneCBCondition* aCB, RMobilePhone::TMobilePhoneCBChangeV1* aCBInfo )
+ {
+ /*
+ Updates the status of call barring.
+ @param aCB condition to set
+ @param aCBInfo details of the call barring status to set
+ */
+ // no sense processing if either condition or change info are NULLS
+ User::LeaveIfNull(aCBInfo);
+ User::LeaveIfNull(aCB);
+
+ // check for more conditions as some of the combinations really do not make sense
+ // and no need to do processing in this case
+ if (*aCB == RMobilePhone::EBarUnspecified)
+ User::Leave(KErrArgument);
+ if ( IsDeactivationConditionOnly(*aCB)
+ && ( !( (aCBInfo->iAction == RMobilePhone::EServiceActionDeactivate )
+ || (aCBInfo->iAction == RMobilePhone::EServiceActionErase ))))
+ User::Leave(KErrArgument);
+
+ //Lets do some work then
+ RMobilePhone::TMobilePhoneCBInfoEntryV1 theNewEntry;
+
+ theNewEntry.iCondition = *aCB;
+ theNewEntry.iServiceGroup = aCBInfo->iServiceGroup;
+ switch (aCBInfo->iAction)
+ {
+ case RMobilePhone::EServiceActionRegister:
+ case RMobilePhone::EServiceActionActivate:
+ theNewEntry.iStatus= RMobilePhone::ECallBarringStatusActive;
+ break;
+ case RMobilePhone::EServiceActionDeactivate:
+ case RMobilePhone::EServiceActionErase:
+ theNewEntry.iStatus= RMobilePhone::ECallBarringStatusNotActive;
+ break;
+ case RMobilePhone::EServiceActionUnspecified:
+ default:
+ // no sense doing any further operation - leave
+ User::Leave(KErrArgument);
+ break;
+ }
+
+ // retain prev version of the list in local variable and in Cleanup stack
+ CMobilePhoneCBList* thePrevCBList = CMobilePhoneCBList::NewL();
+ CleanupStack::PushL(thePrevCBList);
+ // copy existing data into the temp storage
+ for (TInt indx=0; indx<iCBList->Enumerate(); indx++)
+ {
+ thePrevCBList->AddEntryL(iCBList->GetEntryL(indx));
+ }
+ delete iCBList;
+ iCBList = NULL;
+ // get a hold of it in a local variable
+ iCBList = CMobilePhoneCBList::NewL();
+ // get a hold of it in a local variable
+ CMobilePhoneCBList* theNewCBList = iCBList;
+ RMobilePhone::TMobilePhoneCBInfoEntryV1 entry;
+
+ TInt count = thePrevCBList->Enumerate();
+
+ if (theNewEntry.iStatus == RMobilePhone::ECallBarringStatusActive)
+ {
+ if (theNewEntry.iServiceGroup==RMobilePhone::EAllServices)
+ {
+ //Activate all conds
+ //action is to ActivateAllServices with a particular condition;
+ //Only copy entries with a different condition
+ for (TInt i = 0; i<count; i++)
+ {
+ entry = thePrevCBList->GetEntryL(i);
+ //check if the new entry will encompass conditions already defined
+ // if it does the existing entry is not needed
+ if (!(
+ theNewEntry.iCondition==entry.iCondition
+ ||
+ ( IsOutgoingCondition(entry.iCondition) && IsOutgoingCondition(theNewEntry.iCondition))
+ ||
+ ( IsIncomingCondition(entry.iCondition) && IsIncomingCondition(theNewEntry.iCondition))
+ ))
+ theNewCBList->AddEntryL(entry);
+ }//end for
+ theNewCBList->AddEntryL(theNewEntry);
+ }
+ else
+ {
+ //ActivateOne;
+ // working under the assumption that if EBarOutgoingInternational is enabled
+ // for EAllServices then setting the fax group, for example to EBarOutgoingInternational
+ // specifically, will be ignored due to inclusion. Also setting the same condition
+ // for the same service group(s) again will be ignored.
+ TBool addNewElem = TRUE;
+
+ for (TInt i = 0; i<count; i++)
+ {
+ entry = thePrevCBList->GetEntryL(i);
+ // are in the same direction?
+ if ( (IsOutgoingCondition(theNewEntry.iCondition) && IsOutgoingCondition(entry.iCondition))
+ || (IsIncomingCondition(theNewEntry.iCondition) && IsIncomingCondition(entry.iCondition)))
+ {
+ // they are in the same direction
+ // is the current entry specific to a group or not ?
+ if (entry.iServiceGroup != RMobilePhone::EAllServices)
+ {
+ if (theNewEntry.iServiceGroup != entry.iServiceGroup)
+ theNewCBList->AddEntryL(entry);
+ }
+ else
+ {
+ // the entry is for all groups
+ if (theNewEntry.iCondition == entry.iCondition)
+ {
+ // the group already precludes this condition;
+ // just add the existing
+ theNewCBList->AddEntryL(entry);
+ addNewElem = FALSE;
+ }
+ else
+ {
+ // we have to split the entry into entries
+ // per group with the same condition
+ SplitOneEntryIntoSeparateGroupsL(
+ theNewCBList, entry, theNewEntry.iServiceGroup
+ );
+ }// end split entry
+ }
+ }
+ else
+ {
+ // they are in different directions
+ // no need to check further; just add it
+ theNewCBList->AddEntryL(entry);
+ }//end are in the same direction?
+ }// for loop
+ if (addNewElem)
+ {
+ theNewCBList->AddEntryL(theNewEntry);
+ }
+ }//end else
+ }
+ else //deactivate
+ {
+ if (
+ (theNewEntry.iServiceGroup==RMobilePhone::EAllServices)
+ &&(theNewEntry.iCondition==RMobilePhone::EBarAllCases)
+ )
+ ;//Deactivate all conditions: do nothing, list is empty.
+ else
+ {
+ for (TInt i = 0; i<count; i++)
+ {
+ entry = thePrevCBList->GetEntryL(i);
+
+ if (theNewEntry.iCondition == RMobilePhone::EBarAllCases
+ ||
+ (( theNewEntry.iCondition == RMobilePhone::EBarAllOutgoingServices || IsOutgoingCondition(theNewEntry.iCondition))
+ && IsOutgoingCondition(entry.iCondition))
+ ||
+ ((theNewEntry.iCondition == RMobilePhone::EBarAllIncomingServices || IsIncomingCondition(theNewEntry.iCondition))
+ && IsIncomingCondition(entry.iCondition)))
+ {
+ if(theNewEntry.iServiceGroup!=RMobilePhone::EAllServices
+ && entry.iServiceGroup==RMobilePhone::EAllServices)
+ {
+ SplitOneEntryIntoSeparateGroupsL(
+ theNewCBList, entry, theNewEntry.iServiceGroup
+ );
+ }//end if(create others)
+ else
+ {//action applies to different service group
+ if((theNewEntry.iServiceGroup!=RMobilePhone::EAllServices )
+ && (theNewEntry.iServiceGroup!=entry.iServiceGroup))
+ theNewCBList->AddEntryL(entry);
+ }
+
+ }//end if
+ else
+ {//action applies to different condition
+ theNewCBList->AddEntryL(entry);
+ }//end else
+ }//end for (entries)
+ }//end else(all)
+ }//end else(deactivate)
+
+ //destroy the previous version, the local theNewCBList will be destroyed
+ CleanupStack::PopAndDestroy(thePrevCBList);
+ }