// 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// signal strength information.// ///** @file*/#include <testconfigfileparser.h>#include "CSimSignalStrength.h"#include "CSimPhone.h"#include "Simlog.h"#include "simtsyglobalproperties.h"const TInt KSignalStrengthGranularity=5; // < Granularity for signal strength list arrayCSimSignalStrength* CSimSignalStrength::NewL(CSimPhone* aPhone)/** * Standard two-phase constructor. * @param aPhone The parent phone object. * @return CSimSignalStrength The new signal strength class. */ { CSimSignalStrength* self=new(ELeave) CSimSignalStrength(aPhone); CleanupStack::PushL(self); self->ConstructL(); CleanupStack::Pop(); return self; }CSimSignalStrength::CSimSignalStrength(CSimPhone* aPhone) : iPhone(aPhone)/** * Trivial first phase construction. * @param aPhone The parent phone object. */ { }void CSimSignalStrength::ConstructL()/** * Second phase construction. Create instances of the necessary heap-based * objects and read in the signal strength information from the configuration file. * Finally, if any signal strength tags have been read, the initial values * will be loaded and the timer started. * * Entries in the configuration file will take the following format: * "SignalStrengthLevel= <duration>, <dB Level>, <Bar Level>" * A number of these entries may be included to create a signal strength profile * for the duration of the test. */ { iTimer=CSimTimer::NewL(iPhone); iSignalStrengthInfo=new(ELeave) CArrayFixFlat<TSignalStrengthInfo>(KSignalStrengthGranularity); LOGSS1("Starting to parse Signal Strength config parameters..."); const CTestConfigItem* item=NULL; TInt ret=KErrNone; item=CfgFile()->Item(KSSNotifyCap); if (item != NULL) { TInt notifyCap; ret = CTestConfig::GetElement(item->Value(),KStdDelimiter,0,notifyCap); if(ret != KErrNone) { iNotifyCapability = 0; } else { iNotifyCapability = notifyCap; } } else { iNotifyCapability = 0; } TInt count=CfgFile()->ItemCount(KSSLevel); TInt i; for(i=0;i<count;i++) { item=CfgFile()->Item(KSSLevel,i); if(!item) break; TInt duration,ss,ssb,err; ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,duration); if(ret!=KErrNone) { LOGPARSERR("duration",ret,0,&KSSLevel); continue; } ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,ss); if(ret!=KErrNone) { LOGPARSERR("ss",ret,1,&KSSLevel); continue; } ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,ssb); if(ret!=KErrNone) { LOGPARSERR("ssb",ret,2,&KSSLevel); continue; } ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,err); if (ret == KErrNotFound) { err = KErrNone; } else { LOGPARSERRANGE("ssb",ret,3,&KSSLevel,"0 or -1"); } TSignalStrengthInfo ssInfo; ssInfo.iDuration=duration; ssInfo.iLevel=ss; ssInfo.iBar=(TInt8)ssb; ssInfo.iErr = err; iSignalStrengthInfo->AppendL(ssInfo); } LOGSS1("...Finished parsing Signal Strength config parameters..."); if(iSignalStrengthInfo->Count()!=0) { iSSIndex=0; iCurrentLevel=iSignalStrengthInfo->At(0).iLevel; iCurrentBar=iSignalStrengthInfo->At(0).iBar; iCurrentError = iSignalStrengthInfo->At(0).iErr; iTimer->Start(iSignalStrengthInfo->At(0).iDuration,this); } //still have to listen on deprecated P&S uids iSignalStrengthChange = CSimPubSubChange::NewL(this, CSimPubSub::TPubSubProperty(KUidSimtsyCategoryLocal, KSimtsySignalStrengthChange, KSimtsySignalStrengthChangeType)); iPSSignalStrengthChange = CSimPubSubChange::NewL(this, CSimPubSub::TPubSubProperty(KUidPSSimTsyCategory, KPSSimTsySignalStrengthChange, KPSSimTsySignalStrengthChangeKeyType)); }CSimSignalStrength::~CSimSignalStrength()/** * Standard destructor. Destroy the heap-based object owned by this object. */ { delete iTimer; delete iSignalStrengthInfo; delete iSignalStrengthChange; delete iPSSignalStrengthChange; }TInt CSimSignalStrength::GetSignalCaps(TTsyReqHandle aReqHandle,TDes8* aPckg1)/** * Retrieve signal strength capability information. This function completes the * client's request synchronously. If the configuration file contains any signal * strength profile information, then it indicates support for signal strength * requests, otherwise it does not. * * @param aReqHandle The request handle associated with this request. * @param aPckg1 The first parameter package. This will be populated with the * capability data to be returned. * @return TInt Standard error value. */ { TPckg<TUint32>* signalCapsPckg=(TPckg<TUint32>*)aPckg1; TUint32& signalCaps=(*signalCapsPckg)(); if (iNotifyCapability != 0) { signalCaps= RMobilePhone::KCapsGetSignalStrength | RMobilePhone::KCapsNotifySignalStrengthChange; } else if(iSignalStrengthInfo->Count()==0) { signalCaps=0; } else if((iSignalStrengthInfo->Count()-1)<=iSSIndex) { signalCaps= RMobilePhone::KCapsGetSignalStrength; } else { signalCaps= RMobilePhone::KCapsGetSignalStrength | RMobilePhone::KCapsNotifySignalStrengthChange; } iPhone->ReqCompleted(aReqHandle,KErrNone); return KErrNone; }TInt CSimSignalStrength::GetSignalStrength(TTsyReqHandle aReqHandle,TDes8* aPckg1, TDes8* aPckg2)/** * Return the current signal strength information. This function completes synchronously. * If the configuration file contains any signal strength profile information, the * request completes successfully, otherwise it completes with KErrNotSupported. * * @param aReqHandle The request handle associated with this request. * @param aPckg1 The first parameter package. This is populated with the signal * strength dB level. * @param aPckg2 The second parameter package. This is populated with the signal * strength bar level. * @return TInt Standard error value. */ { LOGSS1(">>CSimSignalStrength::GetSignalStrength"); TPckg<TInt32>* ssPckg=(TPckg<TInt32>*)aPckg1; TInt32& ss=(*ssPckg)(); TPckg<TInt8>* ssbPckg=(TPckg<TInt8>*)aPckg2; TInt8& ssb=(*ssbPckg)(); if(iSignalStrengthInfo->Count()==0 && iNotifyCapability == 0) { iPhone->ReqCompleted(aReqHandle,KErrNotSupported); return KErrNone; } ss=iCurrentLevel; ssb=iCurrentBar; LOGSS3("<<CSimSignalStrength::GetSignalStrength with level=%d dB and bar=%d",iCurrentLevel,iCurrentBar); iPhone->ReqCompleted(aReqHandle,iCurrentError); return KErrNone; }TInt CSimSignalStrength::NotifySignalStrengthChange(TTsyReqHandle aReqHandle,TDes8* aPckg1, TDes8* aPckg2)/** * Register a client's interest in being notified when the signal strength changes. * This function records the request's parameters and awaits a change in signal * strength before completing. * * @param aPckg1 The first parameter package. This is populated with the signal * strength dB level. * @param aPckg2 The second parameter package. This is populated with the signal * strength bar level. * @return TInt Standard error value. */ { LOGSS1(">>CSimSignalStrength::NotifySignalStrengthChange"); TPckg<TInt32>* ssPckg=(TPckg<TInt32>*)aPckg1; TInt32& ss=(*ssPckg)(); TPckg<TInt8>* ssbPckg=(TPckg<TInt8>*)aPckg2; TInt8& ssb=(*ssbPckg)(); if(iSignalStrengthInfo->Count()==0 && iNotifyCapability == 0) { iPhone->ReqCompleted(aReqHandle,KErrNotSupported); return KErrNone; } __ASSERT_ALWAYS(!iSSChangeNotificationPending,SimPanic(ENotificationReqAlreadyOutstanding)); iSSChangeNotificationPending=ETrue; iSSChangeNotificationReqHandle=aReqHandle; iSSChangeNotificationSSLevel=&ss; iSSChangeNotificationSSBarLevel=&ssb; return KErrNone; }void CSimSignalStrength::NotifySignalStrengthChangeCancel()/** * Cancel a previous request to be notified of a change in signal strength. */ { if(iSSChangeNotificationPending) { LOGSS1("CSimSignalStrength::NotifySignalStrengthChange has been cancelled"); iSSChangeNotificationPending=EFalse; iPhone->ReqCompleted(iSSChangeNotificationReqHandle,KErrCancel); } else LOGSS1("CSimSignalStrength::NotifySignalStrengthChange was not outstanding and hasn't been cancelled"); }void CSimSignalStrength::TimerCallBack(TInt /*aId*/)/** * The timer callback function. This function will be called when the timer * completes. It indicates a change in signal strength settings. So, the new * signal strength settings must be loaded into the member variables representing * the current settings and any pending signal strength notification requests must * be completed. Finally, the next timer is started. * * @param aId This parameter is unused. It is only required for CSimXxx classes * that have more than one timer instance and need to identify which * timer has expired. */ { iSSIndex++; if(iSignalStrengthInfo->Count()<=iSSIndex) return; iCurrentLevel=iSignalStrengthInfo->At(iSSIndex).iLevel; iCurrentBar=iSignalStrengthInfo->At(iSSIndex).iBar; iCurrentError = iSignalStrengthInfo->At(iSSIndex).iErr; if(iSSChangeNotificationPending) { iSSChangeNotificationPending=EFalse; *iSSChangeNotificationSSLevel=iCurrentLevel; *iSSChangeNotificationSSBarLevel=iCurrentBar; LOGSS3("<<CSimSignalStrength::NotifySignalStrengthChange with level=%d dB and bar=%d",iCurrentLevel,iCurrentBar); iPhone->ReqCompleted(iSSChangeNotificationReqHandle,iCurrentError); } iTimer->Start(iSignalStrengthInfo->At(iSSIndex).iDuration,this); }const CTestConfigSection* CSimSignalStrength::CfgFile()/** * Returns a pointer to the current configuration file section. * * @return CTestConfigSection A pointer to the current configuration file section. */ { return iPhone->CfgFile(); }/** * Called by CSimSignalStrengthChange when a signal strength request has been received. * * @param aNewVal The new signal strength value (number of bars) */void CSimSignalStrength::PubSubCallback(TInt aNewVal) { LOGSS2("CSimSignalStrength::SignalStrengthChangeCallBack newVal=%d", aNewVal); if (iCurrentBar == aNewVal) { return; } iCurrentBar = (TInt8) aNewVal; if(iSSChangeNotificationPending) { iSSChangeNotificationPending=EFalse; *iSSChangeNotificationSSLevel=iCurrentLevel; *iSSChangeNotificationSSBarLevel=iCurrentBar; LOGSS3("<<CSimSignalStrength::NotifySignalStrengthChange with level=%d dB and bar=%d",iCurrentLevel,iCurrentBar); iPhone->ReqCompleted(iSSChangeNotificationReqHandle,iCurrentError); } }